json parser
This commit is contained in:
		
							parent
							
								
									b1c5a3af6e
								
							
						
					
					
						commit
						3aa3cee61c
					
				
					 7 changed files with 114 additions and 204 deletions
				
			
		|  | @ -25,14 +25,15 @@ | ||||||
| 		-u --user <[password:]username>\n\ | 		-u --user <[password:]username>\n\ | ||||||
| 		-p --password <password>\n\ | 		-p --password <password>\n\ | ||||||
| 					Login with Username and Password\n\ | 					Login with Username and Password\n\ | ||||||
| 		-f --file <path>	Not yet implemented:.choose a settings file\n\ | 		-f --file <path>	choose a settings file\n\ | ||||||
| 		-t --timeout <n>	Not yet implemented\n\ | 		-t --timeout <n>	Not yet implemented\n\ | ||||||
| 		-w --wait		Not yet implemented: blocking until operation is completed\n\ | 		-w --wait		Not yet implemented: blocking until operation is completed\n\ | ||||||
| 		-s --permanent		Not yet implemented: make changes immediately permanent\n\n\ | 		-s --permanent		Not yet implemented: make changes immediately permanent\n\n\ | ||||||
| 	Command Summary:\n\ | 	Command Summary:\n\ | ||||||
| 		help			This help text\n\ | 		help			This help text\n\ | ||||||
| 		list			list all connected switches\n\ | 		list			list all connected switches\n\ | ||||||
| 		sniff		capture and display all incoming or outgoing packets\n\ | 		sniff [type:<type>] [<filter>]\n\ | ||||||
|  | 					capture and display all incoming or outgoing packets\n\ | ||||||
| 					depending on the --reverse option\n\ | 					depending on the --reverse option\n\ | ||||||
| 		encode			use encoding algorithm on hex data separated by colon\n\ | 		encode			use encoding algorithm on hex data separated by colon\n\ | ||||||
| 		get			Not yet implemented\n\ | 		get			Not yet implemented\n\ | ||||||
|  |  | ||||||
|  | @ -143,8 +143,10 @@ std::string Packet::opCodeToString() { | ||||||
| 		return "GET"; | 		return "GET"; | ||||||
| 	case SET: | 	case SET: | ||||||
| 		return "SET"; | 		return "SET"; | ||||||
| 	case RECEIVE: | 	case LOGIN: | ||||||
| 		return "RECEIVE"; | 		return "LOGIN"; | ||||||
|  | 	case RETURN: | ||||||
|  | 		return "RETURN"; | ||||||
| 	case READ5: | 	case READ5: | ||||||
| 		return "READ5"; | 		return "READ5"; | ||||||
| 	default: | 	default: | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ | ||||||
| class Packet { | class Packet { | ||||||
| public: | public: | ||||||
| 	enum OpCode { | 	enum OpCode { | ||||||
| 		DISCOVERY, GET, SET, READ4,RECEIVE, READ5 | 		DISCOVERY, GET, SET, LOGIN, RETURN, READ5 | ||||||
| 	}; | 	}; | ||||||
| 	Packet(OpCode); | 	Packet(OpCode); | ||||||
| 	void encode(bytes&); | 	void encode(bytes&); | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "Options.h" | #include "Options.h" | ||||||
| #include "Program.h" | #include "Program.h" | ||||||
|  | #include "File.h" | ||||||
| #include "Host.h" | #include "Host.h" | ||||||
| #include "Socket.h" | #include "Socket.h" | ||||||
| #include "Switch.h" | #include "Switch.h" | ||||||
|  | @ -45,6 +46,8 @@ int Program::list() { | ||||||
| 						datasets d =a.getPayload(); | 						datasets d =a.getPayload(); | ||||||
| 						Switch s = Switch(); | 						Switch s = Switch(); | ||||||
| 						s.parse(d); | 						s.parse(d); | ||||||
|  | 						File f; | ||||||
|  | 						f.write("config.json", s.toString()); | ||||||
| 						std::cout <<"Devices:\n\t"<<s.settings.hostname<<" ("<< s.device.type<<")\tMAC: "<<s.device.mac<<"\tIP: "<<s.settings.ip_addr<<"\n"; | 						std::cout <<"Devices:\n\t"<<s.settings.hostname<<" ("<< s.device.type<<")\tMAC: "<<s.device.mac<<"\tIP: "<<s.settings.ip_addr<<"\n"; | ||||||
| 					} | 					} | ||||||
| 					return 1; | 					return 1; | ||||||
|  | @ -83,7 +86,7 @@ int Program::sniff() { | ||||||
| 							auto lookup=(options.flags & FLAG_REVERSE)?snd_lookup:rcv_lookup; | 							auto lookup=(options.flags & FLAG_REVERSE)?snd_lookup:rcv_lookup; | ||||||
| 							if(lookup.exists(d.type)) { | 							if(lookup.exists(d.type)) { | ||||||
| 								if(d.len>0) { | 								if(d.len>0) { | ||||||
| 									std::cout<<std::dec<<"\t++"<<std::hex<<d.type<<std::dec<<"++\n"; | 									std::cout<<std::dec<<"\t++"<<std::hex<<d.type<<"++ :"<<d.value<<std::dec<<"\n"; | ||||||
| 								} else { | 								} else { | ||||||
| 									std::cout<<std::dec<<"#"<<d.type<<"\tLength: "<<d.len<<"\n"; | 									std::cout<<std::dec<<"#"<<d.type<<"\tLength: "<<d.len<<"\n"; | ||||||
| 									std::cout<<std::hex<< "\tHex: " <<d.value<<"\n"; | 									std::cout<<std::hex<< "\tHex: " <<d.value<<"\n"; | ||||||
|  | @ -163,19 +166,16 @@ int Program::getProperty() { | ||||||
| } | } | ||||||
| int Program::save() { | int Program::save() { | ||||||
| 	Switch sw = Switch(); | 	Switch sw = Switch(); | ||||||
| 	std::string str = sw.toString(); | 	sw.settings.hostname = "testname.lan"; | ||||||
| //File = fopen(otions.file)
 | 	File f; | ||||||
| 
 | 	f.write("config.json", sw.toString()); | ||||||
| 	return 0; | 	return 1; | ||||||
| } | } | ||||||
| int Program::restore() { | int Program::restore() { | ||||||
| 
 | 	File f; | ||||||
| 	const char str[] = | 	Switch sw; | ||||||
| 			" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } "; | 	sw.parse(f.read("config.json")); | ||||||
| 	printf("Original JSON:\n %s\n", str); | 	std::cout <<"Devices:\n\t"<<sw.settings.hostname<<" ("<< sw.device.type<<")\tMAC: "<<sw.device.mac<<"\tIP: "<<sw.settings.ip_addr<<"\n"; | ||||||
| 	Switch sw = Switch(); |  | ||||||
| 	sw.parse(str); |  | ||||||
| //File = fopen(otions.file)
 |  | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
| int Program::flash() { | int Program::flash() { | ||||||
|  |  | ||||||
|  | @ -4,9 +4,6 @@ | ||||||
|  *  Created on: 02.09.2015 |  *  Created on: 02.09.2015 | ||||||
|  *      Author: jdi |  *      Author: jdi | ||||||
|  */ |  */ | ||||||
| //#include <cstdio>
 |  | ||||||
| //#include <cerrno>
 |  | ||||||
| //#include <cstring>
 |  | ||||||
| #include <cstdlib> | #include <cstdlib> | ||||||
| #include <array> | #include <array> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
|  | @ -75,7 +72,7 @@ void Socket::listen() { | ||||||
| 					listen(); | 					listen(); | ||||||
| 				} else { | 				} else { | ||||||
| 					data.resize(bytes_recvd); | 					data.resize(bytes_recvd); | ||||||
| 					Packet p = Packet(Packet::RECEIVE); | 					Packet p = Packet(Packet::RETURN); | ||||||
| 					p.encode(data); | 					p.encode(data); | ||||||
| 					p.parse(data); | 					p.parse(data); | ||||||
| 					datasets l = p.getPayload(); | 					datasets l = p.getPayload(); | ||||||
|  |  | ||||||
							
								
								
									
										141
									
								
								src/Switch.cpp
									
										
									
									
									
								
							
							
						
						
									
										141
									
								
								src/Switch.cpp
									
										
									
									
									
								
							|  | @ -9,6 +9,7 @@ | ||||||
| #include "Types.h" | #include "Types.h" | ||||||
| #include "Switch.h" | #include "Switch.h" | ||||||
| #include "Lookup.h" | #include "Lookup.h" | ||||||
|  | #include "jsonNode.h" | ||||||
| #include "Options.h" | #include "Options.h" | ||||||
| 
 | 
 | ||||||
| int Switch::parse(datasets arr) { | int Switch::parse(datasets arr) { | ||||||
|  | @ -57,40 +58,25 @@ int Switch::parse(std::string str) { | ||||||
| 	if (options.flags & FLAG_DEBUG) | 	if (options.flags & FLAG_DEBUG) | ||||||
| 		std::cout << "\nParsing to document succeeded.\n"; | 		std::cout << "\nParsing to document succeeded.\n"; | ||||||
| 
 | 
 | ||||||
|  | 	if (json.IsObject()) { | ||||||
|  | 		if (json.HasMember("hostname")) | ||||||
|  | 			settings.hostname = json["hostname"].GetString(); | ||||||
|  | 		if (json.HasMember("type")) | ||||||
|  | 			device.type = json["type"].GetString(); | ||||||
|  | 		if (json.HasMember("hardware_version")) | ||||||
|  | 			device.hardware_version = json["hardware_version"].GetString(); | ||||||
|  | 		if (json.HasMember("firmware_version")) | ||||||
|  | 			device.hardware_version = json["firmware_version"].GetString(); | ||||||
| 
 | 
 | ||||||
|  | 	} | ||||||
|  | 	/*
 | ||||||
|  | 	 json.AddMember("ports", jsonNode(ports, json), allocator); | ||||||
|  | 	 json.AddMember("vlans", jsonNode(vlans, json), allocator); | ||||||
|  | 	 */ | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     ////////////////////////////////////////////////////////////////////////////
 |  | ||||||
|         // 2. Access values in document.
 |  | ||||||
| 
 |  | ||||||
|         printf("\nAccess values in document:\n"); |  | ||||||
|         assert(json.IsObject());    // Document is a JSON value represents the root of DOM. Root can be either an object or array.
 |  | ||||||
| 
 |  | ||||||
|         assert(json.HasMember("hello")); |  | ||||||
|         assert(json["hello"].IsString()); |  | ||||||
|         printf("hello = %s\n", json["hello"].GetString()); |  | ||||||
| 
 | 
 | ||||||
| 	// Since version 0.2, you can use single lookup to check the existing of member and its value:
 | 	// Since version 0.2, you can use single lookup to check the existing of member and its value:
 | ||||||
|  | 	/*
 | ||||||
| 	rapidjson::Value::MemberIterator hello = json.FindMember("hello"); | 	rapidjson::Value::MemberIterator hello = json.FindMember("hello"); | ||||||
| 	assert(hello != json.MemberEnd()); | 	assert(hello != json.MemberEnd()); | ||||||
| 	assert(hello->value.IsString()); | 	assert(hello->value.IsString()); | ||||||
|  | @ -124,94 +110,45 @@ int Switch::parse(std::string str) { | ||||||
| 
 | 
 | ||||||
| 		// Iterating array with iterators
 | 		// Iterating array with iterators
 | ||||||
| 		printf("a = "); | 		printf("a = "); | ||||||
|             for (rapidjson::Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr) | 		for (rapidjson::Value::ConstValueIterator itr = a.Begin(); | ||||||
|  | 				itr != a.End(); ++itr) | ||||||
| 			printf("%d ", itr->GetInt()); | 			printf("%d ", itr->GetInt()); | ||||||
| 		printf("\n"); | 		printf("\n"); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Iterating object members
 | 	// Iterating object members
 | ||||||
|         static const char* kTypeNames[] = { "Null", "False", "True", "Object", "Array", "String", "Number" }; | 	static const char* kTypeNames[] = { "Null", "False", "True", "Object", | ||||||
|         for (rapidjson::Value::ConstMemberIterator itr = json.MemberBegin(); itr != json.MemberEnd(); ++itr) | 			"Array", "String", "Number" }; | ||||||
|             printf("Type of member %s is %s\n", itr->name.GetString(), kTypeNames[itr->value.GetType()]); | 	for (rapidjson::Value::ConstMemberIterator itr = json.MemberBegin(); | ||||||
| 
 | 			itr != json.MemberEnd(); ++itr) | ||||||
| 
 | 		printf("Type of member %s is %s\n", itr->name.GetString(), | ||||||
| 
 | 				kTypeNames[itr->value.GetType()]); | ||||||
|  | */ | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string Switch::toString() { | std::string Switch::toString() { | ||||||
| 	////////////////////////////////////////////////////////////////////////////
 |  | ||||||
| 	    // 3. Modify values in document.
 |  | ||||||
| 
 | 
 | ||||||
| 	    // Change i to a bigger number
 | 	if (!json.IsObject()) { | ||||||
| 	    { | 		json.SetObject(); | ||||||
| 	        uint64_t f20 = 1;   // compute factorial of 20
 |  | ||||||
| 	        for (uint64_t j = 1; j <= 20; j++) |  | ||||||
| 	            f20 *= j; |  | ||||||
| 	        json["i"] = f20;    // Alternate form: document["i"].SetUint64(f20)
 |  | ||||||
| 	        assert(!json["i"].IsInt()); // No longer can be cast as int or uint.
 |  | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	    // Adding values to array.
 |  | ||||||
| 	    { |  | ||||||
| 	    	rapidjson::Value& a = json["a"];   // This time we uses non-const reference.
 |  | ||||||
| 	rapidjson::Document::AllocatorType& allocator = json.GetAllocator(); | 	rapidjson::Document::AllocatorType& allocator = json.GetAllocator(); | ||||||
| 	        for (int i = 5; i <= 10; i++) |  | ||||||
| 	            a.PushBack(i, allocator);   // May look a bit strange, allocator is needed for potentially realloc. We normally uses the document's.
 |  | ||||||
| 
 | 
 | ||||||
| 	        // Fluent API
 | 	json.AddMember("hostname", jsonNode(settings.hostname, json), allocator); | ||||||
| 	        a.PushBack("Lua", allocator).PushBack("Mio", allocator); | 	json.AddMember("ip", jsonNode(settings.ip_addr, json), allocator); | ||||||
| 	    } | 	json.AddMember("netmask", jsonNode(settings.ip_mask, json), allocator); | ||||||
|  | 	json.AddMember("gateway", jsonNode(settings.gateway, json), allocator); | ||||||
|  | 	json.AddMember("type", jsonNode(device.type, json), allocator); | ||||||
|  | 	json.AddMember("hardware_version", jsonNode(device.hardware_version, json), | ||||||
|  | 			allocator); | ||||||
|  | 	json.AddMember("firmware_version", jsonNode(device.firmware_version, json), | ||||||
|  | 			allocator); | ||||||
|  | 	json.AddMember("ports", jsonNode(ports, json), allocator); | ||||||
|  | 	json.AddMember("vlans", jsonNode(vlans, json), allocator); | ||||||
| 
 | 
 | ||||||
| 	    // Making string values.
 |  | ||||||
| 
 |  | ||||||
| 	    // This version of SetString() just store the pointer to the string.
 |  | ||||||
| 	    // So it is for literal and string that exists within value's life-cycle.
 |  | ||||||
| 	    { |  | ||||||
| 	        json["hello"] = "hostname"; //settings.hostname;    // This will invoke strlen()
 |  | ||||||
| 	        // Faster version:
 |  | ||||||
| 	        // document["hello"].SetString("rapidjson", 9);
 |  | ||||||
| 	    } |  | ||||||
| 
 |  | ||||||
| 	    // This version of SetString() needs an allocator, which means it will allocate a new buffer and copy the the string into the buffer.
 |  | ||||||
| 	    rapidjson::Value author; |  | ||||||
| 	    { |  | ||||||
| 	        char buffer[10]; |  | ||||||
| 	        int len = sprintf(buffer, "%s %s", "Milo", "Yip");  // synthetic example of dynamically created string.
 |  | ||||||
| 
 |  | ||||||
| 	        author.SetString(buffer, static_cast<size_t>(len), json.GetAllocator()); |  | ||||||
| 	        // Shorter but slower version:
 |  | ||||||
| 	        // document["hello"].SetString(buffer, document.GetAllocator());
 |  | ||||||
| 
 |  | ||||||
| 	        // Constructor version:
 |  | ||||||
| 	        // Value author(buffer, len, document.GetAllocator());
 |  | ||||||
| 	        // Value author(buffer, document.GetAllocator());
 |  | ||||||
| 	        memset(buffer, 0, sizeof(buffer)); // For demonstration purpose.
 |  | ||||||
| 	    } |  | ||||||
| 	    // Variable 'buffer' is unusable now but 'author' has already made a copy.
 |  | ||||||
| 	    json.AddMember("author", author, json.GetAllocator()); |  | ||||||
| 
 |  | ||||||
| 	    assert(author.IsNull());        // Move semantic for assignment. After this variable is assigned as a member, the variable becomes null.
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     std::cout<<"\nModified JSON with reformatting:\n"; |  | ||||||
| 	rapidjson::StringBuffer sb; | 	rapidjson::StringBuffer sb; | ||||||
| 	rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb); | 	rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb); | ||||||
|     json.Accept(writer);    // Accept() traverses the DOM and generates Handler events.
 | 	json.Accept(writer); | ||||||
| 	return sb.GetString(); | 	return sb.GetString(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|  |  | ||||||
							
								
								
									
										31
									
								
								src/Switch.h
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								src/Switch.h
									
										
									
									
									
								
							|  | @ -17,44 +17,17 @@ | ||||||
| #define DEFAULT_USER "admin" | #define DEFAULT_USER "admin" | ||||||
| #define DEFAULT_PASS "admin" | #define DEFAULT_PASS "admin" | ||||||
| 
 | 
 | ||||||
| typedef rapidjson::Value jsonNode; |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
| template<typename T> |  | ||||||
| jsonNode to_json(const T &x) { |  | ||||||
| 	// TODO Throw undefined
 |  | ||||||
| 	return NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| template<> jsonNode to_json<vlan>(const vlan &x) { |  | ||||||
| 	jsonNode ret; |  | ||||||
| 	return ret; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| template<typename T> |  | ||||||
| T from_json(const jsonNode &s) { |  | ||||||
| // TODO Throw not implemented
 |  | ||||||
| 	return NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| template<> vlan from_json<vlan>(const jsonNode &s) { |  | ||||||
| 	vlan ret; |  | ||||||
| 	return ret; |  | ||||||
| }*/ |  | ||||||
| 
 |  | ||||||
| struct vlan { | struct vlan { | ||||||
| 	int vlan_id; | 	int vlan_id; | ||||||
| 	std::string name; | 	std::string name; | ||||||
|  | 	std::vector<byte> tagged_member; | ||||||
|  | 	std::vector<byte> untagged_member; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct port { | struct port { | ||||||
| 	byte id; | 	byte id; | ||||||
| 	byte status; | 	byte status; | ||||||
| 	struct { |  | ||||||
| 		std::vector<vlan*> tagged; |  | ||||||
| 		std::vector<vlan*> untagged; |  | ||||||
| 	int pvid; | 	int pvid; | ||||||
| 	} vlan; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class Switch { | class Switch { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue