summaryrefslogtreecommitdiffstats
path: root/xbmc/settings/SettingsValueFlatJsonSerializer.cpp
blob: 736c37d746457b82c2bbf7c2b21a62125277e151 (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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 *  Copyright (C) 2019 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 "SettingsValueFlatJsonSerializer.h"

#include "settings/lib/Setting.h"
#include "settings/lib/SettingDefinitions.h"
#include "settings/lib/SettingSection.h"
#include "settings/lib/SettingType.h"
#include "settings/lib/SettingsManager.h"
#include "utils/JSONVariantWriter.h"
#include "utils/log.h"

CSettingsValueFlatJsonSerializer::CSettingsValueFlatJsonSerializer(bool compact /* = true */)
  : m_compact(compact)
{ }

std::string CSettingsValueFlatJsonSerializer::SerializeValues(
  const CSettingsManager* settingsManager) const
{
  if (settingsManager == nullptr)
    return "";

  CVariant root(CVariant::VariantTypeObject);

  const auto sections = settingsManager->GetSections();
  for (const auto& section : sections)
    SerializeSection(root, section);

  std::string result;
  if (!CJSONVariantWriter::Write(root, result, m_compact))
  {
    CLog::Log(LOGWARNING,
      "CSettingsValueFlatJsonSerializer: failed to serialize settings into JSON");
    return "";
  }

  return result;
}

void CSettingsValueFlatJsonSerializer::SerializeSection(
    CVariant& parent, const std::shared_ptr<CSettingSection>& section) const
{
  if (section == nullptr)
    return;

  const auto categories = section->GetCategories();
  for (const auto& category : categories)
    SerializeCategory(parent, category);
}

void CSettingsValueFlatJsonSerializer::SerializeCategory(
    CVariant& parent, const std::shared_ptr<CSettingCategory>& category) const
{
  if (category == nullptr)
    return;

  const auto groups = category->GetGroups();
  for (const auto& group : groups)
    SerializeGroup(parent, group);
}

void CSettingsValueFlatJsonSerializer::SerializeGroup(
    CVariant& parent, const std::shared_ptr<CSettingGroup>& group) const
{
  if (group == nullptr)
    return;

  const auto settings = group->GetSettings();
  for (const auto& setting : settings)
    SerializeSetting(parent, setting);
}

void CSettingsValueFlatJsonSerializer::SerializeSetting(
    CVariant& parent, const std::shared_ptr<CSetting>& setting) const
{
  if (setting == nullptr)
    return;

  // ignore references and action settings (which don't have a value)
  if (setting->IsReference() || setting->GetType() == SettingType::Action)
    return;

  const auto valueObj = SerializeSettingValue(setting);
  if (valueObj.isNull())
    return;

  parent[setting->GetId()] = valueObj;
}

CVariant CSettingsValueFlatJsonSerializer::SerializeSettingValue(
    const std::shared_ptr<CSetting>& setting) const
{
  switch (setting->GetType())
  {
    case SettingType::Action:
      return CVariant::ConstNullVariant;

    case SettingType::Boolean:
      return CVariant(std::static_pointer_cast<CSettingBool>(setting)->GetValue());

    case SettingType::Integer:
      return CVariant(std::static_pointer_cast<CSettingInt>(setting)->GetValue());

    case SettingType::Number:
      return CVariant(std::static_pointer_cast<CSettingNumber>(setting)->GetValue());

    case SettingType::String:
      return CVariant(std::static_pointer_cast<CSettingString>(setting)->GetValue());

    case SettingType::List:
    {
      const auto settingList = std::static_pointer_cast<CSettingList>(setting);

      CVariant settingListValuesObj(CVariant::VariantTypeArray);
      const auto settingListValues = settingList->GetValue();
      for (const auto& settingListValue : settingListValues)
      {
        const auto valueObj = SerializeSettingValue(settingListValue);
        if (!valueObj.isNull())
          settingListValuesObj.push_back(valueObj);
      }

      return settingListValuesObj;
    }

    case SettingType::Unknown:
    default:
      CLog::Log(LOGWARNING,
        "CSettingsValueFlatJsonSerializer: failed to serialize setting \"{}\" with value \"{}\" " \
        "of unknown type", setting->GetId(), setting->ToString());
      return CVariant::ConstNullVariant;
  }
}