← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/bug-942161 into lp:zorba

 

Paul J. Lucas has proposed merging lp:~zorba-coders/zorba/bug-942161 into lp:zorba.

Commit message:
Reworked public Zorba_SerializerOption so it's better between C & C++.
Now allow any ICU-supported encoding.

Requested reviews:
  Paul J. Lucas (paul-lucas)
Related bugs:
  Bug #942161 in Zorba: "serializer to support arbitrary encodings"
  https://bugs.launchpad.net/zorba/+bug/942161

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/bug-942161/+merge/179969

Reworked public Zorba_SerializerOption so it's better between C & C++.
Now allow any ICU-supported encoding.
-- 
https://code.launchpad.net/~zorba-coders/zorba/bug-942161/+merge/179969
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'bin/zorbacmd.cpp'
--- bin/zorbacmd.cpp	2013-08-06 17:58:01 +0000
+++ bin/zorbacmd.cpp	2013-08-13 17:44:44 +0000
@@ -715,8 +715,8 @@
     lHints.lib_module = true;
   }
 
-  Zorba_SerializerOptions lSerOptions = 
-  Zorba_SerializerOptions::SerializerOptionsFromStringParams(properties.getSerializerParameters());
+  Zorba_SerializerOptions lSerOptions;
+  lSerOptions.set(properties.getSerializerParameters());
 
   createSerializerOptions(lSerOptions, properties);
 
@@ -1259,9 +1259,8 @@
           lHost = "127.0.0.1";
         }
 
-        Zorba_SerializerOptions lSerOptions =
-            Zorba_SerializerOptions::SerializerOptionsFromStringParams(
-            properties.getSerializerParameters());
+        Zorba_SerializerOptions lSerOptions;
+        lSerOptions.set(properties.getSerializerParameters());
         createSerializerOptions(lSerOptions, properties);
 
         if (!properties.hasNoLogo()) 

=== modified file 'include/zorba/options.h'
--- include/zorba/options.h	2013-06-15 02:57:08 +0000
+++ include/zorba/options.h	2013-08-13 17:44:44 +0000
@@ -13,15 +13,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #ifndef ZORBA_OPTIONS_H
 #define ZORBA_OPTIONS_H
 #include <zorba/config.h>
 
 #ifdef __cplusplus
+#include <utility>                      /* for pair */
 #include <vector>
-#include <zorba/zorba_string.h>
-#endif
-
+#endif /* __cplusplus */
+
+/*****************************************************************************/
+
+#ifdef __cplusplus
+typedef bool Zorba_opt_bool_t;
+#else
+typedef char Zorba_opt_bool_t;
+#endif /* __cplusplus */
 
 /** \brief The optimization level used for optimizing the query. */
 typedef enum {
@@ -36,10 +44,6 @@
                         */
 } Zorba_opt_level_t;
 
-#if !defined(__cplusplus)
-  typedef enum { false = 0, true = 1 } bool;
-#endif
-
 /** \brief Set of hints that can be passed to the query compiler.
  *
  * An instance of this class can be passed to the compileQuery function
@@ -55,15 +59,16 @@
 {
   /** \brief The optimization level that is used */
   Zorba_opt_level_t opt_level;
+
   /** \brief Treat the query as a library module */
-  bool lib_module;
+  Zorba_opt_bool_t lib_module;
 
   /**
    * \brief By default, this flag is set to false. Applications may set it to
    * true if they plan to execute the query only via one of the methods that 
    * serialize the query result.
    */
-  bool for_serialization_only;
+  Zorba_opt_bool_t for_serialization_only;
 
 #ifdef __cplusplus
   /** \brief Default constructor for CompilerHints which assigns default values to all hints (C++ only).
@@ -73,9 +78,24 @@
    *   - library module: false
    */
   ZORBA_DLL_PUBLIC Zorba_CompilerHints();
-#endif
+#endif /* __cplusplus */
 } Zorba_CompilerHints_t;
 
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** \brief Helper function for C to set default values ComplilerHints struct.
+ *
+ * \retval Zorba_CompilerHints_t with default member values
+ */
+ZORBA_DLL_PUBLIC void Zorba_CompilerHints_default(Zorba_CompilerHints_t*);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif /* __cplusplus */
+
+/*****************************************************************************/
 
 typedef enum 
 {
@@ -88,68 +108,61 @@
   ZORBA_SERIALIZATION_METHOD_JSON_XML_HYBRID
 } Zorba_serialization_method_t;
 
-
 typedef enum 
 {
-  ZORBA_BYTE_ORDER_MARK_YES,
-  ZORBA_BYTE_ORDER_MARK_NO
+  ZORBA_BYTE_ORDER_MARK_NO,
+  ZORBA_BYTE_ORDER_MARK_YES
 } Zorba_byte_order_mark_t;
 
