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

Proposed by Matthias Brantner
Status: Merged
Approved by: Paul J. Lucas
Approved revision: 10755
Merged at revision: 10766
Proposed branch: lp:~zorba-coders/zorba/bug-921458
Merge into: lp:zorba
Diff against target: 291 lines (+222/-5)
7 files modified
ChangeLog (+1/-0)
modules/org/expath/ns/file.xq (+1/-5)
modules/org/expath/ns/file.xq.src/file.cpp (+118/-0)
modules/org/expath/ns/file.xq.src/file.h (+64/-0)
modules/org/expath/ns/file.xq.src/file_module.cpp (+2/-0)
test/rbkt/ExpQueryResults/zorba/file/file_read_text_lines.xml.res (+32/-0)
test/rbkt/Queries/zorba/file/file_read_text_lines.xq (+4/-0)
To merge this branch: bzr merge lp:~zorba-coders/zorba/bug-921458
Reviewer Review Type Date Requested Status
Paul J. Lucas Approve
William Candillon Approve
Review via email: mp+102058@code.launchpad.net

This proposal supersedes a proposal from 2012-04-13.

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 : Posted in a previous version of this proposal
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

Works great.

review: Approve
Revision history for this message
Paul J. Lucas (paul-lucas) wrote : Posted in a previous version of this proposal

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) : Posted in a previous version of this proposal
review: Needs Fixing
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

Revision history for this message
William Candillon (wcandillon) :
review: Approve
Revision history for this message
Paul J. Lucas (paul-lucas) :
review: Approve
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-16T14-47-08.502Z is finished. The final status was:

