mirror of
				https://github.com/Tencent/rapidjson.git
				synced 2025-11-04 12:17:41 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			136 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// JSON filterkey example with SAX-style API.
 | 
						|
 | 
						|
// This example parses JSON text from stdin with validation.
 | 
						|
// During parsing, specified key will be filtered using a SAX handler.
 | 
						|
// It re-output the JSON content to stdout without whitespace.
 | 
						|
 | 
						|
#include "rapidjson/reader.h"
 | 
						|
#include "rapidjson/writer.h"
 | 
						|
#include "rapidjson/filereadstream.h"
 | 
						|
#include "rapidjson/filewritestream.h"
 | 
						|
#include "rapidjson/error/en.h"
 | 
						|
#include <stack>
 | 
						|
 | 
						|
using namespace rapidjson;
 | 
						|
 | 
						|
// This handler forwards event into an output handler, with filtering the descendent events of specified key.
 | 
						|
template <typename OutputHandler>
 | 
						|
class FilterKeyHandler {
 | 
						|
public:
 | 
						|
    typedef char Ch;
 | 
						|
 | 
						|
    FilterKeyHandler(OutputHandler& outputHandler, const Ch* keyString, SizeType keyLength) : 
 | 
						|
        outputHandler_(outputHandler), keyString_(keyString), keyLength_(keyLength), filterValueDepth_(), filteredKeyCount_()
 | 
						|
    {}
 | 
						|
 | 
						|
    bool Null()             { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Null()    && EndValue(); }
 | 
						|
    bool Bool(bool b)       { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Bool(b)   && EndValue(); }
 | 
						|
    bool Int(int i)         { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int(i)    && EndValue(); }
 | 
						|
    bool Uint(unsigned u)   { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint(u)   && EndValue(); }
 | 
						|
    bool Int64(int64_t i)   { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Int64(i)  && EndValue(); }
 | 
						|
    bool Uint64(uint64_t u) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Uint64(u) && EndValue(); }
 | 
						|
    bool Double(double d)   { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.Double(d) && EndValue(); }
 | 
						|
    bool RawNumber(const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.RawNumber(str, len, copy) && EndValue(); }
 | 
						|
    bool String   (const Ch* str, SizeType len, bool copy) { return filterValueDepth_ > 0 ? EndValue() : outputHandler_.String   (str, len, copy) && EndValue(); }
 | 
						|
    
 | 
						|
    bool StartObject() { 
 | 
						|
        if (filterValueDepth_ > 0) {
 | 
						|
            filterValueDepth_++;
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            filteredKeyCount_.push(0);
 | 
						|
            return outputHandler_.StartObject();
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    bool Key(const Ch* str, SizeType len, bool copy) { 
 | 
						|
        if (filterValueDepth_ > 0) 
 | 
						|
            return true;
 | 
						|
        else if (len == keyLength_ && std::memcmp(str, keyString_, len) == 0) {
 | 
						|
            filterValueDepth_ = 1;
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            ++filteredKeyCount_.top();
 | 
						|
            return outputHandler_.Key(str, len, copy);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    bool EndObject(SizeType) {
 | 
						|
        if (filterValueDepth_ > 0) {
 | 
						|
            filterValueDepth_--;
 | 
						|
            return EndValue();
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            // Use our own filtered memberCount
 | 
						|
            SizeType memberCount = filteredKeyCount_.top();
 | 
						|
            filteredKeyCount_.pop();
 | 
						|
            return outputHandler_.EndObject(memberCount) && EndValue();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    bool StartArray() {
 | 
						|
        if (filterValueDepth_ > 0) {
 | 
						|
            filterValueDepth_++;
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
        else
 | 
						|
            return outputHandler_.StartArray();
 | 
						|
    }
 | 
						|
 | 
						|
    bool EndArray(SizeType elementCount) {
 | 
						|
        if (filterValueDepth_ > 0) {
 | 
						|
            filterValueDepth_--;
 | 
						|
            return EndValue();
 | 
						|
        }
 | 
						|
        else
 | 
						|
            return outputHandler_.EndArray(elementCount) && EndValue();
 | 
						|
    }
 | 
						|
 | 
						|
private:
 | 
						|
    FilterKeyHandler(const FilterKeyHandler&);
 | 
						|
    FilterKeyHandler& operator=(const FilterKeyHandler&);
 | 
						|
 | 
						|
    bool EndValue() {
 | 
						|
        if (filterValueDepth_ == 1) // Just at the end of value after filtered key
 | 
						|
            filterValueDepth_ = 0;
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
    
 | 
						|
    OutputHandler& outputHandler_;
 | 
						|
    const char* keyString_;
 | 
						|
    const SizeType keyLength_;
 | 
						|
    unsigned filterValueDepth_;
 | 
						|
    std::stack<SizeType> filteredKeyCount_;
 | 
						|
};
 | 
						|
 | 
						|
int main(int argc, char* argv[]) {
 | 
						|
    if (argc != 2) {
 | 
						|
        fprintf(stderr, "filterkey key < input.json > output.json\n");
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
 | 
						|
    // Prepare JSON reader and input stream.
 | 
						|
    Reader reader;
 | 
						|
    char readBuffer[65536];
 | 
						|
    FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
 | 
						|
 | 
						|
    // Prepare JSON writer and output stream.
 | 
						|
    char writeBuffer[65536];
 | 
						|
    FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
 | 
						|
    Writer<FileWriteStream> writer(os);
 | 
						|
 | 
						|
    // Prepare Filter
 | 
						|
    FilterKeyHandler<Writer<FileWriteStream> > filter(writer, argv[1], static_cast<SizeType>(strlen(argv[1])));
 | 
						|
 | 
						|
    // JSON reader parse from the input stream, filter handler filters the events, and forward to writer.
 | 
						|
    // i.e. the events flow is: reader -> filter -> writer
 | 
						|
    if (!reader.Parse(is, filter)) {
 | 
						|
        fprintf(stderr, "\nError(%u): %s\n", static_cast<unsigned>(reader.GetErrorOffset()), GetParseError_En(reader.GetParseErrorCode()));
 | 
						|
        return 1;
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 |