Qore Programming Language  1.12.0
InputStreamLineIterator.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  InputStreamLineIterator.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2016 - 2022 Qore Technologies, s.r.o.
8 
9  Permission is hereby granted, free of charge, to any person obtaining a
10  copy of this software and associated documentation files (the "Software"),
11  to deal in the Software without restriction, including without limitation
12  the rights to use, copy, modify, merge, publish, distribute, sublicense,
13  and/or sell copies of the Software, and to permit persons to whom the
14  Software is furnished to do so, subject to the following conditions:
15 
16  The above copyright notice and this permission notice shall be included in
17  all copies or substantial portions of the Software.
18 
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25  DEALINGS IN THE SOFTWARE.
26 
27  Note that the Qore library is released under a choice of three open-source
28  licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
29  information.
30 */
31 
32 #ifndef _QORE_INPUTSTREAMLINEITERATOR_H
33 #define _QORE_INPUTSTREAMLINEITERATOR_H
34 
35 #include <cerrno>
36 #include <cstring>
37 
38 #include "qore/InputStream.h"
39 #include "qore/intern/BufferedStreamReader.h"
40 #include "qore/intern/StreamReader.h"
41 #include "qore/intern/EncodingConversionInputStream.h"
42 
47 public:
48  DLLLOCAL InputStreamLineIterator(ExceptionSink* xsink, InputStream* is, const QoreEncoding* encoding, const QoreStringNode* n_eol, bool n_trim, size_t bufsize = DefaultStreamBufferSize) :
49  src(is, xsink),
50  reader(xsink),
51  enc(encoding),
52  line(0),
53  eol(0),
54  num(0),
55  validp(false),
56  trim(n_trim)
57  {
58  if (assignEol(n_eol, xsink))
59  return;
60 
61  // reference src for assignment to BufferedStreamReader
62  src->ref();
63  reader = new BufferedStreamReader(xsink, *src, enc, bufsize);
64  }
65 
66  DLLLOCAL InputStreamLineIterator(ExceptionSink* xsink, StreamReader* sr, const QoreStringNode* n_eol = 0, bool n_trim = true) :
67  src(xsink),
68  reader(sr, xsink),
69  enc(sr->getEncoding()),
70  line(0),
71  eol(0),
72  num(0),
73  validp(false),
74  trim(n_trim)
75  {
76  if (assignEol(n_eol, xsink))
77  return;
78 
79  // update the stream reader's encoding if necessary
80  if (enc != sr->getEncoding())
81  sr->setEncoding(enc);
82  }
83 
84  DLLLOCAL ~InputStreamLineIterator() {
85  if (eol)
86  eol->deref();
87  if (line)
88  line->deref();
89  }
90 
91  DLLLOCAL bool next(ExceptionSink* xsink) {
92  // Make sure to use a new string if the iterator was already valid.
93  if (validp && line && !line->empty()) {
94  line->deref();
95  line = 0;
96  }
97  validp = getLine(xsink);
98  if (validp) {
99  ++num; // Increment line number.
100  }
101  else {
102  num = 0; // Reset iterator.
103  }
104  //printd(5, "InputStreamLineIterator::next() this: %p line: %d offset: %lld validp: %d '%s'\n", this, num, offset, validp, line->getBuffer());
105  return validp;
106  }
107 
108  DLLLOCAL int64 index() const {
109  return num;
110  }
111 
112  DLLLOCAL QoreStringNode* getValue() {
113  assert(validp);
114  return line ? line->stringRefSelf() : nullptr;
115  }
116 
117  DLLLOCAL bool valid() const {
118  return validp;
119  }
120 
121  DLLLOCAL int checkValid(ExceptionSink* xsink) const {
122  if (!validp) {
123  xsink->raiseException("ITERATOR-ERROR", "the %s is not pointing at a valid element; make sure %s::next() returns True before calling this method", getName(), getName());
124  return -1;
125  }
126  return 0;
127  }
128 
129  DLLLOCAL StreamReader* getStreamReader() {
130  return *reader;
131  }
132 
133  DLLLOCAL const QoreEncoding* getEncoding() const {
134  return enc;
135  }
136 
137  DLLLOCAL virtual void deref() {
138  if (ROdereference())
139  delete this;
140  }
141 
142  DLLLOCAL virtual const char* getName() const { return "InputStreamLineIterator"; }
143 
144  DLLLOCAL virtual const QoreTypeInfo* getElementType() const {
145  return stringTypeInfo;
146  }
147 
148 private:
149  DLLLOCAL int assignEol(const QoreStringNode* n_eol, ExceptionSink* xsink) {
150  if (!n_eol || n_eol->empty())
151  return 0;
152  if (enc != n_eol->getEncoding()) {
153  SimpleRefHolder<QoreStringNode> neol(n_eol->convertEncoding(enc, xsink));
154  if (*xsink)
155  return -1;
156  eol = q_remove_bom_utf16(neol.release(), enc);
157  }
158  else {
159  eol = n_eol->stringRefSelf();
160  }
161  return 0;
162  }
163 
164  DLLLOCAL bool getLine(ExceptionSink* xsink) {
165  if (line)
166  line->deref();
167  line = reader->readLine(eol, trim, xsink);
168  return (line != 0);
169  }
170 
171 private:
174  const QoreEncoding* enc;
175  QoreStringNode* line;
176  QoreStringNode* eol;
177  int64 num;
178  bool validp;
179  bool trim;
180 };
181 
182 #endif // _QORE_INPUTSTREAMLINEITERATOR_H
DLLLOCAL void ref() const
increments the reference count of the object
Definition: AbstractPrivateData.h:51
Private data for the Qore::BufferedStreamReader class.
Definition: BufferedStreamReader.h:45
container for holding Qore-language exception information and also for registering a "thread_exit" ca...
Definition: ExceptionSink.h:48
DLLEXPORT AbstractQoreNode * raiseException(const char *err, const char *fmt,...)
appends a Qore-language exception to the list
Interface for private data of input streams.
Definition: InputStream.h:44
Private data for the Qore::InputStreamLineIterator class.
Definition: InputStreamLineIterator.h:46
virtual DLLLOCAL void deref()
decrements the reference count of the object without the possibility of throwing a Qore-language exce...
Definition: InputStreamLineIterator.h:137
defines string encoding functions in Qore
Definition: QoreEncoding.h:83
abstract base class for iterator private data
Definition: QoreIteratorBase.h:68
DLLEXPORT bool ROdereference() const
atomically decrements the reference count
DLLEXPORT bool empty() const
returns true if the string is empty, false if not
DLLEXPORT const QoreEncoding * getEncoding() const
returns the encoding for the string
Qore's string value type, reference counted, dynamically-allocated only.
Definition: QoreStringNode.h:50
DLLEXPORT QoreStringNode * stringRefSelf() const
references the object and returns a non-const pointer to "this"
DLLEXPORT QoreStringNode * convertEncoding(const QoreEncoding *nccs, ExceptionSink *xsink) const
converts the encoding of the string to the specified encoding, returns 0 if an error occurs,...
Private data for the Qore::StreamReader class.
Definition: StreamReader.h:45
DLLLOCAL QoreStringNode * readLine(const QoreStringNode *eol, bool trim, ExceptionSink *xsink)
Read one line.
Definition: StreamReader.h:119
long long int64
64bit integer type, cannot use int64_t here since it breaks the API on some 64-bit systems due to equ...
Definition: common.h:260