All tests succeeded!

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-14 06:12:29 +0000
3+++ ChangeLog 2012-04-16 07:12:21 +0000
4@@ -21,6 +21,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-14 01:36:33 +0000
15+++ modules/org/expath/ns/file.xq 2012-04-16 07:12:21 +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-30 19:03:09 +0000
32+++ modules/org/expath/ns/file.xq.src/file.cpp 2012-04-16 07:12:21 +0000
33@@ -223,6 +223,124 @@
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+ if (theStream->bad())
130+ {
131+ return false;
132+ }
133+ else
134+ {
135+ aRes = theFunc->theModule->getItemFactory()->createString(lStr);
136+ return true;
137+ }
138+}
139+
140+void
141+ReadTextLinesFunction::LinesItemSequence::LinesIterator::close()
142+{
143+ delete theStream;
144+ theStream = 0;
145+}
146+
147+bool
148+ReadTextLinesFunction::LinesItemSequence::LinesIterator::isOpen() const
149+{
150+ return theStream != 0;
151+}
152+
153+//*****************************************************************************
154+
155 ExistsFunction::ExistsFunction(const FileModule* aModule)
156 : FileFunction(aModule)
157 {
158
159=== modified file 'modules/org/expath/ns/file.xq.src/file.h'
160--- modules/org/expath/ns/file.xq.src/file.h 2012-03-30 19:03:09 +0000
161+++ modules/org/expath/ns/file.xq.src/file.h 2012-04-16 07:12:21 +0000
162@@ -316,6 +316,70 @@
163
164 //*****************************************************************************
165
166+ class ReadTextLinesFunction : public FileFunction
167+ {
168+ public:
169+ ReadTextLinesFunction(const FileModule* aModule);
170+
171+ virtual String
172+ getLocalName() const { return "read-text-lines"; }
173+
174+ virtual ItemSequence_t
175+ evaluate(const ExternalFunction::Arguments_t& args,
176+ const StaticContext* aSctxCtx,
177+ const DynamicContext* aDynCtx) const;
178+
179+ protected:
180+ class LinesItemSequence : public ItemSequence
181+ {
182+ protected:
183+ File_t theFile;
184+ String theEncoding;
185+ const ReadTextLinesFunction* theFunc;
186+
187+ class LinesIterator : public Iterator
188+ {
189+ protected:
190+ const File_t& theFile;
191+ const String& theEncoding;
192+ const ReadTextLinesFunction* theFunc;
193+
194+ std::ifstream* theStream;
195+
196+ public:
197+ LinesIterator(
198+ const File_t&,
199+ const String&,
200+ const ReadTextLinesFunction*);
201+
202+ virtual ~LinesIterator();
203+
204+ virtual void
205+ open();
206+
207+ virtual bool
208+ next(Item&);
209+
210+ virtual void
211+ close();
212+
213+ virtual bool
214+ isOpen() const;
215+ };
216+
217+ public:
218+ LinesItemSequence(
219+ const File_t& aFile,
220+ const String& aEncoding,
221+ const ReadTextLinesFunction*);
222+
223+ Iterator_t
224+ getIterator();
225+ };
226+ };
227+
228+//*****************************************************************************
229+
230 class WriteTextFunction : public WriterFileFunction
231 {
232 public:
233
234=== modified file 'modules/org/expath/ns/file.xq.src/file_module.cpp'
235--- modules/org/expath/ns/file.xq.src/file_module.cpp 2012-03-30 19:03:09 +0000
236+++ modules/org/expath/ns/file.xq.src/file_module.cpp 2012-04-16 07:12:21 +0000
237@@ -46,6 +46,8 @@
238 lFunc = new ReadBinaryFunction(this);
239 } else if (aLocalname == "read-text") {
240 lFunc = new ReadTextFunction(this);
241+ } else if (aLocalname == "read-text-lines") {
242+ lFunc = new ReadTextLinesFunction(this);
243 } else if (aLocalname == "exists") {
244 lFunc = new ExistsFunction(this);
245 } else if (aLocalname == "is-directory") {
246
247=== added file 'test/rbkt/ExpQueryResults/zorba/file/file_read_text_lines.xml.res'
248--- test/rbkt/ExpQueryResults/zorba/file/file_read_text_lines.xml.res 1970-01-01 00:00:00 +0000
249+++ test/rbkt/ExpQueryResults/zorba/file/file_read_text_lines.xml.res 2012-04-16 07:12:21 +0000
250@@ -0,0 +1,32 @@
251+&lt;products&gt;
252+ &lt;product&gt;
253+ &lt;name&gt;broiler&lt;/name&gt;
254+ &lt;category&gt;kitchen&lt;/category&gt;
255+ &lt;price&gt;100&lt;/price&gt;
256+ &lt;cost&gt;70&lt;/cost&gt;
257+ &lt;/product&gt;
258+ &lt;product&gt;
259+ &lt;name&gt;toaster&lt;/name&gt;
260+ &lt;category&gt;kitchen&lt;/category&gt;
261+ &lt;price&gt;30&lt;/price&gt;
262+ &lt;cost&gt;10&lt;/cost&gt;
263+ &lt;/product&gt;
264+ &lt;product&gt;
265+ &lt;name&gt;blender&lt;/name&gt;
266+ &lt;category&gt;kitchen&lt;/category&gt;
267+ &lt;price&gt;50&lt;/price&gt;
268+ &lt;cost&gt;25&lt;/cost&gt;
269+ &lt;/product&gt;
270+ &lt;product&gt;
271+ &lt;name&gt;socks&lt;/name&gt;
272+ &lt;category&gt;clothes&lt;/category&gt;
273+ &lt;price&gt;10&lt;/price&gt;
274+ &lt;cost&gt;2&lt;/cost&gt;
275+ &lt;/product&gt;
276+ &lt;product&gt;
277+ &lt;name&gt;shirt&lt;/name&gt;
278+ &lt;category&gt;clothes&lt;/category&gt;
279+ &lt;price&gt;10&lt;/price&gt;
280+ &lt;cost&gt;3&lt;/cost&gt;
281+ &lt;/product&gt;
282+&lt;/products&gt;
283
284=== added file 'test/rbkt/Queries/zorba/file/file_read_text_lines.xq'
285--- test/rbkt/Queries/zorba/file/file_read_text_lines.xq 1970-01-01 00:00:00 +0000
286+++ test/rbkt/Queries/zorba/file/file_read_text_lines.xq 2012-04-16 07:12:21 +0000
287@@ -0,0 +1,4 @@
288+import module namespace file = "http://expath.org/ns/file";
289+
290+string-join(file:read-text-lines(fn:resolve-uri("mydata.xml")), '
291+')

Subscribers

People subscribed via source and target branches