Merge lp:~zorba-coders/zorba/bug-921458 into lp:zorba

Proposed by Matthias Brantner
Status: Superseded
Proposed branch: lp:~zorba-coders/zorba/bug-921458
Merge into: lp:zorba
Diff against target: 239 lines (+180/-5)
5 files modified
ChangeLog (+1/-0)
modules/org/expath/ns/file.xq (+1/-5)
modules/org/expath/ns/file.xq.src/file.cpp (+112/-0)
modules/org/expath/ns/file.xq.src/file.h (+64/-0)
modules/org/expath/ns/file.xq.src/file_module.cpp (+2/-0)
To merge this branch: bzr merge lp:~zorba-coders/zorba/bug-921458
Reviewer Review Type Date Requested Status
Paul J. Lucas Needs Fixing
William Candillon Approve
Review via email: mp+101873@code.launchpad.net

This proposal has been superseded by a proposal from 2012-04-16.

Commit message

Fix for bug #921458 (file:read-text-lines() blocking)

Description of the change

Fix for bug #921458 (file:read-text-lines() blocking)

The problem was that the string:split function isn't suitable for tokenizing with newlines as separator.

I have provided a native implementation using C++'s getline.

To post a comment you must log in.
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue job bug-921458-2012-04-13T09-53-08.237Z is finished. The final status was:

All tests succeeded!

Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Voting does not meet specified criteria. Required: Approve > 1, Disapprove < 1, Needs Fixing < 1, Pending < 1. Got: 2 Pending.

Revision history for this message
William Candillon (wcandillon) wrote :

Works great.

review: Approve
Revision history for this message
Paul J. Lucas (paul-lucas) wrote :

Required: After your call to getline(), you should check the state of the stream again for badbit.

Optional: you ought to use std::unique_ptr for the stream member so you don't have to delete it explicitly.

Revision history for this message
Paul J. Lucas (paul-lucas) :
review: Needs Fixing
lp:~zorba-coders/zorba/bug-921458 updated
10755. By Matthias Brantner

