aboutsummaryrefslogtreecommitdiff
path: root/examples/cxx/serializer/minimal
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2009-02-24 15:16:26 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2009-02-24 15:16:26 +0200
commit707cc94fe52463870a9c6c8e2e66eaaa389e601d (patch)
tree13e10ff28bf4455d915f9d59b401bdbb62a393cb /examples/cxx/serializer/minimal
Start tracking XSD/e with git after version 3.0.03.0.0
Diffstat (limited to 'examples/cxx/serializer/minimal')
-rw-r--r--examples/cxx/serializer/minimal/README47
-rw-r--r--examples/cxx/serializer/minimal/driver.cxx139
-rw-r--r--examples/cxx/serializer/minimal/makefile66
-rw-r--r--examples/cxx/serializer/minimal/people-simpl-mixin.hxx82
-rw-r--r--examples/cxx/serializer/minimal/people-simpl-tiein.hxx90
-rw-r--r--examples/cxx/serializer/minimal/people.hxx30
-rw-r--r--examples/cxx/serializer/minimal/people.map9
-rw-r--r--examples/cxx/serializer/minimal/people.xsd37
8 files changed, 500 insertions, 0 deletions
diff --git a/examples/cxx/serializer/minimal/README b/examples/cxx/serializer/minimal/README
new file mode 100644
index 0000000..0121f9a
--- /dev/null
+++ b/examples/cxx/serializer/minimal/README
@@ -0,0 +1,47 @@
+This example is a minimal serializer implementation that is
+intended to work without STL, iostream, or C++ exceptions.
+
+The example consists of the following files:
+
+people.xsd
+ XML Schema which describes a collection of person
+ records.
+
+people.hxx
+ Simple C++ types that corresponds to the XML Schema
+ types in people.xsd. These are hand-written.
+
+people.map
+ Type map. It maps XML Schema types defined in
+ people.xsd to C++ types defined in people.hxx.
+
+people-sskel.hxx
+people-sskel.ixx
+people-sskel.cxx
+ Serializer skeletons generated by XSD/e from people.xsd
+ and people.map. The --no-stl and --no-iostream options
+ were used to produce these files.
+
+people-simpl-mixin.hxx
+
+people-simpl-tiein.hxx
+ Serializer implementations (using either mixin or tiein
+ parser reuse style) that serializes the custom in-memory
+ object model defined in people.hxx to XML. These are hand-
+ written implementations of the parser skeletons defined
+ in people-sskel.hxx.
+
+driver.cxx
+ Driver for the example. It first constructs a sample
+ object model using the types from people.hxx. It then
+ creates a serializer instance using the serializer
+ implementation mentioned above and a couple of predefined
+ serializers for the XML Schema built-in types. Finally, it
+ invokes this serializer instance to serialize the sample
+ object model to an XML document which is printed to STDOUT.
+ It also shows how to handle serialization and validation
+ errors using error codes.
+
+To run the example simply execute:
+
+$ ./driver
diff --git a/examples/cxx/serializer/minimal/driver.cxx b/examples/cxx/serializer/minimal/driver.cxx
new file mode 100644
index 0000000..df8d7f0
--- /dev/null
+++ b/examples/cxx/serializer/minimal/driver.cxx
@@ -0,0 +1,139 @@
+// file : examples/cxx/serializer/minimal/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <stdio.h>
+
+#include "people.hxx"
+#include "people-sskel.hxx" // Get the configuration macros (XSDE_*).
+
+#if defined(XSDE_REUSE_STYLE_MIXIN)
+# include "people-simpl-mixin.hxx"
+#elif defined(XSDE_REUSE_STYLE_TIEIN)
+# include "people-simpl-tiein.hxx"
+#else
+# error this example requires mixin or tiein serializer reuse support
+#endif
+
+struct writer: xml_schema::writer
+{
+ virtual bool
+ write (const char* s, size_t n)
+ {
+ return fwrite (s, n, 1, stdout) == 1;
+ }
+
+ virtual bool
+ flush ()
+ {
+ return fflush (stdout) == 0;
+ }
+};
+
+int
+main ()
+{
+ // Create a sample person list.
+ //
+ people p;
+
+ p.size_ = 2;
+ p.people_ = new person[p.size_];
+
+ if (p.people_ == 0)
+ {
+ fprintf (stderr, "error: no memory\n");
+ return 1;
+ }
+
+ p.people_[0].first_name_ = "John";
+ p.people_[0].last_name_ = "Doe";
+ p.people_[0].gender_ = male;
+ p.people_[0].age_ = 32;
+
+ p.people_[1].first_name_ = "Jane";
+ p.people_[1].last_name_ = "Doe";
+ p.people_[1].gender_ = female;
+ p.people_[1].age_ = 28;
+
+ // Construct the serializer.
+ //
+ xml_schema::unsigned_short_simpl unsigned_short_s;
+ xml_schema::string_simpl string_s;
+
+ gender_simpl gender_s;
+ person_simpl person_s;
+ people_simpl people_s;
+
+ person_s.serializers (string_s, string_s, gender_s, unsigned_short_s);
+ people_s.serializers (person_s);
+
+ // Serialize.
+ //
+ typedef xml_schema::serializer_error error;
+
+ error e;
+ writer w;
+
+ do
+ {
+ xml_schema::document_simpl doc_s (people_s, "people");
+
+ if (e = doc_s._error ())
+ break;
+
+ people_s.pre (p);
+
+ if (e = people_s._error ())
+ break;
+
+ doc_s.serialize (w);
+
+ if (e = doc_s._error ())
+ break;
+
+ people_s.post ();
+
+ e = people_s._error ();
+
+ } while (false);
+
+ delete[] p.people_;
+
+ // Handle errors.
+ //
+ if (e)
+ {
+ switch (e.type ())
+ {
+ case error::sys:
+ {
+ fprintf (stderr, "error: %s\n", e.sys_text ());
+ break;
+ }
+ case error::xml:
+ {
+ fprintf (stderr, "error: %s\n", e.xml_text ());
+ break;
+ }
+#ifdef XSDE_SERIALIZER_VALIDATION
+ case error::schema:
+ {
+ fprintf (stderr, "error: %s\n", e.schema_text ());
+ break;
+ }
+#endif
+ case error::app:
+ {
+ fprintf (stderr, "application error: %d\n", e.app_code ());
+ break;
+ }
+ default:
+ break;
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/examples/cxx/serializer/minimal/makefile b/examples/cxx/serializer/minimal/makefile
new file mode 100644
index 0000000..3337728
--- /dev/null
+++ b/examples/cxx/serializer/minimal/makefile
@@ -0,0 +1,66 @@
+# file : examples/cxx/serializer/minimal/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := people.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-sskel.o))
+dep := $(obj:.o=.o.d)
+
+xsde.l := $(out_root)/libxsde/xsde/xsde.l
+xsde.l.cpp-options := $(out_root)/libxsde/xsde/xsde.l.cpp-options
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Build.
+#
+$(driver): $(obj) $(xsde.l)
+
+$(obj) $(dep): cpp_options := -I$(out_base) -I$(src_base)
+$(obj) $(dep): $(xsde.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-sskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-sskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-sskel.cxx)
+
+$(skel): xsde := $(out_root)/xsde/xsde
+$(skel): xsde_options += --type-map $(src_base)/people.map
+
+$(skel): $(out_root)/xsde/xsde $(src_base)/people.map
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-sskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsde/serializer/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsde/makefile)
+$(call import,$(src_root)/libxsde/xsde/makefile)
diff --git a/examples/cxx/serializer/minimal/people-simpl-mixin.hxx b/examples/cxx/serializer/minimal/people-simpl-mixin.hxx
new file mode 100644
index 0000000..635bed2
--- /dev/null
+++ b/examples/cxx/serializer/minimal/people-simpl-mixin.hxx
@@ -0,0 +1,82 @@
+// file : examples/cxx/serializer/people/people-simpl-mixin.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef PEOPLE_SIMPL_HXX
+#define PEOPLE_SIMPL_HXX
+
+#include "people.hxx"
+#include "people-sskel.hxx"
+
+struct gender_simpl: virtual gender_sskel, xml_schema::string_simpl
+{
+ virtual void
+ pre (gender g)
+ {
+ string_simpl::pre (g == male ? "male" : "female");
+ }
+};
+
+struct person_simpl: virtual person_sskel
+{
+ virtual void
+ pre (const person& p)
+ {
+ person_ = &p;
+ }
+
+ virtual const char*
+ first_name ()
+ {
+ return person_->first_name_;
+ }
+
+ virtual const char*
+ last_name ()
+ {
+ return person_->last_name_;
+ }
+
+ virtual ::gender
+ gender ()
+ {
+ return person_->gender_;
+ }
+
+ virtual unsigned short
+ age ()
+ {
+ return person_->age_;
+ }
+
+private:
+ const person* person_;
+};
+
+struct people_simpl: virtual people_sskel
+{
+ virtual void
+ pre (const people& p)
+ {
+ i_ = 0;
+ people_ = &p;
+ }
+
+ virtual bool
+ person_next ()
+ {
+ return i_ < people_->size_;
+ }
+
+ virtual const ::person&
+ person ()
+ {
+ return people_->people_[i_++];
+ }
+
+private:
+ size_t i_;
+ const people* people_;
+};
+
+#endif // PEOPLE_SIMPL_HXX
diff --git a/examples/cxx/serializer/minimal/people-simpl-tiein.hxx b/examples/cxx/serializer/minimal/people-simpl-tiein.hxx
new file mode 100644
index 0000000..ce7a70d
--- /dev/null
+++ b/examples/cxx/serializer/minimal/people-simpl-tiein.hxx
@@ -0,0 +1,90 @@
+// file : examples/cxx/serializer/people/people-simpl-tiein.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef PEOPLE_SIMPL_HXX
+#define PEOPLE_SIMPL_HXX
+
+#include "people.hxx"
+#include "people-sskel.hxx"
+
+struct gender_simpl: gender_sskel
+{
+ gender_simpl ()
+ : gender_sskel (&base_impl_)
+ {
+ }
+
+ virtual void
+ pre (gender g)
+ {
+ base_impl_.pre (g == male ? "male" : "female");
+ }
+
+private:
+ xml_schema::string_simpl base_impl_;
+};
+
+struct person_simpl: person_sskel
+{
+ virtual void
+ pre (const person& p)
+ {
+ person_ = &p;
+ }
+
+ virtual const char*
+ first_name ()
+ {
+ return person_->first_name_;
+ }
+
+ virtual const char*
+ last_name ()
+ {
+ return person_->last_name_;
+ }
+
+ virtual ::gender
+ gender ()
+ {
+ return person_->gender_;
+ }
+
+ virtual unsigned short
+ age ()
+ {
+ return person_->age_;
+ }
+
+private:
+ const person* person_;
+};
+
+struct people_simpl: people_sskel
+{
+ virtual void
+ pre (const people& p)
+ {
+ i_ = 0;
+ people_ = &p;
+ }
+
+ virtual bool
+ person_next ()
+ {
+ return i_ < people_->size_;
+ }
+
+ virtual const ::person&
+ person ()
+ {
+ return people_->people_[i_++];
+ }
+
+private:
+ size_t i_;
+ const people* people_;
+};
+
+#endif // PEOPLE_SIMPL_HXX
diff --git a/examples/cxx/serializer/minimal/people.hxx b/examples/cxx/serializer/minimal/people.hxx
new file mode 100644
index 0000000..94ae37d
--- /dev/null
+++ b/examples/cxx/serializer/minimal/people.hxx
@@ -0,0 +1,30 @@
+// file : examples/cxx/serializer/minimal/people.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef PEOPLE_HXX
+#define PEOPLE_HXX
+
+#include <stddef.h> // size_t
+
+enum gender
+{
+ male,
+ female
+};
+
+struct person
+{
+ const char* first_name_;
+ const char* last_name_;
+ gender gender_;
+ unsigned short age_;
+};
+
+struct people
+{
+ person* people_;
+ size_t size_;
+};
+
+#endif // PEOPLE_HXX
diff --git a/examples/cxx/serializer/minimal/people.map b/examples/cxx/serializer/minimal/people.map
new file mode 100644
index 0000000..6f51d5b
--- /dev/null
+++ b/examples/cxx/serializer/minimal/people.map
@@ -0,0 +1,9 @@
+# file : examples/cxx/serializer/minimal/people.map
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : not copyrighted - public domain
+
+include "people.hxx";
+
+gender ::gender ::gender;
+person "const ::person&";
+people "const ::people&";
diff --git a/examples/cxx/serializer/minimal/people.xsd b/examples/cxx/serializer/minimal/people.xsd
new file mode 100644
index 0000000..d5e4e1f
--- /dev/null
+++ b/examples/cxx/serializer/minimal/people.xsd
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/serializer/minimal/people.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:simpleType name="gender">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="male"/>
+ <xsd:enumeration value="female"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="first-name" type="xsd:string"/>
+ <xsd:element name="last-name" type="xsd:string"/>
+ <xsd:element name="gender" type="gender"/>
+ <xsd:element name="age" type="xsd:unsignedShort"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="people">
+ <xsd:sequence>
+ <xsd:element name="person" type="person" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="people" type="people"/>
+
+</xsd:schema>