Qore Programming Language 1.14.0
Loading...
Searching...
No Matches
InputStreamLineIterator.h
1/* -*- mode: c++; indent-tabs-mode: nil -*- */
2/*
3 InputStreamLineIterator.h
4
5 Qore Programming Language
6
7 Copyright (C) 2016 - 2023 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
47public:
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
148private:
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
171private:
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:50
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 const QoreEncoding * getEncoding() const
returns the encoding for the string
DLLEXPORT bool empty() const
returns true if the string is empty, false if not
Qore's string value type, reference counted, dynamically-allocated only.
Definition: QoreStringNode.h:50
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,...
DLLEXPORT QoreStringNode * stringRefSelf() const
references the object and returns a non-const pointer to "this"
a templated class to manage a reference count of an object that can throw a Qore-language exception w...
Definition: ReferenceHolder.h:52
manages a reference count of a pointer to a class that takes a simple "deref()" call with no argument...
Definition: ReferenceHolder.h:127
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:126
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