-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjson_intermediary_writer.cpp
151 lines (132 loc) · 7.73 KB
/
json_intermediary_writer.cpp
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
140
141
142
143
144
145
146
147
148
149
150
151
#include "json_intermediary_writer.h"
#include <string>
#include "utilities.h"
using json = nlohmann::json;
JsonIntermediaryWriter::JsonIntermediaryWriter(){
}
/**
* Writes an intermediary file. Some configurations will not comply with official JSON standards.
*
* @param patchText The string stream the intermediary JSON will be written to.
* @param fileSettings The file extension specific settings to use when parsing.
* @param sourceJson The JSON things are parsed from.
* @return How many values the resulting intermediary JSON contains.
*/
int JsonIntermediaryWriter::writeIntermediaryFile(std::stringstream & intermediaryText, FileSettings & fileSettings, const json & sourceJson) {
totalIntermediaryValues = 0;
intermediaryText << "{\n";
//Add patch makers comment if configured.
if (fileSettings.getAddPatchMakersComment()) {
intermediaryText << " //Comment to be added to the top of patches.\n"
<< " \"patchMakerComment\" : \"\",\n\n";
}
//iterate if required
for (const PointerSettings & pointerSettings : fileSettings.getAllPointerSettings()) {
writeRecursivePointerValuePair(intermediaryText, pointerSettings, sourceJson);
}
intermediaryText << "\n}\n";
return totalIntermediaryValues;
}
bool JsonIntermediaryWriter::writePointerValuePair(std::stringstream & intermediaryText, const PointerSettings & pointerSettings, const json & sourceJson) {
//Value path as JSON pointer.
const json::json_pointer valuePointer = json::json_pointer(pointerSettings.path);
//Value present, copy.
if (sourceJson.contains(valuePointer)) {
writePointerValueStart(intermediaryText, pointerSettings);
intermediaryText << " \"" << pointerSettings.path << "\" : ";
if(pointerSettings.convertBreakoutNewlines) {
std::string sourceJsonText = sourceJson[valuePointer];
convertNewlineBreakoutsToNewline(sourceJsonText);
convertQuoteToBreakoutQuote(sourceJsonText);
intermediaryText << '"' << sourceJsonText << '"';
} else {
intermediaryText << sourceJson[valuePointer];
}
//Continue iteration.
return true;
//Value should only be placeholder.
} else if (pointerSettings.reference) {
//Stop iteration.
return false;
//Value missing, use placeholder if possible.
} else if (pointerSettings.intermediaryPlaceholderCondition == whenPossible) {
writePointerValueStart(intermediaryText, pointerSettings);
intermediaryText << " \"" << pointerSettings.path << "\" : \"\"";
//Continue iteration.
return true;
//Value missing, use placeholder if from exists.
} else if (pointerSettings.intermediaryPlaceholderCondition == fromExists && pointerSettings.from != "" && sourceJson.contains(json::json_pointer(pointerSettings.from))) {
writePointerValueStart(intermediaryText, pointerSettings);
intermediaryText << " \"" << pointerSettings.path << "\" : \"\"";
//Continue iteration.
return true;
}
//Stop iteration.
return false;
}
bool JsonIntermediaryWriter::writeRecursivePointerValuePair(std::stringstream & intermediaryText, const PointerSettings & pointerSettings, const json & sourceJson) {
//Check if there is a marker configured.
if (pointerSettings.numericIteratorMarker != "" && (pointerSettings.intermediaryPlaceholderCondition != fromExists || pointerSettings.from != "")) {
//Check if there is a marker position in path.
int pathMarkerPosition = pointerSettings.path.find(pointerSettings.numericIteratorMarker);
//Check if there is a marker position in from.
int fromMarkerPosition = pointerSettings.from.find(pointerSettings.numericIteratorMarker);
//If there is a marker to replace in path and, if required, from.
if (pathMarkerPosition != std::string::npos && (pointerSettings.intermediaryPlaceholderCondition != fromExists || fromMarkerPosition != std::string::npos)) {
//Pointer settings to be modified for the next recursion.
PointerSettings modifiedPointerSettings = pointerSettings;
//Prevent infinite iterations from occurring.
if(modifiedPointerSettings.intermediaryPlaceholderCondition == whenPossible) {
modifiedPointerSettings.intermediaryPlaceholderCondition = never;
}
//Find the marker position in the intermediary label, if there is one.
int intermediaryLabelMarkerPosition = pointerSettings.intermediaryLabel.find(pointerSettings.numericIteratorMarker);
int index = 0;
//Iterate with increasing index until no writes happen.
do {
std::string indexString = std::to_string(index);
//Replace the first marker in modifiedPath with the current index.
std::string modifiedPath = pointerSettings.path;
modifiedPath.erase(pathMarkerPosition, pointerSettings.numericIteratorMarker.length());
modifiedPath.insert(pathMarkerPosition, indexString);
modifiedPointerSettings.path = modifiedPath;
//If this segment of path doesn't exist stop iterating.
std::string testPath = modifiedPointerSettings.path;
testPath.erase(pathMarkerPosition + indexString.length());
if (pointerSettings.intermediaryPlaceholderCondition != fromExists && !sourceJson.contains(json::json_pointer(testPath))) {
break;
}
//Replace the first marker in modifiedFrom with the current index if required.
if (pointerSettings.intermediaryPlaceholderCondition == fromExists) {
std::string modifiedFrom = pointerSettings.from;
modifiedFrom.erase(fromMarkerPosition, pointerSettings.numericIteratorMarker.length());
modifiedFrom.insert(fromMarkerPosition, indexString);
modifiedPointerSettings.from = modifiedFrom;
//If this segment of from doesn't exist stop iterating.
std::string testFrom = modifiedPointerSettings.from;
testFrom.erase(fromMarkerPosition + indexString.length());
if (!sourceJson.contains(json::json_pointer(testFrom)) && !sourceJson.contains(json::json_pointer(testPath))) {
break;
}
}
//Replace the first marker in modifiedIntermediaryLabel with the current index if it exists.
if (pointerSettings.intermediaryLabel != "" && intermediaryLabelMarkerPosition != std::string::npos) {
std::string modifiedIntermediaryLabel = pointerSettings.intermediaryLabel;
modifiedIntermediaryLabel.erase(intermediaryLabelMarkerPosition, pointerSettings.numericIteratorMarker.length());
modifiedIntermediaryLabel.insert(intermediaryLabelMarkerPosition, indexString);
modifiedPointerSettings.intermediaryLabel = modifiedIntermediaryLabel;
}
index++;
//Recurse and get the result.
} while (writeRecursivePointerValuePair(intermediaryText, modifiedPointerSettings, sourceJson));
return true;
}
}
//There is no marker to replace.
return writePointerValuePair(intermediaryText, pointerSettings, sourceJson);
}
void JsonIntermediaryWriter::writePointerValueStart(std::stringstream & intermediaryText, const PointerSettings & pointerSettings) {
if (totalIntermediaryValues > 0) intermediaryText << ",\n\n";
if (pointerSettings.intermediaryLabel != "") intermediaryText << " //" + pointerSettings.intermediaryLabel + '\n';
totalIntermediaryValues++;
}