-
 typedef enum 
 {
-  ZORBA_ESCAPE_URI_ATTRIBUTES_YES,
-  ZORBA_ESCAPE_URI_ATTRIBUTES_NO
+  ZORBA_ESCAPE_URI_ATTRIBUTES_NO,
+  ZORBA_ESCAPE_URI_ATTRIBUTES_YES
 } Zorba_escape_uri_attributes_t;
 
 typedef enum {
-  ZORBA_INCLUDE_CONTENT_TYPE_YES,
-  ZORBA_INCLUDE_CONTENT_TYPE_NO
+  ZORBA_INCLUDE_CONTENT_TYPE_NO,
+  ZORBA_INCLUDE_CONTENT_TYPE_YES
 } Zorba_include_content_type_t;
 
 typedef enum {
-  ZORBA_INDENT_YES,
-  ZORBA_INDENT_NO
+  ZORBA_INDENT_NO,
+  ZORBA_INDENT_YES
 } Zorba_indent_t;
 
 typedef enum {
+  ZORBA_NORMALIZATION_FORM_NONE,
   ZORBA_NORMALIZATION_FORM_NFC,
   ZORBA_NORMALIZATION_FORM_NFD,
   ZORBA_NORMALIZATION_FORM_NFKC,
   ZORBA_NORMALIZATION_FORM_NFKD,
-  ZORBA_NORMALIZATION_FORM_FULLY_normalized,
-  ZORBA_NORMALIZATION_FORM_NONE
+  ZORBA_NORMALIZATION_FORM_FULLY_normalized
 } Zorba_normalization_form_t;
 
 typedef enum {
-  ZORBA_OMIT_XML_DECLARATION_YES,
-  ZORBA_OMIT_XML_DECLARATION_NO
+  ZORBA_OMIT_XML_DECLARATION_NO,
+  ZORBA_OMIT_XML_DECLARATION_YES
 } Zorba_omit_xml_declaration_t;
 
 typedef enum {
+  ZORBA_STANDALONE_NO,
   ZORBA_STANDALONE_YES,
-  ZORBA_STANDALONE_NO,
   ZORBA_STANDALONE_OMIT
 } Zorba_standalone_t;
 
 typedef enum {
-  ZORBA_UNDECLARE_PREFIXES_YES,
-  ZORBA_UNDECLARE_PREFIXES_NO
+  ZORBA_UNDECLARE_PREFIXES_NO,
+  ZORBA_UNDECLARE_PREFIXES_YES
 } Zorba_undeclare_prefixes_t;
 
 typedef enum {
-  ZORBA_ENCODING_UTF8,
-  ZORBA_ENCODING_UTF16
-} Zorba_encoding_t;
-
-typedef enum {
-  DONT_SAVE_UNUSED_FUNCTIONS = 0,
-  SAVE_UNUSED_FUNCTIONS = 1
+  DONT_SAVE_UNUSED_FUNCTIONS,
+  SAVE_UNUSED_FUNCTIONS
 } Zorba_save_plan_options_t;
 
 typedef enum {
-  JSONIQ_EXTENSIONS_YES,
-  JSONIQ_EXTENSIONS_NO
+  JSONIQ_EXTENSIONS_NO,
+  JSONIQ_EXTENSIONS_YES
 } Zorba_jsoniq_extensions_t;
 
 typedef enum {
@@ -157,18 +170,19 @@
   JSONIQ_MULTIPLE_ITEMS_YES
 } Zorba_jsoniq_multiple_items_t;
 
+/*****************************************************************************/
 
 /** \brief Options that configure the serialization process of a query result.
-*         See http://www.w3.org/TR/2005/CR-xslt-xquery-serialization-20051103/.
-*
-* This struct defines options that can be passed to the serialization process of a query
-* result. An instance of this class can be passed to the serialize function.
-*
-* File \link serialization.cpp \endlink contains examples that show how to use
-* the SerializerOptions.
-*/
-#ifdef __cplusplus
-typedef struct ZORBA_DLL_PUBLIC Zorba_SerializerOptions
+ *         See http://www.w3.org/TR/2005/CR-xslt-xquery-serialization-20051103/.
+ *
+ * This struct defines options that can be passed to the serialization process
+ * of a query result. An instance of this class can be passed to the serialize
+ * function.
+ *
+ * File \link serialization.cpp \endlink contains examples that show how to use
+ * the SerializerOptions.
+ */
+typedef struct Zorba_SerializerOptions
 {
   Zorba_serialization_method_t  ser_method;
   Zorba_byte_order_mark_t       byte_order_mark;
@@ -179,97 +193,116 @@
   Zorba_omit_xml_declaration_t  omit_xml_declaration;
   Zorba_standalone_t            standalone;
   Zorba_undeclare_prefixes_t    undeclare_prefixes;
-  Zorba_encoding_t              encoding;
 
-  zorba::String                 media_type;
-  zorba::String                 doctype_system;
-  zorba::String                 doctype_public;
-  zorba::String                 cdata_section_elements;
-  zorba::String                 version;
+  char const*                   encoding;
+  char const*                   media_type;
+  char const*                   doctype_system;
+  char const*                   doctype_public;
+  char const*                   cdata_section_elements;
+  char const*                   version;
 
   Zorba_jsoniq_multiple_items_t jsoniq_multiple_items;
   Zorba_serialization_method_t  jsoniq_xdm_method;
 
-  /** \brief Default constructor for SerializerOptions which assigns default values to all
-   *         options (C++ only).
-   *
-   * Default values:
-   *   - serialization method: XML
-   *   - byte-order-mark: NO
-   *   - esacpe-uri-attributes: NO
-   *   - include-content-type: NO
-   *   - indent: NO
-   *   - normalization-form: none
-   *   - omit-xml-declaration: NO
-   *   - standalone: omit
-   *   - undeclare-prefixes: NO
+#ifdef __cplusplus
+  /**
+   * Default constructor that sets default values as follows:
+   *  - serialization method: XML
+   *  - byte-order-mark: NO
+   *  - esacpe-uri-attributes: NO
+   *  - include-content-type: NO
+   *  - indent: NO
+   *  - normalization-form: none
+   *  - omit-xml-declaration: NO
+   *  - standalone: omit
+   *  - undeclare-prefixes: NO
    */
-
   Zorba_SerializerOptions();
 
-  /** \brief Helper function to set a serializer parameter value from a key / value string pair.
-   *
-   *
-   * \retval None
-   */
-  void SetSerializerOption(const char* parameter, const char* value);
-
-  /** \brief Helper function to create a Zorba_SerializerOptions from a vector of key / value
-   *         string pairs
-   *
-   * \retval The created Zorba_SerializerOptions structure
-   */
-  static Zorba_SerializerOptions SerializerOptionsFromStringParams(const std::vector<std::pair<std::string,std::string> >& params);
+  /**
+   * Copy constructor.
+   */
+  Zorba_SerializerOptions( Zorba_SerializerOptions const& );
+
+  /**
+   * Destructor that frees all internal data.
+   */
+  ~Zorba_SerializerOptions();
+
+  /**
+   * Assignment operator.
+   */
+  Zorba_SerializerOptions& operator=( Zorba_SerializerOptions const& );
+
+  /**
+   * Sets a serializer option value.
+   *
+   * @param option The name of the option to set.
+   * @param value The option's new value.
+   * @throws err::SEPM0016 if an option/value is invalid.
+   */
+  void set( char const *option, char const *value );
+
+  /**
+   * Sets multiple serializer option values.
+   *
+   * @param option_values The option/value pairs to set.
+   * @throws err::SEPM0016 if an option/value is invalid.
+   */
+  void set( std::vector<std::pair<std::string,std::string> > const &option_values );
+#endif /* __cplusplus */
 
 } Zorba_SerializerOptions_t;
