Merge lp:~zorba-coders/zorba/feature-json_parser into lp:zorba

Proposed by Sorin Marian Nasoi
Status: Superseded
Proposed branch: lp:~zorba-coders/zorba/feature-json_parser
Merge into: lp:zorba
Diff against target: 5924 lines (+5008/-67)
113 files modified
include/zorba/diagnostic.h (+4/-1)
include/zorba/pregenerated/diagnostic_list.h (+32/-0)
modules/com/zorba-xquery/www/modules/CMakeLists.txt (+4/-0)
modules/com/zorba-xquery/www/modules/converters/json-options.xsd (+60/-0)
modules/com/zorba-xquery/www/modules/converters/json.xq (+175/-0)
modules/com/zorba-xquery/www/modules/pregenerated/errors.xq (+65/-1)
src/context/static_context.cpp (+5/-0)
src/context/static_context.h (+1/-0)
src/diagnostics/diagnostic.cpp (+3/-0)
src/diagnostics/diagnostic_en.xml (+62/-0)
src/diagnostics/pregenerated/diagnostic_list.cpp (+48/-0)
src/diagnostics/pregenerated/dict_en.cpp (+18/-0)
src/diagnostics/qname.cpp (+6/-0)
src/functions/library.cpp (+2/-0)
src/functions/pregenerated/func_json.cpp (+87/-0)
src/functions/pregenerated/func_json.h (+79/-0)
src/functions/pregenerated/function_enum.h (+2/-0)
src/runtime/CMakeLists.txt (+3/-0)
src/runtime/full_text/ft_match.cpp (+2/-3)
src/runtime/json/common.cpp (+62/-0)
src/runtime/json/common.h (+118/-0)
src/runtime/json/json_impl.cpp (+216/-0)
src/runtime/json/jsonml_array.cpp (+281/-0)
src/runtime/json/jsonml_array.h (+41/-0)
src/runtime/json/pregenerated/json.cpp (+94/-0)
src/runtime/json/pregenerated/json.h (+114/-0)
src/runtime/json/snelson.cpp (+498/-0)
src/runtime/json/snelson.h (+41/-0)
src/runtime/spec/json/json.xml (+52/-0)
src/runtime/spec/mappings.xml (+4/-0)
src/runtime/visitors/pregenerated/planiter_visitor.h (+10/-0)
src/runtime/visitors/pregenerated/printer_visitor.cpp (+29/-0)
src/runtime/visitors/pregenerated/printer_visitor.h (+6/-0)
src/unit_tests/CMakeLists.txt (+1/-0)
src/unit_tests/json_parser.cpp (+636/-0)
src/unit_tests/unit_test_list.h (+1/-0)
src/unit_tests/unit_tests.cpp (+1/-0)
src/util/CMakeLists.txt (+2/-0)
src/util/json_parser.cpp (+653/-0)
src/util/json_parser.h (+561/-0)
src/util/mem_streambuf.cpp (+119/-0)
src/util/mem_streambuf.h (+108/-0)
src/util/omanip.h (+205/-57)
src/util/oseparator.h (+17/-5)
test/rbkt/ExpQueryResults/zorba/json/json-jsonml_array-parse-01.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-jsonml_array-parse-02.xml.res (+4/-0)
test/rbkt/ExpQueryResults/zorba/json/json-jsonml_array-parse-03.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-jsonml_array-parse-wikipedia.xml.res (+10/-0)
test/rbkt/ExpQueryResults/zorba/json/json-jsonml_array-serialize-01.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-jsonml_array-serialize-02.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-jsonml_array-serialize-03.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-jsonml_array-serialize-indent-wikipedia.xml.res (+11/-0)
test/rbkt/ExpQueryResults/zorba/json/json-jsonml_array-serialize-none-wikipedia.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-jsonml_array-serialize-some-wikipedia.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-parse-array-01.xml.res (+3/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-parse-array-02.xml.res (+3/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-parse-array-03.xml.res (+3/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-parse-array-04.xml.res (+3/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-parse-array-05.xml.res (+4/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-parse-example.xml.res (+14/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-parse-object-01.xml.res (+3/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-parse-object-02.xml.res (+4/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-serialize-array-01.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-serialize-array-02.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-serialize-array-03.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-serialize-array-04.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-serialize-array-05.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-serialize-indent-example.xml.res (+11/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-serialize-none-example.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-serialize-object-01.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-serialize-object-02.xml.res (+1/-0)
test/rbkt/ExpQueryResults/zorba/json/json-snelson-serialize-some-example.xml.res (+1/-0)
test/rbkt/Queries/zorba/json/json-jsonml_array-parse-01.xq (+9/-0)
test/rbkt/Queries/zorba/json/json-jsonml_array-parse-02.xq (+14/-0)
test/rbkt/Queries/zorba/json/json-jsonml_array-parse-03.xq (+18/-0)
test/rbkt/Queries/zorba/json/json-jsonml_array-parse-wikipedia.xq (+23/-0)
test/rbkt/Queries/zorba/json/json-jsonml_array-serialize-01.xq (+10/-0)
test/rbkt/Queries/zorba/json/json-jsonml_array-serialize-02.xq (+13/-0)
test/rbkt/Queries/zorba/json/json-jsonml_array-serialize-03.xq (+10/-0)
test/rbkt/Queries/zorba/json/json-jsonml_array-serialize-indent-wikipedia.xq (+20/-0)
test/rbkt/Queries/zorba/json/json-jsonml_array-serialize-none-wikipedia.xq (+19/-0)
test/rbkt/Queries/zorba/json/json-jsonml_array-serialize-some-wikipedia.xq (+20/-0)
test/rbkt/Queries/zorba/json/json-snelson-parse-array-01.xq (+5/-0)
test/rbkt/Queries/zorba/json/json-snelson-parse-array-02.xq (+5/-0)
test/rbkt/Queries/zorba/json/json-snelson-parse-array-03.xq (+5/-0)
test/rbkt/Queries/zorba/json/json-snelson-parse-array-04.xq (+5/-0)
test/rbkt/Queries/zorba/json/json-snelson-parse-array-05.xq (+5/-0)
test/rbkt/Queries/zorba/json/json-snelson-parse-example.xq (+20/-0)
test/rbkt/Queries/zorba/json/json-snelson-parse-object-01.xq (+5/-0)
test/rbkt/Queries/zorba/json/json-snelson-parse-object-02.xq (+5/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-01.xq (+8/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-02.xq (+8/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-03.xq (+8/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-04.xq (+8/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-05.xq (+9/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-06.spec (+1/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-06.xq (+8/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-07.spec (+1/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-07.xq (+8/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-08.spec (+1/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-08.xq (+8/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-09.spec (+1/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-09.xq (+8/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-10.spec (+1/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-10.xq (+8/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-11.spec (+1/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-array-11.xq (+8/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-indent-example.xq (+24/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-none-example.xq (+19/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-object-01.xq (+8/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-object-02.xq (+9/-0)
test/rbkt/Queries/zorba/json/json-snelson-serialize-some-example.xq (+24/-0)
test/unit/CMakeLists.txt (+1/-0)
To merge this branch: bzr merge lp:~zorba-coders/zorba/feature-json_parser
Reviewer Review Type Date Requested Status
William Candillon Needs Fixing
Paul J. Lucas Pending
Sorin Marian Nasoi Pending
Review via email: mp+89008@code.launchpad.net

This proposal has been superseded by a proposal from 2012-01-23.

Commit message

New JSON parser and module.
Fixed the missing quote in the documentation.

Description of the change

New JSON parser and module.
Fixed the missing quote in the documentation.

To post a comment you must log in.
Revision history for this message
Sorin Marian Nasoi (sorin.marian.nasoi) wrote :

I have resubmitted the merge proposal after committing the fix for the JSON tests.

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

The documentation is missing some examples.
The example section at http://docs.basex.org/wiki/JSON_Module is a good place to get inspired.

Why A chars have a backslash in error code descriptions:
ZJSE0001 if \a $xml is not a document or element node.
ZJSE0002 if \a $xml contains an element that is missing a required attribute.
ZJSE0003 if \a $xml contains an attribute having an illegal value.
ZJSE0004 if \a $xml contains an illegal element.
ZJSE0005 if \a $xml contains an illegal child element for a JSON type.
ZJSE0006 if \a $xml contains an illegal child element.
ZJSE0007 if \a $xml contains an illegal text node.
ZJSE0008 if \a $xml contains an illegal value for a JSON type.

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

The \a is the doxygen way to say the following thing is an argument and should be italicized.

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

Doesn't seem to work for xqdoc

10614. By Paul J. Lucas

Removed \a and \c.

10615. By Paul J. Lucas

Added checking of stream state.

10616. By Paul J. Lucas

Merge from trunk.

10617. By Paul J. Lucas

1. Added yet more documentation.
2. Added %ann:streamable.

10618. By Sorin Marian Nasoi <email address hidden>

Added some tests that are marked as EXPECTED_FAILURES with their corresponding Launchpad bugs.

10619. By Sorin Marian Nasoi <email address hidden>

Fixed the following XQDoc issues:
- added module Author
- added correct category
- added examples for all 4 functions
- added zerr:ZJPE0006

10620. By Paul J. Lucas

Merge from trunk.

10621. By Paul J. Lucas

Removed virtually useless and potentially wrong EXPECTED_FAILURES.

10622. By Paul J. Lucas

Added missing "return".

10623. By Paul J. Lucas

Added missing "return".

10624. By Paul J. Lucas

Renamed tests to conform to rest; fixed missing "return" (again).

10625. By Paul J. Lucas

Merge from trunk.

10626. By Paul J. Lucas

Re-enabled test.

10627. By Paul J. Lucas

Updated test for new JSON module options schema.

10628. By Paul J. Lucas

1. Added ZJPE0009 error ("illegal empty string").
2. Now checking for empty strings in module parse() functions.
3. Added json::parser::peek().

10629. By Paul J. Lucas

Test clean-up.

10630. By Paul J. Lucas

Fixed more bugs.

10631. By Paul J. Lucas

Merge from trunk.

10632. By Paul J. Lucas

Added T_const_ptr.

10633. By Paul J. Lucas

s/optimal_arg/call_traits/

10634. By Paul J. Lucas

Added T_const_ptr.

10635. By Sorin Marian Nasoi <email address hidden>

The new core JSON module version 2.0 also fixes a bug reported against the deprecated version 1.0 external JSON module:
lp:878508.

10636. By Paul J. Lucas

Merge from trunk.

10637. By Markos Zaharioudakis

fixed bug #920717

10638. By Paul J. Lucas

Clean-up.

10639. By Paul J. Lucas

Merge from trunk.

10640. By Paul J. Lucas

Yet another fix.

10641. By Paul J. Lucas

Yet another bug fixed.

10642. By Paul J. Lucas

Merge from trunk.

10643. By Paul J. Lucas

Merge from trunk.

10644. By Paul J. Lucas

More documentation.

10645. By Paul J. Lucas

Merge from trunk.

10646. By Paul J. Lucas

Added yet more examples to JSON documentation.

10647. By Paul J. Lucas

Clean-up; new test.

10648. By Paul J. Lucas

Fixed bug 930573.

10649. By Paul J. Lucas

Merge from trunk.

10650. By Paul J. Lucas

Removed data-converters tag.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/zorba/diagnostic.h'
--- include/zorba/diagnostic.h 2011-07-01 16:07:54 +0000
+++ include/zorba/diagnostic.h 2012-01-23 00:53:24 +0000
@@ -239,7 +239,10 @@
239 ZORBA_DEBUGGER, // Zorba Debugger239 ZORBA_DEBUGGER, // Zorba Debugger
240 ZORBA_OS, // Operating System240 ZORBA_OS, // Operating System
241 ZORBA_SERIALIZATION,241 ZORBA_SERIALIZATION,
242 ZORBA_STORE242 ZORBA_STORE,
243
244 JSON_PARSER,
245 JSON_SERIALIZATION
243};246};
244247
245/**248/**
246249
=== modified file 'include/zorba/pregenerated/diagnostic_list.h'
--- include/zorba/pregenerated/diagnostic_list.h 2011-12-21 14:40:33 +0000
+++ include/zorba/pregenerated/diagnostic_list.h 2012-01-23 00:53:24 +0000
@@ -746,6 +746,38 @@
746746
747extern ZORBA_DLL_PUBLIC ZorbaErrorCode XSST0010;747extern ZORBA_DLL_PUBLIC ZorbaErrorCode XSST0010;
748748
749extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJPE0001_ILLEGAL_CHARACTER;
750
751extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJPE0002_ILLEGAL_CODEPOINT;
752
753extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJPE0003_ILLEGAL_ESCAPE;
754
755extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJPE0004_ILLEGAL_LITERAL;
756
757extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJPE0005_ILLEGAL_NUMBER;
758
759extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJPE0006_UNEXPECTED_TOKEN;
760
761extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJPE0007_UNTERMINATED_STRING;
762
763extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJPE0008_ILLEGAL_QNAME;
764
765extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJSE0001_NOT_DOCUMENT_OR_ELEMENT_NODE;
766
767extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJSE0002_ELEMENT_MISSING_ATTRIBUTE;
768
769extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJSE0003_BAD_ATTRIBUTE_VALUE;
770
771extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJSE0004_BAD_ELEMENT;
772
773extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJSE0005_BAD_CHILD_ELEMENT;
774
775extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJSE0006_NO_ELEMENT_CHILD;
776
777extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJSE0007_NO_TEXT_CHILD;
778
779extern ZORBA_DLL_PUBLIC ZorbaErrorCode ZJSE0008_BAD_VALUE;
780
749} // namespace zerr781} // namespace zerr
750782
751namespace zwarn {783namespace zwarn {
752784
=== modified file 'modules/com/zorba-xquery/www/modules/CMakeLists.txt'
--- modules/com/zorba-xquery/www/modules/CMakeLists.txt 2012-01-11 17:30:25 +0000
+++ modules/com/zorba-xquery/www/modules/CMakeLists.txt 2012-01-23 00:53:24 +0000
@@ -68,6 +68,10 @@
68# Subdirectories68# Subdirectories
69DECLARE_ZORBA_MODULE(FILE converters/base64.xq VERSION 2.069DECLARE_ZORBA_MODULE(FILE converters/base64.xq VERSION 2.0
70 URI "http://www.zorba-xquery.com/modules/converters/base64")70 URI "http://www.zorba-xquery.com/modules/converters/base64")
71DECLARE_ZORBA_MODULE(FILE converters/json.xq VERSION 2.0
72 URI "http://www.zorba-xquery.com/modules/converters/json")
73DECLARE_ZORBA_SCHEMA(FILE converters/json-options.xsd
74 URI "http://www.zorba-xquery.com/modules/converters/json-options")
71DECLARE_ZORBA_MODULE(FILE introspection/sctx.xq VERSION 2.075DECLARE_ZORBA_MODULE(FILE introspection/sctx.xq VERSION 2.0
72 URI "http://www.zorba-xquery.com/modules/introspection/sctx")76 URI "http://www.zorba-xquery.com/modules/introspection/sctx")
73DECLARE_ZORBA_MODULE(FILE xqdoc2xhtml/error.xq VERSION 2.077DECLARE_ZORBA_MODULE(FILE xqdoc2xhtml/error.xq VERSION 2.0
7478
=== added file 'modules/com/zorba-xquery/www/modules/converters/json-options.xsd'
--- modules/com/zorba-xquery/www/modules/converters/json-options.xsd 1970-01-01 00:00:00 +0000
+++ modules/com/zorba-xquery/www/modules/converters/json-options.xsd 2012-01-23 00:53:24 +0000
@@ -0,0 +1,60 @@
1<!--
2 ! Copyright 2006-2008 The FLWOR Foundation.
3 !
4 ! Licensed under the Apache License, Version 2.0 (the "License");
5 ! you may not use this file except in compliance with the License.
6 ! You may obtain a copy of the License at
7 !
8 ! http://www.apache.org/licenses/LICENSE-2.0
9 !
10 ! Unless required by applicable law or agreed to in writing, software
11 ! distributed under the License is distributed on an "AS IS" BASIS,
12 ! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ! See the License for the specific language governing permissions and
14 ! limitations under the License.
15-->
16
17<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
18 xmlns:json="http://www.zorba-xquery.com/modules/converters/json-options"
19 targetNamespace="http://www.zorba-xquery.com/modules/converters/json-options"
20 elementFormDefault="qualified"
21 attributeFormDefault="unqualified">
22
23 <xs:element name="options">
24 <xs:complexType>
25 <xs:all>
26
27 <xs:element name="json-format" minOccurs="1" maxOccurs="1">
28 <xs:complexType>
29 <xs:attribute name="value" use="required">
30 <xs:simpleType>
31 <xs:restriction base="xs:string">
32 <xs:enumeration value="Snelson"/>
33 <xs:enumeration value="JsonML-array"/>
34 <xs:enumeration value="JsonML-object"/>
35 </xs:restriction>
36 </xs:simpleType>
37 </xs:attribute>
38 </xs:complexType>
39 </xs:element>
40
41 <xs:element name="whitespace" minOccurs="0" maxOccurs="1">
42 <xs:complexType>
43 <xs:attribute name="value" use="required">
44 <xs:simpleType>
45 <xs:restriction base="xs:string">
46 <xs:enumeration value="none"/>
47 <xs:enumeration value="some"/>
48 <xs:enumeration value="indent"/>
49 </xs:restriction>
50 </xs:simpleType>
51 </xs:attribute>
52 </xs:complexType>
53 </xs:element>
54
55 </xs:all>
56 </xs:complexType>
57 </xs:element>
58</xs:schema>
59
60<!-- vim:set et sw=2 ts=2: -->
061
=== added file 'modules/com/zorba-xquery/www/modules/converters/json.xq'
--- modules/com/zorba-xquery/www/modules/converters/json.xq 1970-01-01 00:00:00 +0000
+++ modules/com/zorba-xquery/www/modules/converters/json.xq 2012-01-23 00:53:24 +0000
@@ -0,0 +1,175 @@
1(:
2 : Copyright 2006-2009 The FLWOR Foundation.
3 :
4 : Licensed under the Apache License, Version 2.0 (the "License");
5 : you may not use this file except in compliance with the License.
6 : You may obtain a copy of the License at
7 :
8 : http://www.apache.org/licenses/LICENSE-2.0
9 :
10 : Unless required by applicable law or agreed to in writing, software
11 : distributed under the License is distributed on an "AS IS" BASIS,
12 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : See the License for the specific language governing permissions and
14 : limitations under the License.
15 :)
16
17xquery version "3.0";
18
19 (:~
20 : Using this module, you can parse JSON data into XML, manipulate it like any
21 : other XML data using XQuery, and serialize the result back as JSON.
22 :
23 : There are many ways to represent JSON data in XML, some loss-less ("round
24 : tripable") and some lossy ("one way"). Loss-less representations preserve
25 : the JSON data types <i>boolean</i>, <i>number</i>, and <i>null</i>; lossy
26 : representations convert all data to strings.
27 :
28 : For a loss-less representation, Zorba implements that proposed by
29 : <a href="http://john.snelson.org.uk/parsing-json-into-xquery">John Snelson</a>;
30 : for a lossy representation, Zorba implements
31 : <a href="http://jsonml.org/">JsonML</a> (the array form).
32 :)
33
34module namespace json = "http://www.zorba-xquery.com/modules/converters/json";
35
36import module namespace schema = "http://www.zorba-xquery.com/modules/schema";
37
38import schema namespace json-options =
39 "http://www.zorba-xquery.com/modules/converters/json-options";
40
41declare namespace err = "http://www.w3.org/2005/xqt-errors";
42
43declare namespace ver = "http://www.zorba-xquery.com/options/versioning";
44declare option ver:module-version "2.0";
45
46(:~
47 : Parses JSON data from a string and returns an XDM instance using one of the
48 : representations described above.
49 :
50 : @param $json The JSON data to parse.
51 : @param $options The parsing options.
52 : @return said XDM instance.
53 : @error err:XQDY0027 if $options can not be validated against the
54 : json-options schema.
55 : @error ZJPE0001 if $json contains an illegal JSON character.
56 : @error ZJPE0002 if $json contains an illegal Unicode code-point.
57 : @error ZJPE0003 if $json contains an illegal JSON character escape.
58 : @error ZJPE0004 if $json contains an illegal JSON literal.
59 : @error ZJPE0005 if $json contains an illegal JSON number.
60 : @error ZJPE0007 if $json contains an unterminated string.
61 : @error ZJPE0008 if $json contains an illegal QName.
62 :)
63declare function json:parse(
64 $json as xs:string?,
65 $options as element(json-options:options)
66) as element(*,xs:untyped)*
67{
68 let $validated-options := if ( schema:is-validated( $options ) ) then
69 $options
70 else
71 validate { $options }
72 return json:parse-internal( $json, $validated-options )
73};
74
75(:~
76 : Parses JSON data from a string and returns an XDM instance using the Snelson
77 : representation described above.
78 :
79 : @param $json The JSON data to parse.
80 : @return said XDM instance.
81 : @error ZJPE0001 if $json contains an illegal JSON character.
82 : @error ZJPE0002 if $json contains an illegal Unicode code-point.
83 : @error ZJPE0003 if $json contains an illegal JSON character escape.
84 : @error ZJPE0004 if $json contains an illegal JSON literal.
85 : @error ZJPE0005 if $json contains an illegal JSON number.
86 : @error ZJPE0007 if $json contains an unterminated string.
87 : @error ZJPE0008 if $json contains an illegal QName.
88 :)
89declare function json:parse(
90 $json as xs:string?
91) as element(*,xs:untyped)*
92{
93 json:parse-internal(
94 $json,
95 validate {
96 <options xmlns="http://www.zorba-xquery.com/modules/converters/json-options" >
97 <json-format value="Snelson"/>
98 </options>
99 }
100 )
101};
102
103(:~
104 : Serializes an XDM into JSON using one of the representations described
105 : above.
106 :
107 : @param $xml The XDM to serialize.
108 : @param $options The serializing options.
109 : @return a JSON string.
110 : @error err:XQDY0027 if $options can not be validated against the
111 : json-options schema.
112 : @error ZJSE0001 if $xml is not a document or element node.
113 : @error ZJSE0002 if $xml contains an element that is missing a required
114 : attribute.
115 : @error ZJSE0003 if $xml contains an attribute having an illegal value.
116 : @error ZJSE0004 if $xml contains an illegal element.
117 : @error ZJSE0005 if $xml contains an illegal child element for a JSON type.
118 : @error ZJSE0006 if $xml contains an illegal child element.
119 : @error ZJSE0007 if $xml contains an illegal text node.
120 : @error ZJSE0008 if $xml contains an illegal value for a JSON type.
121 :)
122declare function json:serialize(
123 $xml as item()*,
124 $options as element(json-options:options)
125) as xs:string
126{
127 let $validated-options := if ( schema:is-validated( $options ) ) then
128 $options
129 else
130 validate { $options }
131 return json:serialize-internal( $xml, $validated-options )
132};
133
134(:~
135 : Serializes an XDM into JSON using one of the representations described
136 : above.
137 :
138 : @param $xml The XDM to serialize.
139 : @return a JSON string.
140 : @error ZJSE0001 if $xml is not a document or element node.
141 : @error ZJSE0002 if $xml contains an element that is missing a required
142 : attribute.
143 : @error ZJSE0003 if $xml contains an attribute having an illegal value.
144 : @error ZJSE0004 if $xml contains an illegal element.
145 : @error ZJSE0005 if $xml contains an illegal child element for a JSON type.
146 : @error ZJSE0006 if $xml contains an illegal child element.
147 : @error ZJSE0007 if $xml contains an illegal text node.
148 : @error ZJSE0008 if $xml contains an illegal value for a JSON type.
149 :)
150declare function json:serialize(
151 $xml as item()*
152) as xs:string
153{
154 json:serialize-internal($xml,
155 validate {
156 <options xmlns="http://www.zorba-xquery.com/modules/converters/json-options" >
157 <json-format value="Snelson"/>
158 </options>
159 }
160 )
161};
162
163(:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::)
164
165declare %private function json:parse-internal(
166 $json as xs:string,
167 $options as item()?
168) as element()* external;
169
170declare %private function json:serialize-internal(
171 $xml as item()*,
172 $options as item()?
173) as xs:string external;
174
175(: vim:set et sw=2 ts=2: :)
0176
=== modified file 'modules/com/zorba-xquery/www/modules/pregenerated/errors.xq'
--- modules/com/zorba-xquery/www/modules/pregenerated/errors.xq 2011-12-21 14:40:33 +0000
+++ modules/com/zorba-xquery/www/modules/pregenerated/errors.xq 2012-01-23 00:53:24 +0000
@@ -784,4 +784,68 @@
784784
785(:~785(:~
786:)786:)
787declare variable $zerr:XSST0010 as xs:QName := fn:QName($zerr:NS, "zerr:XSST0010");
788\ No newline at end of file787\ No newline at end of file
788declare variable $zerr:XSST0010 as xs:QName := fn:QName($zerr:NS, "zerr:XSST0010");
789
790(:~
791:)
792declare variable $zerr:ZJPE0001 as xs:QName := fn:QName($zerr:NS, "zerr:ZJPE0001");
793
794(:~
795:)
796declare variable $zerr:ZJPE0002 as xs:QName := fn:QName($zerr:NS, "zerr:ZJPE0002");
797
798(:~
799:)
800declare variable $zerr:ZJPE0003 as xs:QName := fn:QName($zerr:NS, "zerr:ZJPE0003");
801
802(:~
803:)
804declare variable $zerr:ZJPE0004 as xs:QName := fn:QName($zerr:NS, "zerr:ZJPE0004");
805
806(:~
807:)
808declare variable $zerr:ZJPE0005 as xs:QName := fn:QName($zerr:NS, "zerr:ZJPE0005");
809
810(:~
811:)
812declare variable $zerr:ZJPE0006 as xs:QName := fn:QName($zerr:NS, "zerr:ZJPE0006");
813
814(:~
815:)
816declare variable $zerr:ZJPE0007 as xs:QName := fn:QName($zerr:NS, "zerr:ZJPE0007");
817
818(:~
819:)
820declare variable $zerr:ZJPE0008 as xs:QName := fn:QName($zerr:NS, "zerr:ZJPE0008");
821
822(:~
823:)
824declare variable $zerr:ZJSE0001 as xs:QName := fn:QName($zerr:NS, "zerr:ZJSE0001");
825
826(:~
827:)
828declare variable $zerr:ZJSE0002 as xs:QName := fn:QName($zerr:NS, "zerr:ZJSE0002");
829
830(:~
831:)
832declare variable $zerr:ZJSE0003 as xs:QName := fn:QName($zerr:NS, "zerr:ZJSE0003");
833
834(:~
835:)
836declare variable $zerr:ZJSE0004 as xs:QName := fn:QName($zerr:NS, "zerr:ZJSE0004");
837
838(:~
839:)
840declare variable $zerr:ZJSE0005 as xs:QName := fn:QName($zerr:NS, "zerr:ZJSE0005");
841
842(:~
843:)
844declare variable $zerr:ZJSE0006 as xs:QName := fn:QName($zerr:NS, "zerr:ZJSE0006");
845
846(:~
847:)
848declare variable $zerr:ZJSE0007 as xs:QName := fn:QName($zerr:NS, "zerr:ZJSE0007");
849
850(:~
851:)
852declare variable $zerr:ZJSE0008 as xs:QName := fn:QName($zerr:NS, "zerr:ZJSE0008");
789\ No newline at end of file853\ No newline at end of file
790854
=== modified file 'src/context/static_context.cpp'
--- src/context/static_context.cpp 2012-01-11 17:30:25 +0000
+++ src/context/static_context.cpp 2012-01-23 00:53:24 +0000
@@ -349,6 +349,9 @@
349static_context::ZORBA_STRING_FN_NS = NS_PRE + "modules/string";349static_context::ZORBA_STRING_FN_NS = NS_PRE + "modules/string";
350350
351const zstring351const zstring
352static_context::ZORBA_JSON_FN_NS = NS_PRE + "modules/converters/json";
353
354const zstring
352static_context::ZORBA_FETCH_FN_NS = NS_PRE + "modules/fetch";355static_context::ZORBA_FETCH_FN_NS = NS_PRE + "modules/fetch";
353356
354const zstring357const zstring
@@ -414,6 +417,7 @@
414 ns == ZORBA_REFLECTION_FN_NS ||417 ns == ZORBA_REFLECTION_FN_NS ||
415 ns == ZORBA_SCRIPTING_FN_NS ||418 ns == ZORBA_SCRIPTING_FN_NS ||
416 ns == ZORBA_STRING_FN_NS ||419 ns == ZORBA_STRING_FN_NS ||
420 ns == ZORBA_JSON_FN_NS ||
417 ns == ZORBA_FETCH_FN_NS ||421 ns == ZORBA_FETCH_FN_NS ||
418 ns == ZORBA_NODE_FN_NS ||422 ns == ZORBA_NODE_FN_NS ||
419 ns == ZORBA_XML_FN_NS);423 ns == ZORBA_XML_FN_NS);
@@ -460,6 +464,7 @@
460 {464 {
461 return (ns == ZORBA_MATH_FN_NS ||465 return (ns == ZORBA_MATH_FN_NS ||
462 ns == ZORBA_INTROSP_SCTX_FN_NS ||466 ns == ZORBA_INTROSP_SCTX_FN_NS ||
467 ns == ZORBA_JSON_FN_NS ||
463 ns == ZORBA_RANDOM_FN_NS);468 ns == ZORBA_RANDOM_FN_NS);
464 }469 }
465470
466471
=== modified file 'src/context/static_context.h'
--- src/context/static_context.h 2012-01-11 17:30:25 +0000
+++ src/context/static_context.h 2012-01-23 00:53:24 +0000
@@ -464,6 +464,7 @@
464 static const zstring ZORBA_INTROSP_SCTX_FN_NS;464 static const zstring ZORBA_INTROSP_SCTX_FN_NS;
465 static const zstring ZORBA_REFLECTION_FN_NS;465 static const zstring ZORBA_REFLECTION_FN_NS;
466 static const zstring ZORBA_STRING_FN_NS;466 static const zstring ZORBA_STRING_FN_NS;
467 static const zstring ZORBA_JSON_FN_NS;
467 static const zstring ZORBA_FETCH_FN_NS;468 static const zstring ZORBA_FETCH_FN_NS;
468 static const zstring ZORBA_NODE_FN_NS;469 static const zstring ZORBA_NODE_FN_NS;
469 static const zstring ZORBA_XML_FN_NS;470 static const zstring ZORBA_XML_FN_NS;
470471
=== modified file 'src/diagnostics/diagnostic.cpp'
--- src/diagnostics/diagnostic.cpp 2011-07-11 21:01:20 +0000
+++ src/diagnostics/diagnostic.cpp 2012-01-23 00:53:24 +0000
@@ -134,6 +134,9 @@
134 case ZORBA_STORE : o << "Zorba store" ; break;134 case ZORBA_STORE : o << "Zorba store" ; break;
135 case ZORBA_XQP : o << "Zorba" ; break;135 case ZORBA_XQP : o << "Zorba" ; break;
136136
137 case JSON_PARSER : o << "JSON parser" ; break;
138 case JSON_SERIALIZATION : o << "JSON serialization" ; break;
139
137 default : /* suppresses warning */ break;140 default : /* suppresses warning */ break;
138 }141 }
139 return o;142 return o;
140143
=== modified file 'src/diagnostics/diagnostic_en.xml'
--- src/diagnostics/diagnostic_en.xml 2011-12-21 14:40:33 +0000
+++ src/diagnostics/diagnostic_en.xml 2012-01-23 00:53:24 +0000
@@ -2307,6 +2307,60 @@
2307 <value>"continue loop" statement not inside while statement</value>2307 <value>"continue loop" statement not inside while statement</value>
2308 </diagnostic>2308 </diagnostic>
23092309
2310 <!--////////// JSON Parse Errors ////////////////////////////////////////-->
2311
2312 <diagnostic code="ZJPE0001" name="ILLEGAL_CHARACTER">
2313 <value>'$1': illegal JSON character</value>
2314 </diagnostic>
2315 <diagnostic code="ZJPE0002" name="ILLEGAL_CODEPOINT">
2316 <value>"$1": illegal Unicode code-point</value>
2317 </diagnostic>
2318 <diagnostic code="ZJPE0003" name="ILLEGAL_ESCAPE">
2319 <value>'\\$1': illegal JSON character escape</value>
2320 </diagnostic>
2321 <diagnostic code="ZJPE0004" name="ILLEGAL_LITERAL">
2322 <value>illegal JSON literal</value>
2323 </diagnostic>
2324 <diagnostic code="ZJPE0005" name="ILLEGAL_NUMBER">
2325 <value>illegal JSON number</value>
2326 </diagnostic>
2327 <diagnostic code="ZJPE0006" name="UNEXPECTED_TOKEN">
2328 <value>"$1": unexpected JSON token</value>
2329 </diagnostic>
2330 <diagnostic code="ZJPE0007" name="UNTERMINATED_STRING">
2331 <value>unterminated JSON string</value>
2332 </diagnostic>
2333 <diagnostic code="ZJPE0008" name="ILLEGAL_QNAME">
2334 <value>"$1": illegal QName</value>
2335 </diagnostic>
2336
2337 <!--////////// JSON Serialization Errors ////////////////////////////////-->
2338
2339 <diagnostic code="ZJSE0001" name="NOT_DOCUMENT_OR_ELEMENT_NODE">
2340 <value>JSON serialization requires document or element node</value>
2341 </diagnostic>
2342 <diagnostic code="ZJSE0002" name="ELEMENT_MISSING_ATTRIBUTE">
2343 <value>"$1" element missing required "$2" attribute</value>
2344 </diagnostic>
2345 <diagnostic code="ZJSE0003" name="BAD_ATTRIBUTE_VALUE">
2346 <value>"$1": illegal value for attribute "$2"</value>
2347 </diagnostic>
2348 <diagnostic code="ZJSE0004" name="BAD_ELEMENT">
2349 <value>"$1": illegal element${; must be "2"}${ or "3"}</value>
2350 </diagnostic>
2351 <diagnostic code="ZJSE0005" name="BAD_CHILD_ELEMENT">
2352 <value>"$1": illegal child element of "$2" type; must be "$3"</value>
2353 </diagnostic>
2354 <diagnostic code="ZJSE0006" name="NO_ELEMENT_CHILD">
2355 <value>JSON type "$1" can not have a child element node</value>
2356 </diagnostic>
2357 <diagnostic code="ZJSE0007" name="NO_TEXT_CHILD">
2358 <value>JSON type "$1" can not have a child text node</value>
2359 </diagnostic>
2360 <diagnostic code="ZJSE0008" name="BAD_VALUE">
2361 <value>"$1": illegal value for JSON type "$2"</value>
2362 </diagnostic>
2363
2310 </namespace>2364 </namespace>
23112365
2312 <!--////////// Zorba Warnings ////////////////////////////////////////////-->2366 <!--////////// Zorba Warnings ////////////////////////////////////////////-->
@@ -3264,6 +3318,14 @@
3264 <value>Zorba warning</value>3318 <value>Zorba warning</value>
3265 </entry>3319 </entry>
32663320
3321 <entry key="JSON parser error">
3322 <value>JSON parser error</value>
3323 </entry>
3324
3325 <entry key="JSON serialization error">
3326 <value>JSON serialization error</value>
3327 </entry>
3328
3267 <entry key="dynamic error">3329 <entry key="dynamic error">
3268 <value>dynamic error</value>3330 <value>dynamic error</value>
3269 </entry>3331 </entry>
32703332
=== modified file 'src/diagnostics/pregenerated/diagnostic_list.cpp'
--- src/diagnostics/pregenerated/diagnostic_list.cpp 2011-12-21 14:40:33 +0000
+++ src/diagnostics/pregenerated/diagnostic_list.cpp 2012-01-23 00:53:24 +0000
@@ -1097,6 +1097,54 @@
1097ZorbaErrorCode XSST0010( "XSST0010" );1097ZorbaErrorCode XSST0010( "XSST0010" );
10981098
10991099
1100ZorbaErrorCode ZJPE0001_ILLEGAL_CHARACTER( "ZJPE0001" );
1101
1102
1103ZorbaErrorCode ZJPE0002_ILLEGAL_CODEPOINT( "ZJPE0002" );
1104
1105
1106ZorbaErrorCode ZJPE0003_ILLEGAL_ESCAPE( "ZJPE0003" );
1107
1108
1109ZorbaErrorCode ZJPE0004_ILLEGAL_LITERAL( "ZJPE0004" );
1110
1111
1112ZorbaErrorCode ZJPE0005_ILLEGAL_NUMBER( "ZJPE0005" );
1113
1114
1115ZorbaErrorCode ZJPE0006_UNEXPECTED_TOKEN( "ZJPE0006" );
1116
1117
1118ZorbaErrorCode ZJPE0007_UNTERMINATED_STRING( "ZJPE0007" );
1119
1120
1121ZorbaErrorCode ZJPE0008_ILLEGAL_QNAME( "ZJPE0008" );
1122
1123
1124ZorbaErrorCode ZJSE0001_NOT_DOCUMENT_OR_ELEMENT_NODE( "ZJSE0001" );
1125
1126
1127ZorbaErrorCode ZJSE0002_ELEMENT_MISSING_ATTRIBUTE( "ZJSE0002" );
1128
1129
1130ZorbaErrorCode ZJSE0003_BAD_ATTRIBUTE_VALUE( "ZJSE0003" );
1131
1132
1133ZorbaErrorCode ZJSE0004_BAD_ELEMENT( "ZJSE0004" );
1134
1135
1136ZorbaErrorCode ZJSE0005_BAD_CHILD_ELEMENT( "ZJSE0005" );
1137
1138
1139ZorbaErrorCode ZJSE0006_NO_ELEMENT_CHILD( "ZJSE0006" );
1140
1141
1142ZorbaErrorCode ZJSE0007_NO_TEXT_CHILD( "ZJSE0007" );
1143
1144
1145ZorbaErrorCode ZJSE0008_BAD_VALUE( "ZJSE0008" );
1146
1147
1100} // namespace zerr1148} // namespace zerr
11011149
1102namespace zwarn {1150namespace zwarn {
11031151
=== modified file 'src/diagnostics/pregenerated/dict_en.cpp'
--- src/diagnostics/pregenerated/dict_en.cpp 2011-12-21 14:40:33 +0000
+++ src/diagnostics/pregenerated/dict_en.cpp 2012-01-23 00:53:24 +0000
@@ -332,6 +332,22 @@
332#if defined(ZORBA_WITH_DEBUGGER)332#if defined(ZORBA_WITH_DEBUGGER)
333 { "ZGDB0001", "" },333 { "ZGDB0001", "" },
334#endif334#endif
335 { "ZJPE0001", "'$1': illegal JSON character" },
336 { "ZJPE0002", "\"$1\": illegal Unicode code-point" },
337 { "ZJPE0003", "'\\$1': illegal JSON character escape" },
338 { "ZJPE0004", "illegal JSON literal" },
339 { "ZJPE0005", "illegal JSON number" },
340 { "ZJPE0006", "\"$1\": unexpected JSON token" },
341 { "ZJPE0007", "unterminated JSON string" },
342 { "ZJPE0008", "\"$1\": illegal QName" },
343 { "ZJSE0001", "JSON serialization requires document or element node" },
344 { "ZJSE0002", "\"$1\" element missing required \"$2\" attribute" },
345 { "ZJSE0003", "\"$1\": illegal value for attribute \"$2\"" },
346 { "ZJSE0004", "\"$1\": illegal element${; must be \"2\"}${ or \"3\"}" },
347 { "ZJSE0005", "\"$1\": illegal child element of \"$2\" type; must be \"$3\"" },
348 { "ZJSE0006", "JSON type \"$1\" can not have a child element node" },
349 { "ZJSE0007", "JSON type \"$1\" can not have a child text node" },
350 { "ZJSE0008", "\"$1\": illegal value for JSON type \"$2\"" },
335 { "ZOSE0001", "\"$1\": file not found" },351 { "ZOSE0001", "\"$1\": file not found" },
336 { "ZOSE0002", "\"$1\": not plain file" },352 { "ZOSE0002", "\"$1\": not plain file" },
337 { "ZOSE0003", "stream read failure" },353 { "ZOSE0003", "stream read failure" },
@@ -494,6 +510,8 @@
494 { "~HexBinaryMustBeEven", "HexBinary value must contain an even number of characters" },510 { "~HexBinaryMustBeEven", "HexBinary value must contain an even number of characters" },
495 { "~IncompleteKeyInIndexBuild", "incomplete key during index build" },511 { "~IncompleteKeyInIndexBuild", "incomplete key during index build" },
496 { "~IncompleteKeyInIndexRefresh", "incomplete key during index refresh" },512 { "~IncompleteKeyInIndexRefresh", "incomplete key during index refresh" },
513 { "~JSON parser error", "JSON parser error" },
514 { "~JSON serialization error", "JSON serialization error" },
497 { "~LibModVersionMismatch_3", "XQuery library version can not be imported by a $3 version module" },515 { "~LibModVersionMismatch_3", "XQuery library version can not be imported by a $3 version module" },
498 { "~ModuleDeclNotInMain", "module declaration must not be in main module" },516 { "~ModuleDeclNotInMain", "module declaration must not be in main module" },
499 { "~ModuleNotFound", "module not found" },517 { "~ModuleNotFound", "module not found" },
500518
=== modified file 'src/diagnostics/qname.cpp'
--- src/diagnostics/qname.cpp 2011-07-01 16:07:54 +0000
+++ src/diagnostics/qname.cpp 2012-01-23 00:53:24 +0000
@@ -79,9 +79,15 @@
79 case 'C': return ZORBA_SERIALIZATION;79 case 'C': return ZORBA_SERIALIZATION;
80 case 'D': return ZORBA_DDF;80 case 'D': return ZORBA_DDF;
81 case 'G': return ZORBA_DEBUGGER;81 case 'G': return ZORBA_DEBUGGER;
82 case 'J': switch ( name[2] ) {
83 case 'P': return JSON_PARSER;
84 case 'S': return JSON_SERIALIZATION;
85 default : ZORBA_ASSERT( false );
86 }
82 case 'O': return ZORBA_OS;87 case 'O': return ZORBA_OS;
83 case 'S': return ZORBA_STORE;88 case 'S': return ZORBA_STORE;
84 case 'X': return ZORBA_XQP;89 case 'X': return ZORBA_XQP;
90
85 default : ZORBA_ASSERT( false );91 default : ZORBA_ASSERT( false );
86 }92 }
87}93}
8894
=== modified file 'src/functions/library.cpp'
--- src/functions/library.cpp 2011-10-14 07:35:51 +0000
+++ src/functions/library.cpp 2012-01-23 00:53:24 +0000
@@ -57,6 +57,7 @@
57#include "functions/func_sequences.h"57#include "functions/func_sequences.h"
58#include "functions/func_sequences_impl.h"58#include "functions/func_sequences_impl.h"
59#include "functions/func_strings.h"59#include "functions/func_strings.h"
60#include "functions/func_json.h"
60#include "functions/func_var_decl.h"61#include "functions/func_var_decl.h"
61#include "functions/func_xqdoc.h"62#include "functions/func_xqdoc.h"
62#include "functions/func_documents.h"63#include "functions/func_documents.h"
@@ -107,6 +108,7 @@
107 populate_context_fnput(sctx);108 populate_context_fnput(sctx);
108 populate_context_index_ddl(sctx);109 populate_context_index_ddl(sctx);
109 populate_context_ic_ddl(sctx);110 populate_context_ic_ddl(sctx);
111 populate_context_json(sctx);
110 populate_context_maths(sctx);112 populate_context_maths(sctx);
111 populate_context_nodes(sctx);113 populate_context_nodes(sctx);
112 populate_context_node_position(sctx);114 populate_context_node_position(sctx);
113115
=== added file 'src/functions/pregenerated/func_json.cpp'
--- src/functions/pregenerated/func_json.cpp 1970-01-01 00:00:00 +0000
+++ src/functions/pregenerated/func_json.cpp 2012-01-23 00:53:24 +0000
@@ -0,0 +1,87 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// ******************************************
18// * *
19// * THIS IS A GENERATED FILE. DO NOT EDIT! *
20// * SEE .xml FILE WITH SAME NAME *
21// * *
22// ******************************************
23
24
25#include "stdafx.h"
26#include "runtime/json/json.h"
27#include "functions/func_json.h"
28
29
30namespace zorba{
31
32
33
34PlanIter_t fn_zorba_json_parse_internal::codegen(
35 CompilerCB*,
36 static_context* sctx,
37 const QueryLoc& loc,
38 std::vector<PlanIter_t>& argv,
39 AnnotationHolder& ann) const
40{
41 return new JSONParseInternal(sctx, loc, argv);
42}
43
44PlanIter_t fn_zorba_json_serialize_internal::codegen(
45 CompilerCB*,
46 static_context* sctx,
47 const QueryLoc& loc,
48 std::vector<PlanIter_t>& argv,
49 AnnotationHolder& ann) const
50{
51 return new JSONSerializeInternal(sctx, loc, argv);
52}
53
54void populate_context_json(static_context* sctx)
55{
56 {
57
58
59 DECL_WITH_KIND(sctx, fn_zorba_json_parse_internal,
60 (createQName("http://www.zorba-xquery.com/modules/converters/json","","parse-internal"),
61 GENV_TYPESYSTEM.STRING_TYPE_ONE,
62 GENV_TYPESYSTEM.ITEM_TYPE_QUESTION,
63 GENV_TYPESYSTEM.ELEMENT_TYPE_STAR),
64 FunctionConsts::FN_ZORBA_JSON_PARSE_INTERNAL_2);
65
66 }
67
68
69 {
70
71
72 DECL_WITH_KIND(sctx, fn_zorba_json_serialize_internal,
73 (createQName("http://www.zorba-xquery.com/modules/converters/json","","serialize-internal"),
74 GENV_TYPESYSTEM.ITEM_TYPE_STAR,
75 GENV_TYPESYSTEM.ITEM_TYPE_QUESTION,
76 GENV_TYPESYSTEM.STRING_TYPE_ONE),
77 FunctionConsts::FN_ZORBA_JSON_SERIALIZE_INTERNAL_2);
78
79 }
80
81}
82
83
84}
85
86
87
088
=== added file 'src/functions/pregenerated/func_json.h'
--- src/functions/pregenerated/func_json.h 1970-01-01 00:00:00 +0000
+++ src/functions/pregenerated/func_json.h 2012-01-23 00:53:24 +0000
@@ -0,0 +1,79 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// ******************************************
18// * *
19// * THIS IS A GENERATED FILE. DO NOT EDIT! *
20// * SEE .xml FILE WITH SAME NAME *
21// * *
22// ******************************************
23
24
25#ifndef ZORBA_FUNCTIONS_JSON_H
26#define ZORBA_FUNCTIONS_JSON_H
27
28
29#include "common/shared_types.h"
30#include "functions/function_impl.h"
31
32
33namespace zorba {
34
35
36void populate_context_json(static_context* sctx);
37
38
39
40
41//fn-zorba-json:parse-internal
42class fn_zorba_json_parse_internal : public function
43{
44public:
45 fn_zorba_json_parse_internal(const signature& sig, FunctionConsts::FunctionKind kind)
46 :
47 function(sig, kind)
48 {
49
50 }
51
52 CODEGEN_DECL();
53};
54
55
56//fn-zorba-json:serialize-internal
57class fn_zorba_json_serialize_internal : public function
58{
59public:
60 fn_zorba_json_serialize_internal(const signature& sig, FunctionConsts::FunctionKind kind)
61 :
62 function(sig, kind)
63 {
64
65 }
66
67 CODEGEN_DECL();
68};
69
70
71} //namespace zorba
72
73
74#endif
75/*
76 * Local variables:
77 * mode: c++
78 * End:
79 */
080
=== modified file 'src/functions/pregenerated/function_enum.h'
--- src/functions/pregenerated/function_enum.h 2012-01-11 17:30:25 +0000
+++ src/functions/pregenerated/function_enum.h 2012-01-23 00:53:24 +0000
@@ -166,6 +166,8 @@
166 FN_ZORBA_INTROSPECT_SCTX_IN_SCOPE_ATTRIBUTE_GROUPS_0,166 FN_ZORBA_INTROSPECT_SCTX_IN_SCOPE_ATTRIBUTE_GROUPS_0,
167 FN_ZORBA_INTROSPECT_SCTX_OPTION_1,167 FN_ZORBA_INTROSPECT_SCTX_OPTION_1,
168 FN_ZORBA_INTROSPECT_SCTX_FUNCTION_ANNOTATIONS_2,168 FN_ZORBA_INTROSPECT_SCTX_FUNCTION_ANNOTATIONS_2,
169 FN_ZORBA_JSON_PARSE_INTERNAL_2,
170 FN_ZORBA_JSON_SERIALIZE_INTERNAL_2,
169 MATH_SQRT_1,171 MATH_SQRT_1,
170 MATH_EXP_1,172 MATH_EXP_1,
171 MATH_EXP10_1,173 MATH_EXP10_1,
172174
=== modified file 'src/runtime/CMakeLists.txt'
--- src/runtime/CMakeLists.txt 2011-06-01 13:16:28 +0000
+++ src/runtime/CMakeLists.txt 2012-01-23 00:53:24 +0000
@@ -115,6 +115,9 @@
115 durations_dates_times/DurationsDatesTimesImpl.cpp115 durations_dates_times/DurationsDatesTimesImpl.cpp
116 indexing/doc_indexer.cpp116 indexing/doc_indexer.cpp
117 indexing/index_ddl.cpp117 indexing/index_ddl.cpp
118 json/common.cpp
119 json/jsonml_array.cpp
120 json/snelson.cpp
118 numerics/NumericsImpl.cpp121 numerics/NumericsImpl.cpp
119 numerics/format_integer_impl.cpp122 numerics/format_integer_impl.cpp
120 sequences/SequencesImpl.cpp123 sequences/SequencesImpl.cpp
121124
=== modified file 'src/runtime/full_text/ft_match.cpp'
--- src/runtime/full_text/ft_match.cpp 2011-06-14 17:26:33 +0000
+++ src/runtime/full_text/ft_match.cpp 2012-01-23 00:53:24 +0000
@@ -31,7 +31,7 @@
31 return o << "0x" << hex << reinterpret_cast<unsigned long>( obj ) << dec;31 return o << "0x" << hex << reinterpret_cast<unsigned long>( obj ) << dec;
32}32}
3333
34DEF_OMANIP1( print_addr, void const*, obj )34DEF_OMANIP1( print_addr, void const* )
3535
36ostream& operator<<( ostream &o, ft_string_match const &sm ) {36ostream& operator<<( ostream &o, ft_string_match const &sm ) {
37 return o << "{SM: "37 return o << "{SM: "
@@ -52,8 +52,7 @@
52 return o;52 return o;
53}53}
5454
55DEF_OMANIP2( print_string_matches, char const*, label,55DEF_OMANIP2( print_string_matches, char const*, ft_string_matches const& )
56 ft_string_matches const&, sms )
5756
58ostream& operator<<( ostream &o, ft_match const &m ) {57ostream& operator<<( ostream &o, ft_match const &m ) {
59 return o << indent << "ft_match @ " << print_addr( &m ) << '\n'58 return o << indent << "ft_match @ " << print_addr( &m ) << '\n'
6059
=== added directory 'src/runtime/json'
=== added file 'src/runtime/json/common.cpp'
--- src/runtime/json/common.cpp 1970-01-01 00:00:00 +0000
+++ src/runtime/json/common.cpp 2012-01-23 00:53:24 +0000
@@ -0,0 +1,62 @@
1/*
2 * Copyright 2006-2011 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "stdafx.h"
17
18#include "store/api/iterator.h"
19
20#include "common.h"
21
22using namespace std;
23
24namespace zorba {
25
26///////////////////////////////////////////////////////////////////////////////
27
28bool get_attribute_value( store::Item_t const &element, char const *att_name,
29 zstring *att_value ) {
30 store::Iterator_t i( element->getAttributes() );
31 bool found = false;
32 i->open();
33 store::Item_t att_item;
34 while ( i->next( att_item ) ) {
35 if ( att_item->getNodeName()->getStringValue() == att_name ) {
36 att_item->getStringValue2( *att_value );
37 found = true;
38 break;
39 }
40 }
41 i->close();
42 return found;
43}
44
45///////////////////////////////////////////////////////////////////////////////
46
47#if ZORBA_DEBUG_JSON
48
49ostream& operator<<( ostream &o, parse_state s ) {
50 static char const *const string_of[] = {
51 "in_array",
52 "in_object"
53 };
54 return o << string_of[ s ];
55}
56
57#endif /* ZORBA_DEBUG_JSON */
58
59///////////////////////////////////////////////////////////////////////////////
60
61} // namespace zorba
62/* vim:set et sw=2 ts=2: */
063
=== added file 'src/runtime/json/common.h'
--- src/runtime/json/common.h 1970-01-01 00:00:00 +0000
+++ src/runtime/json/common.h 2012-01-23 00:53:24 +0000
@@ -0,0 +1,118 @@
1/*
2 * Copyright 2006-2011 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ZORBA_RUNTIME_JSON_COMMON_H
18#define ZORBA_RUNTIME_JSON_COMMON_H
19
20#include <iostream>
21#include <stack>
22
23#include "store/api/item.h"
24#include "store/api/item_factory.h"
25#include "util/indent.h"
26#include "util/omanip.h"
27#include "zorbatypes/zstring.h"
28
29#define ZORBA_DEBUG_JSON 0
30
31namespace zorba {
32
33///////////////////////////////////////////////////////////////////////////////
34
35typedef std::stack<store::Item*> item_stack_type;
36
37enum parse_state {
38 in_array,
39 in_object
40};
41
42typedef std::stack<int> state_stack_type;
43
44namespace whitespace {
45 enum type {
46 none,
47 some,
48 indent
49 };
50}
51
52///////////////////////////////////////////////////////////////////////////////
53
54bool get_attribute_value( store::Item_t const &element, char const *att_name,
55 zstring *att_value );
56
57typedef std::ostream& (*std_omanip_type)(std::ostream&);
58
59inline std::ostream& if_do( std::ostream &o, bool expr, std_omanip_type fn ) {
60 if ( expr )
61 o << fn;
62 return o;
63}
64DEF_OMANIP2( if_do, bool, std_omanip_type )
65
66#define if_indent(WS,FN) if_do( (WS) == whitespace::indent, FN )
67
68inline std::ostream& if_emit( std::ostream &o, bool expr, char c ) {
69 if ( expr )
70 o << c;
71 return o;
72}
73DEF_OMANIP2( if_emit, bool, char )
74
75///////////////////////////////////////////////////////////////////////////////
76
77#if ZORBA_DEBUG_JSON
78
79std::ostream& operator<<( std::ostream &o, parse_state s );
80
81# define PUSH_ITEM(I) \
82 do { \
83 cout << __LINE__ << ":PUSH_ITEM( " << (I)->show() << " )" << endl; \
84 item_stack.push( (I).getp() ); \
85 } while (0)
86
87# define POP_ITEM() \
88 do { \
89 cout << __LINE__ << ":POP_ITEM()" << endl; \
90 cur_item = ztd::pop_stack( item_stack ); \
91 } while (0)
92
93# define PUSH_STATE(S) \
94 do { \
95 cout << __LINE__ << ":PUSH_STATE( " << (S) << " )" << endl; \
96 state_stack.push( S ); \
97 } while (0)
98
99# define POP_STATE() \
100 do { \
101 cout << __LINE__ << ":POP_STATE()" << endl; \
102 state_stack.pop(); \
103 } while (0) \
104
105#else
106
107# define PUSH_ITEM(I) item_stack.push( (I).getp() )
108# define POP_ITEM() cur_item = ztd::pop_stack( item_stack )
109# define PUSH_STATE(S) state_stack.push( S )
110# define POP_STATE() state_stack.pop()
111
112#endif /* ZORBA_DEBUG_JSON */
113
114///////////////////////////////////////////////////////////////////////////////
115
116} // namespace zorba
117#endif /* ZORBA_RUNTIME_JSON_COMMON_H */
118/* vim:set et sw=2 ts=2: */
0119
=== added file 'src/runtime/json/json_impl.cpp'
--- src/runtime/json/json_impl.cpp 1970-01-01 00:00:00 +0000
+++ src/runtime/json/json_impl.cpp 2012-01-23 00:53:24 +0000
@@ -0,0 +1,216 @@
1/*
2 * Copyright 2006-2011 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "stdafx.h"
17
18#include <map>
19#include <sstream>
20
21#include <zorba/diagnostic_list.h>
22
23#include "runtime/json/json.h"
24#include "store/api/item_factory.h"
25#include "system/globalenv.h"
26#include "util/mem_streambuf.h"
27
28#include "jsonml_array.h"
29#include "snelson.h"
30
31using namespace std;
32
33namespace zorba {
34
35///////////////////////////////////////////////////////////////////////////////
36
37typedef map<zstring,zstring> options_type;
38
39static void get_options( store::Item_t const &options_element,
40 options_type *options ) {
41 ZORBA_ASSERT( options_element->getNodeKind() ==
42 store::StoreConsts::elementNode );
43 store::Iterator_t i = options_element->getChildren();
44 i->open();
45 store::Item_t option_item;
46 while ( i->next( option_item ) ) {
47 if ( option_item->getNodeKind() == store::StoreConsts::elementNode ) {
48 zstring const name( option_item->getNodeName()->getStringValue() );
49 zstring value;
50 get_attribute_value( option_item, "value", &value );
51 (*options)[ name ] = value;
52 }
53 }
54 i->close();
55}
56
57///////////////////////////////////////////////////////////////////////////////
58
59bool JSONParseInternal::nextImpl( store::Item_t& result,
60 PlanState &planState ) const {
61 store::Item_t cur_item;
62 options_type options;
63 istringstream iss;
64 mem_streambuf buf;
65
66 PlanIteratorState *state;
67 DEFAULT_STACK_INIT( PlanIteratorState, state, planState );
68
69 ZORBA_ASSERT( theChildren.size() == 2 );
70 ZORBA_ASSERT( consumeNext( cur_item, theChildren[1], planState ) );
71 get_options( cur_item, &options );
72
73 if ( consumeNext( cur_item, theChildren[0], planState ) ) {
74 istream *is;
75 if ( cur_item->isStreamable() ) {
76 is = &cur_item->getStream();
77 } else {
78 zstring s;
79 cur_item->getStringValue2( s );
80 // Doing it this way uses the string data in-place with no copy.
81 buf.set( s.data(), s.size() );
82 iss.ios::rdbuf( &buf );
83 is = &iss;
84 }
85
86 try {
87 json::parser p( *is );
88 p.set_loc(
89 loc.getFilename().c_str(), loc.getLineBegin(), loc.getColumnBegin()
90 );
91
92 options_type::mapped_type const &format = options[ "json-format" ];
93 ZORBA_ASSERT( !format.empty() );
94 if ( format == "Snelson" )
95 snelson::parse( p, &result );
96 else if ( format == "JsonML-array" )
97 jsonml_array::parse( p, &result );
98 else
99 ZORBA_ASSERT( false );
100 }
101 catch ( json::illegal_character const &e ) {
102 throw XQUERY_EXCEPTION(
103 zerr::ZJPE0001_ILLEGAL_CHARACTER,
104 ERROR_PARAMS( e.get_char() ),
105 ERROR_LOC( e.get_loc() )
106 );
107 }
108 catch ( json::illegal_codepoint const &e ) {
109 throw XQUERY_EXCEPTION(
110 zerr::ZJPE0002_ILLEGAL_CODEPOINT,
111 ERROR_PARAMS( e.get_codepoint() ),
112 ERROR_LOC( e.get_loc() )
113 );
114 }
115 catch ( json::illegal_escape const &e ) {
116 throw XQUERY_EXCEPTION(
117 zerr::ZJPE0003_ILLEGAL_ESCAPE,
118 ERROR_PARAMS( e.get_escape() ),
119 ERROR_LOC( e.get_loc() )
120 );
121 }
122 catch ( json::illegal_literal const &e ) {
123 throw XQUERY_EXCEPTION(
124 zerr::ZJPE0004_ILLEGAL_LITERAL,
125 ERROR_LOC( e.get_loc() )
126 );
127 }
128 catch ( json::illegal_number const &e ) {
129 throw XQUERY_EXCEPTION(
130 zerr::ZJPE0005_ILLEGAL_NUMBER,
131 ERROR_LOC( e.get_loc() )
132 );
133 }
134 catch ( json::unexpected_token const &e ) {
135 throw XQUERY_EXCEPTION(
136 zerr::ZJPE0006_UNEXPECTED_TOKEN,
137 ERROR_PARAMS( e.get_token() ),
138 ERROR_LOC( e.get_loc() )
139 );
140 }
141 catch ( json::unterminated_string const &e ) {
142 throw XQUERY_EXCEPTION(
143 zerr::ZJPE0007_UNTERMINATED_STRING,
144 ERROR_LOC( e.get_loc() )
145 );
146 }
147
148 STACK_PUSH( !!result, state );
149 } // if ( consumeNext( ...
150 STACK_END( state );
151}
152
153///////////////////////////////////////////////////////////////////////////////
154
155bool JSONSerializeInternal::nextImpl( store::Item_t& result,
156 PlanState &planState ) const {
157 store::Item_t cur_item;
158 options_type options;
159
160 PlanIteratorState *state;
161 DEFAULT_STACK_INIT( PlanIteratorState, state, planState );
162
163 ZORBA_ASSERT( theChildren.size() == 2 );
164 ZORBA_ASSERT( consumeNext( cur_item, theChildren[1], planState ) );
165 get_options( cur_item, &options );
166
167 if ( consumeNext( cur_item, theChildren[0], planState ) ) {
168 try {
169 options_type::mapped_type const &format_opt = options[ "json-format" ];
170 ZORBA_ASSERT( !format_opt.empty() );
171
172 whitespace::type ws;
173 options_type::mapped_type const &whitespace_opt = options[ "whitespace" ];
174 if ( whitespace_opt.empty() || whitespace_opt == "none" )
175 ws = whitespace::none;
176 else if ( whitespace_opt == "some" )
177 ws = whitespace::some;
178 else if ( whitespace_opt == "indent" )
179 ws = whitespace::indent;
180 else
181 ZORBA_ASSERT( false );
182
183 ostringstream oss;
184 switch ( cur_item->getNodeKind() ) {
185 case store::StoreConsts::documentNode:
186 case store::StoreConsts::elementNode:
187 if ( format_opt == "Snelson" )
188 snelson::serialize( oss, cur_item, ws );
189 else if ( format_opt == "JsonML-array" )
190 jsonml_array::serialize( oss, cur_item, ws );
191 else
192 ZORBA_ASSERT( false );
193 break;
194 default:
195 throw XQUERY_EXCEPTION(
196 zerr::ZJSE0001_NOT_DOCUMENT_OR_ELEMENT_NODE,
197 ERROR_LOC( loc )
198 );
199 }
200 // This string copying is inefficient, but I can't see another way.
201 zstring temp( oss.str() );
202 GENV_ITEMFACTORY->createString( result, temp );
203 }
204 catch ( ZorbaException &e ) {
205 set_source( e, loc );
206 throw;
207 }
208 } // if ( consumeNext( ...
209 STACK_PUSH( !!result, state );
210 STACK_END( state );
211}
212
213///////////////////////////////////////////////////////////////////////////////
214
215} // namespace zorba
216/* vim:set et sw=2 ts=2: */
0217
=== added file 'src/runtime/json/jsonml_array.cpp'
--- src/runtime/json/jsonml_array.cpp 1970-01-01 00:00:00 +0000
+++ src/runtime/json/jsonml_array.cpp 2012-01-23 00:53:24 +0000
@@ -0,0 +1,281 @@
1/*
2 * Copyright 2006-2011 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "stdafx.h"
17
18#include <sstream>
19
20#include <zorba/diagnostic_list.h>
21
22#include "runtime/json/json.h"
23#include "store/api/item_factory.h"
24#include "system/globalenv.h"
25#include "types/root_typemanager.h"
26#include "util/ascii_util.h"
27#include "util/cxx_util.h"
28#include "util/json_parser.h"
29#include "util/mem_streambuf.h"
30#include "util/omanip.h"
31#include "util/oseparator.h"
32#include "util/stl_util.h"
33
34#include "jsonml_array.h"
35
36using namespace std;
37
38namespace zorba {
39
40///////////////////////////////////////////////////////////////////////////////
41
42static void split_name( zstring const &name, zstring *prefix, zstring *local ) {
43 zstring::size_type const colon = name.find( ':' );
44 if ( colon != zstring::npos ) {
45 *prefix = name.substr( 0, colon );
46 *local = name.substr( colon + 1 );
47 if ( prefix->empty() || local->empty() )
48 throw XQUERY_EXCEPTION(
49 zerr::ZJPE0008_ILLEGAL_QNAME,
50 ERROR_PARAMS( name )
51 );
52 } else {
53 prefix->clear();
54 *local = name;
55 }
56}
57
58namespace expect {
59 enum type {
60 none,
61 element_name,
62 attribute_name,
63 attribute_value
64 };
65}
66
67///////////////////////////////////////////////////////////////////////////////
68
69namespace jsonml_array {
70
71void parse( json::parser &p, store::Item_t *result ) {
72 ZORBA_ASSERT( result );
73
74 state_stack_type state_stack;
75
76 store::Item_t cur_item, junk_item, value_item;
77 store::Item_t att_name, element_name, type_name;
78
79 zstring base_uri;
80 item_stack_type item_stack;
81 expect::type expect_what = expect::none;
82 store::NsBindings ns_bindings;
83 zstring value;
84
85 json::token token;
86 while ( p.next( &token ) ) {
87 switch ( token.get_type() ) {
88
89 case '[':
90 PUSH_STATE( in_array );
91 expect_what = expect::element_name;
92 break;
93
94 case '{':
95 PUSH_STATE( in_object );
96 expect_what = expect::attribute_name;
97 break;
98
99 case ']':
100 POP_ITEM();
101 // no break;
102 case '}':
103 POP_STATE();
104 expect_what = expect::none;
105 break;
106
107 case ',':
108 expect_what = state_stack.top() == in_object ?
109 expect::attribute_name : expect::none;
110 break;
111
112 case ':':
113 expect_what = expect::attribute_value;
114 break;
115
116 case json::token::number:
117 case 'F':
118 case 'T':
119 case json::token::json_null:
120 case json::token::string: {
121 value = token.get_value();
122 zstring prefix, local;
123 switch ( expect_what ) {
124 case expect::element_name:
125 split_name( value, &prefix, &local );
126 GENV_ITEMFACTORY->createQName( element_name, "", prefix, local );
127 type_name = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
128 GENV_ITEMFACTORY->createElementNode(
129 cur_item,
130 item_stack.empty() ? nullptr : item_stack.top(),
131 element_name, type_name, false, false, ns_bindings, base_uri
132 );
133 PUSH_ITEM( cur_item );
134 if ( !*result )
135 *result = cur_item;
136 break;
137 case expect::attribute_name:
138 split_name( value, &prefix, &local );
139 GENV_ITEMFACTORY->createQName( att_name, "", prefix, local );
140 break;
141 case expect::attribute_value:
142 type_name = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
143 GENV_ITEMFACTORY->createString( value_item, value );
144 GENV_ITEMFACTORY->createAttributeNode(
145 junk_item, cur_item, att_name, type_name, value_item
146 );
147 break;
148 case expect::none:
149 GENV_ITEMFACTORY->createTextNode( junk_item, cur_item, value );
150 break;
151 }
152 break;
153 }
154
155 case json::token::none:
156 break;
157
158 default:
159 assert( false );
160 } // switch
161 } // while
162}
163
164} // namespace jsonml_array
165
166///////////////////////////////////////////////////////////////////////////////
167
168static ostream& serialize_attributes( ostream &o, store::Item_t const &element,
169 oseparator &sep, whitespace::type ws ) {
170 bool emitted_attributes = false;
171 oseparator att_sep;
172 switch ( ws ) {
173 case whitespace::none : att_sep.sep( "," ); break;
174 case whitespace::some : att_sep.sep( ", " ); break;
175 case whitespace::indent: att_sep.sep( ",\n" ); break;
176 }
177
178 store::Iterator_t i( element->getAttributes() );
179 i->open();
180 store::Item_t att_item;
181 while ( i->next( att_item ) ) {
182 zstring const att_name( att_item->getNodeName()->getStringValue() );
183 if ( att_name == "xmlns" )
184 continue;
185 if ( !emitted_attributes ) {
186 o << sep
187 << if_emit( ws == whitespace::indent, '\n' )
188 << if_indent( ws, indent ) << '{'
189 << if_indent( ws, inc_indent );
190 emitted_attributes = true;
191 }
192 bool const was_printing = att_sep.printing();
193 o << att_sep;
194 if ( was_printing )
195 o << if_indent( ws, indent );
196 else
197 o << if_emit( ws, ' ' );
198
199 o << '"' << att_name << '"'
200 << if_emit( ws, ' ' ) << ':' << if_emit( ws, ' ' )
201 << '"' << att_item->getStringValue() << '"';
202 }
203 i->close();
204 if ( emitted_attributes )
205 o << if_emit( ws, ' ' ) << '}' << if_indent( ws, dec_indent );
206 return o;
207}
208DEF_OMANIP3( serialize_attributes, store::Item_t const&, oseparator&,
209 whitespace::type )
210
211static ostream& serialize_children( ostream&, store::Item_t const &parent,
212 oseparator&, whitespace::type );
213DEF_OMANIP3( serialize_children, store::Item_t const&, oseparator&,
214 whitespace::type )
215
216static ostream& serialize_element( ostream &o, store::Item_t const &element,
217 oseparator &sep, whitespace::type ws ) {
218 if ( sep.printing() )
219 o << if_emit( ws == whitespace::indent, '\n' );
220 sep.printing( true );
221 o << if_indent( ws, indent ) << '[' << if_emit( ws, ' ' )
222 << '"' << element->getNodeName()->getStringValue() << '"'
223 << if_indent( ws, inc_indent )
224 << serialize_attributes( element, sep, ws )
225 << serialize_children( element, sep, ws )
226 << if_emit( ws, ' ' ) << ']'
227 << if_indent( ws, dec_indent );
228 return o;
229}
230DEF_OMANIP3( serialize_element, store::Item_t const&, oseparator&,
231 whitespace::type )
232
233static ostream& serialize_children( ostream &o, store::Item_t const &parent,
234 oseparator &sep, whitespace::type ws ) {
235 store::Iterator_t i( parent->getChildren() );
236 i->open();
237 store::Item_t child;
238 while ( i->next( child ) ) {
239 switch ( child->getNodeKind() ) {
240 case store::StoreConsts::elementNode:
241 o << sep << serialize_element( child, sep, ws );
242 break;
243 case store::StoreConsts::textNode:
244 o << sep << '"' << child->getStringValue() << '"';
245 break;
246 default:
247 break;
248 }
249 }
250 i->close();
251 return o;
252}
253
254///////////////////////////////////////////////////////////////////////////////
255
256namespace jsonml_array {
257
258void serialize( ostream &o, store::Item_t const &item, whitespace::type ws ) {
259 oseparator sep;
260 if ( ws )
261 sep.sep( ", " );
262 else
263 sep.sep( "," );
264 switch ( item->getNodeKind() ) {
265 case store::StoreConsts::documentNode:
266 o << serialize_children( item, sep, ws );
267 break;
268 case store::StoreConsts::elementNode:
269 o << serialize_element( item, sep, ws );
270 break;
271 default:
272 throw XQUERY_EXCEPTION( zerr::ZJSE0001_NOT_DOCUMENT_OR_ELEMENT_NODE );
273 }
274}
275
276} // namespace jsonml_array
277
278///////////////////////////////////////////////////////////////////////////////
279
280} // namespace zorba
281/* vim:set et sw=2 ts=2: */
0282
=== added file 'src/runtime/json/jsonml_array.h'
--- src/runtime/json/jsonml_array.h 1970-01-01 00:00:00 +0000
+++ src/runtime/json/jsonml_array.h 2012-01-23 00:53:24 +0000
@@ -0,0 +1,41 @@
1/*
2 * Copyright 2006-2011 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "stdafx.h"
17
18#ifndef ZORBA_RUNTIME_JSON_JSONML_ARRAY_H
19#define ZORBA_RUNTIME_JSON_JSONML_ARRAY_H
20
21#include <iostream>
22
23#include "store/api/item.h"
24#include "util/json_parser.h"
25
26#include "common.h"
27
28namespace zorba {
29namespace jsonml_array {
30
31///////////////////////////////////////////////////////////////////////////////
32
33void parse( json::parser &p, store::Item_t *result );
34void serialize( std::ostream&, store::Item_t const &item, whitespace::type );
35
36///////////////////////////////////////////////////////////////////////////////
37
38} // namespace jsonml_array
39} // namespace zorba
40#endif /* ZORBA_RUNTIME_JSON_JSONML_ARRAY_H */
41/* vim:set et sw=2 ts=2: */
042
=== added directory 'src/runtime/json/pregenerated'
=== added file 'src/runtime/json/pregenerated/json.cpp'
--- src/runtime/json/pregenerated/json.cpp 1970-01-01 00:00:00 +0000
+++ src/runtime/json/pregenerated/json.cpp 2012-01-23 00:53:24 +0000
@@ -0,0 +1,94 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// ******************************************
18// * *
19// * THIS IS A GENERATED FILE. DO NOT EDIT! *
20// * SEE .xml FILE WITH SAME NAME *
21// * *
22// ******************************************
23
24#include "stdafx.h"
25#include "zorbatypes/rchandle.h"
26#include "zorbatypes/zstring.h"
27#include "runtime/visitors/planiter_visitor.h"
28#include "runtime/json/json.h"
29#include "system/globalenv.h"
30
31
32
33namespace zorba {
34
35// <JSONParseInternal>
36const char* JSONParseInternal::class_name_str = "JSONParseInternal";
37JSONParseInternal::class_factory<JSONParseInternal>
38JSONParseInternal::g_class_factory;
39
40const serialization::ClassVersion
41JSONParseInternal::class_versions[] ={{ 1, 0x000905, false}};
42
43const int JSONParseInternal::class_versions_count =
44sizeof(JSONParseInternal::class_versions)/sizeof(struct serialization::ClassVersion);
45
46void JSONParseInternal::accept(PlanIterVisitor& v) const {
47 v.beginVisit(*this);
48
49 std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
50 std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
51 for ( ; lIter != lEnd; ++lIter ){
52 (*lIter)->accept(v);
53 }
54
55 v.endVisit(*this);
56}
57
58JSONParseInternal::~JSONParseInternal() {}
59
60// </JSONParseInternal>
61
62
63// <JSONSerializeInternal>
64const char* JSONSerializeInternal::class_name_str = "JSONSerializeInternal";
65JSONSerializeInternal::class_factory<JSONSerializeInternal>
66JSONSerializeInternal::g_class_factory;
67
68const serialization::ClassVersion
69JSONSerializeInternal::class_versions[] ={{ 1, 0x000905, false}};
70
71const int JSONSerializeInternal::class_versions_count =
72sizeof(JSONSerializeInternal::class_versions)/sizeof(struct serialization::ClassVersion);
73
74void JSONSerializeInternal::accept(PlanIterVisitor& v) const {
75 v.beginVisit(*this);
76
77 std::vector<PlanIter_t>::const_iterator lIter = theChildren.begin();
78 std::vector<PlanIter_t>::const_iterator lEnd = theChildren.end();
79 for ( ; lIter != lEnd; ++lIter ){
80 (*lIter)->accept(v);
81 }
82
83 v.endVisit(*this);
84}
85
86JSONSerializeInternal::~JSONSerializeInternal() {}
87
88// </JSONSerializeInternal>
89
90
91
92}
93
94
095
=== added file 'src/runtime/json/pregenerated/json.h'
--- src/runtime/json/pregenerated/json.h 1970-01-01 00:00:00 +0000
+++ src/runtime/json/pregenerated/json.h 2012-01-23 00:53:24 +0000
@@ -0,0 +1,114 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// ******************************************
18// * *
19// * THIS IS A GENERATED FILE. DO NOT EDIT! *
20// * SEE .xml FILE WITH SAME NAME *
21// * *
22// ******************************************
23#ifndef ZORBA_RUNTIME_JSON_JSON_H
24#define ZORBA_RUNTIME_JSON_JSON_H
25
26
27#include "common/shared_types.h"
28
29
30
31#include "runtime/base/narybase.h"
32
33
34namespace zorba {
35
36/**
37 *
38 * function for parsing strings into json-xdm
39 *
40 * Author: Zorba Team
41 */
42class JSONParseInternal : public NaryBaseIterator<JSONParseInternal, PlanIteratorState>
43{
44public:
45 SERIALIZABLE_CLASS(JSONParseInternal);
46
47 SERIALIZABLE_CLASS_CONSTRUCTOR2T(JSONParseInternal,
48 NaryBaseIterator<JSONParseInternal, PlanIteratorState>);
49
50 void serialize( ::zorba::serialization::Archiver& ar)
51 {
52 serialize_baseclass(ar,
53 (NaryBaseIterator<JSONParseInternal, PlanIteratorState>*)this);
54 }
55
56 JSONParseInternal(
57 static_context* sctx,
58 const QueryLoc& loc,
59 std::vector<PlanIter_t>& children)
60 :
61 NaryBaseIterator<JSONParseInternal, PlanIteratorState>(sctx, loc, children)
62 {}
63
64 virtual ~JSONParseInternal();
65
66 void accept(PlanIterVisitor& v) const;
67
68 bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
69};
70
71
72/**
73 *
74 * Function to serialize json/jsonml xdm to string
75 *
76 * Author: Zorba Team
77 */
78class JSONSerializeInternal : public NaryBaseIterator<JSONSerializeInternal, PlanIteratorState>
79{
80public:
81 SERIALIZABLE_CLASS(JSONSerializeInternal);
82
83 SERIALIZABLE_CLASS_CONSTRUCTOR2T(JSONSerializeInternal,
84 NaryBaseIterator<JSONSerializeInternal, PlanIteratorState>);
85
86 void serialize( ::zorba::serialization::Archiver& ar)
87 {
88 serialize_baseclass(ar,
89 (NaryBaseIterator<JSONSerializeInternal, PlanIteratorState>*)this);
90 }
91
92 JSONSerializeInternal(
93 static_context* sctx,
94 const QueryLoc& loc,
95 std::vector<PlanIter_t>& children)
96 :
97 NaryBaseIterator<JSONSerializeInternal, PlanIteratorState>(sctx, loc, children)
98 {}
99
100 virtual ~JSONSerializeInternal();
101
102 void accept(PlanIterVisitor& v) const;
103
104 bool nextImpl(store::Item_t& result, PlanState& aPlanState) const;
105};
106
107
108}
109#endif
110/*
111 * Local variables:
112 * mode: c++
113 * End:
114 */
0115
=== added file 'src/runtime/json/snelson.cpp'
--- src/runtime/json/snelson.cpp 1970-01-01 00:00:00 +0000
+++ src/runtime/json/snelson.cpp 2012-01-23 00:53:24 +0000
@@ -0,0 +1,498 @@
1/*
2 * Copyright 2006-2011 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "stdafx.h"
17
18#include <sstream>
19
20#include <zorba/diagnostic_list.h>
21
22#include "runtime/json/json.h"
23#include "store/api/item_factory.h"
24#include "system/globalenv.h"
25#include "types/root_typemanager.h"
26#include "util/ascii_util.h"
27#include "util/cxx_util.h"
28#include "util/indent.h"
29#include "util/json_parser.h"
30#include "util/mem_streambuf.h"
31#include "util/omanip.h"
32#include "util/oseparator.h"
33#include "util/stl_util.h"
34
35#include "snelson.h"
36
37#define SNELSON_NS "http://john.snelson.org.uk/parsing-json-into-xquery"
38
39using namespace std;
40
41namespace zorba {
42
43///////////////////////////////////////////////////////////////////////////////
44
45static void add_type_attribute( store::Item *parent, char const *value ) {
46 store::Item_t junk_item, att_name, type_name, value_item;
47 GENV_ITEMFACTORY->createQName( att_name, "", "", "type" );
48 type_name = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
49 zstring value_string( value );
50 GENV_ITEMFACTORY->createString( value_item, value_string );
51 GENV_ITEMFACTORY->createAttributeNode(
52 junk_item, parent, att_name, type_name, value_item
53 );
54}
55
56#define ADD_TYPE_ATTRIBUTE(T) \
57 do { \
58 if ( needs_type_attribute ) { \
59 add_type_attribute( cur_item, T ); \
60 needs_type_attribute = false; \
61 } \
62 } while (0)
63
64static void add_item_element( item_stack_type &item_stack,
65 state_stack_type &state_stack,
66 store::Item_t &cur_item,
67 char const *type ) {
68 if ( !state_stack.empty() && state_stack.top() == in_array ) {
69 store::Item_t element_name, type_name;
70 zstring base_uri;
71 store::NsBindings ns_bindings;
72 GENV_ITEMFACTORY->createQName( element_name, SNELSON_NS, "", "item" );
73 type_name = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
74 GENV_ITEMFACTORY->createElementNode(
75 cur_item, item_stack.top(),
76 element_name, type_name, false, false, ns_bindings, base_uri
77 );
78 add_type_attribute( cur_item.getp(), type );
79 }
80}
81
82#define ADD_ITEM_ELEMENT(T) \
83 add_item_element( item_stack, state_stack, cur_item, T );
84
85static void escape_json_chars( zstring *s ) {
86 ascii::replace_all( *s, "\"", 1, "\\\"", 2 );
87 ascii::replace_all( *s, "\\", 1, "\\\\", 2 );
88 ascii::replace_all( *s, "\b", 1, "\\b", 2 );
89 ascii::replace_all( *s, "\f", 1, "\\f", 2 );
90 ascii::replace_all( *s, "\n", 1, "\\n", 2 );
91 ascii::replace_all( *s, "\r", 1, "\\r", 2 );
92 ascii::replace_all( *s, "\t", 1, "\\t", 2 );
93}
94
95///////////////////////////////////////////////////////////////////////////////
96
97namespace snelson {
98
99void parse( json::parser &p, store::Item_t *result ) {
100 ZORBA_ASSERT( result );
101
102 state_stack_type state_stack;
103
104 store::Item_t cur_item, junk_item, value_item;
105 store::Item_t att_name, element_name, type_name;
106
107 zstring base_uri;
108 item_stack_type item_stack;
109 bool needs_type_attribute = false;
110 bool next_string_is_key = false;
111 store::NsBindings ns_bindings;
112 zstring value;
113
114 json::token token;
115 while ( p.next( &token ) ) {
116 if ( !*result ) {
117 GENV_ITEMFACTORY->createQName( element_name, SNELSON_NS, "", "json" );
118 type_name = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
119 GENV_ITEMFACTORY->createElementNode(
120 cur_item, nullptr,
121 element_name, type_name, false, false, ns_bindings, base_uri
122 );
123 *result = cur_item;
124 needs_type_attribute = true;
125 }
126
127 switch ( token.get_type() ) {
128
129 case '[':
130 PUSH_ITEM( cur_item );
131 ADD_TYPE_ATTRIBUTE( "array" );
132 ADD_ITEM_ELEMENT( "array" );
133 PUSH_STATE( in_array );
134 break;
135
136 case '{':
137 PUSH_ITEM( cur_item );
138 ADD_TYPE_ATTRIBUTE( "object" );
139 ADD_ITEM_ELEMENT( "object" );
140 PUSH_STATE( in_object );
141 next_string_is_key = true;
142 break;
143
144 case ']':
145 case '}':
146 POP_ITEM();
147 POP_STATE();
148 break;
149
150 case ',':
151 next_string_is_key = (state_stack.top() == in_object);
152 break;
153
154 case json::token::number:
155 ADD_TYPE_ATTRIBUTE( "number" );
156 ADD_ITEM_ELEMENT( "number" );
157 value = token.get_value();
158 GENV_ITEMFACTORY->createTextNode( junk_item, cur_item, value );
159 break;
160
161 case json::token::string:
162 ADD_TYPE_ATTRIBUTE( "string" );
163 value = token.get_value();
164#if 0
165 escape_json_chars( &value );
166#endif
167
168 if ( next_string_is_key ) {
169 // <pair name="..." ...>
170 GENV_ITEMFACTORY->createQName( element_name, SNELSON_NS, "", "pair" );
171 type_name = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
172 GENV_ITEMFACTORY->createElementNode(
173 cur_item, item_stack.top(),
174 element_name, type_name, false, false, ns_bindings, base_uri
175 );
176
177 GENV_ITEMFACTORY->createQName( att_name, "", "", "name" );
178 type_name = GENV_TYPESYSTEM.XS_UNTYPED_QNAME;
179 GENV_ITEMFACTORY->createString( value_item, value );
180 GENV_ITEMFACTORY->createAttributeNode(
181 junk_item, cur_item, att_name, type_name, value_item
182 );
183
184 needs_type_attribute = true;
185 next_string_is_key = false;
186 } else {
187 ADD_ITEM_ELEMENT( "string" );
188 GENV_ITEMFACTORY->createTextNode( junk_item, cur_item, value );
189 }
190 break;
191
192 case 'F':
193 case 'T':
194 ADD_TYPE_ATTRIBUTE( "boolean" );
195 ADD_ITEM_ELEMENT( "boolean" );
196 value = token.get_type() == 'F' ? "false" : "true";
197 GENV_ITEMFACTORY->createTextNode( junk_item, cur_item, value );
198 break;
199
200 case json::token::json_null:
201 ADD_TYPE_ATTRIBUTE( "null" );
202 ADD_ITEM_ELEMENT( "null" );
203 break;
204
205 case ':':
206 case json::token::none:
207 break;
208
209 default:
210 assert( false );
211 } // switch
212 } // while
213}
214
215} // namespace snelson
216
217///////////////////////////////////////////////////////////////////////////////
218
219static void assert_json_type( json::type t, zstring const &s ) {
220 // Doing it this way uses the string data in-place with no copy.
221 mem_streambuf::char_type *const p =
222 const_cast<mem_streambuf::char_type*>( s.data() );
223 mem_streambuf buf( p, s.size() );
224 istringstream iss;
225 iss.ios::rdbuf( &buf );
226
227 json::lexer lex( iss );
228 json::token token;
229 try {
230 if ( lex.next( &token ) && json::map_type( token.get_type() ) == t )
231 return;
232 }
233 catch ( json::exception const& ) {
234 // do nothing
235 }
236 throw XQUERY_EXCEPTION(
237 zerr::ZJSE0008_BAD_VALUE,
238 ERROR_PARAMS( s, t )
239 );
240}
241
242static void require_attribute_value( store::Item_t const &element,
243 char const *att_name,
244 zstring *att_value ) {
245 if ( !get_attribute_value( element, att_name, att_value ) )
246 throw XQUERY_EXCEPTION(
247 zerr::ZJSE0002_ELEMENT_MISSING_ATTRIBUTE,
248 ERROR_PARAMS( element->getNodeName()->getStringValue(), att_name )
249 );
250}
251
252static json::type get_json_type( store::Item_t const &element,
253 bool allow_all_types = true ) {
254 zstring att_value;
255 require_attribute_value( element, "type", &att_value );
256 if ( att_value == "array" )
257 return json::array;
258 if ( att_value == "object" )
259 return json::object;
260 if ( allow_all_types ) {
261 if ( att_value == "boolean" )
262 return json::boolean;
263 if ( att_value == "null" )
264 return json::null;
265 if ( att_value == "number" )
266 return json::number;
267 if ( att_value == "string" )
268 return json::string;
269 }
270 throw XQUERY_EXCEPTION(
271 zerr::ZJSE0003_BAD_ATTRIBUTE_VALUE,
272 ERROR_PARAMS( att_value, "type" )
273 );
274}
275
276inline std::ostream& if_space_or_newline( std::ostream &o,
277 whitespace::type ws ) {
278 if ( ws == whitespace::some )
279 o << ' ';
280 else
281 o << if_emit( ws == whitespace::indent, '\n' );
282 return o;
283}
284DEF_OMANIP1( if_space_or_newline, whitespace::type )
285
286static ostream& serialize_begin( ostream &o, json::type t,
287 whitespace::type ws ) {
288 switch ( t ) {
289 case json::array :
290 o << '[' << if_emit( ws, ' ' );
291 break;
292 case json::object:
293 o << '{' << if_space_or_newline( ws ) << if_indent( ws, inc_indent );
294 break;
295 default:
296 /* suppress warning */;
297 }
298 return o;
299}
300DEF_OMANIP2( serialize_begin, json::type, whitespace::type )
301
302static ostream& serialize_end( ostream &o, json::type t, whitespace::type ws ) {
303 switch ( t ) {
304 case json::array:
305 o << if_emit( ws, ' ' ) << ']';
306 break;
307 case json::object:
308 o << if_space_or_newline( ws ) << if_indent( ws, dec_indent )
309 << if_indent( ws, indent ) << '}';
310 break;
311 default:
312 /* suppress warning */;
313 }
314 return o;
315}
316DEF_OMANIP2( serialize_end, json::type, whitespace::type )
317
318static ostream& serialize_boolean( ostream &o, zstring const &s ) {
319 assert_json_type( json::boolean, s );
320 return o << s;
321}
322DEF_OMANIP1( serialize_boolean, zstring const& )
323
324static ostream& serialize_number( ostream &o, zstring const &s ) {
325 assert_json_type( json::number, s );
326 return o << s;
327}
328DEF_OMANIP1( serialize_number, zstring const& )
329
330static ostream& serialize_string( ostream &o, zstring const &s ) {
331 zstring temp( s );
332 escape_json_chars( &temp );
333 temp.insert( (zstring::size_type)0, 1, '"' );
334 temp.append( 1, '"' );
335 assert_json_type( json::string, temp );
336 return o << temp;
337}
338DEF_OMANIP1( serialize_string, zstring const& )
339
340static ostream& serialize_children( ostream&, store::Item_t const&, json::type,
341 whitespace::type );
342DEF_OMANIP3( serialize_children, store::Item_t const&, json::type,
343 whitespace::type )
344
345static ostream& serialize_json_element( ostream &o,
346 store::Item_t const &element,
347 whitespace::type ws ) {
348 zstring const element_name( element->getNodeName()->getStringValue() );
349 if ( element_name != "json" )
350 throw XQUERY_EXCEPTION(
351 zerr::ZJSE0004_BAD_ELEMENT,
352 ERROR_PARAMS( element_name, "json" )
353 );
354
355 json::type const t = get_json_type( element, false );
356
357 return o
358 << serialize_begin( t, ws )
359 << serialize_children( element, t, ws )
360 << serialize_end( t, ws );
361}
362DEF_OMANIP2( serialize_json_element, store::Item_t const&, whitespace::type )
363
364static ostream& serialize_item_element( ostream &o,
365 store::Item_t const &element,
366 whitespace::type ws ) {
367 zstring const element_name( element->getNodeName()->getStringValue() );
368 if ( element_name != "item" )
369 throw XQUERY_EXCEPTION(
370 zerr::ZJSE0005_BAD_CHILD_ELEMENT,
371 ERROR_PARAMS( element_name, "array", "item" )
372 );
373
374 json::type const t = get_json_type( element );
375
376 return o
377 << serialize_begin( t, ws )
378 << serialize_children( element, t, ws )
379 << serialize_end( t, ws );
380}
381DEF_OMANIP2( serialize_item_element, store::Item_t const&, whitespace::type )
382
383static ostream& serialize_pair_element( ostream &o,
384 store::Item_t const &element,
385 whitespace::type ws ) {
386 zstring const element_name( element->getNodeName()->getStringValue() );
387 if ( element_name != "pair" )
388 throw XQUERY_EXCEPTION(
389 zerr::ZJSE0005_BAD_CHILD_ELEMENT,
390 ERROR_PARAMS( element_name, "object", "pair" )
391 );
392
393 zstring name_att_value;
394 require_attribute_value( element, "name", &name_att_value );
395 json::type const t = get_json_type( element );
396
397 return o
398 << if_indent( ws, indent ) << serialize_string( name_att_value )
399 << if_emit( ws, ' ' ) << ':' << if_emit( ws, ' ' )
400 << serialize_begin( t, ws )
401 << serialize_children( element, t, ws )
402 << serialize_end( t, ws );
403}
404DEF_OMANIP2( serialize_pair_element, store::Item_t const&, whitespace::type )
405
406static ostream& serialize_children( ostream &o, store::Item_t const &parent,
407 json::type parent_type,
408 whitespace::type ws ) {
409 if ( parent_type == json::null )
410 o << "null";
411 else {
412 oseparator sep;
413 if ( ws == whitespace::none )
414 sep.sep( "," );
415 else if ( ws == whitespace::some || parent_type == json::array )
416 sep.sep( ", " );
417 else
418 sep.sep( ",\n" );
419
420 store::Iterator_t i = parent->getChildren();
421 i->open();
422 store::Item_t child;
423 while ( i->next( child ) ) {
424 o << sep;
425
426 switch ( child->getNodeKind() ) {
427
428 case store::StoreConsts::elementNode:
429 switch ( parent_type ) {
430 case json::none:
431 o << serialize_json_element( child, ws );
432 break;
433 case json::array:
434 o << serialize_item_element( child, ws );
435 break;
436 case json::object:
437 o << serialize_pair_element( child, ws );
438 break;
439 default:
440 throw XQUERY_EXCEPTION(
441 zerr::ZJSE0006_NO_ELEMENT_CHILD,
442 ERROR_PARAMS( json::type_string_of[ parent_type ] )
443 );
444 }
445 break;
446
447 case store::StoreConsts::textNode:
448 switch ( parent_type ) {
449 case json::boolean:
450 o << serialize_boolean( child->getStringValue() );
451 break;
452 case json::number:
453 o << serialize_number( child->getStringValue() );
454 break;
455 case json::string:
456 o << serialize_string( child->getStringValue() );
457 break;
458 default:
459 throw XQUERY_EXCEPTION(
460 zerr::ZJSE0007_NO_TEXT_CHILD,
461 ERROR_PARAMS( json::type_string_of[ parent_type ] )
462 );
463 }
464 break;
465
466 default:
467 // do nothing
468 break;
469 } // switch
470 } // while
471 i->close();
472 }
473 return o;
474}
475
476///////////////////////////////////////////////////////////////////////////////
477
478namespace snelson {
479
480void serialize( ostream &o, store::Item_t const &item, whitespace::type ws ) {
481 switch ( item->getNodeKind() ) {
482 case store::StoreConsts::documentNode:
483 o << serialize_children( item, json::none, ws );
484 break;
485 case store::StoreConsts::elementNode:
486 o << serialize_json_element( item, ws );
487 break;
488 default:
489 throw XQUERY_EXCEPTION( zerr::ZJSE0001_NOT_DOCUMENT_OR_ELEMENT_NODE );
490 }
491}
492
493} // namespace snelson
494
495///////////////////////////////////////////////////////////////////////////////
496
497} // namespace zorba
498/* vim:set et sw=2 ts=2: */
0499
=== added file 'src/runtime/json/snelson.h'
--- src/runtime/json/snelson.h 1970-01-01 00:00:00 +0000
+++ src/runtime/json/snelson.h 2012-01-23 00:53:24 +0000
@@ -0,0 +1,41 @@
1/*
2 * Copyright 2006-2011 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "stdafx.h"
17
18#ifndef ZORBA_RUNTIME_JSON_SNELSON_H
19#define ZORBA_RUNTIME_JSON_SNELSON_H
20
21#include <iostream>
22
23#include "store/api/item.h"
24#include "util/json_parser.h"
25
26#include "common.h"
27
28namespace zorba {
29namespace snelson {
30
31///////////////////////////////////////////////////////////////////////////////
32
33void parse( json::parser &p, store::Item_t *result );
34void serialize( std::ostream&, store::Item_t const &item, whitespace::type );
35
36///////////////////////////////////////////////////////////////////////////////
37
38} // namespace snelson
39} // namespace zorba
40#endif /* ZORBA_RUNTIME_JSON_SNELSON_H */
41/* vim:set et sw=2 ts=2: */
042
=== added directory 'src/runtime/spec/json'
=== added file 'src/runtime/spec/json/json.xml'
--- src/runtime/spec/json/json.xml 1970-01-01 00:00:00 +0000
+++ src/runtime/spec/json/json.xml 2012-01-23 00:53:24 +0000
@@ -0,0 +1,52 @@
1<?xml version="1.0" encoding="UTF-8"?>
2
3<!--
4////////////////////////////////////////////////////////////////////////////////
5////////////////////////////////////////////////////////////////////////////////
6-->
7<zorba:iterators
8 xmlns:zorba="http://www.zorba-xquery.com"
9 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10 xsi:schemaLocation="http://www.zorba-xquery.com ../runtime.xsd">
11
12<!--
13/*******************************************************************************
14*******************************************************************************/
15-->
16<zorba:iterator name="JSONParseInternal" arity="nary">
17
18 <zorba:description author="Zorba Team">
19 function for parsing strings into json-xdm
20 </zorba:description>
21
22 <zorba:function isDeterministic="true">
23 <zorba:signature localname="parse-internal" prefix="fn-zorba-json">
24 <zorba:param>xs:string</zorba:param>
25 <zorba:param>item()?</zorba:param>
26 <zorba:output>element()*</zorba:output>
27 </zorba:signature>
28 </zorba:function>
29
30</zorba:iterator>
31
32<!--
33/*******************************************************************************
34*******************************************************************************/
35-->
36<zorba:iterator name="JSONSerializeInternal" arity="nary">
37
38 <zorba:description author="Zorba Team">
39 Function to serialize json/jsonml xdm to string
40 </zorba:description>
41
42 <zorba:function isDeterministic="true">
43 <zorba:signature localname="serialize-internal" prefix="fn-zorba-json">
44 <zorba:param>item()*</zorba:param>
45 <zorba:param>item()?</zorba:param>
46 <zorba:output>xs:string</zorba:output>
47 </zorba:signature>
48 </zorba:function>
49
50</zorba:iterator>
51
52</zorba:iterators>
053
=== modified file 'src/runtime/spec/mappings.xml'
--- src/runtime/spec/mappings.xml 2011-10-14 07:35:51 +0000
+++ src/runtime/spec/mappings.xml 2012-01-23 00:53:24 +0000
@@ -106,6 +106,10 @@
106 define="ZORBA_STRING_FN_NS" 106 define="ZORBA_STRING_FN_NS"
107 prefix="fn-zorba-string"/>107 prefix="fn-zorba-string"/>
108108
109 <zorba:namespace uri="http://www.zorba-xquery.com/modules/converters/json"
110 define="ZORBA_JSON_FN_NS"
111 prefix="fn-zorba-json"/>
112
109 <zorba:namespace uri="http://www.zorba-xquery.com/modules/fetch"113 <zorba:namespace uri="http://www.zorba-xquery.com/modules/fetch"
110 define="ZORBA_FETCH_FN_NS" 114 define="ZORBA_FETCH_FN_NS"
111 prefix="fn-zorba-fetch"/>115 prefix="fn-zorba-fetch"/>
112116
=== modified file 'src/runtime/visitors/pregenerated/planiter_visitor.h'
--- src/runtime/visitors/pregenerated/planiter_visitor.h 2012-01-11 17:30:25 +0000
+++ src/runtime/visitors/pregenerated/planiter_visitor.h 2012-01-23 00:53:24 +0000
@@ -251,6 +251,10 @@
251251
252 class FunctionAnnotationsIterator;252 class FunctionAnnotationsIterator;
253253
254 class JSONParseInternal;
255
256 class JSONSerializeInternal;
257
254 class SqrtIterator;258 class SqrtIterator;
255259
256 class ExpIterator;260 class ExpIterator;
@@ -929,6 +933,12 @@
929 virtual void beginVisit ( const FunctionAnnotationsIterator& ) = 0;933 virtual void beginVisit ( const FunctionAnnotationsIterator& ) = 0;
930 virtual void endVisit ( const FunctionAnnotationsIterator& ) = 0;934 virtual void endVisit ( const FunctionAnnotationsIterator& ) = 0;
931935
936 virtual void beginVisit ( const JSONParseInternal& ) = 0;
937 virtual void endVisit ( const JSONParseInternal& ) = 0;
938
939 virtual void beginVisit ( const JSONSerializeInternal& ) = 0;
940 virtual void endVisit ( const JSONSerializeInternal& ) = 0;
941
932 virtual void beginVisit ( const SqrtIterator& ) = 0;942 virtual void beginVisit ( const SqrtIterator& ) = 0;
933 virtual void endVisit ( const SqrtIterator& ) = 0;943 virtual void endVisit ( const SqrtIterator& ) = 0;
934944
935945
=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.cpp'
--- src/runtime/visitors/pregenerated/printer_visitor.cpp 2012-01-11 17:30:25 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.cpp 2012-01-23 00:53:24 +0000
@@ -50,6 +50,7 @@
50#include "runtime/function_item/function_item_iter.h"50#include "runtime/function_item/function_item_iter.h"
51#include "runtime/indexing/ic_ddl.h"51#include "runtime/indexing/ic_ddl.h"
52#include "runtime/introspection/sctx.h"52#include "runtime/introspection/sctx.h"
53#include "runtime/json/json.h"
53#include "runtime/maths/maths.h"54#include "runtime/maths/maths.h"
54#include "runtime/nodes/node_position.h"55#include "runtime/nodes/node_position.h"
55#include "runtime/nodes/nodes.h"56#include "runtime/nodes/nodes.h"
@@ -1650,6 +1651,34 @@
1650// </FunctionAnnotationsIterator>1651// </FunctionAnnotationsIterator>
16511652
16521653
1654// <JSONParseInternal>
1655void PrinterVisitor::beginVisit ( const JSONParseInternal& a) {
1656 thePrinter.startBeginVisit("JSONParseInternal", ++theId);
1657 printCommons( &a, theId );
1658 thePrinter.endBeginVisit( theId );
1659}
1660
1661void PrinterVisitor::endVisit ( const JSONParseInternal& ) {
1662 thePrinter.startEndVisit();
1663 thePrinter.endEndVisit();
1664}
1665// </JSONParseInternal>
1666
1667
1668// <JSONSerializeInternal>
1669void PrinterVisitor::beginVisit ( const JSONSerializeInternal& a) {
1670 thePrinter.startBeginVisit("JSONSerializeInternal", ++theId);
1671 printCommons( &a, theId );
1672 thePrinter.endBeginVisit( theId );
1673}
1674
1675void PrinterVisitor::endVisit ( const JSONSerializeInternal& ) {
1676 thePrinter.startEndVisit();
1677 thePrinter.endEndVisit();
1678}
1679// </JSONSerializeInternal>
1680
1681
1653// <SqrtIterator>1682// <SqrtIterator>
1654void PrinterVisitor::beginVisit ( const SqrtIterator& a) {1683void PrinterVisitor::beginVisit ( const SqrtIterator& a) {
1655 thePrinter.startBeginVisit("SqrtIterator", ++theId);1684 thePrinter.startBeginVisit("SqrtIterator", ++theId);
16561685
=== modified file 'src/runtime/visitors/pregenerated/printer_visitor.h'
--- src/runtime/visitors/pregenerated/printer_visitor.h 2012-01-11 17:30:25 +0000
+++ src/runtime/visitors/pregenerated/printer_visitor.h 2012-01-23 00:53:24 +0000
@@ -379,6 +379,12 @@
379 void beginVisit( const FunctionAnnotationsIterator& );379 void beginVisit( const FunctionAnnotationsIterator& );
380 void endVisit ( const FunctionAnnotationsIterator& );380 void endVisit ( const FunctionAnnotationsIterator& );
381381
382 void beginVisit( const JSONParseInternal& );
383 void endVisit ( const JSONParseInternal& );
384
385 void beginVisit( const JSONSerializeInternal& );
386 void endVisit ( const JSONSerializeInternal& );
387
382 void beginVisit( const SqrtIterator& );388 void beginVisit( const SqrtIterator& );
383 void endVisit ( const SqrtIterator& );389 void endVisit ( const SqrtIterator& );
384390
385391
=== modified file 'src/unit_tests/CMakeLists.txt'
--- src/unit_tests/CMakeLists.txt 2011-12-21 14:40:33 +0000
+++ src/unit_tests/CMakeLists.txt 2012-01-23 00:53:24 +0000
@@ -16,4 +16,5 @@
16SET(UNIT_TEST_SRCS16SET(UNIT_TEST_SRCS
17 unit_tests.cpp17 unit_tests.cpp
18 test_uri.cpp18 test_uri.cpp
19 json_parser.cpp
19)20)
2021
=== added file 'src/unit_tests/json_parser.cpp'
--- src/unit_tests/json_parser.cpp 1970-01-01 00:00:00 +0000
+++ src/unit_tests/json_parser.cpp 2012-01-23 00:53:24 +0000
@@ -0,0 +1,636 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <sstream>
18
19#include "util/json_parser.h"
20
21using namespace std;
22using namespace zorba;
23using namespace zorba::json;
24
25///////////////////////////////////////////////////////////////////////////////
26
27static int failures;
28
29static bool assert_true( char const *expr, int line, bool result ) {
30 if ( !result ) {
31 cout << "FAILED, line " << line << ": " << expr << endl;
32 ++failures;
33 }
34 return result;
35}
36
37static void print_exception( char const *expr, int line,
38 std::exception const &e ) {
39 assert_true( expr, line, false );
40 cout << "+ exception: ";
41 if ( json::exception const *j = dynamic_cast<json::exception const*>( &e ) ) {
42 json::location const &loc = j->get_loc();
43 if ( loc.file() && *loc.file() )
44 cout << '"' << loc.file() << "\": ";
45 cout << loc.line();
46 if ( loc.column() )
47 cout << ',' << loc.column();
48 cout << ": ";
49 }
50 cout << e.what() << endl;
51}
52
53#define ASSERT_TRUE( EXPR ) assert_true( #EXPR, __LINE__, !!(EXPR) )
54
55#define ASSERT_EXCEPTION( EXPR, EXCEPTION ) \
56 try { EXPR; assert_true( #EXPR, __LINE__, false ); } \
57 catch ( EXCEPTION const& ) { }
58
59#define ASSERT_NO_EXCEPTION( EXPR ) \
60 try { EXPR; } \
61 catch ( std::exception const &e ) { print_exception( #EXPR, __LINE__, e ); } \
62 catch ( ... ) { assert_true( #EXPR, __LINE__, false ); }
63
64#define ASSERT_TRUE_AND_NO_EXCEPTION( EXPR ) \
65 try { ASSERT_TRUE( EXPR ); } \
66 catch ( std::exception const &e ) { print_exception( #EXPR, __LINE__, e ); } \
67 catch ( ... ) { assert_true( #EXPR, __LINE__, false ); }
68
69///////////////////////////////////////////////////////////////////////////////
70
71static void test_empty_stream() {
72 char const source[] = "";
73 istringstream iss( source );
74 parser p( iss );
75 token t;
76 ASSERT_NO_EXCEPTION( p.next( &t ) );
77}
78
79static void test_illegal_character() {
80 char const source[] = " x ";
81 istringstream iss( source );
82 lexer lex( iss );
83 token t;
84 ASSERT_EXCEPTION( lex.next( &t ), illegal_character );
85}
86
87static void test_illegal_codepoint() {
88 static char const *const sources[] = {
89 " \" \\u \" ",
90 " \" \\u0 \" ",
91 " \" \\u00 \" ",
92 " \" \\u000 \" ",
93 " \" \\uG \" ",
94 " \" \\u\" ",
95 0
96 };
97
98 for ( char const *const *s = sources; *s; ++s ) {
99 istringstream iss( *s );
100 lexer lex( iss );
101 token t;
102 ASSERT_EXCEPTION( lex.next( &t ), illegal_codepoint );
103 }
104}
105
106static void test_illegal_escape() {
107 char const source[] = " \" \\x \" ";
108 istringstream iss( source );
109 lexer lex( iss );
110 token t;
111 ASSERT_EXCEPTION( lex.next( &t ), illegal_escape );
112}
113
114static void test_illegal_literal() {
115 static char const *const sources[] = {
116 " f ",
117 " fa ",
118 " fal ",
119 " fals ",
120 " falsee ",
121 " t ",
122 " tr ",
123 " tru ",
124 " truee ",
125 " n ",
126 " nu ",
127 " nul ",
128 " nulll ",
129 0
130 };
131
132 for ( char const *const *s = sources; *s; ++s ) {
133 istringstream iss( *s );
134 lexer lex( iss );
135 token t;
136 ASSERT_EXCEPTION( lex.next( &t ), illegal_literal );
137 }
138}
139
140static void test_illegal_number() {
141}
142
143static void test_json_org_example() {
144 char const source[] =
145/* 1 */ "{" "\n"
146/* 2 */ " \"glossary\": {" "\n"
147/* 3 */ " \"title\": \"example glossary\"," "\n"
148/* 4 */ " \"GlossDiv\": {" "\n"
149/* 5 */ " \"title\": \"S\"," "\n"
150/* 6 */ " \"GlossList\": {" "\n"
151/* 7 */ " \"GlossEntry\": {" "\n"
152/* 8 */ " \"ID\": \"SGML\"," "\n"
153/* 9 */ " \"SortAs\": \"SGML\"," "\n"
154/* 10 */ " \"GlossTerm\": \"Standard Generalized Markup Language\"," "\n"
155/* 11 */ " \"Acronym\": \"SGML\"," "\n"
156/* 12 */ " \"Abbrev\": \"ISO 8879:1986\"," "\n"
157/* 13 */ " \"GlossDef\": {" "\n"
158/* 14 */ " \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\"," "\n"
159/* 15 */ " \"GlossSeeAlso\": [\"GML\", \"XML\"]" "\n"
160/* 16 */ " }," "\n"
161/* 17 */ " \"GlossSee\": \"markup\"" "\n"
162/* 18 */ " }" "\n"
163/* 19 */ " }" "\n"
164/* 20 */ " }" "\n"
165/* 21 */ " }" "\n"
166/* 22 */ "}" "\n" ;
167
168 istringstream iss( source );
169 parser p( iss );
170 token t;
171
172 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 1: {
173 ASSERT_TRUE( t == token::begin_object );
174
175 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 2: "glossary"
176 ASSERT_TRUE( t == token::string );
177
178 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 2: :
179 ASSERT_TRUE( t == token::name_separator );
180
181 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 2: {
182 ASSERT_TRUE( t == token::begin_object );
183
184 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 3: "title"
185 ASSERT_TRUE( t == token::string );
186
187 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 3: :
188 ASSERT_TRUE( t == token::name_separator );
189
190 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 3: "example glossary"
191 ASSERT_TRUE( t == token::string );
192
193 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 3: ,
194 ASSERT_TRUE( t == token::value_separator );
195
196 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 4: "GlossDiv"
197 ASSERT_TRUE( t == token::string );
198
199 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 4: :
200 ASSERT_TRUE( t == token::name_separator );
201
202 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 4: {
203 ASSERT_TRUE( t == token::begin_object );
204
205 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 5: "title"
206 ASSERT_TRUE( t == token::string );
207
208 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 5: :
209 ASSERT_TRUE( t == token::name_separator );
210
211 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 5: "S"
212 ASSERT_TRUE( t == token::string );
213
214 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 5: ,
215 ASSERT_TRUE( t == token::value_separator );
216
217 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 6: "GlossList"
218 ASSERT_TRUE( t == token::string );
219
220 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 6: :
221 ASSERT_TRUE( t == token::name_separator );
222
223 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 6: {
224 ASSERT_TRUE( t == token::begin_object );
225
226 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 7: "GlossEntry"
227 ASSERT_TRUE( t == token::string );
228
229 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 7: :
230 ASSERT_TRUE( t == token::name_separator );
231
232 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 7: {
233 ASSERT_TRUE( t == token::begin_object );
234
235 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 8: "ID"
236 ASSERT_TRUE( t == token::string );
237
238 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 8: :
239 ASSERT_TRUE( t == token::name_separator );
240
241 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 8: "SGML"
242 ASSERT_TRUE( t == token::string );
243
244 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 8: ,
245 ASSERT_TRUE( t == token::value_separator );
246
247 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 9: "SortAs"
248 ASSERT_TRUE( t == token::string );
249
250 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 9: :
251 ASSERT_TRUE( t == token::name_separator );
252
253 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 9: "SGML"
254 ASSERT_TRUE( t == token::string );
255
256 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 9: ,
257 ASSERT_TRUE( t == token::value_separator );
258
259 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 10: "GlossTerm"
260 ASSERT_TRUE( t == token::string );
261
262 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 10: :
263 ASSERT_TRUE( t == token::name_separator );
264
265 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 10: "Standard ..."
266 ASSERT_TRUE( t == token::string );
267
268 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 10: ,
269 ASSERT_TRUE( t == token::value_separator );
270
271 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 11: "Acronym"
272 ASSERT_TRUE( t == token::string );
273
274 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 11: :
275 ASSERT_TRUE( t == token::name_separator );
276
277 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 11: "SGML"
278 ASSERT_TRUE( t == token::string );
279
280 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 11: ,
281 ASSERT_TRUE( t == token::value_separator );
282
283 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 12: "Abbrev"
284 ASSERT_TRUE( t == token::string );
285
286 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 12: :
287 ASSERT_TRUE( t == token::name_separator );
288
289 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 12: "ISO 8879:1986"
290 ASSERT_TRUE( t == token::string );
291
292 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 12: ,
293 ASSERT_TRUE( t == token::value_separator );
294
295 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 13: "GlossDef"
296 ASSERT_TRUE( t == token::string );
297
298 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 13: :
299 ASSERT_TRUE( t == token::name_separator );
300
301 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 13: {
302 ASSERT_TRUE( t == token::begin_object );
303
304 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 14: "para"
305 ASSERT_TRUE( t == token::string );
306
307 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 14: :
308 ASSERT_TRUE( t == token::name_separator );
309
310 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 14: "A meta-markup ..."
311 ASSERT_TRUE( t == token::string );
312
313 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 14: ,
314 ASSERT_TRUE( t == token::value_separator );
315
316 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 15: "GlossSeeAlso"
317 ASSERT_TRUE( t == token::string );
318
319 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 15: :
320 ASSERT_TRUE( t == token::name_separator );
321
322 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 15: [
323 ASSERT_TRUE( t == token::begin_array );
324
325 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 15: "GML"
326 ASSERT_TRUE( t == token::string );
327
328 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 15: ,
329 ASSERT_TRUE( t == token::value_separator );
330
331 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 15: "XML"
332 ASSERT_TRUE( t == token::string );
333
334 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 15: ]
335 ASSERT_TRUE( t == token::end_array );
336
337 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 16: }
338 ASSERT_TRUE( t == token::end_object );
339
340 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 16: ,
341 ASSERT_TRUE( t == token::value_separator );
342
343 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 17: "GlossSee"
344 ASSERT_TRUE( t == token::string );
345
346 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 17: :
347 ASSERT_TRUE( t == token::name_separator );
348
349 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 17: "markup"
350 ASSERT_TRUE( t == token::string );
351
352 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 18: }
353 ASSERT_TRUE( t == token::end_object );
354
355 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 19: }
356 ASSERT_TRUE( t == token::end_object );
357
358 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 20: }
359 ASSERT_TRUE( t == token::end_object );
360
361 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 21: }
362 ASSERT_TRUE( t == token::end_object );
363
364 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) ); // 22: }
365 ASSERT_TRUE( t == token::end_object );
366
367 ASSERT_TRUE( !p.next( &t ) );
368}
369
370static void test_lexer_array() {
371 char const source[] = "[ 1, \"2\", false, true, null ]";
372 istringstream iss( source );
373 lexer lex( iss );
374 token t;
375
376 ASSERT_TRUE( lex.next( &t ) );
377 ASSERT_TRUE( t == token::begin_array );
378
379 ASSERT_TRUE( lex.next( &t ) );
380 ASSERT_TRUE( t == token::number );
381 ASSERT_TRUE( t.get_value() == "1" );
382
383 ASSERT_TRUE( lex.next( &t ) );
384 ASSERT_TRUE( t == token::value_separator );
385
386 ASSERT_TRUE( lex.next( &t ) );
387 ASSERT_TRUE( t == token::string );
388 ASSERT_TRUE( t.get_value() == "2" );
389
390 ASSERT_TRUE( lex.next( &t ) );
391 ASSERT_TRUE( t == token::value_separator );
392
393 ASSERT_TRUE( lex.next( &t ) );
394 ASSERT_TRUE( t == token::json_false );
395
396 ASSERT_TRUE( lex.next( &t ) );
397 ASSERT_TRUE( t == token::value_separator );
398
399 ASSERT_TRUE( lex.next( &t ) );
400 ASSERT_TRUE( t == token::json_true );
401
402 ASSERT_TRUE( lex.next( &t ) );
403 ASSERT_TRUE( t == token::value_separator );
404
405 ASSERT_TRUE( lex.next( &t ) );
406 ASSERT_TRUE( t == token::json_null );
407
408 ASSERT_TRUE( lex.next( &t ) );
409 ASSERT_TRUE( t == token::end_array );
410
411 ASSERT_TRUE( !lex.next( &t ) );
412}
413
414static void test_lexer_object() {
415 char const source[] = "{ \"a\" : 1, \"b\" : \"2\" }";
416 istringstream iss( source );
417 lexer lex( iss );
418 token t;
419
420 ASSERT_TRUE( lex.next( &t ) );
421 ASSERT_TRUE( t == token::begin_object );
422
423 ASSERT_TRUE( lex.next( &t ) );
424 ASSERT_TRUE( t == token::string );
425
426 ASSERT_TRUE( lex.next( &t ) );
427 ASSERT_TRUE( t == token::name_separator );
428
429 ASSERT_TRUE( lex.next( &t ) );
430 ASSERT_TRUE( t == token::number );
431
432 ASSERT_TRUE( lex.next( &t ) );
433 ASSERT_TRUE( t == token::value_separator );
434
435 ASSERT_TRUE( lex.next( &t ) );
436 ASSERT_TRUE( t == token::string );
437
438 ASSERT_TRUE( lex.next( &t ) );
439 ASSERT_TRUE( t == token::name_separator );
440
441 ASSERT_TRUE( lex.next( &t ) );
442 ASSERT_TRUE( t == token::string );
443
444 ASSERT_TRUE( lex.next( &t ) );
445 ASSERT_TRUE( t == token::end_object );
446
447 ASSERT_TRUE( !lex.next( &t ) );
448}
449
450static void test_parser_array() {
451 char const source[] = "[ 1, \"2\", false, true, null ]";
452 istringstream iss( source );
453 parser p( iss );
454 token t;
455
456 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
457 ASSERT_TRUE( t == token::begin_array );
458
459 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
460 ASSERT_TRUE( t == token::number );
461 ASSERT_TRUE( t.get_value() == "1" );
462
463 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
464 ASSERT_TRUE( t == token::value_separator );
465
466 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
467 ASSERT_TRUE( t == token::string );
468 ASSERT_TRUE( t.get_value() == "2" );
469
470 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
471 ASSERT_TRUE( t == token::value_separator );
472
473 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
474 ASSERT_TRUE( t == token::json_false );
475
476 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
477 ASSERT_TRUE( t == token::value_separator );
478
479 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
480 ASSERT_TRUE( t == token::json_true );
481
482 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
483 ASSERT_TRUE( t == token::value_separator );
484
485 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
486 ASSERT_TRUE( t == token::json_null );
487
488 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
489 ASSERT_TRUE( t == token::end_array );
490
491 ASSERT_TRUE( !p.next( &t ) );
492}
493
494static void test_parser_object() {
495 char const source[] = "{ \"a\" : 1, \"b\" : \"2\" }";
496 istringstream iss( source );
497 parser p( iss );
498 token t;
499
500 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
501 ASSERT_TRUE( t == token::begin_object );
502
503 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
504 ASSERT_TRUE( t == token::string );
505
506 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
507 ASSERT_TRUE( t == token::name_separator );
508
509 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
510 ASSERT_TRUE( t == token::number );
511
512 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
513 ASSERT_TRUE( t == token::value_separator );
514
515 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
516 ASSERT_TRUE( t == token::string );
517
518 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
519 ASSERT_TRUE( t == token::name_separator );
520
521 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
522 ASSERT_TRUE( t == token::string );
523
524 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
525 ASSERT_TRUE( t == token::end_object );
526
527 ASSERT_TRUE( !p.next( &t ) );
528}
529
530static void test_unexpected_token() {
531 token t;
532 {
533 char const source[] = "{ 1 }";
534 istringstream iss( source );
535 parser p( iss );
536
537 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
538 ASSERT_TRUE( t == token::begin_object );
539 ASSERT_EXCEPTION( p.next( &t ), unexpected_token );
540 }
541 {
542 char const source[] = "{ \"a\" : 1, }";
543 istringstream iss( source );
544 parser p( iss );
545
546 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
547 ASSERT_TRUE( t == token::begin_object );
548
549 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
550 ASSERT_TRUE( t == token::string );
551
552 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
553 ASSERT_TRUE( t == token::name_separator );
554
555 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
556 ASSERT_TRUE( t == token::number );
557
558 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
559 ASSERT_TRUE( t == token::value_separator );
560
561 ASSERT_EXCEPTION( p.next( &t ), unexpected_token );
562 }
563 {
564 char const source[] = "{ \"t\" : true \"f\" : false }";
565 istringstream iss( source );
566 parser p( iss );
567
568 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
569 ASSERT_TRUE( t == token::begin_object );
570
571 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
572 ASSERT_TRUE( t == token::string );
573
574 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
575 ASSERT_TRUE( t == token::name_separator );
576
577 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
578 ASSERT_TRUE( t == token::json_true );
579
580 ASSERT_EXCEPTION( p.next( &t ), unexpected_token );
581 }
582 {
583 char const source[] = "[ 1";
584 istringstream iss( source );
585 parser p( iss );
586
587 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
588 ASSERT_TRUE( t == token::begin_array );
589
590 ASSERT_TRUE_AND_NO_EXCEPTION( p.next( &t ) );
591 ASSERT_TRUE( t == token::number );
592
593 ASSERT_EXCEPTION( p.next( &t ), unexpected_token );
594 }
595}
596
597static void test_unterminated_string() {
598 char const source[] = " \"hello ";
599 istringstream iss( source );
600 lexer lex( iss );
601 token t;
602
603 ASSERT_EXCEPTION( lex.next( &t ), unterminated_string );
604}
605
606///////////////////////////////////////////////////////////////////////////////
607
608namespace zorba {
609namespace UnitTests {
610
611int json_parser( int, char*[] ) {
612
613 // lexer-only tests
614 test_lexer_array();
615 test_lexer_object();
616 test_illegal_character();
617 test_illegal_codepoint();
618 test_illegal_escape();
619 test_illegal_literal();
620 test_illegal_number();
621 test_unterminated_string();
622
623 // parser tests
624 test_empty_stream();
625 test_parser_array();
626 test_parser_object();
627 test_unexpected_token();
628 test_json_org_example();
629
630 cout << failures << " test(s) failed\n";
631 return failures ? 1 : 0;
632}
633
634} // namespace UnitTests
635} // namespace zorba
636/* vim:set et sw=2 ts=2: */
0637
=== modified file 'src/unit_tests/unit_test_list.h'
--- src/unit_tests/unit_test_list.h 2011-06-14 17:26:33 +0000
+++ src/unit_tests/unit_test_list.h 2012-01-23 00:53:24 +0000
@@ -28,6 +28,7 @@
28 /**28 /**
29 * ADD NEW UNIT TESTS HERE29 * ADD NEW UNIT TESTS HERE
30 */30 */
31 int json_parser( int, char*[] );
3132
3233
33 void initializeTestList();34 void initializeTestList();
3435
=== modified file 'src/unit_tests/unit_tests.cpp'
--- src/unit_tests/unit_tests.cpp 2011-06-14 17:26:33 +0000
+++ src/unit_tests/unit_tests.cpp 2012-01-23 00:53:24 +0000
@@ -38,6 +38,7 @@
38 */38 */
39 void initializeTestList() {39 void initializeTestList() {
40 libunittests["uri"] = runUriTest;40 libunittests["uri"] = runUriTest;
41 libunittests["json_parser"] = json_parser;
41#ifdef ZORBA_WITH_DEBUGGER42#ifdef ZORBA_WITH_DEBUGGER
42// libunittests["debugger_protocol"] = runDebuggerProtocolTest;43// libunittests["debugger_protocol"] = runDebuggerProtocolTest;
43#endif44#endif
4445
=== modified file 'src/util/CMakeLists.txt'
--- src/util/CMakeLists.txt 2011-07-18 14:25:21 +0000
+++ src/util/CMakeLists.txt 2012-01-23 00:53:24 +0000
@@ -20,6 +20,8 @@
20 dir.cpp20 dir.cpp
21 fs_util.cpp21 fs_util.cpp
22 indent.cpp22 indent.cpp
23 json_parser.cpp
24 mem_streambuf.cpp
23 regex.cpp25 regex.cpp
24 string_util.cpp26 string_util.cpp
25 unicode_util.cpp27 unicode_util.cpp
2628
=== added file 'src/util/json_parser.cpp'
--- src/util/json_parser.cpp 1970-01-01 00:00:00 +0000
+++ src/util/json_parser.cpp 2012-01-23 00:53:24 +0000
@@ -0,0 +1,653 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "diagnostics/assert.h"
18
19#include "ascii_util.h"
20#include "stl_util.h"
21#include "string_util.h"
22#include "utf8_util.h"
23
24#define DEBUG_JSON_PARSER 0
25
26#if DEBUG_JSON_PARSER
27# include "indent.h"
28#endif /* DEBUG_JSON_PARSER */
29
30#include "json_parser.h"
31
32using namespace std;
33
34namespace zorba {
35namespace json {
36
37///////////////////////////////////////////////////////////////////////////////
38
39char const *const type_string_of[] = {
40 "none",
41 "array",
42 "boolean",
43 "null",
44 "number",
45 "object",
46 "string"
47};
48
49type map_type( token::type tt ) {
50 switch ( tt ) {
51 case token::string:
52 return string;
53 case token::number:
54 return number;
55 case token::json_false:
56 case token::json_true:
57 return boolean;
58 case token::json_null:
59 return null;
60 default:
61 return none;
62 }
63}
64
65///////////////////////////////////////////////////////////////////////////////
66
67exception::exception( location const &loc, std::string const &message ) :
68 loc_( loc ), message_( message )
69{
70}
71
72exception::~exception() throw() {
73 // out-of-line since it's virtual
74}
75
76char const* exception::what() const throw() {
77 return message_.c_str();
78}
79
80illegal_character::illegal_character( location const &loc, char c ) :
81 exception( loc, BUILD_STRING( '\'', c, "': illegal character" ) ),
82 c_( c )
83{
84}
85
86illegal_character::~illegal_character() throw() {
87 // out-of-line since it's virtual
88}
89
90illegal_codepoint::illegal_codepoint( location const &loc,
91 token::value_type const &cp ) :
92 exception( loc, BUILD_STRING( '"', cp, "\": illegal codepoint" ) ),
93 codepoint_( cp )
94{
95}
96
97illegal_codepoint::~illegal_codepoint() throw() {
98 // out-of-line since it's virtual
99}
100
101illegal_escape::illegal_escape( location const &loc, char c ) :
102 exception( loc, BUILD_STRING( "\"\\", c, "\": illegal character escape" ) ),
103 esc_( c )
104{
105}
106
107illegal_escape::~illegal_escape() throw() {
108 // out-of-line since it's virtual
109}
110
111illegal_literal::illegal_literal( location const &loc ) :
112 exception( loc, "illegal literal" )
113{
114}
115
116illegal_literal::~illegal_literal() throw() {
117 // out-of-line since it's virtual
118}
119
120illegal_number::illegal_number( location const &loc ) :
121 exception( loc, "illegal number" )
122{
123}
124
125illegal_number::~illegal_number() throw() {
126 // out-of-line since it's virtual
127}
128
129unexpected_token::unexpected_token( token const &t ) :
130 exception( t.get_loc(), BUILD_STRING( '"', t, "\": unexpected token" ) ),
131 token_( t )
132{
133}
134
135unexpected_token::~unexpected_token() throw() {
136 // out-of-line since it's virtual
137}
138
139unterminated_string::unterminated_string( location const &loc ) :
140 exception( loc, "unterminated string" )
141{
142}
143
144unterminated_string::~unterminated_string() throw() {
145 // out-of-line since it's virtual
146}
147
148///////////////////////////////////////////////////////////////////////////////
149
150token::token() :
151 type_( none )
152{
153}
154
155ostream& operator<<( ostream &o, token::type tt ) {
156 switch ( tt ) {
157 case token::string : o << "string"; break;
158 case token::number : o << "number"; break;
159 case token::json_false: o << "false" ; break;
160 case token::json_null : o << "null" ; break;
161 case token::json_true : o << "true" ; break;
162 case token::none : o << "<none>"; break;
163 default : o << static_cast<char>( tt );
164 }
165 return o;
166}
167
168ostream& operator<<( ostream &o, token const &t ) {
169 switch ( t.get_type() ) {
170 case token::string: o << '"' << t.get_value() << '"'; break;
171 case token::number: o << t.get_value() ; break;
172 default : o << t.get_type() ;
173 }
174 return o;
175}
176
177///////////////////////////////////////////////////////////////////////////////
178
179lexer::lexer( istream &in ) :
180 in_( &in ),
181 line_( 1 ),
182 col_( 1 )
183{
184}
185
186bool lexer::get_char( char *c ) {
187 char const temp = in_->get();
188 if ( in_->good() ) {
189 if ( temp == '\n' )
190 ++line_, col_ = 1;
191 else
192 ++col_;
193 if ( c )
194 *c = temp;
195 return true;
196 }
197 return false;
198}
199
200bool lexer::peek_char( char *c ) {
201 *c = in_->peek();
202 return in_->good();
203}
204
205bool lexer::next( token *t ) {
206 while ( true ) {
207 cur_loc_ = cur_loc();
208 char c;
209 if ( !get_char( &c ) )
210 return false;
211 switch ( c ) {
212 case ' ':
213 case '\n':
214 case '\r':
215 case '\t':
216 continue;
217 case '"':
218 t->type_ = token::string;
219 t->loc_ = cur_loc_;
220 parse_string( &t->value_ );
221 return true;
222 case '-':
223 case '0':
224 case '1':
225 case '2':
226 case '3':
227 case '4':
228 case '5':
229 case '6':
230 case '7':
231 case '8':
232 case '9':
233 t->type_ = token::number;
234 t->loc_ = cur_loc_;
235 parse_number( c, &t->value_ );
236 return true;
237 case 'f':
238 case 'n':
239 case 't':
240 t->type_ = parse_literal( c, &t->value_ );
241 t->loc_ = cur_loc_;
242 return true;
243 case '[':
244 case '{':
245 case ']':
246 case '}':
247 case ':':
248 case ',':
249 t->type_ = static_cast<token::type>( c );
250 t->loc_ = cur_loc_;
251 return true;
252 default:
253 throw illegal_character( cur_loc_, c );
254 }
255 } // while
256}
257
258unicode::code_point lexer::parse_codepoint() {
259 static char const hex_digits[] = "0123456789ABCDEF";
260
261 zstring cp_string( "\\u" ); // needed only for error message
262
263 unicode::code_point cp = 0;
264 for ( int i = 1; i <= 4; ++i ) {
265 char c;
266 if ( !get_char( &c ) || !ascii::is_xdigit( c ) )
267 throw illegal_codepoint( cur_loc_, cp_string );
268 cp_string += c;
269 c = ascii::to_upper( c );
270 char const *const p = std::strchr( hex_digits, c );
271 assert( p );
272 cp = (cp << 4) | (p - hex_digits);
273 }
274 return cp;
275}
276
277token::type lexer::parse_literal( char first_c, token::value_type *value ) {
278 static token::value_type const false_value( "false" );
279 static token::value_type const null_value ( "null" );
280 static token::value_type const true_value ( "true" );
281
282 token::type tt;
283 switch ( first_c ) {
284 case 'f': *value = false_value; tt = token::json_false; break;
285 case 'n': *value = null_value ; tt = token::json_null ; break;
286 case 't': *value = true_value ; tt = token::json_true ; break;
287 default : assert( false );
288 }
289
290 char c;
291 for ( char const *s = value->c_str(); *++s; ) {
292 if ( !get_char( &c ) || c != *s )
293 throw illegal_literal( cur_loc_ );
294 }
295 if ( peek_char( &c ) && ascii::is_alnum( c ) )
296 throw illegal_literal( cur_loc_ );
297
298 return tt;
299}
300
301void lexer::parse_number( char first_c, token::value_type *value ) {
302 value->clear();
303
304 // <number> ::= [-] <int> [<frac>] [<exp>]
305 char c = first_c;
306 if ( c == '-' ) {
307 *value += c;
308 if ( !get_char( &c ) )
309 throw illegal_number( cur_loc_ );
310 }
311
312 // <int> := '0' | <1-9> <digit>*
313 if ( !ascii::is_digit( c ) )
314 throw illegal_number( cur_loc_ );
315 *value += c;
316 if ( c == '0' ) {
317 if ( !get_char( &c ) )
318 return;
319 } else {
320 while ( true ) {
321 if ( !get_char( &c ) )
322 return;
323 if ( !ascii::is_digit( c ) )
324 break;
325 *value += c;
326 }
327 }
328
329 // <frac> ::= '.' <digit>+
330 if ( c == '.' ) {
331 *value += c;
332 if ( !get_char( &c ) || !ascii::is_digit( c ) )
333 throw illegal_number( cur_loc_ );
334 *value += c;
335 while ( true ) {
336 if ( !get_char( &c ) )
337 return;
338 if ( !ascii::is_digit( c ) )
339 break;
340 *value += c;
341 }
342 }
343
344 // <exp> ::= <e> [<sign>] <digit>+
345 // <e> ::= 'e' | 'E'
346 // <sign> ::= '-' | '+'
347 if ( c == 'e' || c == 'E' ) {
348 *value += c;
349 if ( !get_char( &c ) )
350 throw illegal_number( cur_loc_ );
351 if ( c == '+' || c == '-' ) {
352 *value += c;
353 if ( !get_char( &c ) )
354 throw illegal_number( cur_loc_ );
355 }
356 if ( !ascii::is_digit( c ) )
357 throw illegal_number( cur_loc_ );
358 *value += c;
359 while ( true ) {
360 if ( !get_char( &c ) )
361 return;
362 if ( !ascii::is_digit( c ) )
363 break;
364 *value += c;
365 }
366 }
367
368 in_->putback( c );
369}
370
371void lexer::parse_string( token::value_type *value ) {
372 value->clear();
373 bool got_backslash = false;
374 location const start_loc( cur_loc_ );
375
376 while ( true ) {
377 cur_loc_ = cur_loc();
378 char c;
379 if ( !get_char( &c ) )
380 throw unterminated_string( start_loc );
381 if ( got_backslash ) {
382 got_backslash = false;
383 switch ( c ) {
384 case '"':
385 case '/':
386 case '\\':
387 *value += c;
388 break;
389 case 'b':
390 *value += '\b';
391 break;
392 case 'f':
393 *value += '\f';
394 break;
395 case 'n':
396 *value += '\n';
397 break;
398 case 'r':
399 *value += '\r';
400 break;
401 case 't':
402 *value += '\t';
403 break;
404 case 'u':
405 utf8::encode( parse_codepoint(), value );
406 break;
407 default:
408 throw illegal_escape( cur_loc_, c );
409 }
410 continue;
411 }
412
413 switch ( c ) {
414 case '\\':
415 got_backslash = true;
416 break;
417 case '"':
418 return;
419 default:
420 *value += c;
421 }
422 } // while
423}
424
425void lexer::set_loc( char const *file, line_type line, column_type col ) {
426 if ( file )
427 file_ = file;
428 line_ = line;
429 col_ = col;
430}
431
432///////////////////////////////////////////////////////////////////////////////
433
434#if DEBUG_JSON_PARSER
435
436ostream& operator<<( ostream &o, parser::state s ) {
437 static char const *const string_of[] = {
438 "A0", "A1", "A2",
439 "E0", "E1",
440 "J0", "J1",
441 "M0", "M1",
442 "O0", "O1", "O2",
443 "P0", "P1",
444 "V0"
445 };
446 return o << string_of[ s ];
447}
448
449static void throw_unexpected_token( int line, token const &t ) {
450 try {
451 throw unexpected_token( t );
452 }
453 catch ( exception const &e ) {
454 cerr << line << ": " << e.what() << endl;
455 throw;
456 }
457}
458
459bool parser::get_token_debug( int line, token *t ) {
460 bool const got_token = get_token( t );
461 cout << line << ": get_token => " << *t << endl;
462 return got_token;
463}
464
465bool parser::matches_token_debug( int line, token::type tt, token *t ) {
466 bool const matched = matches_token( tt, t );
467 cout << line << ": token " << *t << " matches " << tt << " => " << (matched ? 'T' : 'F') << endl;
468 return matched;
469}
470
471token::type parser::peek_token_debug( int line ) {
472 token::type const tt = peek_token();
473 cout << line << ": peek_token => " << peeked_token_ << endl;
474 return tt;
475}
476
477void parser::require_token_debug( int line, token::type tt, token *t ) {
478 if ( !get_token_debug( line, t ) || t->get_type() != tt )
479 throw_unexpected_token( line, *t );
480}
481
482# define GET_TOKEN(T) get_token_debug( __LINE__, T )
483# define MATCHES_TOKEN(TT,T) matches_token_debug( __LINE__, TT, T )
484# define PEEK_TOKEN() peek_token_debug( __LINE__ )
485# define REQUIRE_TOKEN(TT,T) require_token_debug( __LINE__, TT, T )
486# define THROW_UNEXPECTED_TOKEN(T) throw_unexpected_token( __LINE__, T )
487
488# define GOTO_STATE(S) \
489 if (0) ; else { \
490 state_ = (S); \
491 cout << __LINE__ << ':' << indent << "GOTO_STATE( " << state_ << " )" << endl; \
492 continue; \
493 }
494
495# define PUSH_STATE(S) \
496 if (0) ; else { \
497 state_stack_.push(S); \
498 cout << __LINE__ << ':' << indent << "PUSH_STATE( " << (S) << " )" << endl << inc_indent; \
499 }
500
501# define POP_STATE() \
502 if (0) ; else { \
503 state_ = ztd::pop_stack( state_stack_ ); \
504 cout << __LINE__ << ':' << indent << "POP_STATE() => " << state_ << endl << dec_indent; \
505 }
506
507#else
508
509# define GET_TOKEN(T) get_token( T )
510# define MATCHES_TOKEN(TT,T) matches_token( TT, T )
511# define PEEK_TOKEN() peek_token()
512# define REQUIRE_TOKEN(TT,T) require_token( TT, T )
513# define THROW_UNEXPECTED_TOKEN(T) throw unexpected_token( T )
514
515# define GOTO_STATE(S) { state_ = (S); continue; }
516# define PUSH_STATE(S) state_stack_.push(S)
517# define POP_STATE() state_ = ztd::pop_stack( state_stack_ )
518
519#endif /* DEBUG_JSON_PARSER */
520
521///////////////////////////////////////////////////////////////////////////////
522
523parser::parser( istream &in ) : lexer_( in ) {
524#if DEBUG_JSON_PARSER
525 get_indent( cout ) = 0;
526#endif /* DEBUG_JSON_PARSER */
527 PUSH_STATE( J0 );
528}
529
530bool parser::get_token( token *t ) {
531 if ( peeked_token_ ) {
532 *t = peeked_token_;
533 peeked_token_.clear();
534 return true;
535 }
536 t->clear();
537 return lexer_.next( t );
538}
539
540bool parser::matches_token( token::type tt, token *t ) {
541 if ( peek_token() == tt )
542 return get_token( t );
543 *t = peeked_token_;
544 return false;
545}
546
547token::type parser::peek_token() {
548 if ( !peeked_token_ )
549 lexer_.next( &peeked_token_ );
550 return peeked_token_.get_type();
551}
552
553#if ! DEBUG_JSON_PARSER
554void parser::require_token( token::type tt, token *t ) {
555 if ( !get_token( t ) || t->get_type() != tt )
556 THROW_UNEXPECTED_TOKEN( *t );
557}
558#endif /* DEBUG_JSON_PARSER */
559
560bool parser::next( token *t ) {
561 if ( state_stack_.empty() )
562 return false;
563 POP_STATE();
564 while ( true ) {
565 switch ( state_ ) {
566
567 // <JSON> ::= <Array> | <Object>
568 case J0: PUSH_STATE( J1 );
569 switch ( PEEK_TOKEN() ) {
570 case token::begin_array : GOTO_STATE( A0 );
571 case token::begin_object: GOTO_STATE( O0 );
572 case token::none : break;
573 default: THROW_UNEXPECTED_TOKEN( peeked_token_ );
574 }
575 case J1: return false;
576
577 // <Array> ::= '[' <Element>* ']'
578 case A0: REQUIRE_TOKEN( token::begin_array, t );
579 PUSH_STATE( A1 );
580 return true;
581 case A1: if ( MATCHES_TOKEN( token::end_array, t ) )
582 return true;
583 PUSH_STATE( A2 );
584 GOTO_STATE( E0 );
585 case A2: REQUIRE_TOKEN( token::end_array, t );
586 return true;
587
588 // <Element> ::= <Value> [ ',' <Element> ]
589 case E0: PUSH_STATE( E1 );
590 GOTO_STATE( V0 );
591 case E1: if ( MATCHES_TOKEN( token::value_separator, t ) ) {
592 PUSH_STATE( E0 );
593 return true;
594 }
595 POP_STATE();
596 continue;
597
598 // <Object> ::= '{' <Member>* '}'
599 case O0: REQUIRE_TOKEN( token::begin_object, t );
600 PUSH_STATE( O1 );
601 return true;
602 case O1: if ( MATCHES_TOKEN( token::end_object, t ) )
603 return true;
604 PUSH_STATE( O2 );
605 GOTO_STATE( M0 );
606 case O2: REQUIRE_TOKEN( token::end_object, t );
607 return true;
608
609 // <Member> ::= <Pair> [ ',' <Member> ]
610 case M0: PUSH_STATE( M1 );
611 GOTO_STATE( P0 );
612 case M1: if ( MATCHES_TOKEN( token::value_separator, t ) ) {
613 PUSH_STATE( M0 );
614 return true;
615 }
616 POP_STATE();
617 continue;
618
619 // <Pair> ::= <String> ':' <Value>
620 case P0: REQUIRE_TOKEN( token::string, t );
621 PUSH_STATE( P1 );
622 return true;
623 case P1: REQUIRE_TOKEN( token::name_separator, t );
624 PUSH_STATE( V0 );
625 return true;
626
627 // <Value> ::= <Array> | <Object> | <String> | <Number>
628 // | false | null | true
629 case V0: switch ( PEEK_TOKEN() ) {
630 case token::begin_array:
631 GOTO_STATE( A0 );
632 case token::begin_object:
633 GOTO_STATE( O0 );
634 case token::string:
635 case token::number:
636 case token::json_false:
637 case token::json_null:
638 case token::json_true:
639 GET_TOKEN( t );
640 return true;
641 default:
642 THROW_UNEXPECTED_TOKEN( peeked_token_ );
643 }
644 } // switch ( state_ )
645 } // while
646}
647
648///////////////////////////////////////////////////////////////////////////////
649
650} // namespace json
651} // namespace zorba
652
653/* vim:set et sw=2 ts=2: */
0654
=== added file 'src/util/json_parser.h'
--- src/util/json_parser.h 1970-01-01 00:00:00 +0000
+++ src/util/json_parser.h 2012-01-23 00:53:24 +0000
@@ -0,0 +1,561 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ZORBA_JSON_PARSER_H
18#define ZORBA_JSON_PARSER_H
19
20#include <zorba/config.h>
21
22#include <exception>
23#include <iostream>
24#include <stack>
25#include <string>
26
27#include <zorba/internal/diagnostic.h>
28
29#include "zorbatypes/zstring.h"
30
31#include "cxx_util.h"
32#include "unicode_util.h"
33
34namespace zorba {
35namespace json {
36
37///////////////////////////////////////////////////////////////////////////////
38
39typedef internal::diagnostic::location location;
40
41///////////////////////////////////////////////////////////////////////////////
42
43/**
44 * A JSON %type is the type of JSON data. This isn't used by the lexer or
45 * parser implementation at all, but it's handy.
46 */
47enum type {
48 none, // meaning "not set" as opposed to "null"
49 array,
50 boolean,
51 null,
52 number,
53 object,
54 string
55};
56extern char const *const type_string_of[];
57
58inline std::ostream& operator<<( std::ostream &o, type t ) {
59 return o << type_string_of[ t ];
60}
61
62/**
63 * A JSON %token. Tokens have a type, location at which they were found, and
64 * sometimes a value.
65 *
66 * See: "RFC 4627: The application/json Media Type for JavaScript Object
67 * Notation (JSON)."
68 */
69class token {
70 // see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2333.html
71 struct pointer_conversion { int valid; };
72 typedef int pointer_conversion::*explicit_bool;
73public:
74 typedef zstring value_type;
75
76 /**
77 * The types of tokens in JSON. The first 6 constants have values that
78 * correspond to the actual structural characters used by JSON; the rest were
79 * assigned non-standard, mnemonic values for convenience.
80 */
81 enum type {
82 none,
83 begin_array = '[',
84 begin_object = '{',
85 end_array = ']',
86 end_object = '}',
87 name_separator = ':',
88 value_separator = ',',
89 string = 'S',
90 number = 'N',
91 json_false = 'F',
92 json_null = '0',
93 json_true = 'T',
94 };
95
96 /**
97 * Default constructor.
98 */
99 token();
100
101 /**
102 * Clears this %token.
103 */
104 void clear() {
105 type_ = none;
106 value_.clear();
107 }
108
109 /**
110 * Gets the location at which this %token was found.
111 *
112 * @return Returns said location.
113 */
114 location const& get_loc() const {
115 return loc_;
116 }
117
118 /**
119 * Gets the type of this %token.
120 *
121 * @return Returns said type.
122 */
123 type get_type() const {
124 return type_;
125 }
126
127 /**
128 * Gets the value of this %token, if any. Only %token types string, number,
129 * false, null, and true have a value.
130 *
131 * @return Returns said value or the empty string.
132 */
133 value_type const& get_value() const {
134 return value_;
135 }
136
137 /**
138 * Conversion to \c bool.
139 *
140 * @return Returns \c true only if this token's type is not \c none.
141 */
142 operator explicit_bool() const {
143 return type_ ? &pointer_conversion::valid : nullptr;
144 }
145
146private:
147 location loc_;
148 type type_;
149 value_type value_;
150
151 friend class lexer;
152};
153
154/**
155 * Map a token's type to a JSON type.
156 *
157 * @param tt The token::type to map.
158 * @return Returns the corresponding JSON type or \c none if \a tt doesn't map.
159 */
160type map_type( token::type tt );
161
162/**
163 * Emits the given token type to an ostream.
164 *
165 * @param o The ostream to emit to.
166 * @param tt The token type to emit.
167 * @return Returns \a o.
168 */
169std::ostream& operator<<( std::ostream &o, token::type tt );
170
171/**
172 * Emits the given token to an ostream.
173 *
174 * @param o The ostream to emit to.
175 * @param t The token to emit.
176 * @return Returns \a o.
177 */
178std::ostream& operator<<( std::ostream &o, token const &t );
179
180/**
181 * Compares two tokens for equality.
182 *
183 * @param t1 The first token.
184 * @param t2 The second token.
185 * @return Returns \c true only if the two tokens' types and values are equal.
186 */
187inline bool operator==( token const &t1, token const &t2 ) {
188 return t1.get_type() == t2.get_type() && t1.get_value() == t2.get_value();
189}
190
191/**
192 * Compares a token's type to another type for equality.
193 *
194 * @param t The token whose type to compare.
195 * @param tt The type to compare to.
196 * @return Returns \c true only if the token's type equals \a tt.
197 */
198inline bool operator==( token const &t, token::type tt ) {
199 return t.get_type() == tt;
200}
201
202/**
203 * Compares a token's type to another type for equality.
204 *
205 * @param tt The type to compare.
206 * @param t The token whose type to compare to.
207 * @return Returns \c true only if \a tt equals the token's type.
208 */
209inline bool operator==( token::type tt, token const &t ) {
210 return t == tt;
211}
212
213/**
214 * Compares a token's value to a C string for equality.
215 *
216 * @param t The token whose value to compare.
217 * @param value The value to compare to.
218 * @return Returns \c true only if the token's value equals \a value.
219 */
220inline bool operator==( token const &t, char const *value ) {
221 return t.get_value() == value;
222}
223
224/**
225 * Compares a C string to a token's value for equality.
226 *
227 * @param value The value to compare.
228 * @param t The token whose value to compare to.
229 * @return Returns \c true only if \a value equals the token's value.
230 */
231inline bool operator==( char const *value, token const &t ) {
232 return t == value;
233}
234
235/**
236 * Compares two tokens for inequality.
237 *
238 * @param t1 The first token.
239 * @param t2 The second token.
240 * @return Returns \c true if either the two tokens' types or values are not
241 * equal.
242 */
243inline bool operator!=( token const &t1, token const &t2 ) {
244 return !(t1 == t2);
245}
246
247/**
248 * Compares a token's type to another type for inequality.
249 *
250 * @param t The token whose type to compare.
251 * @param tt The type to compare to.
252 * @return Returns \c true only if the token's type is not equal to \a tt.
253 */
254inline bool operator!=( token const &t, token::type tt ) {
255 return !(t == tt);
256}
257
258/**
259 * Compares a token's type to another type for inequality.
260 *
261 * @param tt The type to compare.
262 * @param t The token whose type to compare to.
263 * @return Returns \c true only if \a tt is not equal to the token's type.
264 */
265inline bool operator!=( token::type tt, token const &t ) {
266 return !(tt == t);
267}
268
269/**
270 * Compares a token's value to a C string for inequality.
271 *
272 * @param t The token whose value to compare.
273 * @param value The value to compare to.
274 * @return Returns \c true only if the token's value is not equal to \a value.
275 */
276inline bool operator!=( token const &t, char const *value ) {
277 return !(t == value);
278}
279
280/**
281 * Compares a token's value to a C string for inequality.
282 *
283 * @param value The value to compare.
284 * @param t The token whose value to compare to.
285 * @return Returns \c true only if \a value is not equal to the token's value.
286 */
287inline bool operator!=( char const *value, token const &t ) {
288 return !(value == t);
289}
290
291///////////////////////////////////////////////////////////////////////////////
292
293/**
294 * An %exception is the root of the JSON %exception hierarchy.
295 */
296class exception : public std::exception {
297public:
298 ~exception() throw();
299
300 /**
301 * Gets the location in the JSON source whence this exception was thrown.
302 */
303 location const& get_loc() const {
304 return loc_;
305 }
306
307 // inherited
308 char const* what() const throw();
309
310protected:
311 exception( location const &loc, std::string const &message );
312
313private:
314 location loc_;
315 std::string message_;
316};
317
318/**
319 * This exception is thrown when an illegal character is encountered in a JSON
320 * data stream.
321 */
322class illegal_character : public exception {
323public:
324 illegal_character( location const &loc, char c );
325 ~illegal_character() throw();
326
327 /**
328 * Gets the illegal character.
329 *
330 * @return Returns said character.
331 */
332 char get_char() const {
333 return c_;
334 }
335
336private:
337 char c_;
338};
339
340/**
341 * This exception is thrown when an illegal Unicode code-point escape sequence
342 * (\uHHHH) is encountered.
343 */
344class illegal_codepoint : public exception {
345public:
346 illegal_codepoint( location const &loc, token::value_type const &cp );
347 ~illegal_codepoint() throw();
348
349 /**
350 * Gets the illegal code-point.
351 *
352 * @return Returns said code-point.
353 */
354 token::value_type get_codepoint() const {
355 return codepoint_;
356 }
357
358private:
359 token::value_type codepoint_;
360};
361
362/**
363 * This exception is thrown when an illegal character follows a backslash
364 * (escape) within a string literal. The legal escape characters are:
365 * ["/\bfnrtu].
366 */
367class illegal_escape : public exception {
368public:
369 illegal_escape( location const &loc, char escape );
370 ~illegal_escape() throw();
371
372 /**
373 * Gets the illegal escape character.
374 *
375 * @return Returns said character.
376 */
377 char get_escape() const {
378 return esc_;
379 }
380
381private:
382 char esc_;
383};
384
385/**
386 * This exception is thrown when a literal other than \c false, \c null, or
387 * \c true is encountered.
388 */
389class illegal_literal : public exception {
390public:
391 illegal_literal( location const &loc );
392 ~illegal_literal() throw();
393};
394
395/**
396 * This exception is thrown when an illegal number is encountered.
397 */
398class illegal_number : public exception {
399public:
400 illegal_number( location const &loc );
401 ~illegal_number() throw();
402};
403
404/**
405 * This exception is thrown when an unexpected token is encountered.
406 */
407class unexpected_token : public exception {
408public:
409 unexpected_token( token const &t );
410 ~unexpected_token() throw();
411
412 /**
413 * Gets the unexpected token
414 *
415 * @return Returns said token.
416 */
417 token const& get_token() const {
418 return token_;
419 }
420
421private:
422 token token_;
423};
424
425/**
426 * This exception is thrown when an EOF is encountered before a string's
427 * terminating quote.
428 */
429class unterminated_string : public exception {
430public:
431 unterminated_string( location const &loc );
432 ~unterminated_string() throw();
433};
434
435///////////////////////////////////////////////////////////////////////////////
436
437/**
438 * A %lexer extracts JSON tokens from an istream.
439 */
440class lexer {
441public:
442 typedef location::line_type line_type;
443 typedef location::column_type column_type;
444
445 /**
446 * Constructs a %lexer on the given istream.
447 *
448 * @param in The istream to read from.
449 */
450 lexer( std::istream &in );
451
452 /**
453 * Gets the next token, if any.
454 *
455 * @param result A pointer to the token to get into.
456 * @return Returns \c true only if there was a next token.
457 * @throws exception upon error.
458 */
459 bool next( token *result );
460
461 /**
462 * Sets the file location.
463 *
464 * @param file The source file name.
465 * @param line The source line number.
466 * @param col The source column number.
467 */
468 void set_loc( char const *file, line_type line, column_type col );
469
470private:
471 location cur_loc() const {
472 return location( file_, line_, col_ );
473 }
474
475 bool get_char( char* = nullptr );
476 bool peek_char( char* );
477 unicode::code_point parse_codepoint();
478 token::type parse_literal( char, token::value_type* );
479 void parse_number( char, token::value_type* );
480 void parse_string( token::value_type* );
481
482 std::istream *in_;
483 std::string file_;
484 line_type line_;
485 column_type col_;
486 location cur_loc_;
487};
488
489///////////////////////////////////////////////////////////////////////////////
490
491/**
492 * A %parser extracts JSON tokens from an istream while checking to ensure the
493 * token sequence is valid.
494 */
495class parser {
496public:
497 typedef lexer::line_type line_type;
498 typedef lexer::column_type column_type;
499
500 /**
501 * Constructs a %parser on the given istream.
502 *
503 * @param in The istream to read from.
504 */
505 parser( std::istream &in );
506
507 /**
508 * Gets the next token, if any.
509 *
510 * @param result A pointer to the token to get into.
511 * @return Returns \c true only if there was a next token.
512 * @throws exception upon error.
513 */
514 bool next( token *result );
515
516 /**
517 * Sets the file location.
518 *
519 * @param file The source file name.
520 * @param line The source line number.
521 * @param col The source column number.
522 */
523 void set_loc( char const *file, line_type line, column_type col ) {
524 lexer_.set_loc( file, line, col );
525 }
526
527private:
528 enum state {
529 A0, A1, A2, // Array
530 E0, E1, // Element
531 J0, J1, // JSON
532 M0, M1, // Member
533 O0, O1, O2, // Object
534 P0, P1, // Pair
535 V0 // Value
536 };
537
538 friend std::ostream& operator<<( std::ostream&, state );
539
540 bool get_token( token* );
541 bool get_token_debug( int, token* );
542 bool matches_token( token::type, token* );
543 bool matches_token_debug( int, token::type, token* );
544 token::type peek_token();
545 token::type peek_token_debug( int );
546 void require_token( token::type, token* );
547 void require_token_debug( int, token::type, token* );
548
549 lexer lexer_;
550 token peeked_token_;
551 std::stack<state> state_stack_;
552 state state_;
553};
554
555///////////////////////////////////////////////////////////////////////////////
556
557} // namespace json
558} // namespace zorba
559
560#endif /* ZORBA_JSON_PARSER_H */
561/* vim:set et sw=2 ts=2: */
0562
=== added file 'src/util/mem_streambuf.cpp'
--- src/util/mem_streambuf.cpp 1970-01-01 00:00:00 +0000
+++ src/util/mem_streambuf.cpp 2012-01-23 00:53:24 +0000
@@ -0,0 +1,119 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <cstring> /* for memcpy(3) */
18
19#include "diagnostics/assert.h"
20
21#include "cxx_util.h"
22#include "mem_streambuf.h"
23
24using namespace std;
25
26namespace zorba {
27
28///////////////////////////////////////////////////////////////////////////////
29
30mem_streambuf::mem_streambuf() {
31 set( nullptr, nullptr );
32}
33
34mem_streambuf::mem_streambuf( char_type *begin, char_type *end ) {
35 set( begin, end );
36}
37
38mem_streambuf::mem_streambuf( char_type *begin, off_type size ) {
39 set( begin, size );
40}
41
42mem_streambuf::int_type mem_streambuf::overflow( int_type c ) {
43 if ( traits_type::eq_int_type( c, traits_type::eof() ) )
44 return traits_type::not_eof( c );
45 if ( pptr() >= epptr() )
46 return traits_type::eof();
47 *pptr() = traits_type::to_char_type( c );
48 pbump( 1 );
49 return c;
50}
51
52mem_streambuf::int_type mem_streambuf::pbackfail( int_type c ) {
53 if ( !traits_type::eq_int_type( c, traits_type::eof() ) ) {
54 *pptr() = traits_type::to_int_type( c );
55 pbump( -1 );
56 }
57 return traits_type::to_int_type( *pptr() );
58}
59
60mem_streambuf::pos_type mem_streambuf::seekoff( off_type off,
61 ios_base::seekdir dir,
62 ios_base::openmode ) {
63 switch ( dir ) {
64 case ios_base::beg:
65 our_setg( begin_ + off );
66 break;
67 case ios_base::cur:
68 our_setg( gptr() + off );
69 break;
70 case ios_base::end:
71 our_setg( end_ + off );
72 break;
73 default:
74 ZORBA_ASSERT( false );
75 }
76 return off;
77}
78
79mem_streambuf::pos_type mem_streambuf::seekpos( pos_type pos,
80 ios_base::openmode mode ) {
81 return seekoff( pos, ios_base::beg, mode );
82}
83
84void mem_streambuf::set( char_type *begin, char_type *end ) {
85 begin_ = begin;
86 end_ = end;
87 our_setg( begin );
88 our_setp( end );
89}
90
91streamsize mem_streambuf::showmanyc() {
92 return egptr() - gptr();
93}
94
95mem_streambuf::int_type mem_streambuf::underflow() {
96 return gptr() < egptr() ?
97 traits_type::to_int_type( *gptr() ) : traits_type::eof();
98}
99
100streamsize mem_streambuf::xsgetn( char_type *buf, std::streamsize size ) {
101 streamsize const remaining = showmanyc();
102 if ( size > remaining )
103 size = remaining;
104 ::memcpy( buf, gptr(), size );
105 return size;
106}
107
108streamsize mem_streambuf::xsputn( char_type const *buf, streamsize size ) {
109 streamsize const remaining = epptr() - pptr();
110 if ( size > remaining )
111 size = remaining;
112 ::memcpy( pptr(), buf, size );
113 return size;
114}
115
116///////////////////////////////////////////////////////////////////////////////
117
118} // namespace zorba
119/* vim:set et sw=2 ts=2: */
0120
=== added file 'src/util/mem_streambuf.h'
--- src/util/mem_streambuf.h 1970-01-01 00:00:00 +0000
+++ src/util/mem_streambuf.h 2012-01-23 00:53:24 +0000
@@ -0,0 +1,108 @@
1/*
2 * Copyright 2006-2008 The FLWOR Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ZORBA_MMAP_STREAMBUF_H
18#define ZORBA_MMAP_STREAMBUF_H
19
20#include <streambuf>
21
22namespace zorba {
23
24///////////////////////////////////////////////////////////////////////////////
25
26/**
27 * A %mem_streambuf is-a std::streambuf for a fixed-size chunk of memory.
28 */
29class mem_streambuf : public std::streambuf {
30public:
31 typedef std::streambuf::char_type char_type;
32 typedef std::streambuf::int_type int_type;
33 typedef std::streambuf::off_type off_type;
34 typedef std::streambuf::pos_type pos_type;
35 typedef std::streambuf::traits_type traits_type;
36
37 /**
38 * Default constructor.
39 */
40 mem_streambuf();
41
42 /**
43 * Constructs a %mem_streambuf.
44 *
45 * @param begin A pointer to the beginning of the memory chunk.
46 * @param end A pointer to one past the end of the memory chunk.
47 */
48 mem_streambuf( char_type *begin, char_type *end );
49
50 /**
51 * Constructs a %mem_streambuf.
52 *
53 * @param begin A pointer to the beginning of the memory chunk.
54 * @param size The size of the memory chunk.
55 */
56 mem_streambuf( char_type *begin, off_type size );
57
58 /**
59 * Sets the memory chunk.
60 *
61 * @param begin A pointer to the beginning of the memory chunk.
62 * @param end A pointer to one past the end of the memory chunk.
63 */
64 void set( char_type *begin, char_type *end );
65
66 /**
67 * Sets the memory chunk.
68 *
69 * @param begin A pointer to the beginning of the memory chunk.
70 * @param size The size of the memory chunk.
71 */
72 void set( char_type *begin, off_type size );
73
74protected:
75 int_type overflow( int_type c );
76 int_type pbackfail( int_type c );
77 pos_type seekoff( off_type, std::ios_base::seekdir, std::ios_base::openmode );
78 pos_type seekpos( pos_type, std::ios_base::openmode );
79 std::streamsize showmanyc();
80 int_type underflow();
81 std::streamsize xsgetn( char_type*, std::streamsize );
82 std::streamsize xsputn( char_type const*, std::streamsize );
83
84private:
85 char_type *begin_, *end_;
86
87 void our_setg( char_type *ptr ) {
88 setg( begin_, ptr, end_ );
89 }
90
91 void our_setp( char_type *ptr ) {
92 setp( ptr, end_ );
93 }
94
95 // forbid
96 mem_streambuf( mem_streambuf const& );
97 mem_streambuf& operator=( mem_streambuf const& );
98};
99
100inline void mem_streambuf::set( char_type *begin, off_type size ) {
101 set( begin, begin + size );
102}
103
104///////////////////////////////////////////////////////////////////////////////
105
106} // namespace zorba
107#endif /* ZORBA_MMAP_STREAMBUF_H */
108/* vim:set et sw=2 ts=2: */
0109
=== modified file 'src/util/omanip.h'
--- src/util/omanip.h 2011-06-14 17:26:33 +0000
+++ src/util/omanip.h 2012-01-23 00:53:24 +0000
@@ -25,127 +25,275 @@
25///////////////////////////////////////////////////////////////////////////////25///////////////////////////////////////////////////////////////////////////////
2626
27/**27/**
28 * An omanip1 is a class for assisting in the creation of ostream manipulators28 * An %omanip1 is a class for assisting in the creation of ostream manipulators
29 * by storing a pointer to a function and its argument to be called later via29 * by storing a pointer to a function and its argument to be called later via
30 * operator<<().30 * operator<<().
31 *31 *
32 * See also: "Standard C++ IOStreams and Locales," Angelika Langer and Klaus32 * See also: "Standard C++ IOStreams and Locales," Angelika Langer and Klaus
33 * Kreft, Addison-Wesley, pp. 179-191.33 * Kreft, Addison-Wesley, pp. 179-191.
34 */34 */
35template<typename Arg1Type> class omanip1 {35template<typename Arg1Type>
36class omanip1 {
36public:37public:
3738
38 /**39 /**
39 * The signature of functions this omanip1 can handle.40 * The signature of functions this %omanip1 can handle.
40 */41 */
41 typedef std::ostream& (*func_type)( std::ostream&, Arg1Type );42 typedef std::ostream& (*func_type)( std::ostream&, Arg1Type );
4243
43 /**44 /**
44 * Constructs an omanip1.45 * Constructs an %omanip1.
45 *46 *
46 * @param f The function to call when this omanip1 is inserted into an47 * @param f The function to call when this %omanip1 is inserted into an
47 * ostream.48 * ostream.
48 * @param arg1 The argument to be passed to the function.49 * @param a1 The argument to be passed to the function.
49 */50 */
50 omanip1( func_type f, Arg1Type arg1 ) :51 omanip1( func_type f, Arg1Type a1 ) :
51 f_( f ), arg1_( arg1 )52 f_( f ), a1_( a1 )
52 {53 {
53 }54 }
5455
55 /**56 /**
56 * Inserts the given omanip1 into the given ostream. This has the effect of57 * Inserts the given %omanip1 into the given ostream. This has the effect of
57 * calling the function and argument bound to the omanip1 at the time of its58 * calling the function and argument bound to the %omanip1 at the time of its
58 * construction.59 * construction.
59 *60 *
60 * @param o The ostream to insert into.61 * @param o The ostream to insert into.
61 * @param m The omanip1 to insert.62 * @param m The %omanip1 to insert.
62 */63 */
63 friend std::ostream& operator<<( std::ostream &o, omanip1 const &m ) {64 friend std::ostream& operator<<( std::ostream &o, omanip1 const &m ) {
64 return (*m.f_)( o, m.arg1_ );65 if ( o.good() )
66 (*m.f_)( o, m.a1_ );
67 return o;
65 }68 }
6669
67private:70private:
68 func_type const f_;71 func_type const f_;
69 Arg1Type const arg1_;72 Arg1Type const a1_;
70};73};
7174
72/**75/**
73 * Defines an ostream manipulator "thunk" function that calls an existing76 * Defines an ostream manipulator "thunk" function that calls an existing
74 * non-manipulator function having the same name.77 * non-manipulator function having the same name.
75 *78 *
76 * @param FN_NAME The name of the existing function.79 * @param FN_NAME The name of the existing function.
77 * @param ARG1_TYPE The type of the non-ostream argument.80 * @param ARG1_T The type of the non-ostream argument.
78 * @param ARG1_NAME The name of the non-ostream argument.
79 */81 */
80#define DEF_OMANIP1(FN_NAME,ARG1_TYPE,ARG1_NAME) \82#define DEF_OMANIP1(FN_NAME,ARG1_T) \
81 inline omanip1<ARG1_TYPE> \83 inline omanip1<ARG1_T> \
82 FN_NAME( ARG1_TYPE ARG1_NAME ) { \84 FN_NAME( ARG1_T a1 ) { \
83 return omanip1<ARG1_TYPE>( FN_NAME, ARG1_NAME ); \85 return omanip1<ARG1_T>( FN_NAME, a1 ); \
84 }86 }
8587
86///////////////////////////////////////////////////////////////////////////////88///////////////////////////////////////////////////////////////////////////////
8789
88/**90/**
89 * An omanip2 is a class for assisting in the creation of ostream manipulators91 * An %omanip2 is a class for assisting in the creation of ostream manipulators
90 * by storing a pointer to a function and its arguments to be called later via92 * by storing a pointer to a function and its arguments to be called later via
91 * operator<<().93 * operator<<().
92 *94 *
93 * See also: "Standard C++ IOStreams and Locales," Angelika Langer and Klaus95 * See also: "Standard C++ IOStreams and Locales," Angelika Langer and Klaus
94 * Kreft, Addison-Wesley, pp. 179-191.96 * Kreft, Addison-Wesley, pp. 179-191.
95 */97 */
96template<typename Arg1Type, typename Arg2Type> class omanip2 {98template<typename Arg1Type,typename Arg2Type>
99class omanip2 {
97public:100public:
98101
99 /**102 /**
100 * The signature of functions this omanip2 can handle.103 * The signature of functions this %omanip2 can handle.
101 */104 */
102 typedef std::ostream& (*func_type)( std::ostream&, Arg1Type, Arg2Type );105 typedef std::ostream& (*func_type)( std::ostream&, Arg1Type, Arg2Type );
103106
104 /**107 /**
105 * Constructs an omanip2.108 * Constructs an %omanip2.
106 *109 *
107 * @param f The function to call when this omanip2 is inserted into an110 * @param f The function to call when this %omanip2 is inserted into an
108 * ostream.111 * ostream.
109 * @param arg1 The first argument to be passed to the function.112 * @param a1 The first argument to be passed to the function.
110 * @param arg2 The second argument to be passed to the function.113 * @param a2 The second argument to be passed to the function.
111 */114 */
112 omanip2( func_type f, Arg1Type arg1, Arg2Type arg2 ) :115 omanip2( func_type f, Arg1Type a1, Arg2Type a2 ) :
113 f_( f ), arg1_( arg1 ), arg2_( arg2 )116 f_( f ), a1_( a1 ), a2_( a2 )
114 {117 {
115 }118 }
116119
117 /**120 /**
118 * Inserts the given omanip2 into the given ostream. This has the effect of121 * Inserts the given %omanip2 into the given ostream. This has the effect of
119 * calling the function and argument bound to the omanip2 at the time of its122 * calling the function and argument bound to the %omanip2 at the time of its
120 * construction.123 * construction.
121 *124 *
122 * @param o The ostream to insert into.125 * @param o The ostream to insert into.
123 * @param m The omanip2 to insert.126 * @param m The %omanip2 to insert.
124 */127 */
125 friend std::ostream& operator<<( std::ostream &o, omanip2 const &m ) {128 friend std::ostream& operator<<( std::ostream &o, omanip2 const &m ) {
126 return (*m.f_)( o, m.arg1_, m.arg2_ );129 if ( o.good() )
127 }130 (*m.f_)( o, m.a1_, m.a2_ );
128131 return o;
129private:132 }
130 func_type const f_;133
131 Arg1Type const arg1_;134private:
132 Arg2Type const arg2_;135 func_type const f_;
133};136 Arg1Type const a1_;
134137 Arg2Type const a2_;
135/**138};
136 * Defines an ostream manipulator "thunk" function that calls an existing139
137 * non-manipulator function having the same name.140/**
138 *141 * Defines an ostream manipulator "thunk" function that calls an existing
139 * @param FN_NAME The name of the existing function.142 * non-manipulator function having the same name.
140 * @param ARG1_TYPE The type of the first non-ostream argument.143 *
141 * @param ARG1_NAME The name of the first non-ostream argument.144 * @param FN_NAME The name of the existing function.
142 * @param ARG2_TYPE The type of the second non-ostream argument.145 * @param ARG1_T The type of the first non-ostream argument.
143 * @param ARG2_NAME The name of the second non-ostream argument.146 * @param ARG2_T The type of the second non-ostream argument.
144 */147 */
145#define DEF_OMANIP2(FN_NAME,ARG1_TYPE,ARG1_NAME,ARG2_TYPE,ARG2_NAME) \148#define DEF_OMANIP2(FN_NAME,ARG1_T,ARG2_T) \
146 inline omanip2<ARG1_TYPE,ARG2_TYPE> \149 inline omanip2<ARG1_T,ARG2_T> \
147 FN_NAME( ARG1_TYPE ARG1_NAME, ARG2_TYPE ARG2_NAME ) { \150 FN_NAME( ARG1_T a1, ARG2_T a2 ) { \
148 return omanip2<ARG1_TYPE,ARG2_TYPE>( FN_NAME, ARG1_NAME, ARG2_NAME ); \151 return omanip2<ARG1_T,ARG2_T>( FN_NAME, a1, a2 ); \
152 }
153
154///////////////////////////////////////////////////////////////////////////////
155
156/**
157 * An %omanip3 is a class for assisting in the creation of ostream manipulators
158 * by storing a pointer to a function and its arguments to be called later via
159 * operator<<().
160 *
161 * See also: "Standard C++ IOStreams and Locales," Angelika Langer and Klaus
162 * Kreft, Addison-Wesley, pp. 179-191.
163 */
164template<typename Arg1Type,typename Arg2Type,typename Arg3Type>
165class omanip3 {
166public:
167
168 /**
169 * The signature of functions this %omanip3 can handle.
170 */
171 typedef std::ostream& (*func_type)( std::ostream&, Arg1Type, Arg2Type,
172 Arg3Type );
173
174 /**
175 * Constructs an %omanip3.
176 *
177 * @param f The function to call when this %omanip3 is inserted into an
178 * ostream.
179 * @param a1 The first argument to be passed to the function.
180 * @param a2 The second argument to be passed to the function.
181 * @param a3 The third argument to be passed to the function.
182 */
183 omanip3( func_type f, Arg1Type a1, Arg2Type a2, Arg3Type a3 ) :
184 f_( f ), a1_( a1 ), a2_( a2 ), a3_( a3 )
185 {
186 }
187
188 /**
189 * Inserts the given %omanip3 into the given ostream. This has the effect of
190 * calling the function and argument bound to the %omanip3 at the time of its
191 * construction.
192 *
193 * @param o The ostream to insert into.
194 * @param m The %omanip3 to insert.
195 */
196 friend std::ostream& operator<<( std::ostream &o, omanip3 const &m ) {
197 if ( o.good() )
198 (*m.f_)( o, m.a1_, m.a2_, m.a3_ );
199 return o;
200 }
201
202private:
203 func_type const f_;
204 Arg1Type const a1_;
205 Arg2Type const a2_;
206 Arg3Type const a3_;
207};
208
209/**
210 * Defines an ostream manipulator "thunk" function that calls an existing
211 * non-manipulator function having the same name.
212 *
213 * @param FN_NAME The name of the existing function.
214 * @param ARG1_T The type of the first non-ostream argument.
215 * @param ARG2_T The type of the second non-ostream argument.
216 * @param ARG3_T The type of the third non-ostream argument.
217 */
218#define DEF_OMANIP3(FN_NAME,ARG1_T,ARG2_T,ARG3_T) \
219 inline omanip3<ARG1_T,ARG2_T,ARG3_T> \
220 FN_NAME( ARG1_T a1, ARG2_T a2, ARG3_T a3 ) { \
221 return omanip3<ARG1_T,ARG2_T,ARG3_T>( FN_NAME, a1, a2, a3 ); \
222 }
223
224///////////////////////////////////////////////////////////////////////////////
225
226/**
227 * An %omanip4 is a class for assisting in the creation of ostream manipulators
228 * by storing a pointer to a function and its arguments to be called later via
229 * operator<<().
230 *
231 * See also: "Standard C++ IOStreams and Locales," Angelika Langer and Klaus
232 * Kreft, Addison-Wesley, pp. 179-191.
233 */
234template<
235 typename Arg1Type,typename Arg2Type,typename Arg3Type,typename Arg4Type
236>
237class omanip4 {
238public:
239
240 /**
241 * The signature of functions this %omanip4 can handle.
242 */
243 typedef std::ostream& (*func_type)( std::ostream&, Arg1Type, Arg2Type,
244 Arg3Type, Arg4Type );
245
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches