| 16 | // This handler forwards event into an output handler, with filtering the descendent events of specified key. |
| 17 | template <typename OutputHandler> |
| 18 | class FilterKeyHandler { |
| 19 | public: |
| 20 | typedef char Ch; |
| 21 | |
| 22 | FilterKeyHandler(OutputHandler& outputHandler, const Ch* keyString, SizeType keyLength) : |
| 23 | outputHandler_(outputHandler), keyString_(keyString), keyLength_(keyLength), filterValueDepth_(), filteredKeyCount_() |
| 24 | {} |
| 25 | |
| 26 | bool Null() { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Null() && EndValue(); } |
| 27 | bool Bool(bool b) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Bool(b) && EndValue(); } |
| 28 | bool Int(int i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int(i) && EndValue(); } |
| 29 | bool Uint(unsigned u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint(u) && EndValue(); } |
| 30 | bool Int64(int64_t i) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int64(i) && EndValue(); } |
| 31 | bool Uint64(uint64_t u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint64(u) && EndValue(); } |
| 32 | bool Double(double d) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Double(d) && EndValue(); } |
| 33 | bool RawNumber(const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.RawNumber(str, len, copy) && EndValue(); } |
| 34 | bool String (const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.String (str, len, copy) && EndValue(); } |
| 35 | |
| 36 | bool StartObject() { |
| 37 | if (filterValueDepth_ > 0) { |
| 38 | filterValueDepth_++; |
| 39 | return true; |
| 40 | } |
| 41 | else { |
| 42 | filteredKeyCount_.push(0); |
| 43 | return outputHandler_.StartObject(); |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | bool Key(const Ch* str, SizeType len, bool copy) { |
| 48 | if (filterValueDepth_ > 0) |
| 49 | return true; |
| 50 | else if (len == keyLength_ && std::memcmp(str, keyString_, len) == 0) { |
| 51 | filterValueDepth_ = 1; |
| 52 | return true; |
| 53 | } |
| 54 | else { |
| 55 | ++filteredKeyCount_.top(); |
| 56 | return outputHandler_.Key(str, len, copy); |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | bool EndObject(SizeType) { |
| 61 | if (filterValueDepth_ > 0) { |
| 62 | filterValueDepth_--; |
| 63 | return EndValue(); |
| 64 | } |
| 65 | else { |
| 66 | // Use our own filtered memberCount |
| 67 | SizeType memberCount = filteredKeyCount_.top(); |
| 68 | filteredKeyCount_.pop(); |
| 69 | return outputHandler_.EndObject(memberCount) && EndValue(); |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | bool StartArray() { |
| 74 | if (filterValueDepth_ > 0) { |
| 75 | filterValueDepth_++; |
nothing calls this directly
no outgoing calls
no test coverage detected