source: tags/ms_r17q2/CORE/BufferedFileReader.cxx

Last change on this file was 15176, checked in by westram, 8 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 "arb_mem.h"
16
17#include <cstdlib>
18#include <cstring>
19#include <cerrno>
20#include <smartptr.h>
21
22using namespace std;
23
24void BufferedFileReader::fillBuffer()
25{
26    if (read==BUFFERSIZE) {
27        read = fread(buf, sizeof(buf[0]), BUFFERSIZE, fp);
28        offset = 0;
29    }
30    else {
31        offset = read;
32    }
33}
34
35static char eol[3] = "\n\r";
36static inline bool is_EOL(char c) { return c == eol[0] || c == eol[1]; }
37
38bool BufferedFileReader::getLine_intern(string& line)
39{
40    if (offset==read) return false;
41
42    size_t lineEnd = 0;
43    {
44        size_t  rest   = read-offset;
45        char   *eolPos = (char*)memchr(buf+offset, eol[0], rest);
46
47        if (!eolPos) {
48            eolPos = (char*)memchr(buf+offset, eol[1], rest);
49            if (!eolPos) {
50                lineEnd = read;
51            }
52            else {
53                swap(eol[0], eol[1]);
54                lineEnd = eolPos-buf;
55            }
56        }
57        else {
58            lineEnd = eolPos-buf;
59            if (lineEnd>0 && lineEnd>offset && buf[lineEnd-1] == eol[1]) {
60                swap(eol[0], eol[1]);
61                lineEnd--;
62            }
63        }
64    }
65
66    fb_assert(lineEnd >= offset);
67
68    if (lineEnd<read) { // found end of line char
69        line    = string(buf+offset, lineEnd-offset);
70        char lf = buf[lineEnd];
71
72        offset = lineEnd+1;
73        if (offset == read) fillBuffer();
74
75        if (offset<read) { // otherwise EOF!
76            char nextChar = buf[offset];
77            if (is_EOL(nextChar) && nextChar != lf) offset++; // skip DOS linefeed
78            if (offset == read) fillBuffer();
79        }
80    }
81    else { // reached end of buffer
82        line = string(buf+offset, read-offset);
83        fillBuffer();
84        string rest;
85        if (getLine_intern(rest)) line = line+rest;
86    }
87
88    return true;
89}
90
91string LineReader::lineError(const string& msg) const {
92    static SmartCharPtr buffer;
93    static size_t       allocated = 0;
94
95    const string& source = getFilename();
96
97    size_t len;
98    if (showFilename) {
99        len = msg.length()+source.length()+100;
100    }
101    else {
102        len = msg.length()+100;
103    }
104
105    if (len>allocated) {
106        allocated = len;
107        buffer    = ARB_alloc<char>(allocated);
108    }
109
110    if (showFilename) {
111#if defined(ASSERTION_USED)
112        int printed =
113#endif // ASSERTION_USED
114            sprintf(&*buffer, "%s:%zu: %s", source.c_str(), lineNumber, msg.c_str());
115        fb_assert((size_t)printed < allocated);
116    }
117    else {
118#if defined(ASSERTION_USED)
119        int printed =
120#endif // ASSERTION_USED
121            sprintf(&*buffer, "while reading line #%zu:\n%s", lineNumber, msg.c_str());
122        fb_assert((size_t)printed < allocated);
123    }
124
125    return &*buffer;
126}
127
128void BufferedFileReader::rewind() {
129    errno = 0;
130    std::rewind(fp);
131    fb_assert(errno == 0); // not handled yet
132
133    read = BUFFERSIZE;
134    fillBuffer();
135    reset();
136}
137
Note: See TracBrowser for help on using the repository browser.