-#endif
-
-
-#ifndef __cplusplus
-struct Zorba_SerializerOptions;
-typedef struct Zorba_SerializerOptions Zorba_SerializerOptions_t;
-#endif
-
 
 #ifdef __cplusplus
 extern "C" {
-#endif
-
-/** \brief Helper function for C to set default values ComplilerHints struct.
- *
- * \retval Zorba_CompilerHints_t with default member values
- */
-ZORBA_DLL_PUBLIC void Zorba_CompilerHints_default(Zorba_CompilerHints_t*);
-
-/** \brief Helper function to create a Zorba_SerializerOptions_t struct because
- *         of missing default constructor. C++ code can delete the
- *         returned Zorba_SerializerOptions_t* struct, while C code
- *         must call Zorba_SerializerOptions_free().
- *
- * \retval Zorba_CompilerHints_t with default member values
- */
-ZORBA_DLL_PUBLIC Zorba_SerializerOptions_t* Zorba_SerializerOptions_default();
-
-/** \brief Helper function to delete a Zorba_SerializerOptions_t struct
- *
- * \retval Zorba_CompilerHints_t with default member values
- */
-ZORBA_DLL_PUBLIC void Zorba_SerializerOptions_free(Zorba_SerializerOptions_t* serializerOptions);
-
-/** \brief Helper function to set an option in a Zorba_SerializerOptions_t structure
- *
- * \param serializerOptions serializer options
- * \param parameter the serializer parameter to be configured
- * \param value the value to which the parameter should be set
- * \retval Zorba_CompilerHints_t with default member values
- */
-ZORBA_DLL_PUBLIC void Zorba_SerializerOptions_set(Zorba_SerializerOptions_t* serializerOptions, const char* parameter, const char* value);
-
+#endif /* __cplusplus */
+
+/**
+ * Initializes a Zorba_SerializerOptions.  This is needed only in C code; C++
+ * code calls the default constructor.
+ *
+ * @param opts The Zorba_SerializerOptions to be initialized.
+ */
+ZORBA_DLL_PUBLIC
+void Zorba_SerializerOptions_init( Zorba_SerializerOptions_t *opts );
+
+/**
+ * Frees all internal data used by a Zorba_SerializerOptions.  This is needed
+ * only in C code; C++ code calls the destructor. Note that this does \e not
+ * free \a opts itself (which may be on the stack).
+ *
+ * @param opts The Zorba_SerializerOptions to be freed.
+ */
+ZORBA_DLL_PUBLIC
+void Zorba_SerializerOptions_free( Zorba_SerializerOptions_t *opts );
+
+/**
+ * Sets an option in a Zorba_SerializerOptions.
+ *
+ * @param opts The Zorba_SerializerOptions to affect.
+ * @param option The name of the option to be set.
+ * @param value The option's new value.
+ * @return \c true only if all the arguments were valid; \c false otherwise.
+ */
+ZORBA_DLL_PUBLIC
+Zorba_opt_bool_t Zorba_SerializerOptions_set( Zorba_SerializerOptions_t *opts,
+                                              char const *option,
+                                              char const *value );
 
 #ifdef __cplusplus
-}
-#endif
-
-#endif
-
+} // extern "C"
+
+inline Zorba_SerializerOptions::Zorba_SerializerOptions() {
+  Zorba_SerializerOptions_init( this );
+}
+
+inline Zorba_SerializerOptions::~Zorba_SerializerOptions() {
+  Zorba_SerializerOptions_free( this );
+}
+#endif /* __cplusplus */
+
+/*****************************************************************************/
+
+#endif /* ZORBA_OPTIONS_H */
 /* vim:set et sw=2 ts=2: */

=== modified file 'modules/org/expath/ns/file.xq.src/file.h'
--- modules/org/expath/ns/file.xq.src/file.h	2013-08-05 22:12:13 +0000
+++ modules/org/expath/ns/file.xq.src/file.h	2013-08-13 17:44:44 +0000
@@ -17,6 +17,7 @@
 #define ZORBA_FILEMODULE_FILE_H
 
 #include <zorba/util/fs_util.h>
+#include <zorba/zorba_string.h>
 
 #include "file_function.h"
 

=== modified file 'src/api/options.cpp'
--- src/api/options.cpp	2013-06-15 02:57:08 +0000
+++ src/api/options.cpp	2013-08-13 17:44:44 +0000
@@ -15,176 +15,220 @@
  */
 #include "stdafx.h"
 
-#include <string.h>
+#include <cstring>
+
 #include <zorba/options.h>
+#include <zorba/util/transcode_stream.h>
+
 #include "diagnostics/xquery_diagnostics.h"
