+++ /dev/null
-
-/*******************************************************************************
-
- Copyright (c) 2009, Charles McGarvey
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-*******************************************************************************/
-
-#include <fstream>
-
-#include <yajl/yajl_gen.h>
-
-#include "stringtools.hh"
-#include "serializer.hh"
-
-
-namespace dc {
-
-
-class serializer::serializer_impl
-{
-public:
- serializer_impl(const std::string& filePath, const std::string& indent = "")
- {
- std::ofstream* output = new std::ofstream(filePath.c_str());
- init(*output, true, indent);
- }
-
- serializer_impl(std::ostream& output, const std::string& indent = "")
- {
- init(output, false, indent);
- }
-
- ~serializer_impl()
- {
- if (deleteWhenDone)
- {
- delete out;
- }
- yajl_gen_free(gen);
- }
-
- static void throwError(yajl_gen_status err)
- {
- switch (err)
- {
- case yajl_gen_generation_complete:
- throw serializer::exception("the archive has already terminated");
- case yajl_gen_keys_must_be_strings:
- throw serializer::exception("map keys must be strings");
- case yajl_max_depth_exceeded:
- throw serializer::exception("maximum archive depth exceeded");
- case yajl_gen_in_error_state:
- throw serializer::exception("serializer already in error state");
- case yajl_gen_status_ok:
- ; // There is no error here. Move along...
- }
- }
-
- yajl_gen gen;
-
- std::ostream* out;
- bool deleteWhenDone;
-
-private:
- void init(std::ostream& output, bool deleteOut, const std::string& indent)
- {
- yajl_gen_config config;
-
- out = &output;
- deleteWhenDone = deleteOut;
-
- if (indent != "")
- {
- config.beautify = true;
- config.indentString = 0;
- // FIXME: a yajl bug prevents using heap-allocated strings
- //config.indentString = indent.c_str();
- }
- else
- {
- config.beautify = false;
- }
- gen = yajl_gen_alloc(&config, 0);
- }
-};
-
-
-serializer::serializer(const std::string& filePath, const std::string& indent) :
- // pass through
- impl(new serializer::serializer_impl(filePath, indent)) {}
-
-serializer::serializer(std::ostream& output, const std::string& indent) :
- // pass through
- impl(new serializer::serializer_impl(output, indent)) {}
-
-serializer::~serializer()
-{
- flush();
-}
-
-
-void serializer::push(long value)
-{
- yajl_gen_status stat = yajl_gen_integer(impl->gen, value);
- if (stat != yajl_gen_status_ok)
- serializer::serializer_impl::throwError(stat);
-}
-
-void serializer::push(double value)
-{
- yajl_gen_status stat = yajl_gen_double(impl->gen, value);
- if (stat != yajl_gen_status_ok)
- serializer::serializer_impl::throwError(stat);
-}
-
-void serializer::push(bool value)
-{
- yajl_gen_status stat = yajl_gen_bool(impl->gen, value);
- if (stat != yajl_gen_status_ok)
- serializer::serializer_impl::throwError(stat);
-}
-
-void serializer::push(const std::string& value)
-{
- yajl_gen_status stat = yajl_gen_string(impl->gen,
- (const unsigned char*)value.c_str(), value.length());
- if (stat != yajl_gen_status_ok)
- serializer::serializer_impl::throwError(stat);
-}
-
-void serializer::push(const std::wstring& value)
-{
- push(wideToMulti(value));
-}
-
-void serializer::pushNull()
-{
- yajl_gen_status stat = yajl_gen_null(impl->gen);
- if (stat != yajl_gen_status_ok)
- serializer::serializer_impl::throwError(stat);
-}
-
-
-void serializer::pushMapHead()
-{
- yajl_gen_status stat = yajl_gen_map_open(impl->gen);
- if (stat != yajl_gen_status_ok)
- serializer::serializer_impl::throwError(stat);
-}
-
-void serializer::pushMapTail()
-{
- yajl_gen_status stat = yajl_gen_map_close(impl->gen);
- if (stat != yajl_gen_status_ok)
- serializer::serializer_impl::throwError(stat);
-}
-
-void serializer::pushArrayHead()
-{
- yajl_gen_status stat = yajl_gen_array_open(impl->gen);
- if (stat != yajl_gen_status_ok)
- serializer::serializer_impl::throwError(stat);
-}
-
-void serializer::pushArrayTail()
-{
- yajl_gen_status stat = yajl_gen_array_close(impl->gen);
- if (stat != yajl_gen_status_ok)
- serializer::serializer_impl::throwError(stat);
-}
-
-
-void serializer::flush()
-{
- const unsigned char* buffer;
- unsigned length;
-
- yajl_gen_get_buf(impl->gen, &buffer, &length);
- impl->out->write((const char*)buffer, length);
- yajl_gen_clear(impl->gen);
-}
-
-
-} // namespace dc
-
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
-