//////////////////////////////////////////////////////////////////////////////// /// @brief json result generator /// /// @file /// /// DISCLAIMER /// /// Copyright 2010-2011 triagens GmbH, Cologne, Germany /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// /// Copyright holder is triAGENS GmbH, Cologne, Germany /// /// @author Dr. Frank Celler /// @author Achim Brandt /// @author Copyright 2008-2011, triAGENS GmbH, Cologne, Germany //////////////////////////////////////////////////////////////////////////////// #include "JsonResultGenerator.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace triagens::basics; namespace triagens { namespace rest { // ----------------------------------------------------------------------------- // output methods // ----------------------------------------------------------------------------- namespace { void generateVariantArray (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { VariantArray* array = dynamic_cast(object); vector const& attributes = array->getAttributes(); vector const& values = array->getValues(); // generate array header output.appendText("{"); char const * sep = ""; // generate attributes vector::const_iterator ai = attributes.begin(); vector::const_iterator vi = values.begin(); for (; ai != attributes.end() && vi != values.end(); ++ai, ++vi) { output.appendText(sep); generator->generateAtom(output, *ai); output.appendText(":"); generator->generateVariant(output, *vi); sep = ","; } // generate array trailer output.appendText("}"); } void generateVariantBoolean (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { generator->generateAtom(output, dynamic_cast(object)->getValue()); } void generateVariantBlob (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { VariantBlob* blob = dynamic_cast(object); generator->generateAtom(output, blob->getValue(), blob->getLength(), false); } void generateVariantDate (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { generator->generateAtom(output, dynamic_cast(object)->getValue()); } void generateVariantDatetime (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { generator->generateAtom(output, dynamic_cast(object)->getValue()); } void generateVariantDouble (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { generator->generateAtom(output, dynamic_cast(object)->getValue()); } void generateVariantFloat (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { generator->generateAtom(output, dynamic_cast(object)->getValue()); } void generateVariantInt16 (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { generator->generateAtom(output, dynamic_cast(object)->getValue()); } void generateVariantInt32 (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { generator->generateAtom(output, dynamic_cast(object)->getValue()); } void generateVariantInt64 (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { generator->generateAtom(output, dynamic_cast(object)->getValue()); } void generateVariantMatrix2 (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { VariantMatrix2* matrix2 = dynamic_cast(object); vector ds[2]; ds[0] = matrix2->getDimension(0); ds[1] = matrix2->getDimension(1); // generate array header output.appendText("{"); // generate dimensions generator->generateAtom(output, "dimensions"); output.appendText(":["); char const * sep1 = ""; for (size_t n = 0; n < 2; ++n) { output.appendText(sep1); output.appendText("["); char const * sep2 = ""; for (vector::const_iterator j = ds[n].begin(); j != ds[n].end(); ++j) { output.appendText(sep2); generator->generateAtom(output, *j); sep2 = ", "; } output.appendText("]"); sep1 = ", "; } output.appendText("], "); // generate matrix generator->generateAtom(output, "matrix"); output.appendText(":["); sep1 = ""; for (size_t x = 0; x < ds[0].size(); ++x) { output.appendText(sep1); output.appendText("["); char const * sep2 = ""; for (size_t y = 0; y < ds[1].size(); ++y) { output.appendText(sep2); VariantObject* obj = matrix2->getValue(x, y); if (obj != 0) { generator->generateVariant(output, obj); } sep2 = ","; } output.appendText("]"); sep1 = ", "; } output.appendText("]"); // generate array trailer output.appendText("}"); } void generateVariantNull (ResultGenerator const*, StringBuffer& output, VariantObject*) { output.appendText("null"); } void generateVariantString (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { generator->generateAtom(output, dynamic_cast(object)->getValue()); } void generateVariantUInt16 (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { generator->generateAtom(output, dynamic_cast(object)->getValue()); } void generateVariantUInt32 (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { generator->generateAtom(output, dynamic_cast(object)->getValue()); } void generateVariantUInt64 (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { generator->generateAtom(output, dynamic_cast(object)->getValue()); } void generateVariantVector (ResultGenerator const* generator, StringBuffer& output, VariantObject* object) { VariantVector* vec = dynamic_cast(object); output.appendText("["); vector const& values = vec->getValues(); string sep = ""; for (vector::const_iterator i = values.begin(); i != values.end(); ++i) { output.appendText(sep); generator->generateVariant(output, *i); sep = ", "; } output.appendText("]"); } } // ----------------------------------------------------------------------------- // static public methods // ----------------------------------------------------------------------------- void JsonResultGenerator::initialise (ResultGeneratorType type) { registerObject(VariantObject::VARIANT_ARRAY, type, generateVariantArray); registerObject(VariantObject::VARIANT_BLOB, type, generateVariantBlob); registerObject(VariantObject::VARIANT_BOOLEAN, type, generateVariantBoolean); registerObject(VariantObject::VARIANT_DATE, type, generateVariantDate); registerObject(VariantObject::VARIANT_DATETIME, type, generateVariantDatetime); registerObject(VariantObject::VARIANT_DOUBLE, type, generateVariantDouble); registerObject(VariantObject::VARIANT_FLOAT, type, generateVariantFloat); registerObject(VariantObject::VARIANT_INT16, type, generateVariantInt16); registerObject(VariantObject::VARIANT_INT32, type, generateVariantInt32); registerObject(VariantObject::VARIANT_INT64, type, generateVariantInt64); registerObject(VariantObject::VARIANT_MATRIX2, type, generateVariantMatrix2); registerObject(VariantObject::VARIANT_NULL, type, generateVariantNull); registerObject(VariantObject::VARIANT_STRING, type, generateVariantString); registerObject(VariantObject::VARIANT_UINT16, type, generateVariantUInt16); registerObject(VariantObject::VARIANT_UINT32, type, generateVariantUInt32); registerObject(VariantObject::VARIANT_UINT64, type, generateVariantUInt64); registerObject(VariantObject::VARIANT_VECTOR, type, generateVariantVector); } // ----------------------------------------------------------------------------- // ResultGenerator methods // ----------------------------------------------------------------------------- void JsonResultGenerator::generateAtom (StringBuffer& output, string const& value) const { output.appendText("\""); output.appendText(StringUtils::escapeUnicode(value)); output.appendText("\""); } void JsonResultGenerator::generateAtom (StringBuffer& output, char const* value) const { if (value == 0) { output.appendText("null"); } else { output.appendText("\""); output.appendText(StringUtils::escapeUnicode(value)); output.appendText("\""); } } void JsonResultGenerator::generateAtom (StringBuffer& output, char const* value, size_t length, bool quote) const { if (value == 0) { if (quote) { output.appendText("null"); } } else { string v(value, length); if (quote) { output.appendText("\""); output.appendText(StringUtils::escapeUnicode(v)); output.appendText("\""); } else { output.appendText(v); } } } void JsonResultGenerator::generateAtom (StringBuffer& output, bool value) const { output.appendText(value ? "true" : "false"); } void JsonResultGenerator::generateAtom (StringBuffer& output, double value) const { if (value == 0.0) { output.appendText("0.0", 3); } else if (isnormal(value)) { output.appendDecimal(value); } else { int a = isinf(value); if (a == -1) { generateAtom(output, "-INF"); } else if (a == 1) { generateAtom(output, "INF"); } else /* if (isnan(value)) */ { generateAtom(output, "NAN"); } } } void JsonResultGenerator::generateAtom (StringBuffer& output, float value) const { if (value == 0.0) { output.appendText("0.0", 3); } else if (isnormal(value)) { output.appendDecimal(value); } else { int a = isinf(value); if (a == -1) { generateAtom(output, "-INF"); } else if (a == 1) { generateAtom(output, "INF"); } else /* if (isnan(value)) */ { generateAtom(output, "NAN"); } } } void JsonResultGenerator::generateAtom (StringBuffer& output, int16_t value) const { output.appendInteger(value); } void JsonResultGenerator::generateAtom (StringBuffer& output, int32_t value) const { output.appendInteger(value); } void JsonResultGenerator::generateAtom (StringBuffer& output, int64_t value) const { output.appendInteger(value); } void JsonResultGenerator::generateAtom (StringBuffer& output, uint16_t value) const { output.appendInteger(value); } void JsonResultGenerator::generateAtom (StringBuffer& output, uint32_t value) const { output.appendInteger(value); } void JsonResultGenerator::generateAtom (StringBuffer& output, uint64_t value) const { output.appendInteger(value); } } }