-
-Zorba_CompilerHints::Zorba_CompilerHints()
-  :
+#include "util/ascii_util.h"
+#include "util/stl_util.h"
+
+using namespace std;
+using namespace zorba;
+
+///////////////////////////////////////////////////////////////////////////////
+
+Zorba_CompilerHints::Zorba_CompilerHints() :
   opt_level(ZORBA_OPT_LEVEL_O1),
   lib_module(false),
   for_serialization_only(false)
 {
 }
 
-
-void Zorba_CompilerHints_default(Zorba_CompilerHints_t* aHints)
-{
-  Zorba_CompilerHints_t lDefault;
-  *aHints = lDefault;
-}
-
-
-Zorba_SerializerOptions::Zorba_SerializerOptions()
-  :
-  ser_method(ZORBA_SERIALIZATION_METHOD_JSON_XML_HYBRID),
-  byte_order_mark(ZORBA_BYTE_ORDER_MARK_NO),
-  escape_uri_attributes(ZORBA_ESCAPE_URI_ATTRIBUTES_NO),
-  include_content_type(ZORBA_INCLUDE_CONTENT_TYPE_NO),
-  indent(ZORBA_INDENT_NO),
-  normalization_form(ZORBA_NORMALIZATION_FORM_NONE),
-  omit_xml_declaration(ZORBA_OMIT_XML_DECLARATION_NO),
-  standalone(ZORBA_STANDALONE_OMIT),
-  undeclare_prefixes(ZORBA_UNDECLARE_PREFIXES_NO),
-  encoding(ZORBA_ENCODING_UTF8),
-  jsoniq_multiple_items(JSONIQ_MULTIPLE_ITEMS_YES),
-  jsoniq_xdm_method(ZORBA_SERIALIZATION_METHOD_XML)
-{
-}
-
-Zorba_serialization_method_t convertMethodString(const char* value, const char* parameter)
-{
-  if (strcmp(value, "xml") == 0) return ZORBA_SERIALIZATION_METHOD_XML;
-  else if (strcmp(value, "html") == 0) return ZORBA_SERIALIZATION_METHOD_HTML;
-  else if (strcmp(value, "xhtml") == 0) return ZORBA_SERIALIZATION_METHOD_XHTML;
-  else if (strcmp(value, "text") == 0) return ZORBA_SERIALIZATION_METHOD_TEXT;
-  else if (strcmp(value, "binary") == 0) return ZORBA_SERIALIZATION_METHOD_BINARY;
-  else if (strcmp(value, "json") == 0) return ZORBA_SERIALIZATION_METHOD_JSON;
-  else if (strcmp(value, "json-xml-hybrid") == 0) return ZORBA_SERIALIZATION_METHOD_JSON_XML_HYBRID;
-  else
-  {
-    throw XQUERY_EXCEPTION
-        (err::SEPM0016, ERROR_PARAMS( value, parameter, ZED( GoodValuesAreXMLEtc ) ));
-  }
-}
-
-void Zorba_SerializerOptions::SetSerializerOption(
-    const char* parameter,
-    const char* value)
-{
-  if (parameter == NULL || value == NULL)
-    return;
-
-  if (strcmp(parameter, "method") == 0)
-  {
-    ser_method = convertMethodString(value, parameter);
-  }
-  else if (strcmp(parameter, "byte-order-mark") == 0)
-  {
-    if (strcmp(value, "yes") == 0) byte_order_mark = ZORBA_BYTE_ORDER_MARK_YES;
-    else if (strcmp(value, "no") == 0) byte_order_mark = ZORBA_BYTE_ORDER_MARK_NO;
-  }
-  else if (strcmp(parameter, "include-content-type") == 0)
-  {
-    if (strcmp(value, "yes") == 0) include_content_type = ZORBA_INCLUDE_CONTENT_TYPE_YES;
-    else if (strcmp(value, "no") == 0) include_content_type = ZORBA_INCLUDE_CONTENT_TYPE_NO;
-  }
-  else if (strcmp(parameter, "indent") == 0)
-  {
-    if (strcmp(value, "yes") == 0) indent = ZORBA_INDENT_YES;
-    else if (strcmp(value, "no") == 0) indent= ZORBA_INDENT_NO;
-  }
-  else if (strcmp(parameter, "omit-xml-declaration") == 0)
-  {
-    if (strcmp(value, "yes") == 0) omit_xml_declaration = ZORBA_OMIT_XML_DECLARATION_YES;
-    else if (strcmp(value, "no") == 0) omit_xml_declaration= ZORBA_OMIT_XML_DECLARATION_NO;
-  }
-  else if (strcmp(parameter, "standalone") == 0)
-  {
-    if (strcmp(value, "yes") == 0) standalone = ZORBA_STANDALONE_YES;
-    else if (strcmp(value, "no") == 0) standalone= ZORBA_STANDALONE_NO;
-    else if (strcmp(value, "omit") == 0) standalone= ZORBA_STANDALONE_OMIT;
-  }
-  else if (strcmp(parameter, "undeclare-prefixes") == 0)
-  {
-    if (strcmp(value, "yes") == 0) undeclare_prefixes = ZORBA_UNDECLARE_PREFIXES_YES;
-    else if (strcmp(value, "no") == 0) undeclare_prefixes = ZORBA_UNDECLARE_PREFIXES_NO;
-  }
-  else if (strcmp(parameter, "encoding") == 0)
-  {
-    if (strcmp(value, "UTF-8") == 0) encoding = ZORBA_ENCODING_UTF8;
-    else if (strcmp(value, "utf-8") == 0) encoding = ZORBA_ENCODING_UTF8;
-    else if (strcmp(value, "utf-16") == 0) encoding = ZORBA_ENCODING_UTF16;
-    else if (strcmp(value, "UTF-16") == 0) encoding = ZORBA_ENCODING_UTF16;
-  }
-  else if (strcmp(parameter, "media-type") == 0)
-  {
-    media_type = value;
-  }
-  else if (strcmp(parameter, "doctype-system") == 0)
-  {
-    doctype_system = value;
-  }
-  else if (strcmp(parameter, "doctype-public") == 0)
-  {
-    doctype_public = value;
-  }
-  else if (strcmp(parameter, "cdata-section-elements") == 0)
-  {
-    cdata_section_elements = value;
-  }
-  else if (strcmp(parameter, "version") == 0)
-  {
-    version = value;
-  }
-  else if (strcmp(parameter, "jsoniq-multiple-items") == 0)
-  {
-    if (strcmp(value, "no") == 0)
-      jsoniq_multiple_items = JSONIQ_MULTIPLE_ITEMS_NO;
-    else if (strcmp(value, "yes") == 0)
-      jsoniq_multiple_items = JSONIQ_MULTIPLE_ITEMS_YES;
-  }
-  else if (strcmp(parameter, "jsoniq-xdm-node-output-method") == 0)
-  {
-    jsoniq_xdm_method = convertMethodString(value, parameter);
-  }
-}
-
-
-Zorba_SerializerOptions_t Zorba_SerializerOptions::SerializerOptionsFromStringParams(const std::vector<std::pair<std::string, std::string> >& params)
-{
-  Zorba_SerializerOptions_t opt;
-
-  for (
-    std::vector<std::pair<std::string, std::string> >::const_iterator iter = params.begin();
-    iter != params.end();
-    ++iter)
-  {
-    opt.SetSerializerOption(iter->first.c_str(), iter->second.c_str());
-  }
-
-  return opt;
-}
-
-
-Zorba_SerializerOptions_t* Zorba_SerializerOptions_default()
-{
-  Zorba_SerializerOptions_t* lDefault = new Zorba_SerializerOptions();
-  return lDefault;
-}
-
-
-void Zorba_SerializerOptions_free(Zorba_SerializerOptions_t* serializerOptions)
-{
-  delete serializerOptions;
-}
-
-
-void Zorba_SerializerOptions_set(Zorba_SerializerOptions_t* serializerOptions, const char* parameter, const char* value)
-{
-  if (serializerOptions == NULL || parameter == NULL || value == NULL)
-    return;
-
-  serializerOptions->SetSerializerOption(parameter, value);
-}
+///////////////////////////////////////////////////////////////////////////////
+
+static void copy_from_to( Zorba_SerializerOptions const *from,
+                          Zorba_SerializerOptions *to ) {
+  ::memcpy( to, from, sizeof( Zorba_SerializerOptions ) );
+  if ( from->encoding )
+    to->encoding = ztd::new_strdup( from->encoding );
+  if ( from->media_type )
+    to->media_type = ztd::new_strdup( from->media_type );
+  if ( from->doctype_system )
+    to->doctype_system = ztd::new_strdup( from->doctype_system );
+  if ( from->doctype_public )
+    to->doctype_public = ztd::new_strdup( from->doctype_public );
+  if ( from->cdata_section_elements )
+    to->cdata_section_elements = ztd::new_strdup( from->cdata_section_elements );
+  if ( from->version )
+    to->version = ztd::new_strdup( from->version );
+}
+
+static void null_ptrs( Zorba_SerializerOptions_t *opts ) {
+  opts->encoding = nullptr;
+  opts->media_type = nullptr;
+  opts->doctype_system = nullptr;
+  opts->doctype_public = nullptr;
+  opts->cdata_section_elements = nullptr;
+  opts->version = nullptr;
+}
+
+static bool parse_method( char const *value, Zorba_serialization_method_t *m ) {
+  if ( strcmp( value, "binary" ) == 0 )
+    *m = ZORBA_SERIALIZATION_METHOD_BINARY;
+  else if ( strcmp( value, "html" ) == 0 )
+    *m = ZORBA_SERIALIZATION_METHOD_HTML;
+  else if ( strcmp( value, "json" ) == 0 )
+    *m = ZORBA_SERIALIZATION_METHOD_JSON;
+  else if ( strcmp( value, "json-xml-hybrid" ) == 0 )
+    *m = ZORBA_SERIALIZATION_METHOD_JSON_XML_HYBRID;
+  else if ( strcmp( value, "text" ) == 0 )
+    *m = ZORBA_SERIALIZATION_METHOD_TEXT;
+  else if ( strcmp( value, "xhtml" ) == 0 )
+    *m = ZORBA_SERIALIZATION_METHOD_XHTML;
+  else if ( strcmp( value, "xml" ) == 0 )
+    *m = ZORBA_SERIALIZATION_METHOD_XML;
+  else
+    return false;
+  return true;
+}
+
+template<typename EnumType>
+inline bool parse_yes_no( char const *value, EnumType *e ) {
+  if ( strcmp( value, "no" ) == 0 || strcmp( value, "yes" ) == 0 ) {
+    *e = static_cast<EnumType>( *value == 'y' );
+    return true;
+  }
+  return false;
+}
+
+void Zorba_SerializerOptions_init( Zorba_SerializerOptions_t *opts ) {
+  opts->byte_order_mark = ZORBA_BYTE_ORDER_MARK_NO;
+  opts->escape_uri_attributes = ZORBA_ESCAPE_URI_ATTRIBUTES_NO;
+  opts->include_content_type = ZORBA_INCLUDE_CONTENT_TYPE_NO;
+  opts->indent = ZORBA_INDENT_NO;
+  opts->jsoniq_multiple_items = JSONIQ_MULTIPLE_ITEMS_YES;
+  opts->jsoniq_xdm_method = ZORBA_SERIALIZATION_METHOD_XML;
+  opts->normalization_form = ZORBA_NORMALIZATION_FORM_NONE;
+  opts->omit_xml_declaration = ZORBA_OMIT_XML_DECLARATION_NO;
+  opts->ser_method = ZORBA_SERIALIZATION_METHOD_JSON_XML_HYBRID;
+  opts->standalone = ZORBA_STANDALONE_OMIT;
+  opts->undeclare_prefixes = ZORBA_UNDECLARE_PREFIXES_NO;
+  null_ptrs( opts );
+}
+
+void Zorba_SerializerOptions_free( Zorba_SerializerOptions_t *opts ) {
+  delete[] opts->encoding;
+  delete[] opts->media_type;
+  delete[] opts->doctype_system;
+  delete[] opts->doctype_public;
+  delete[] opts->cdata_section_elements;
+  delete[] opts->version;
+  null_ptrs( opts );
+}
+
+Zorba_opt_bool_t Zorba_SerializerOptions_set( Zorba_SerializerOptions_t *opts,
+                                              char const *option,
+                                              char const *value ) {
+  if ( !opts || !option || !value )
+    return false;
+
+  if ( strcmp( option, "byte-order-mark" ) == 0 )
+    return parse_yes_no( value, &opts->byte_order_mark );
+
+  if ( strcmp( option, "cdata-section-elements" ) == 0 ) {
+    delete[] opts->cdata_section_elements;
+    opts->cdata_section_elements = ztd::new_strdup( value );
+    return true;
+  }
+
+  if ( strcmp( option, "doctype-public" ) == 0 ) {
+    delete[] opts->doctype_public;
+    opts->doctype_public = ztd::new_strdup( value );
+    return true;
+  }
+
+  if ( strcmp( option, "doctype-system" ) == 0 ) {
+    delete[] opts->doctype_system;
+    opts->doctype_system = ztd::new_strdup( value );
+    return true;
+  }
+
+  if ( strcmp( option, "encoding" ) == 0 ) {
+    if ( !transcode::is_supported( value ) )
+      return false;
+    zstring temp( value );
+    ascii::to_upper( temp );
+    delete[] opts->encoding;
+    opts->encoding = ztd::new_strdup( temp.c_str() );
+    return true;
+  }
+
+  if ( strcmp( option, "include-content-type" ) == 0 )
+    return parse_yes_no( value, &opts->include_content_type );
+
+  if ( strcmp( option, "indent" ) == 0 )
+    return parse_yes_no( value, &opts->indent );
+
+  if ( strcmp( option, "jsoniq-multiple-items" ) == 0 )
+    return parse_yes_no( value, &opts->jsoniq_multiple_items );
+
+  if ( strcmp( option, "jsoniq-xdm-node-output-method" ) == 0 )
+    return parse_method( value, &opts->jsoniq_xdm_method );
+
+  if ( strcmp( option, "media-type" ) == 0 ) {
+    delete[] opts->media_type;
+    opts->media_type = ztd::new_strdup( value );
+    return true;
+  }
+
+  if ( strcmp( option, "method" ) == 0 )
+    return parse_method( value, &opts->ser_method );
+
+  if ( strcmp( option, "omit-xml-declaration" ) == 0 )
+    return parse_yes_no( value, &opts->omit_xml_declaration );
+
+  if ( strcmp( option, "standalone" ) == 0 ) {
+    if ( parse_yes_no( value, &opts->standalone ) )
+      return true;
+    if ( strcmp( value, "omit" ) != 0 )
+      return false;
+    opts->standalone = ZORBA_STANDALONE_OMIT;
+    return true;
+  }
+
+  if ( strcmp( option, "undeclare-prefixes" ) == 0 )
+    return parse_yes_no( value, &opts->undeclare_prefixes );
+
+  if ( strcmp( option, "version" ) == 0 ) {
+    delete[] opts->version;
+    opts->version = ztd::new_strdup( value );
+    return true;
+  }
+
+  return false;
+}
+
+Zorba_SerializerOptions::
+Zorba_SerializerOptions( Zorba_SerializerOptions const &that ) {
+  if ( &that != this )
+    copy_from_to( &that, this );
+  else
+    Zorba_SerializerOptions_init( this );
+}
+
+Zorba_SerializerOptions&
+Zorba_SerializerOptions::operator=( Zorba_SerializerOptions const &that ) {
+  if ( &that != this ) {
+    Zorba_SerializerOptions_free( this );
+    copy_from_to( &that, this );
+  }
+  return *this;
+}
+
+void Zorba_SerializerOptions::set( char const *option, char const *value ) {
+  if ( !Zorba_SerializerOptions_set( this, option, value ) )
+    throw XQUERY_EXCEPTION(
+      err::SEPM0016,
+      ERROR_PARAMS( value, option, ZED( GoodValuesAreXMLEtc ) )
+    );
+}
+
+void Zorba_SerializerOptions::set( std::vector<std::pair<std::string,std::string> > const &option_values ) {
+  typedef std::pair<std::string,std::string> string_pair;
+  FOR_EACH( std::vector<string_pair>, i, option_values )
+    set( i->first.c_str(), i->second.c_str() );
+}
+
 /* vim:set et sw=2 ts=2: */

