source: tags/ms_r16q2/CORE/BufferedFileReader.cxx

Last change on this file was 11844, checked in by westram, 10 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.5 KB
Line 
1// --------------------------------------------------------------------------------
2// Copyright (C) 2000
3// Ralf Westram
4//
5// Permission to use, copy, modify, distribute and sell this software
6// and its documentation for any purpose is hereby granted without fee,
7// provided that the above copyright notice appear in all copies and
8// that both that copyright notice and this permission notice appear
9// in supporting documentation.  Ralf Westram makes no
10// representations about the suitability of this software for any
11// purpose.  It is provided "as is" without express or implied warranty.
12// --------------------------------------------------------------------------------
13
14#include "BufferedFileReader.h"
15#include <cstdlib>
16#include <cstring>
17#include <cerrno>
18#include <smartptr.h>
19
20using namespace std;
21
22void BufferedFileReader::fillBuffer()
23{
24    if (read==BUFFERSIZE) {
25        read = fread(buf, sizeof(buf[0]), BUFFERSIZE, fp);
26        offset = 0;
27    }
28    else {
29        offset = read;
30    }
31}
32
33static char eol[3] = "\n\r";
34static inline bool is_EOL(char c) { return c == eol[0] || c == eol[1]; }
35
36bool BufferedFileReader::getLine_intern(string& line)
37{
38    if (offset==read) return false;
39
40    size_t lineEnd = 0;
41    {
42        size_t  rest   = read-offset;
43        char   *eolPos = (char*)memchr(buf+offset, eol[0], rest);
44
45        if (!eolPos) {
46            eolPos = (char*)memchr(buf+offset, eol[1], rest);
47            if (!eolPos) {
48                lineEnd = read;
49            }
50            else {
51                swap(eol[0], eol[1]);
52                lineEnd = eolPos-buf;
53            }
54        }
55        else {
56            lineEnd = eolPos-buf;
57            if (lineEnd>0 && lineEnd>offset && buf[lineEnd-1] == eol[1]) {
58                swap(eol[0], eol[1]);
59                lineEnd--;
60            }
61        }
62    }
63
64    fb_assert(lineEnd >= offset);
65
66    if (lineEnd<read) { // found end of line char
67        line    = string(buf+offset, lineEnd-offset);
68        char lf = buf[lineEnd];
69
70        offset = lineEnd+1;
71        if (offset == read) fillBuffer();
72
73        if (offset<read) { // otherwise EOF!
74            char nextChar = buf[offset];
75            if (is_EOL(nextChar) && nextChar != lf) offset++; // skip DOS linefeed
76            if (offset == read) fillBuffer();
77        }
78    }
79    else { // reached end of buffer
80        line = string(buf+offset, read-offset);
81        fillBuffer();
82        string rest;
83        if (getLine_intern(rest)) line = line+rest;
84    }
85
86    return true;
87}
88
89string LineReader::lineError(const string& msg) const {
90    static SmartCharPtr buffer;
91    static size_t       allocated = 0;
92
93    const string& source = getFilename();
94
95    size_t len;
96    if (showFilename) {
97        len = msg.length()+source.length()+100;
98    }
99    else {
100        len = msg.length()+100;
101    }
102
103    if (len>allocated) {
104        allocated = len;
105        buffer    = (char*)malloc(allocated);
106    }
107
108    if (showFilename) {
109#if defined(ASSERTION_USED)
110        int printed =
111#endif // ASSERTION_USED
112            sprintf(&*buffer, "%s:%zu: %s", source.c_str(), lineNumber, msg.c_str());
113        fb_assert((size_t)printed < allocated);
114    }
115    else {
116#if defined(ASSERTION_USED)
117        int printed =
118#endif // ASSERTION_USED
119            sprintf(&*buffer, "while reading line #%zu:\n%s", lineNumber, msg.c_str());
120        fb_assert((size_t)printed < allocated);
121    }
122
123    return &*buffer;
124}
125
126void BufferedFileReader::rewind() {
127    errno = 0;
128    std::rewind(fp);
129    fb_assert(errno == 0); // not handled yet
130
131    read = BUFFERSIZE;
132    fillBuffer();
133    reset();
134}
135
Note: See TracBrowser for help on using the repository browser.