summaryrefslogtreecommitdiff
path: root/ext/librethinkdbxx/src/json.cc
blob: c908eefb60b8f752a42ca429bdd14e5df7c9f1c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include "json_p.h"
#include "error.h"
#include "utils.h"

#include "rapidjson-config.h"
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "rapidjson/prettywriter.h"

namespace RethinkDB {

Datum read_datum(const std::string& json) {
    rapidjson::Document document;
    document.Parse(json);
    return read_datum(document);
}

Datum read_datum(const rapidjson::Value &json) {
    switch(json.GetType()) {
    case rapidjson::kNullType: return Nil();
    case rapidjson::kFalseType: return false;
    case rapidjson::kTrueType: return true;
    case rapidjson::kNumberType: return json.GetDouble();
    case rapidjson::kStringType:
        return std::string(json.GetString(), json.GetStringLength());

    case rapidjson::kObjectType: {
        Object result;
        for (rapidjson::Value::ConstMemberIterator it = json.MemberBegin();
             it != json.MemberEnd(); ++it) {
            result.insert(std::make_pair(std::string(it->name.GetString(),
                                         it->name.GetStringLength()),
                                         read_datum(it->value)));
        }

        if (result.count("$reql_type$"))
            return Datum(std::move(result)).from_raw();
        return std::move(result);
    } break;
    case rapidjson::kArrayType: {
        Array result;
        result.reserve(json.Size());
        for (rapidjson::Value::ConstValueIterator it = json.Begin();
             it != json.End(); ++it) {
            result.push_back(read_datum(*it));
        }
        return std::move(result);
    } break;
    default:
        throw Error("invalid rapidjson value");
    }
}

std::string write_datum(const Datum& datum) {
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    datum.write_json(&writer);
    return std::string(buffer.GetString(), buffer.GetSize());
}

}