blob: 2b6d6f5c9730df2b6aff8b3fd8741df6edcabaf5 [file] [log] [blame]
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).
/*
* This header file defines miscellaneous utility classes.
*
* @author Tian Xia <tianx@fb.com>
*/
#ifndef FBSON_FBSONUTIL_H
#define FBSON_FBSONUTIL_H
#include <sstream>
#include "FbsonDocument.h"
namespace fbson {
#define OUT_BUF_SIZE 1024
/*
* FbsonToJson converts an FbsonValue object to a JSON string.
*/
class FbsonToJson {
public:
FbsonToJson() : os_(buffer_, OUT_BUF_SIZE) {}
// get json string
const char* json(const FbsonValue* pval) {
os_.clear();
os_.seekp(0);
if (pval) {
intern_json(pval);
}
os_.put(0);
return os_.getBuffer();
}
private:
// recursively convert FbsonValue
void intern_json(const FbsonValue* val) {
switch (val->type()) {
case FbsonType::T_Null: {
os_.write("null", 4);
break;
}
case FbsonType::T_True: {
os_.write("true", 4);
break;
}
case FbsonType::T_False: {
os_.write("false", 5);
break;
}
case FbsonType::T_Int8: {
os_.write(((Int8Val*)val)->val());
break;
}
case FbsonType::T_Int16: {
os_.write(((Int16Val*)val)->val());
break;
}
case FbsonType::T_Int32: {
os_.write(((Int32Val*)val)->val());
break;
}
case FbsonType::T_Int64: {
os_.write(((Int64Val*)val)->val());
break;
}
case FbsonType::T_Double: {
os_.write(((DoubleVal*)val)->val());
break;
}
case FbsonType::T_String: {
os_.put('"');
os_.write(((StringVal*)val)->getBlob(), ((StringVal*)val)->getBlobLen());
os_.put('"');
break;
}
case FbsonType::T_Binary: {
os_.write("\"<BINARY>", 9);
os_.write(((BinaryVal*)val)->getBlob(), ((BinaryVal*)val)->getBlobLen());
os_.write("<BINARY>\"", 9);
break;
}
case FbsonType::T_Object: {
object_to_json((ObjectVal*)val);
break;
}
case FbsonType::T_Array: {
array_to_json((ArrayVal*)val);
break;
}
default:
break;
}
}
// convert object
void object_to_json(const ObjectVal* val) {
os_.put('{');
auto iter = val->begin();
auto iter_fence = val->end();
while (iter < iter_fence) {
// write key
if (iter->klen()) {
os_.put('"');
os_.write(iter->getKeyStr(), iter->klen());
os_.put('"');
} else {
os_.write(iter->getKeyId());
}
os_.put(':');
// convert value
intern_json(iter->value());
++iter;
if (iter != iter_fence) {
os_.put(',');
}
}
assert(iter == iter_fence);
os_.put('}');
}
// convert array to json
void array_to_json(const ArrayVal* val) {
os_.put('[');
auto iter = val->begin();
auto iter_fence = val->end();
while (iter != iter_fence) {
// convert value
intern_json((const FbsonValue*)iter);
++iter;
if (iter != iter_fence) {
os_.put(',');
}
}
assert(iter == iter_fence);
os_.put(']');
}
private:
FbsonOutStream os_;
char buffer_[OUT_BUF_SIZE];
};
} // namespace fbson
#endif // FBSON_FBSONUTIL_H