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

Proposed by Paul J. Lucas
Status: Merged
Approved by: Chris Hillery
Approved revision: 10957
Merged at revision: 10953
Proposed branch: lp:~zorba-coders/zorba/bug-878508
Merge into: lp:zorba
Diff against target: 359 lines (+169/-65)
9 files modified
ChangeLog (+1/-0)
src/api/serialization/serializer.cpp (+2/-42)
src/runtime/json/jsonml_array.cpp (+3/-2)
src/runtime/json/snelson.cpp (+5/-18)
src/util/CMakeLists.txt (+1/-0)
src/util/json_util.cpp (+85/-0)
src/util/json_util.h (+72/-0)
test/rbkt/ExpQueryResults/zorba/jsoniq/supplemental_plane.xml.res (+0/-1)
test/rbkt/Queries/zorba/jsoniq/supplemental_plane.xq (+0/-2)
To merge this branch: bzr merge lp:~zorba-coders/zorba/bug-878508
Reviewer Review Type Date Requested Status
Chris Hillery Approve
Paul J. Lucas Approve
Review via email: mp+116781@code.launchpad.net

Commit message

Now properly serializing JSON for JsonML.

Description of the change

Now properly serializing JSON for JsonML.

To post a comment you must log in.
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-878508-2012-07-25T23-46-57.424Z 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: 1 Approve.

lp:~zorba-coders/zorba/bug-878508 updated
10956. By Paul J. Lucas

Now emitting JSON supplemental plane characters as ordinary UTF-8.

10957. By Paul J. Lucas

Added ZORBA_JSON_EMIT_SURROGATES.