- check for badbit after reading from stream
- added a test

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2--- ChangeLog 2012-04-12 09:32:55 +0000
3+++ ChangeLog 2012-04-13 09:06:22 +0000
4@@ -18,6 +18,7 @@
5 * Fixed bug #872234 (prevent a rewritting to take place in case of sequential expr)
6 * Fixed bug #906494 (default compile with D_FILE_OFFSET_BITS=64)
7 * Fixed bug #912586, #912593 and #912722 (assertion failures with lax validation)
8+ * Fixed bug #921458 (file:read-text-lines() blocking)
9 * Fixed bug #949910 (has-children may be invoked on all nodes). Internally, zorba::store::Item::getChildren() now returns NULL on node classes without offspring (instead of raising an error).
10
11
12
13=== modified file 'modules/org/expath/ns/file.xq'
14--- modules/org/expath/ns/file.xq 2012-04-11 09:14:41 +0000
15+++ modules/org/expath/ns/file.xq 2012-04-13 09:06:22 +0000
16@@ -422,11 +422,7 @@
17 declare %an:nondeterministic function file:read-text-lines(
18 $file as xs:string,
19 $encoding as xs:string
20-) as xs:string*
21-{
22- let $content := file:read-text($file, $encoding)
23- return fn:tokenize($content, "\n")
24-};
25+) as xs:string* external;
26
27 (:~
28 : This is an internal function that copies an entire source directory to an
29
30=== modified file 'modules/org/expath/ns/file.xq.src/file.cpp'
31--- modules/org/expath/ns/file.xq.src/file.cpp 2012-03-28 05:19:57 +0000
32+++ modules/org/expath/ns/file.xq.src/file.cpp 2012-04-13 09:06:22 +0000
33@@ -223,6 +223,118 @@
34
35 //*****************************************************************************
36
37+ReadTextLinesFunction::ReadTextLinesFunction(const FileModule* aModule)
38+ : FileFunction(aModule)
39+{
40+}
41+
42+ItemSequence_t
43+ReadTextLinesFunction::evaluate(
44+ const ExternalFunction::Arguments_t& aArgs,
45+ const StaticContext* aSctxCtx,
46+ const DynamicContext* aDynCtx) const
47+{
48+ String lFileStr = getFilePathString(aArgs, 0);
49+ File_t lFile = File::createFile(lFileStr.c_str());
50+ String lEncoding("UTF-8");
51+
52+ // preconditions
53+ if (!lFile->exists()) {
54+ raiseFileError("FOFL0001", "A file does not exist at this path", lFile->getFilePath());
55+ }
56+ if (lFile->isDirectory()) {
57+ raiseFileError("FOFL0004", "The given path points to a directory", lFile->getFilePath());
58+ }
59+
60+ lEncoding = getEncodingArg(aArgs, 1);
61+
62+ return ItemSequence_t(new LinesItemSequence(lFile, lEncoding, this));
63+}
64+
65+ReadTextLinesFunction::LinesItemSequence::LinesItemSequence(
66+ const File_t& aFile,
67+ const String& aEncoding,
68+ const ReadTextLinesFunction* aFunc)
69+ : theFile(aFile),
70+ theEncoding(aEncoding),
71+ theFunc(aFunc)
72+{
73+}
74+
75+Iterator_t
76+ReadTextLinesFunction::LinesItemSequence::getIterator()
77+{
78+ return new ReadTextLinesFunction::LinesItemSequence::LinesIterator(
79+ theFile, theEncoding, theFunc
80+ );
81+}
82+
83+ReadTextLinesFunction::LinesItemSequence::LinesIterator::LinesIterator(
84+ const File_t& aFile,
85+ const String& aEncoding,
86+ const ReadTextLinesFunction* aFunc)
87+ : theFile(aFile),
88+ theEncoding(aEncoding),
89+ theFunc(aFunc),
90+ theStream(0)
91+{
92+}
93+
94+ReadTextLinesFunction::LinesItemSequence::LinesIterator::~LinesIterator()
95+{
96+ delete theStream;
97+}
98+
99+void
100+ReadTextLinesFunction::LinesItemSequence::LinesIterator::open()
101+{
102+ if ( transcode::is_necessary( theEncoding.c_str() ) )
103+ {
104+ try
105+ {
106+ theStream = new transcode::stream<std::ifstream>(theEncoding.c_str());
107+ }
108+ catch (std::invalid_argument const& e)
109+ {
110+ theFunc->raiseFileError("FOFL0006", "Unsupported encoding", theEncoding.c_str());
111+ }
112+ }
113+ else
114+ {
115+ theStream = new std::ifstream();
116+ }
117+ theFile->openInputStream(*theStream, false, true);
118+}
119+
120+bool
121+ReadTextLinesFunction::LinesItemSequence::LinesIterator::next(Item& aRes)
122+{
123+ if (!theStream || !theStream->good())
124+ return false;
125+
126+ std::string lStr;
127+ getline(*theStream, lStr);
128+
129+ aRes = theFunc->theModule->getItemFactory()->createString(lStr);
130+
131+ return true;
132+}
133+
134+void
135+ReadTextLinesFunction::LinesItemSequence::LinesIterator::close()
136+{
137+ delete theStream;
138+ theStream = 0;
139+}
140+
141+bool
142+ReadTextLinesFunction::LinesItemSequence::LinesIterator::isOpen() const
143+{
144+ return theStream != 0;
145+}
146+
147+//*****************************************************************************
148+
149 ExistsFunction::ExistsFunction(const FileModule* aModule)
150 : FileFunction(aModule)
151 {
152
153=== modified file 'modules/org/expath/ns/file.xq.src/file.h'
154--- modules/org/expath/ns/file.xq.src/file.h 2012-03-28 05:19:57 +0000
155+++ modules/org/expath/ns/file.xq.src/file.h 2012-04-13 09:06:22 +0000
156@@ -316,6 +316,70 @@
157
158 //*****************************************************************************
159
160+ class ReadTextLinesFunction : public FileFunction
161+ {
162+ public:
163+ ReadTextLinesFunction(const FileModule* aModule);
164+
165+ virtual String
166+ getLocalName() const { return "read-text-lines"; }
167+
168+ virtual ItemSequence_t
169+ evaluate(const ExternalFunction::Arguments_t& args,
170+ const StaticContext* aSctxCtx,
171+ const DynamicContext* aDynCtx) const;
172+
173+ protected:
174+ class LinesItemSequence : public ItemSequence
175+ {
176+ protected:
177+ File_t theFile;
178+ String theEncoding;
179+ const ReadTextLinesFunction* theFunc;
180+
181+ class LinesIterator : public Iterator
182+ {
183+ protected:
184+ const File_t& theFile;
185+ const String& theEncoding;
186+ const ReadTextLinesFunction* theFunc;
187+
188+ std::ifstream* theStream;
189+
190+ public:
191+ LinesIterator(
192+ const File_t&,
193+ const String&,
194+ const ReadTextLinesFunction*);
195+
196+ virtual ~LinesIterator();
197+
198+ virtual void
199+ open();
200+
201+ virtual bool
202+ next(Item&);
203+
204+ virtual void
205+ close();
206+
207+ virtual bool
208+ isOpen() const;
209+ };
210+
211+ public:
212+ LinesItemSequence(
213+ const File_t& aFile,
214+ const String& aEncoding,
215+ const ReadTextLinesFunction*);
216+
217+ Iterator_t
218+ getIterator();
219+ };
220+ };
221+
222+//*****************************************************************************
223+
224 class WriteTextFunction : public WriterFileFunction
225 {
226 public:
227
228=== modified file 'modules/org/expath/ns/file.xq.src/file_module.cpp'
229--- modules/org/expath/ns/file.xq.src/file_module.cpp 2012-03-28 05:19:57 +0000
230+++ modules/org/expath/ns/file.xq.src/file_module.cpp 2012-04-13 09:06:22 +0000
231@@ -46,6 +46,8 @@
232 lFunc = new ReadBinaryFunction(this);
233 } else if (aLocalname == "read-text") {
234 lFunc = new ReadTextFunction(this);
235+ } else if (aLocalname == "read-text-lines") {
236+ lFunc = new ReadTextLinesFunction(this);
237 } else if (aLocalname == "exists") {
238 lFunc = new ExistsFunction(this);
239 } else if (aLocalname == "is-directory") {

Subscribers

People subscribed via source and target branches