=== modified file 'src/api/serialization/serializer.cpp'
--- src/api/serialization/serializer.cpp	2013-07-24 22:41:12 +0000
+++ src/api/serialization/serializer.cpp	2013-08-13 17:44:44 +0000
@@ -350,17 +350,15 @@
 ********************************************************************************/
 void serializer::emitter::emit_declaration()
 {
-  if (ser->byte_order_mark == PARAMETER_VALUE_YES )
+  if ( ser->byte_order_mark == PARAMETER_VALUE_YES )
   {
-    if (ser->encoding == PARAMETER_VALUE_UTF_8 )
-    {
-      transcode::orig_streambuf( tr )->sputn( "\xEF\xBB\xBF", 3 );
-    }
-    else if (ser->encoding == PARAMETER_VALUE_UTF_16)
-    {
-      // Little-endian
-      transcode::orig_streambuf( tr )->sputn( "\xFF\xFE", 2 );
-    }
+    std::streambuf *const orig_buf = transcode::orig_streambuf( tr );
+    if ( ser->encoding == "UTF-8" )
+      orig_buf->sputn( utf8::BOM, sizeof utf8::BOM );
+    else if ( ser->encoding == "UTF-16LE" || ser->encoding == "UTF-16" )
+      orig_buf->sputn( (char const*)&unicode::BOM_LE, sizeof unicode::BOM_LE );
+    else if ( ser->encoding == "UTF-16BE" )
+      orig_buf->sputn( (char const*)&unicode::BOM_BE, sizeof unicode::BOM_BE );
   }
 }
 