Revision history for this message
Chris Hillery (ceejatec) :
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-878508-2012-07-26T07-37-01.736Z 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-07-24 08:48:48 +0000
3+++ ChangeLog 2012-07-26 04:33:22 +0000
4@@ -50,6 +50,7 @@
5 var folding into if-then-else)
6 * Fixed bug #1006166 (disabling 2 functions with the same qname)
7 * Fixed bug #960083 (improper error handling of NaN comparisons)
8+ * Fixed bug #878508 (JsonML serialization not escaping characters)
9 * Xml-format plan serialization not supported anymore.
10
11
12
13=== modified file 'src/api/serialization/serializer.cpp'
14--- src/api/serialization/serializer.cpp 2012-07-25 00:15:29 +0000
15+++ src/api/serialization/serializer.cpp 2012-07-26 04:33:22 +0000
16@@ -31,9 +31,9 @@
17 #include "api/unmarshaller.h"
18
19 #include "util/ascii_util.h"
20+#include "util/json_util.h"
21 #include "util/string_util.h"
22 #include "util/unicode_util.h"
23-#include "util/utf8_string.h"
24 #include "util/utf8_util.h"
25 #include "util/xml_util.h"
26
27@@ -1208,47 +1208,7 @@
28 ********************************************************************************/
29 void serializer::json_emitter::emit_json_string(zstring const &string)
30 {
31- tr << '"';
32- utf8_string<zstring const> const u( string );
33- FOR_EACH( utf8_string<zstring const>, i, u ) {
34- unicode::code_point const cp = *i;
35- if ( ascii::is_cntrl( cp ) ) {
36- switch ( cp ) {
37- case '\b': tr << "\\b"; break;
38- case '\f': tr << "\\f"; break;
39- case '\n': tr << "\\n"; break;
40- case '\r': tr << "\\r"; break;
41- case '\t': tr << "\\t"; break;
42- default: {
43- std::ostringstream oss;
44- oss << std::hex << std::setfill('0') << "\\u" << std::setw(4) << cp;
45- tr << oss.str();
46- }
47- }
48- continue;
49- }
50- if ( unicode::is_supplementary_plane( cp ) ) {
51- unsigned high, low;
52- unicode::convert_surrogate( cp, &high, &low );
53- std::ostringstream oss;
54- oss << std::hex << std::setfill('0')
55- << "\\u" << std::setw(4) << high
56- << "\\u" << std::setw(4) << low;
57- tr << oss.str();
58- continue;
59- }
60- switch ( cp ) {
61- case '\\':
62- case '"':
63- tr << '\\';
64- // no break;
65- default: {
66- utf8::encoded_char_type ec;
67- tr.write( ec, utf8::encode( cp, ec ) );
68- }
69- }
70- }
71- tr << '"';
72+ tr << '"' << json::serialize( string ) << '"';
73 }
74
75
76
77=== modified file 'src/runtime/json/jsonml_array.cpp'
78--- src/runtime/json/jsonml_array.cpp 2012-07-24 08:48:48 +0000
79+++ src/runtime/json/jsonml_array.cpp 2012-07-26 04:33:22 +0000
80@@ -26,6 +26,7 @@
81 #include "util/ascii_util.h"
82 #include "util/cxx_util.h"
83 #include "util/json_parser.h"
84+#include "util/json_util.h"
85 #include "util/mem_streambuf.h"
86 #include "util/omanip.h"
87 #include "util/oseparator.h"
88@@ -199,7 +200,7 @@
89
90 o << '"' << att_name << '"'
91 << if_emit( ws, ' ' ) << ':' << if_emit( ws, ' ' )
92- << '"' << att_item->getStringValue() << '"';
93+ << '"' << json::serialize( att_item->getStringValue() ) << '"';
94 }
95 i->close();
96 if ( emitted_attributes )
97@@ -242,7 +243,7 @@
98 o << sep << serialize_element( child, sep, ws );
99 break;
100 case store::StoreConsts::textNode:
101- o << sep << '"' << child->getStringValue() << '"';
102+ o << sep << '"' << json::serialize( child->getStringValue() ) << '"';
103 break;
104 default:
105 break;
106
107=== modified file 'src/runtime/json/snelson.cpp'
108--- src/runtime/json/snelson.cpp 2012-02-14 03:41:58 +0000
109+++ src/runtime/json/snelson.cpp 2012-07-26 04:33:22 +0000
110@@ -16,6 +16,7 @@
111 #include "stdafx.h"
112
113 #include <sstream>
114+#include <string>
115
116 #include <zorba/diagnostic_list.h>
117
118@@ -27,6 +28,7 @@
119 #include "util/cxx_util.h"
120 #include "util/indent.h"
121 #include "util/json_parser.h"
122+#include "util/json_util.h"
123 #include "util/mem_streambuf.h"
124 #include "util/omanip.h"
125 #include "util/oseparator.h"
126@@ -85,16 +87,6 @@
127 #define POP_ITEM_ELEMENT() \
128 if ( !IN_STATE( in_array ) ) ; else POP_ITEM()
129
130-static void escape_json_chars( zstring *s ) {
131- ascii::replace_all( *s, "\"", 1, "\\\"", 2 );
132- ascii::replace_all( *s, "\\", 1, "\\\\", 2 );
133- ascii::replace_all( *s, "\b", 1, "\\b", 2 );
134- ascii::replace_all( *s, "\f", 1, "\\f", 2 );
135- ascii::replace_all( *s, "\n", 1, "\\n", 2 );
136- ascii::replace_all( *s, "\r", 1, "\\r", 2 );
137- ascii::replace_all( *s, "\t", 1, "\\t", 2 );
138-}
139-
140 ///////////////////////////////////////////////////////////////////////////////
141
142 namespace snelson {
143@@ -172,10 +164,6 @@
144 case json::token::string:
145 ADD_TYPE_ATTRIBUTE( "string" );
146 value = token.get_value();
147-#if 0
148- escape_json_chars( &value );
149-#endif
150-
151 if ( next_string_is_key ) {
152 // <pair name="..." ...>
153 GENV_ITEMFACTORY->createQName( element_name, SNELSON_NS, "", "pair" );
154@@ -344,10 +332,9 @@
155 DEF_OMANIP1( serialize_number, zstring const& )
156
157 static ostream& serialize_string( ostream &o, zstring const &s ) {
158- zstring temp( s );
159- escape_json_chars( &temp );
160- temp.insert( (zstring::size_type)0, 1, '"' );
161- temp.append( 1, '"' );
162+ ostringstream oss;
163+ oss << '"' << json::serialize( s ) << '"';
164+ string const temp( oss.str() );
165 assert_json_type( json::string, temp );
166 return o << temp;
167 }
168
169=== modified file 'src/util/CMakeLists.txt'
170--- src/util/CMakeLists.txt 2012-07-24 08:48:48 +0000
171+++ src/util/CMakeLists.txt 2012-07-26 04:33:22 +0000
172@@ -21,6 +21,7 @@
173 fs_util.cpp
174 indent.cpp
175 json_parser.cpp
176+ json_util.cpp
177 mem_streambuf.cpp
178 regex.cpp
179 string_util.cpp
180
181=== added file 'src/util/json_util.cpp'
182--- src/util/json_util.cpp 1970-01-01 00:00:00 +0000
183+++ src/util/json_util.cpp 2012-07-26 04:33:22 +0000
184@@ -0,0 +1,85 @@
185+/*
186+ * Copyright 2006-2008 The FLWOR Foundation.
187+ *
188+ * Licensed under the Apache License, Version 2.0 (the "License");
189+ * you may not use this file except in compliance with the License.
190+ * You may obtain a copy of the License at
191+ *
192+ * http://www.apache.org/licenses/LICENSE-2.0
193+ *
194+ * Unless required by applicable law or agreed to in writing, software
195+ * distributed under the License is distributed on an "AS IS" BASIS,
196+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
197+ * See the License for the specific language governing permissions and
198+ * limitations under the License.
199+ */
200+
201+#include <iomanip>
202+#include <iostream>
203+
204+//#define ZORBA_JSON_EMIT_SURROGATES
205+
206+#include "util/stl_util.h"
207+#ifdef ZORBA_JSON_EMIT_SURROGATES
208+#include "util/unicode_util.h"
209+#endif /* ZORBA_JSON_EMIT_SURROGATES */
210+#include "util/utf8_util.h"
211+
212+using namespace std;
213+
214+namespace zorba {
215+namespace json {
216+
217+///////////////////////////////////////////////////////////////////////////////
218+
219+ostream& serialize( ostream &os, char const *s ) {
220+ while ( true ) {
221+ unicode::code_point const cp = utf8::next_char( s );
222+ if ( !cp )
223+ break;
224+ if ( ascii::is_cntrl( cp ) ) {
225+ switch ( cp ) {
226+ case '\b': os << "\\b"; break;
227+ case '\f': os << "\\f"; break;
228+ case '\n': os << "\\n"; break;
229+ case '\r': os << "\\r"; break;
230+ case '\t': os << "\\t"; break;
231+ default: {
232+ std::ostringstream oss;
233+ oss << std::hex << std::setfill('0') << "\\u" << std::setw(4) << cp;
234+ os << oss.str();
235+ }
236+ }
237+ continue;
238+ }
239+#ifdef ZORBA_JSON_EMIT_SURROGATES
240+ if ( unicode::is_supplementary_plane( cp ) ) {
241+ unsigned high, low;
242+ unicode::convert_surrogate( cp, &high, &low );
243+ std::ostringstream oss;
244+ oss << std::hex << std::setfill('0')
245+ << "\\u" << std::setw(4) << high
246+ << "\\u" << std::setw(4) << low;
247+ os << oss.str();
248+ continue;
249+ }
250+#endif /* ZORBA_JSON_EMIT_SURROGATES */
251+ switch ( cp ) {
252+ case '\\':
253+ case '"':
254+ os << '\\';
255+ // no break;
256+ default: {
257+ utf8::encoded_char_type ec;
258+ os.write( ec, utf8::encode( cp, ec ) );
259+ }
260+ }
261+ }
262+ return os;
263+}
264+
265+///////////////////////////////////////////////////////////////////////////////
266+
267+} // namespace json
268+} // namespace zorba
269+/* vim:set et sw=2 ts=2: */
270
271=== added file 'src/util/json_util.h'
272--- src/util/json_util.h 1970-01-01 00:00:00 +0000
273+++ src/util/json_util.h 2012-07-26 04:33:22 +0000
274@@ -0,0 +1,72 @@
275+/*
276+ * Copyright 2006-2008 The FLWOR Foundation.
277+ *
278+ * Licensed under the Apache License, Version 2.0 (the "License");
279+ * you may not use this file except in compliance with the License.
280+ * You may obtain a copy of the License at
281+ *
282+ * http://www.apache.org/licenses/LICENSE-2.0
283+ *
284+ * Unless required by applicable law or agreed to in writing, software
285+ * distributed under the License is distributed on an "AS IS" BASIS,
286+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
287+ * See the License for the specific language governing permissions and
288+ * limitations under the License.
289+ */
290+
291+#ifndef ZORBA_JSON_UTIL_H
292+#define ZORBA_JSON_UTIL_H
293+
294+#include <iostream>
295+
296+#include <zorba/config.h>
297+
298+#include "string_util.h"
299+#include "omanip.h"
300+
301+namespace zorba {
302+namespace json {
303+
304+///////////////////////////////////////////////////////////////////////////////
305+
306+/**
307+ * Serializes the given string as a valid JSON string: any characters that must
308+ * be escaped are escaped.
309+ *
310+ * @param os The ostream to serialize to.
311+ * @param s The C string to serialize as JSON.
312+ * @return Returns \a os.
313+ */
314+std::ostream& serialize( std::ostream &os, char const *s );
315+
316+// An ostream manipulator version of the above.
317+DEF_OMANIP1( serialize, char const* )
318+
319+/**
320+ * Serializes the given string as a valid JSON string: any characters that must
321+ * be escaped are escaped.
322+ *
323+ * @tparam The string type.
324+ * @param os The ostream to serialize to.
325+ * @param s The string to serialize as JSON.
326+ * @return Returns \a os.
327+ */
328+template<class StringType> inline
329+typename std::enable_if<ztd::has_c_str<StringType,
330+ char const* (StringType::*)() const>::value,
331+ std::ostream&>::type
332+serialize( std::ostream &os, StringType const &s ) {
333+ return serialize( os, s.c_str() );
334+}
335+
336+// An ostream manipulator version of the above.
337+template<class StringType>
338+DEF_OMANIP1( serialize, StringType const& )
339+
340+///////////////////////////////////////////////////////////////////////////////
341+
342+} // namespace json
343+} // namespace zorba
344+
345+#endif /* ZORBA_JSON_UTIL_H */
346+/* vim:set et sw=2 ts=2: */
347
348=== removed file 'test/rbkt/ExpQueryResults/zorba/jsoniq/supplemental_plane.xml.res'
349--- test/rbkt/ExpQueryResults/zorba/jsoniq/supplemental_plane.xml.res 2012-07-19 00:13:14 +0000
350+++ test/rbkt/ExpQueryResults/zorba/jsoniq/supplemental_plane.xml.res 1970-01-01 00:00:00 +0000
351@@ -1,1 +0,0 @@
352-{ "string" : "\ud83d\udc4a" }
353
354=== removed file 'test/rbkt/Queries/zorba/jsoniq/supplemental_plane.xq'
355--- test/rbkt/Queries/zorba/jsoniq/supplemental_plane.xq 2012-07-19 00:13:14 +0000
356+++ test/rbkt/Queries/zorba/jsoniq/supplemental_plane.xq 1970-01-01 00:00:00 +0000
357@@ -1,2 +0,0 @@
358-let $s := "&#128074;"
359-return { "string": $s }

Subscribers

People subscribed via source and target branches