1
// ================================================================ //
3
// File : FileBuffer.cxx //
6
// Coded by Ralf Westram (coder@reallysoft.de) in December 2006 //
7
// Institute of Microbiology (Technical University Munich) //
8
// http://www.arb-home.de/ //
10
// ================================================================ //
12
#include "FileBuffer.h"
20
void FileBuffer::fillBuffer()
22
if (read==BUFFERSIZE) {
23
read = fread(buf, sizeof(buf[0]), BUFFERSIZE, fp);
31
static char eol[3] = "\n\r";
32
static inline bool is_EOL(char c) { return c == eol[0] || c == eol[1]; }
34
bool FileBuffer::getLine_intern(string& line)
36
if (offset==read) return false;
40
size_t rest = read-offset;
41
char *eolPos = (char*)memchr(buf+offset, eol[0], rest);
44
eolPos = (char*)memchr(buf+offset, eol[1], rest);
55
if (lineEnd>0 && buf[lineEnd-1] == eol[1]) {
62
if (lineEnd<read) { // found end of line char
63
line = string(buf+offset, lineEnd-offset);
64
char lf = buf[lineEnd];
67
if (offset == read) fillBuffer();
69
if (offset<read) { // otherwise EOF!
70
char nextChar = buf[offset];
71
if (is_EOL(nextChar) && nextChar != lf) offset++; // skip DOS linefeed
72
if (offset == read) fillBuffer();
75
else { // reached end of buffer
76
line = string(buf+offset, read-offset);
79
if (getLine_intern(rest)) line = line+rest;
85
string FileBuffer::lineError(const char *msg) {
87
static size_t allocated = 0;
91
len = strlen(msg)+filename.length()+100;
94
len = strlen(msg)+100;
100
buffer = (char*)malloc(allocated);
107
sprintf(buffer, "while reading %s (line #%li):\n%s", filename.c_str(), lineNumber, msg);
108
fb_assert((size_t)printed < allocated);
114
sprintf(buffer, "while reading line #%li:\n%s", lineNumber, msg);
115
fb_assert((size_t)printed < allocated);
121
void FileBuffer::rewind() {
124
fb_assert(errno == 0); // not handled yet
136
// --------------------------------------------------------------------------------
139
inline FileBuffer *to_FileBuffer(FILE_BUFFER fb) {
140
FileBuffer *fileBuffer = reinterpret_cast<FileBuffer*>(fb);
141
fb_assert(fileBuffer);
142
fb_assert(fileBuffer->good());
146
extern "C" FILE_BUFFER create_FILE_BUFFER(const char *filename, FILE *in) {
147
FileBuffer *fb = new FileBuffer(filename, in);
148
return reinterpret_cast<FILE_BUFFER>(fb);
151
extern "C" void destroy_FILE_BUFFER(FILE_BUFFER file_buffer) {
152
delete to_FileBuffer(file_buffer);
155
extern "C" const char *FILE_BUFFER_read(FILE_BUFFER file_buffer, size_t *lengthPtr) {
158
if (to_FileBuffer(file_buffer)->getLine(line)) {
159
if (lengthPtr) *lengthPtr = line.length();
165
extern "C" void FILE_BUFFER_back(FILE_BUFFER file_buffer, const char *backline) {
168
to_FileBuffer(file_buffer)->backLine(line);
171
extern "C" void FILE_BUFFER_rewind(FILE_BUFFER file_buffer) {
172
to_FileBuffer(file_buffer)->rewind();