source: tags/old_import_filter/CORE/FileBuffer.cxx

Last change on this file was 8916, checked in by westram, 12 years ago
  • fixed cppcheck warnings
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.6 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 "FileBuffer.h"
15#include <cstdlib>
16#include <cstring>
17#include <cerrno>
18#include <smartptr.h>
19
20using namespace std;
21
22void FileBuffer::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 FileBuffer::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        // cppcheck-suppress redundantOperationIn (fails to track 'offset' and 'read' modified by fillBuffer)
74        if (offset<read) { // otherwise EOF!
75            char nextChar = buf[offset];
76            if (is_EOL(nextChar) && nextChar != lf) offset++; // skip DOS linefeed
77            if (offset == read) fillBuffer();
78        }
79    }
80    else { // reached end of buffer
81        line = string(buf+offset, read-offset);
82        fillBuffer();
83        string rest;
84        if (getLine_intern(rest)) line = line+rest;
85    }
86
87    return true;
88}
89
90string FileBuffer::lineError(const string& msg) const {
91    static SmartCharPtr buffer;
92    static size_t  allocated = 0;
93
94    size_t len;
95    if (showFilename) {
96        len = msg.length()+filename.length()+100;
97    }
98    else {
99        len = msg.length()+100;
100    }
101
102    if (len>allocated) {
103        allocated = len;
104        buffer    = (char*)malloc(allocated);
105    }
106
107    if (showFilename) {
108#if defined(ASSERTION_USED)
109        int printed =
110#endif // ASSERTION_USED
111            sprintf(&*buffer, "%s:%zu: %s", filename.c_str(), lineNumber, msg.c_str());
112        fb_assert((size_t)printed < allocated);
113    }
114    else {
115#if defined(ASSERTION_USED)
116        int printed =
117#endif // ASSERTION_USED
118            sprintf(&*buffer, "while reading line #%zu:\n%s", lineNumber, msg.c_str());
119        fb_assert((size_t)printed < allocated);
120    }
121
122    return &*buffer;
123}
124
125void FileBuffer::rewind() {
126    errno = 0;
127    std::rewind(fp);
128    fb_assert(errno == 0); // not handled yet
129
130    read = BUFFERSIZE;
131    fillBuffer();
132
133    if (next_line) {
134        delete next_line;
135        next_line = 0;
136    }
137    lineNumber = 0;
138}
139
Note: See TracBrowser for help on using the repository browser.