blob: 7161111f0d3785420e6c55ef7f0199436c430175 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Adaptor.hh"
#include "gzip.hh"
#include <iostream>
#include <stdexcept>
#ifdef __clang__
#pragma clang diagnostic ignored "-Wold-style-cast"
#endif
namespace orc {
GzipTextReader::GzipTextReader(const std::string& _filename
): filename(_filename) {
file = fopen(filename.c_str(), "rb");
if (file == nullptr) {
throw std::runtime_error("can't open " + filename);
}
stream.zalloc = nullptr;
stream.zfree = nullptr;
stream.opaque = nullptr;
stream.avail_in = 0;
stream.avail_out = 1;
stream.next_in = nullptr;
int ret = inflateInit2(&stream, 16+MAX_WBITS);
if (ret != Z_OK) {
throw std::runtime_error("zlib failed initialization for " + filename);
}
outPtr = nullptr;
outEnd = nullptr;
isDone = false;
}
bool GzipTextReader::nextBuffer() {
// if we are done, return
if (isDone) {
return false;
}
// if the last read is done, read more
if (stream.avail_in == 0 && stream.avail_out != 0) {
stream.next_in = input;
stream.avail_in = static_cast<unsigned>(fread(input, 1, sizeof(input),
file));
if (ferror(file)) {
throw std::runtime_error("failure reading " + filename);
}
}
stream.avail_out = sizeof(output);
stream.next_out = output;
int ret = inflate(&stream, Z_NO_FLUSH);
switch (ret) {
case Z_OK:
break;
case Z_STREAM_END:
isDone = true;
break;
case Z_STREAM_ERROR:
throw std::runtime_error("zlib stream problem");
case Z_NEED_DICT:
case Z_DATA_ERROR:
throw std::runtime_error("zlib data problem");
case Z_MEM_ERROR:
throw std::runtime_error("zlib memory problem");
case Z_BUF_ERROR:
throw std::runtime_error("zlib buffer problem");
default:
throw std::runtime_error("zlib unknown problem");
}
outPtr = output;
outEnd = output + (sizeof(output) - stream.avail_out);
return true;
}
bool GzipTextReader::nextLine(std::string& line) {
bool result = false;
line.clear();
while (true) {
if (outPtr == outEnd) {
if (!nextBuffer()) {
return result;
}
}
unsigned char ch = *(outPtr++);
if (ch == '\n') {
return true;
}
line += static_cast<char>(ch);
}
}
GzipTextReader::~GzipTextReader() {
inflateEnd(&stream);
if (fclose(file) != 0) {
std::cerr << "can't close file " << filename;
}
}
}