@@ -911,19 +909,9 @@
 
   if (ser->omit_xml_declaration == PARAMETER_VALUE_NO)
   {
-    tr << "<?xml version=\"" << ser->version_string;
-    switch (ser->encoding) {
-      case PARAMETER_VALUE_UTF_8:
-      case PARAMETER_VALUE_UTF_16:
-        tr << "\" encoding=\"";
-        switch (ser->encoding) {
-          case PARAMETER_VALUE_UTF_8 : tr << "UTF-8" ; break;
-          case PARAMETER_VALUE_UTF_16: tr << "UTF-16"; break;
-          default                    : ZORBA_ASSERT(false);
-        }
-        break;
-    }
-    tr << "\"";
+    tr << "<?xml version=\"" << ser->version_string << '"';
+    if ( !ser->encoding.empty() )
+      tr << " encoding=\"" << ser->encoding << '"';
 
     if (ser->standalone != PARAMETER_VALUE_OMIT) {
       tr << " standalone=\"";
@@ -1502,19 +1490,9 @@
       }
 
       tr << "<meta http-equiv=\"content-type\" content=\""
-         << ser->media_type;
-      switch (ser->encoding) {
-        case PARAMETER_VALUE_UTF_8:
-        case PARAMETER_VALUE_UTF_16:
-          tr << "\" charset=\"";
-          switch (ser->encoding) {
-            case PARAMETER_VALUE_UTF_8 : tr << "UTF-8" ; break;
-            case PARAMETER_VALUE_UTF_16: tr << "UTF-16"; break;
-            default                    : ZORBA_ASSERT(false);
-          }
-          break;
-      }
-      tr << "\"";
+         << ser->media_type << '"';
+      if ( !ser->encoding.empty() )
+        tr << "\" charset=\"" << ser->encoding << '"';
       // closed_parent_tag = 1;
     }
 
