ARB
BufferedFileReader.cxx
Go to the documentation of this file.
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 
22 using namespace std;
23 
24 void BufferedFileReader::fillBuffer() {
25  if (read==BUFFERSIZE) {
26  read = fread(buf, sizeof(buf[0]), BUFFERSIZE, fp);
27  offset = 0;
28  }
29  else {
30  offset = read;
31  }
32 }
33 
34 static char eol[3] = "\n\r";
35 static inline bool is_EOL(char c) { return c == eol[0] || c == eol[1]; }
36 
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 
89 string 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 = ARB_alloc<char>(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 
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 
return string(buffer, length)
bool getLine_intern(string &line) OVERRIDE
STL namespace.
char buffer[MESSAGE_BUFFERSIZE]
Definition: seq_search.cxx:34
string lineError(const string &msg) const
CONSTEXPR_INLINE_Cxx14 void swap(unsigned char &c1, unsigned char &c2)
Definition: ad_io_inline.h:19
static bool is_EOL(char c)
#define fb_assert(cond)
const size_t BUFFERSIZE
static char eol[3]
static int line
Definition: arb_a2ps.c:296
#define offset(field)
Definition: GLwDrawA.c:73