summaryrefslogtreecommitdiffstats
path: root/xbmc/utils/JSONVariantWriter.cpp
blob: b48a8ae151f2b367e712c60914bc7cc3cf46ae68 (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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
 *  Copyright (C) 2015-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "JSONVariantWriter.h"

#include "utils/Variant.h"

#include <rapidjson/prettywriter.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>

template<class TWriter>
bool InternalWrite(TWriter& writer, const CVariant &value)
{
  switch (value.type())
  {
  case CVariant::VariantTypeInteger:
    return writer.Int64(value.asInteger());

  case CVariant::VariantTypeUnsignedInteger:
    return writer.Uint64(value.asUnsignedInteger());

  case CVariant::VariantTypeDouble:
    return writer.Double(value.asDouble());

  case CVariant::VariantTypeBoolean:
    return writer.Bool(value.asBoolean());

  case CVariant::VariantTypeString:
    return writer.String(value.c_str(), value.size());

  case CVariant::VariantTypeArray:
    if (!writer.StartArray())
      return false;

    for (CVariant::const_iterator_array itr = value.begin_array(); itr != value.end_array(); ++itr)
    {
      if (!InternalWrite(writer, *itr))
        return false;
    }

    return writer.EndArray(value.size());

  case CVariant::VariantTypeObject:
    if (!writer.StartObject())
      return false;

    for (CVariant::const_iterator_map itr = value.begin_map(); itr != value.end_map(); ++itr)
    {
      if (!writer.Key(itr->first.c_str()) ||
        !InternalWrite(writer, itr->second))
        return false;
    }

    return writer.EndObject(value.size());

  case CVariant::VariantTypeConstNull:
  case CVariant::VariantTypeNull:
  default:
    return writer.Null();
  }

  return false;
}

bool CJSONVariantWriter::Write(const CVariant &value, std::string& output, bool compact)
{
  rapidjson::StringBuffer stringBuffer;
  if (compact)
  {
    rapidjson::Writer<rapidjson::StringBuffer> writer(stringBuffer);

    if (!InternalWrite(writer, value) || !writer.IsComplete())
      return false;
  }
  else
  {
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(stringBuffer);
    writer.SetIndent('\t', 1);

    if (!InternalWrite(writer, value) || !writer.IsComplete())
      return false;
  }

  output = stringBuffer.GetString();
  return true;
}