@@ -1701,19 +1679,9 @@
         }
 
         tr << "<meta http-equiv=\"content-type\" content=\""
-           << ser->media_type;
-        switch (ser->encoding) {
-          case PARAMETER_VALUE_UTF_8:
-          case PARAMETER_VALUE_UTF_16:
-            tr << "\" charset=\"";
-            switch (ser->encoding) {
-              case PARAMETER_VALUE_UTF_8 : tr << "UTF-8" ; break;
-              case PARAMETER_VALUE_UTF_16: tr << "UTF-16"; break;
-              default                    : ZORBA_ASSERT(false);
-            }
-            break;
-        }
-        tr << "\"/";
+           << ser->media_type << '"';
+        if ( !ser->encoding.empty() )
+          tr << "\" charset=\"" << ser->encoding << '"';
         //closed_parent_tag = 1;
       }
     }
@@ -2328,7 +2296,7 @@
   doctype_system.clear();
   doctype_public.clear();
 
-  encoding = PARAMETER_VALUE_UTF_8;
+  encoding = "UTF-8";
 
   include_content_type = PARAMETER_VALUE_NO;
 
@@ -2457,14 +2425,13 @@
   }
   else if (!strcmp(aName, "encoding"))
   {
-    if (!strcmp(aValue, "UTF-8"))
-      encoding = PARAMETER_VALUE_UTF_8;
-    else if (!strcmp(aValue, "UTF-16"))
-      encoding = PARAMETER_VALUE_UTF_16;
-    else
+    if ( !transcode::is_supported( aValue ) )
       throw XQUERY_EXCEPTION(
         err::SEPM0016, ERROR_PARAMS( aValue, aName, ZED( GoodValuesAreUTF8 ) )
       );
+    zstring temp( aValue );
+    ascii::to_upper( temp );
+    encoding = aValue;
   }
   else if (!strcmp(aName, "media-type"))
   {
@@ -2645,20 +2612,10 @@
 
 void serializer::attach_transcoder(std::ostream &os)
 {
-  if (encoding == PARAMETER_VALUE_UTF_8)
-  {
-    // do nothing
-  }
 #ifndef ZORBA_NO_UNICODE
-  else if (encoding == PARAMETER_VALUE_UTF_16)
-  {
-    transcode::attach( os, "UTF-16LE" );
-  }
-#endif
-  else
-  {
-    ZORBA_ASSERT(0);
-  }
+  if ( transcode::is_necessary( encoding.c_str() ) )
+    transcode::attach( os, encoding.c_str() );
+#endif /* ZORBA_NO_UNICODE */
 }
 
 /*******************************************************************************

=== modified file 'src/api/serialization/serializer.h'
--- src/api/serialization/serializer.h	2013-06-17 20:05:21 +0000
+++ src/api/serialization/serializer.h	2013-08-13 17:44:44 +0000
@@ -71,9 +71,6 @@
     PARAMETER_VALUE_JSON,
     PARAMETER_VALUE_JSON_XML_HYBRID,
 
-    PARAMETER_VALUE_UTF_8,
-    PARAMETER_VALUE_UTF_16,
-    
     // Values for the XML/HTML version
     PARAMETER_VALUE_VERSION_1_0,          // used for XML 1.0
     PARAMETER_VALUE_VERSION_1_1,          // used for XML 1.1
@@ -95,7 +92,7 @@
                                    // or semicolons, implemented
   zstring doctype_system;          // string, implemented
   zstring doctype_public;          // string, implemented
-  int encoding;                    // UTF-8 and UTF-16 supported, add others?
+  zstring encoding;
   short int escape_uri_attributes; // TODO: yes/no requires unicode normalization
   short int include_content_type;  // yes/no, implemented
   zstring media_type;              // string, implemented

=== modified file 'src/api/serializerimpl.cpp'
--- src/api/serializerimpl.cpp	2013-06-15 02:57:08 +0000
+++ src/api/serializerimpl.cpp	2013-08-13 17:44:44 +0000
@@ -191,28 +191,23 @@
     aInternalSerializer.setParameter("undeclare-prefixes", "no"); break;
   }
 
-  switch(aSerializerOptions.encoding)
-  {
-  case ZORBA_ENCODING_UTF8:
-    aInternalSerializer.setParameter("encoding", "UTF-8"); break;
-  case ZORBA_ENCODING_UTF16:
-    aInternalSerializer.setParameter("encoding", "UTF-16"); break;
-  }
-
-  if (aSerializerOptions.media_type != "")
-    aInternalSerializer.setParameter("media-type", aSerializerOptions.media_type.c_str());
-
-  if (aSerializerOptions.doctype_system != "")
-    aInternalSerializer.setParameter("doctype-system", aSerializerOptions.doctype_system.c_str());
-
-  if (aSerializerOptions.doctype_public != "")
-    aInternalSerializer.setParameter("doctype-public", aSerializerOptions.doctype_public.c_str());
-
-  if (aSerializerOptions.cdata_section_elements != "")
-    aInternalSerializer.setParameter("cdata-section-elements", aSerializerOptions.cdata_section_elements.c_str());
-
-  if (aSerializerOptions.version != "")
-    aInternalSerializer.setParameter("version", aSerializerOptions.version.c_str());
+  if (aSerializerOptions.encoding)
+    aInternalSerializer.setParameter("encoding", aSerializerOptions.encoding);
+
+  if (aSerializerOptions.media_type)
+    aInternalSerializer.setParameter("media-type", aSerializerOptions.media_type);
+
+  if (aSerializerOptions.doctype_system)
+    aInternalSerializer.setParameter("doctype-system", aSerializerOptions.doctype_system);
+
+  if (aSerializerOptions.doctype_public)
+    aInternalSerializer.setParameter("doctype-public", aSerializerOptions.doctype_public);
+
+  if (aSerializerOptions.cdata_section_elements)
+    aInternalSerializer.setParameter("cdata-section-elements", aSerializerOptions.cdata_section_elements);
+
+  if (aSerializerOptions.version)
+    aInternalSerializer.setParameter("version", aSerializerOptions.version);
 
   switch (aSerializerOptions.jsoniq_multiple_items)
   {

=== modified file 'src/util/unicode_util.h'
--- src/util/unicode_util.h	2013-05-09 00:48:27 +0000
+++ src/util/unicode_util.h	2013-08-13 17:44:44 +0000
@@ -131,9 +131,14 @@
 ////////// constants //////////////////////////////////////////////////////////
 
 /**
- * Byte Order Mark (BOM).
- */
-code_point const BOM = 0xFEFF;
+ * Byte Order Mark (BOM), big-endian .
+ */
+code_point const BOM_BE = 0xFFFE;
+
+/**
+ * Byte Order Mark (BOM), little-endian .
+ */
+code_point const BOM_LE = 0xFEFF;
 
 /**
  * An invalid code-point.

=== modified file 'swig/SerializationOptions.i'
--- swig/SerializationOptions.i	2012-03-27 00:56:11 +0000
+++ swig/SerializationOptions.i	2013-08-13 17:44:44 +0000
@@ -117,7 +117,7 @@
   }
 
   void SerializationOptions::setSerializerOption(const std::string &parameter, const std::string &value) {
-    lOptions.SetSerializerOption(parameter.c_str(), value.c_str());
+    lOptions.set(parameter.c_str(), value.c_str());
   }
   
 %}  // end Implementation

=== modified file 'test/apitest.cpp'
--- test/apitest.cpp	2013-08-05 11:24:53 +0000
+++ test/apitest.cpp	2013-08-13 17:44:44 +0000
@@ -288,7 +288,8 @@
     {
       if (lProp->useSerializer()) 
       {
-        Zorba_SerializerOptions opts = Zorba_SerializerOptions::SerializerOptionsFromStringParams(lProp->getSerializerParameters());
+        Zorba_SerializerOptions opts;
+	opts.set(lProp->getSerializerParameters());
         query->execute(*resultFile, &opts);
       }
       else if (lProp->iterPlanTest())

=== modified file 'test/driver/testdriver.cpp'
--- test/driver/testdriver.cpp	2013-08-09 08:27:30 +0000
+++ test/driver/testdriver.cpp	2013-08-13 17:44:44 +0000
@@ -443,8 +443,8 @@
              lIter != lSpec.serializerOptionsEnd();
              ++lIter)
         {
-          lSerOptions.SetSerializerOption(lIter->theOptName.c_str(),
-                                          lIter->theOptValue.c_str());
+          lSerOptions.set(lIter->theOptName.c_str(),
+                          lIter->theOptValue.c_str());
         }
         
         lQuery->execute(lResFileStream, &lSerOptions);


Follow ups