|
32 | 32 |
|
33 | 33 | namespace pt = boost::property_tree;
|
34 | 34 |
|
| 35 | +/// abstraction for higher-level decoders for various JSON-based tree formats |
| 36 | +class AbstractTreeDecoder { |
| 37 | + public: |
| 38 | + virtual ~AbstractTreeDecoder() { } |
| 39 | + |
| 40 | + /// read the given ptree node, decode, and store the result into def |
| 41 | + virtual void readNode(Defect *def, const pt::ptree &node) = 0; |
| 42 | +}; |
| 43 | + |
| 44 | +/// tree decoder of the native JSON format of csdiff |
| 45 | +class SimpleTreeDecoder: public AbstractTreeDecoder { |
| 46 | + public: |
| 47 | + virtual void readNode(Defect *def, const pt::ptree &node); |
| 48 | + |
| 49 | + private: |
| 50 | + KeyEventDigger keDigger; |
| 51 | +}; |
| 52 | + |
35 | 53 | struct JsonParser::Private {
|
36 | 54 | const std::string fileName;
|
37 | 55 | const bool silent;
|
38 | 56 | bool jsonValid;
|
39 | 57 | bool hasError;
|
| 58 | + AbstractTreeDecoder *decoder; |
40 | 59 | pt::ptree root;
|
41 | 60 | pt::ptree *defList;
|
42 | 61 | pt::ptree::const_iterator defIter;
|
43 | 62 | int defNumber;
|
44 | 63 | TScanProps scanProps;
|
45 |
| - KeyEventDigger keDigger; |
46 | 64 |
|
47 | 65 | Private(const std::string &fileName_, bool silent_):
|
48 | 66 | fileName(fileName_),
|
49 | 67 | silent(silent_),
|
50 | 68 | jsonValid(false),
|
51 | 69 | hasError(false),
|
| 70 | + decoder(0), |
52 | 71 | defNumber(0)
|
53 | 72 | {
|
54 | 73 | }
|
55 | 74 |
|
| 75 | + ~Private() |
| 76 | + { |
| 77 | + delete this->decoder; |
| 78 | + } |
| 79 | + |
56 | 80 | void parseError(const std::string &msg, unsigned long line = 0UL);
|
57 | 81 | void dataError(const std::string &msg);
|
58 |
| - void readNode(Defect *def, const pt::ptree &defNode); |
59 | 82 | bool readNext(Defect *def);
|
60 | 83 | };
|
61 | 84 |
|
@@ -95,6 +118,7 @@ JsonParser::JsonParser(
|
95 | 118 | read_json(input, d->root);
|
96 | 119 |
|
97 | 120 | // get the defect list
|
| 121 | + d->decoder = new SimpleTreeDecoder; |
98 | 122 | d->defList = &d->root.get_child("defects");
|
99 | 123 | d->defIter = d->defList->begin();
|
100 | 124 | d->jsonValid = true;
|
@@ -133,7 +157,38 @@ inline T valueOf(const pt::ptree &node, const char *path, const T &defVal)
|
133 | 157 | return opt.get_value_or(defVal);
|
134 | 158 | }
|
135 | 159 |
|
136 |
| -void JsonParser::Private::readNode( |
| 160 | +bool JsonParser::Private::readNext(Defect *def) { |
| 161 | + try { |
| 162 | + // get the current node and move to the next one |
| 163 | + const pt::ptree &defNode = this->defIter->second; |
| 164 | + this->defIter++; |
| 165 | + this->defNumber++; |
| 166 | + |
| 167 | + // read the current node |
| 168 | + this->decoder->readNode(def, defNode); |
| 169 | + return true; |
| 170 | + } |
| 171 | + catch (pt::ptree_error &e) { |
| 172 | + this->dataError(e.what()); |
| 173 | + return false; |
| 174 | + } |
| 175 | +} |
| 176 | + |
| 177 | +bool JsonParser::getNext(Defect *def) { |
| 178 | + if (!d->jsonValid) |
| 179 | + return false; |
| 180 | + |
| 181 | + // error recovery loop |
| 182 | + for (;;) { |
| 183 | + if (d->defList->end() == d->defIter) |
| 184 | + return false; |
| 185 | + |
| 186 | + if (d->readNext(def)) |
| 187 | + return true; |
| 188 | + } |
| 189 | +} |
| 190 | + |
| 191 | +void SimpleTreeDecoder::readNode( |
137 | 192 | Defect *def,
|
138 | 193 | const pt::ptree &defNode)
|
139 | 194 | {
|
@@ -191,34 +246,3 @@ void JsonParser::Private::readNode(
|
191 | 246 | // read annotation if available
|
192 | 247 | def->annotation = valueOf<std::string>(defNode, "annotation", "");
|
193 | 248 | }
|
194 |
| - |
195 |
| -bool JsonParser::Private::readNext(Defect *def) { |
196 |
| - try { |
197 |
| - // get the current node and move to the next one |
198 |
| - const pt::ptree &defNode = this->defIter->second; |
199 |
| - this->defIter++; |
200 |
| - this->defNumber++; |
201 |
| - |
202 |
| - // read the current node |
203 |
| - this->readNode(def, defNode); |
204 |
| - return true; |
205 |
| - } |
206 |
| - catch (pt::ptree_error &e) { |
207 |
| - this->dataError(e.what()); |
208 |
| - return false; |
209 |
| - } |
210 |
| -} |
211 |
| - |
212 |
| -bool JsonParser::getNext(Defect *def) { |
213 |
| - if (!d->jsonValid) |
214 |
| - return false; |
215 |
| - |
216 |
| - // error recovery loop |
217 |
| - for (;;) { |
218 |
| - if (d->defList->end() == d->defIter) |
219 |
| - return false; |
220 |
| - |
221 |
| - if (d->readNext(def)) |
222 |
| - return true; |
223 |
| - } |
224 |
| -} |
|
0 commit comments