Java序列化解析类

C/C++代码 blackfeather


java可以将任意对象序列化为一段内存流,也可以反序列化回对象。


此代码用于dump序列化内容流,是用了Jsoncpp作为父类。


主要参考了https://github.com/NickstaDB/SerializationDumper这个项目。






#pragma once

#include <string>
#include <vector>
#include <cassert>
#include "FStream.h"

#include "json/json.h"

// #ifdef _DEBUG
// #pragma comment(lib, "jsoncpp/lib_json_mtd.lib")
// #else
// #pragma comment(lib, "jsoncpp/lib_json_mt.lib")
// #endif // _DEBUG

/*
Java序列化内容(以0xACED开头)解析工具,转为jsoncpp的Json::Value
参考链接: https://github.com/NickstaDB/SerializationDumper

用法:
JavaSerializationHandler jsonSerialize;
jsonSerialize.OpenSerializationBuffer(buf);
jsonSerialize.OpenSerializationFile(filepath);
dumpjson(jsonSerialize); //直接就是Json::Value的子类,可以直接按照json使用

说明:
如果对象是Object,那么会该Object的json节点会出现几个元素(使用前还是要校验一下存在与否):
	"_desc" : 类的描述信息,包括类名、字段描述、父类信息等等
	"_data" : 类的数据
	"_block": 类的附加块数据,一些内置的java类型例如hashmap或者list等等会使用该字段,这里的数据一般需要二次整理,不要直接使用
	"_array": 如果是Array类型数据例如java.util.ArrayList等,会出现该字段,类型是数组,数组的元素由_block字段中整理并保存到该字段下
	"_hashmap":如果是java.util.HashMap类型数据会出现该字段,由_block字段中的数据整理并保存到该字段下
	"_enum" : 暂时还没碰到过这个类型的数据样本,围观。。。
	
实例:
	末尾部分。
*/


class JavaSerializationHandler : public Json::Value
{
	/*******************
	 * Read a content element from the data stream.
	 *
	 * Could be any of:
	 *	TC_OBJECT			(0x73)
	 *	TC_CLASS			(0x76)
	 *	TC_ARRAY			(0x75)
	 *	TC_STRING			(0x74)
	 *	TC_LONGSTRING		(0x7c)
	 *	TC_ENUM				(0x7e)
	 *	TC_CLASSDESC		(0x72)
	 *	TC_PROXYCLASSDESC	(0x7d)
	 *	TC_REFERENCE		(0x71)
	 *	TC_NULL				(0x70)
	 *	TC_EXCEPTION		(0x7b)
	 *	TC_RESET			(0x79)
	 *	TC_BLOCKDATA		(0x77)
	 *	TC_BLOCKDATALONG	(0x7a)
	 ******************/

	enum classElementType
	{
		TC_NULL = 0x70,
		TC_REFERENCE = 0x71,
		TC_CLASSDESC = 0x72,
		TC_OBJECT = 0x73,
		TC_STRING = 0x74,
		TC_ARRAY = 0x75,
		TC_CLASS = 0x76,
		TC_BLOCKDATA = 0x77,
		TC_ENDBLOCKDATA = 0x78,
		TC_RESET = 0x79,
		TC_BLOCKDATALONG = 0x7a,
		TC_EXCEPTION = 0x7b,
		TC_LONGSTRING = 0x7c,
		TC_ENUM = 0x7e,
		TC_PROXYCLASSDESC = 0x7d
	};

	enum classDescFlags
	{
		SC_WRITE_METHOD = 0x01,
		SC_SERIALIZABLE = 0x02,
		SC_EXTERNALIZABLE = 0x04,
		SC_BLOCK_DATA = 0x08
	};

	struct OBJECT_REF_DATA
	{
		uint32_t ref;
		uint8_t type;
		Json::Value data;
	};


#ifndef _bswap_16
	/* Swap bytes in 16 bit value.  */
#define _bswap_16(x) \
	     ((unsigned short int) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))
#endif

#ifndef _bswap_32
/* Swap bytes in 32 bit value.  */
#define _bswap_32(x) \
	     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |		      \
	      (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
#endif

#ifndef _bswap_64
/* Swap bytes in 64 bit value.  */
# define _bswap_64(x) \
	     ((((x) & 0xff00000000000000ull) >> 56)				      \
	      | (((x) & 0x00ff000000000000ull) >> 40)				      \
	      | (((x) & 0x0000ff0000000000ull) >> 24)				      \
	      | (((x) & 0x000000ff00000000ull) >> 8)				      \
	      | (((x) & 0x00000000ff000000ull) << 8)				      \
	      | (((x) & 0x0000000000ff0000ull) << 24)				      \
	      | (((x) & 0x000000000000ff00ull) << 40)				      \
	      | (((x) & 0x00000000000000ffull) << 56))
#endif

	
public:
	JavaSerializationHandler() : m_refIndex(0x7e0000) {};
	~JavaSerializationHandler() {};

	template<typename _T>
	bool OpenSerializationFile(const _T& filepath)
	{
		FFileStream infile(filepath);
		m_bufstream = &infile;

		bool ret = false;
#ifdef _DEBUG
		ret = JavaSerializationParser(*this);
#else
		try
		{
			ret = JavaSerializationParser(*this);
		}
		catch (...) {}
#endif // _DEBUG

		return ret;
	}

	bool OpenSerializationBuffer(const std::string &buf)
	{
		FBufferStream stream(buf);
		m_bufstream = &stream;
		
		bool ret = false;
#ifdef _DEBUG
		ret = JavaSerializationParser(*this);
#else
		try
		{
			ret = JavaSerializationParser(*this);
		}
		catch (...) {}
#endif // _DEBUG

		return ret;
	}
	
private:
	FStream* m_bufstream;
	std::vector<OBJECT_REF_DATA> m_objectRefs;
	uint32_t m_refIndex;
	

	const char* getTypeString(uint8_t type)
	{
		//获取enum类型的字符串
		switch (type)
		{
		case TC_NULL:
			return "TC_NULL";
		case TC_REFERENCE:
			return "TC_REFERENCE";
		case TC_CLASSDESC:
			return "TC_CLASSDESC";
		case TC_OBJECT:
			return "TC_OBJECT";
		case TC_STRING:
			return "TC_STRING";
		case TC_ARRAY:
			return "TC_ARRAY";
		case TC_CLASS:
			return "TC_CLASS";
		case TC_BLOCKDATA:
			return "TC_BLOCKDATA";
		case TC_ENDBLOCKDATA:
			return "TC_ENDBLOCKDATA";
		case TC_RESET:
			return "TC_RESET";
		case TC_BLOCKDATALONG:
			return "TC_BLOCKDATALONG";
		case TC_EXCEPTION:
			return "TC_EXCEPTION";
		case TC_LONGSTRING:
			return "TC_LONGSTRING";
		case TC_ENUM:
			return "TC_ENUM";
		}

		return "UNKNOWN";
	}

	Json::Value getObjectByRef(uint32_t ref)
	{
		for (auto& obj : m_objectRefs)
		{
			if (obj.ref == ref)
			{
#ifdef _DEBUG
//				if (obj.type == TC_STRING || obj.type == TC_LONGSTRING)
//					printf("get ref:0x%x, string:%s \n", ref, obj.data.asCString());
//				else
//					printf("get ref:0x%x, type:%s(%x) \n", ref, getTypeString(obj.type), obj.type);
#endif // _DEBUG

				return obj.data;
				break;
			}
		}

		return {};
	}

	uint32_t setObjectRef(uint8_t type, const Json::Value& val)
	{
		m_objectRefs.emplace_back(OBJECT_REF_DATA{ m_refIndex , type, val });
#ifdef _DEBUG
// 		if (type == TC_STRING || type == TC_LONGSTRING)
// 			printf("new ref:0x%x, string:%s \n", m_refIndex, val.asCString());
// 		else
// 			printf("new ref:0x%x, type:%s(%x) \n", m_refIndex, getTypeString(type), type);
#endif // _DEBUG
		return m_refIndex++;
	}

	void updateObjectRef(uint32_t ref, uint8_t type, const Json::Value& val)
	{
		for (auto& obj : m_objectRefs)
		{
			if (obj.ref == ref)
			{
				obj.type = type;
				obj.data = val;
				break;
			}
		}
	}

	std::string tohex(const std::string& data)
	{
		std::string strRet;
		if (data.empty())
			return strRet;

		strRet.reserve(data.length() * 2);
		const char* hex = "0123456789abcdef";
		for (char ch : data)
		{
			strRet.push_back(hex[(unsigned char)ch >> 4]);
			strRet.push_back(hex[(unsigned char)ch & 0xf]);
		}

		return strRet;
	}


	bool readReference(uint32_t& ref)
	{
		if (!m_bufstream->read_data(ref))
			return false;

		ref = _bswap_32(ref);
		return true;
	}

	bool readUtf(std::string& ret)
	{
		uint16_t len;
		if (!m_bufstream->read_data(len))
			return false;
		len = _bswap_16(len);

		if (len && !m_bufstream->read_buffer(ret, len))
			return false;

		return true;
	}

	bool readLongUtf(std::string& ret)
	{
		uint64_t len;
		if (!m_bufstream->read_data(len))
			return false;
		len = _bswap_64(len);

		if (!m_bufstream->read_buffer(ret, (size_t)len))
			return false;

		return true;
	}

	bool readNewString(Json::Value& val)
	{
		uint8_t type;
		if (!m_bufstream->read_data(type))
			return false;

		if (type == TC_STRING || type == TC_LONGSTRING || type == TC_REFERENCE)
			return readContentElement(type, val);

		//剩下的类型都不对
		return false;
	}

	bool readNewArray(Json::Value& jsonarray)
	{
		Json::Value jsonDesc;
		//Read the class data description to enable array elements to be read
		if (!readClassDesc(jsonDesc))
			return false;

		if (!jsonDesc.isObject() || !jsonDesc["classname"].isString())
			return false;

		std::string str = jsonDesc["classname"].asString();
		if (str.length() < 2 || str[0] != '[')
			return false;
		uint8_t type = str[1];

		jsonarray["_desc"] = jsonDesc;

		//索引值+1
		int refindex = setObjectRef(TC_ARRAY, jsonarray);

		//array size
		uint32_t arraysize;
		if (!m_bufstream->read_data(arraysize))
			return false;

		for (uint32_t i = 0; i < arraysize; i++)
		{
			if (!readFieldValue(type, jsonarray["_array"][i]))
				return false;
		}

		//更新值
		updateObjectRef(refindex, TC_ARRAY, jsonarray);

		return true;
	}

	bool readFieldValue(int type, Json::Value& jsonvalue)
	{
		switch (type)
		{
		case 'B':		//byte 1
			uint8_t val;
			if (!m_bufstream->read_data(val))
				return false;
			jsonvalue = val;
			break;

		case 'C':		//char java里面的char占用2字节
		case 'S':		//short
		{
			uint16_t val;
			if (!m_bufstream->read_data(val))
				return false;
			jsonvalue = _bswap_16(val);
			break;
		}
		case 'D':		//double
		{
			uint64_t val;
			if (!m_bufstream->read_data(val))
				return false;
			val = _bswap_64(val);
			jsonvalue = *(double*)&val;
			break;
		}
		case 'F':		//float
		{
			uint32_t val;
			if (!m_bufstream->read_data(val))
				return false;
			val = _bswap_32(val);
			jsonvalue = *(float*)&val;
			break;
		}
		case 'I':		//int
		{
			uint32_t val;
			if (!m_bufstream->read_data(val))
				return false;
			jsonvalue = (int32_t)_bswap_32(val);
			break;
		}
		case 'J':		//long
		{
			uint64_t val;
			if (!m_bufstream->read_data(val))
				return false;
			jsonvalue = (int64_t)_bswap_64(val);
			break;
		}
		case 'Z':		//boolean
		{
			uint8_t val;
			if (!m_bufstream->read_data(val))
				return false;
			if (val)
				jsonvalue = true;
			else
				jsonvalue = false;
			break;
		}
		case '[':		//array
		case 'L':		//object
			if (!readContentElement(jsonvalue))
				return false;
			break;

		default:		//Unknown field type
			printf("unknown filed type: %c\n", type);
			return false;
		}

		return true;
	}

	bool readClassAnnotation(Json::Value& jsonret)
	{
		//classAnnotation
		int index = 0;
		while (true)
		{
			uint8_t type;
			if (!m_bufstream->read_data(type))
				return false;

			if (type == TC_ENDBLOCKDATA)
				break;

			if (!readContentElement(type, jsonret[index]))
				return false;

			index++;
		}

		return true;
	}

	bool readNewClassDesc(Json::Value& jsonret)
	{
		//由于desc很长很长,先占个坑把ref的index占了
		uint32_t refindex = setObjectRef(TC_CLASSDESC, jsonret);

		//className
		std::string className;
		if (!readUtf(className))
			return false;
		if (className.empty())
		{
			printf("Error: class name is empty.\n");
			return false;
		}
		jsonret["classname"] = className;

		//serialVersionUID 固定8字节
		std::string serialVersionUID;
		if (!m_bufstream->read_buffer(serialVersionUID, 8))
			return false;
		jsonret["uid"] = tohex(serialVersionUID);

		//classDescFlags
		uint8_t classflags;
		if (!m_bufstream->read_data(classflags))
			return false;
		////Validate classDescFlags
		if ((classflags & 0x02) == 0x02)
		{
			if ((classflags & 0x04) == 0x04)
			{
				printf("Error: Illegal classDescFlags, SC_SERIALIZABLE is not compatible with SC_EXTERNALIZABLE. \n");
				return false;
			}
			if ((classflags & 0x08) == 0x08)
			{
				printf("Error: Illegal classDescFlags, SC_SERIALIZABLE is not compatible with SC_BLOCK_DATA. \n");
				return false;
			}
		}
		else if ((classflags & 0x04) == 0x04)
		{
			if ((classflags & 0x01) == 0x01)
			{
				printf("Error: Illegal classDescFlags, SC_EXTERNALIZABLE is not compatible with SC_WRITE_METHOD.\n");
				return false;
			}
		}
		else if (classflags != 0x00)
		{
			printf("Error: Illegal classDescFlags, must include either SC_SERIALIZABLE or SC_EXTERNALIZABLE. \n");
			return false;
		}
		jsonret["flags"] = classflags;

		//read fields
		uint16_t fieldcount;
		if (!m_bufstream->read_data(fieldcount))
			return false;
		fieldcount = _bswap_16(fieldcount);
		jsonret["fields"].resize(0);
		for (uint16_t i = 0; i < fieldcount; i++)
		{
			uint8_t fieldtype;
			if (!m_bufstream->read_data(fieldtype))
				return false;
			jsonret["fields"][i]["type"] = fieldtype;

			std::string fieldname;
			if (!readUtf(fieldname))
				return false;
			if (fieldname.empty())
			{
				printf("Error: field name is empty.\n");
				//return false;
			}
			jsonret["fields"][i]["name"] = fieldname;

			if (fieldtype == '[' || fieldtype == 'L')
			{
				if (!readNewString(jsonret["fields"][i]["classname"]))
					return false;
			}
		}

		//ClassAnnotation
		if (!readClassAnnotation(jsonret["annotation"]))
			return false;

		//SuperClassDesc ???
		if (!readClassDesc(jsonret["superclass"]))
			return false;

		//更新refs
		updateObjectRef(refindex, TC_CLASSDESC, jsonret);

		return true;
	}

	bool readNewProxyClassDesc(Json::Value& jsonret)
	{
		//由于desc很长很长,先占个坑把ref的index占了
		uint32_t refindex = setObjectRef(TC_PROXYCLASSDESC, jsonret);

		uint32_t count;
		if (!m_bufstream->read_data(count))
			return false;
		count = _bswap_32(count);

		//proxyInterfaceNames
		for (uint32_t i = 0; i < count; i++)
		{
			std::string classname;
			if (!readUtf(classname))
				return false;
			jsonret["proxyclass"][i] = classname;
		}

		//ClassAnnotation
		if (!readClassAnnotation(jsonret["annotation"]))
			return false;

		//SuperClassDesc ???
		if (!readClassDesc(jsonret["superclass"]))
			return false;

		//更新refs
		updateObjectRef(refindex, TC_PROXYCLASSDESC, jsonret);

		return true;
	}

	//读取class的描述信息
	bool readClassDesc(Json::Value& jsonClassDesc)
	{
		uint8_t t;
		if (!m_bufstream->read_data(t))
			return false;

		if (t == TC_CLASSDESC || t == TC_PROXYCLASSDESC || t == TC_REFERENCE || t == TC_NULL)
			return readContentElement(t, jsonClassDesc);

		return false;
	}

	bool readClassData(const Json::Value& classDesc, Json::Value& jsonret)
	{
		//通过遍历递归的手法  让superclass排到读取的前面去
		if (classDesc["superclass"].isObject() && classDesc["superclass"]["classname"].isString())
		{
			//递归走起
			if (!readClassData(classDesc["superclass"], jsonret["_super"]))
				return false;
		}

		//搞自己的吧
		//仅支持标准TC_CLASSDESC  TC_PROXYCLASSDESC暂无数据没办法测试研究。。。
		assert(classDesc["classname"].isString());
		assert(classDesc["fields"].isArray());
		assert(classDesc["flags"].isInt());
		if (!classDesc["classname"].isString())
		{
			printf("Error:no class name.\n");
			return false;
		}
		if (!classDesc["fields"].isArray())
		{
			printf("Error:no fields.\n");
			return false;
		}
		if (!classDesc["flags"].isInt())
		{
			printf("Error:no flags.\n");
			return false;
		}

		int flags = classDesc["flags"].asInt();
		jsonret["_desc"] = classDesc;

		if (flags & SC_SERIALIZABLE)
		{
			//读取字段数据
			size_t fieldscount = classDesc["fields"].size();
			for (size_t i = 0; i < fieldscount; i++)
			{
				const Json::Value& jsonField = classDesc["fields"][i];
				if (!readFieldValue(jsonField["type"].asInt(), jsonret["_data"][jsonField["name"].asString()]))
					return false;
			}
		}

		bool hasBlockData = false;
		if ((flags & SC_SERIALIZABLE) && (flags & SC_WRITE_METHOD))
			hasBlockData = true;
		if (flags & SC_EXTERNALIZABLE)
		{
			if (flags & SC_BLOCK_DATA)
			{
				hasBlockData = true;
			}
			else
			{
				printf("Unable to parse externalContents for protocol version 1.\n");
				return false;
			}
		}

		if (hasBlockData)
		{
			if (!readClassAnnotation(jsonret["_block"]))
				return false;
		}

		//额外处理几种类型的显示
		//"java.util.HashMap"
		if (classDesc["classname"].asString() == "java.util.HashMap" && jsonret["_block"].isArray())
		{
			jsonret["_hashmap"].resize(0);

			//hashmap 在block里面第0个疑似是hashmap的size(),直接无视,解析内容
			//内容是size;key-value;key-value;key-value;
			size_t blockcount = jsonret["_block"].size();
			if (blockcount % 2) //第一块是size  后面是kv对
			{
				size_t kvcount = blockcount / 2;
				//printf("Hashmap size: %d\n", kvcount);

				for (size_t i = 0; i < kvcount; i++)
				{
					//key
					Json::Value key;
					const Json::Value& keytmp = jsonret["_block"][i * 2 + 1];
					if (keytmp.isObject() && keytmp["_data"].isObject() && !keytmp["_data"]["value"].isNull())
						key = keytmp["_data"]["value"];
					else
						key = keytmp;

					//value
					const Json::Value& valuetmp = jsonret["_block"][i * 2 + 2];
					if (valuetmp.isObject() && valuetmp["_data"].isObject() && !valuetmp["_data"]["value"].isNull())
						jsonret["_hashmap"][i][key.asString()] = valuetmp["_data"]["value"];
					else
						jsonret["_hashmap"][i][key.asString()] = valuetmp;

#ifdef _DEBUG
					//printf("key:%s, value:%s\n", Json2String(key).c_str(), Json2String(jsonret["_hashmap"][i][key.asString()]).c_str());
#endif // _DEBUG
				}
			}
		}

		//java.util.ArrayList
		if (classDesc["classname"].asString() == "java.util.ArrayList" && jsonret["_block"].isArray())
		{
			jsonret["_array"].resize(0);

			//_data里面有一个"size": 1表示的就是size
			//blockdata里面第一个元素应该也是长度,直接无视,读取所有blockdata
			size_t blockcount = jsonret["_block"].size();
			if (blockcount > 1)
			{
				blockcount--; //将第一个元素去掉
				for (size_t i = 0; i < blockcount; i++)
				{
					Json::Value& datatmp = jsonret["_block"][i + 1];
					if (datatmp.isObject() && !datatmp["_data"].isNull())
						jsonret["_array"][i] = datatmp["_data"];
					else
						jsonret["_array"][i] = datatmp;
				}
			}
		}

		//其他的类型待补充
		//...

		return true;
	}

	bool readNewObject(Json::Value& jsonret)
	{
		//printf("TC_OBJECT\n");

		//读取类描述
		Json::Value classDesc;
		if (!readClassDesc(classDesc))
			return false;

		//这中间要让索引值加1
		uint32_t refindex = setObjectRef(TC_OBJECT, jsonret);

		//读取值
		if (!readClassData(classDesc, jsonret))
			return false;

		//更新值
		updateObjectRef(refindex, TC_OBJECT, jsonret);

		return true;
	}

	bool readNewClass(Json::Value& jsonret)
	{
		//printf("TC_CLASS\n");

		Json::Value classDesc;
		if (!readClassDesc(classDesc))
			return false;

		assert(classDesc["classname"].isString());
		if (!classDesc["classname"].isString())
		{
			//printf("Error:no class name.\n");
			return false;
		}

		jsonret["_desc"] = classDesc;

		//增加引用 不知道还能干啥
		m_refIndex++;

		return true;
	}


	bool readNewEnum(Json::Value& jsonret)
	{
		//printf("TC_ENUM\n");

		Json::Value classDesc;
		if (!readClassDesc(classDesc))
			return false;

		assert(classDesc["classname"].isString());
		if (!classDesc["classname"].isString())
		{
			printf("Error:no class name.\n");
			return false;
		}

		//先增加引用
		int refindex = setObjectRef(TC_ENUM, jsonret);

		jsonret["_desc"] = classDesc;

		//enumConstantName ???
		if (!readNewString(jsonret["_enum"]))
			return false;

		//更新引用的值
		updateObjectRef(refindex, TC_ENUM, jsonret);

		return true;
	}

	bool readBlockData(Json::Value& jsonret)
	{
		//printf("TC_BLOCKDATA\n");

		uint8_t len;
		if (!m_bufstream->read_data(len))
			return false;

		if (len)
		{
			std::string block;
			if (!m_bufstream->read_buffer(block, len))
				return false;
			jsonret = tohex(block);
		}
		else
		{
			jsonret = "";
		}

		return true;
	}

	bool readBlockDataLong(Json::Value& jsonret)
	{
		//printf("TC_BLOCKDATALONG\n");

		uint32_t len;
		if (!m_bufstream->read_data(len))
			return false;

		len = _bswap_32(len);
		if (len)
		{
			std::string block;
			if (!m_bufstream->read_buffer(block, len))
				return false;
			jsonret = tohex(block);
		}
		else
		{
			jsonret = "";
		}

		return true;
	}

	bool readContentElement(uint8_t type, Json::Value& jsonret)
	{
		switch (type)
		{
		case TC_OBJECT:
			if (!readNewObject(jsonret))
				return false;
			break;
		case TC_CLASS:
			if (!readNewClass(jsonret))
				return false;
			break;
		case TC_ARRAY:
			if (!readNewArray(jsonret))
				return false;
			break;
		case TC_STRING:
		{
			std::string val;
			if (!readUtf(val))
				return false;
			jsonret = val;

			setObjectRef(TC_STRING, jsonret);
			break;
		}
		case TC_LONGSTRING:
		{
			std::string val;
			if (!readLongUtf(val))
				return false;
			jsonret = val;

			setObjectRef(TC_STRING, jsonret);
			break;
		}
		case TC_ENUM:
			if (!readNewEnum(jsonret))
				return false;
			break;
		case TC_CLASSDESC:
			if (!readNewClassDesc(jsonret))
				return false;
			break;
		case TC_PROXYCLASSDESC:
			if (!readNewProxyClassDesc(jsonret))
				return false;
			break;
		case TC_REFERENCE:
			uint32_t ref;
			if (!readReference(ref))
				return false;
			jsonret = getObjectByRef(ref);
			break;
		case TC_NULL:
			jsonret = NULL;
			break;
			// 	case TC_EXCEPTION:
			// 		printf("TC_EXCEPTION\n");
			// 		break;
			// 	case TC_RESET:
			// 		printf("TC_RESET\n");
			// 		break;
		case TC_BLOCKDATA:
			if (!readBlockData(jsonret))
				return false;
			break;
		case TC_BLOCKDATALONG:
			if (!readBlockDataLong(jsonret))
				return false;
			break;

		default:
			printf("Unknown type - %x\n", type);
			break;
		}

		return true;
	}
	bool readContentElement(Json::Value& jsonret)
	{
		uint8_t t;
		if (!m_bufstream->read_data(t))
			return false;

		return readContentElement(t, jsonret);
	}

	bool JavaSerializationParser(Json::Value& jsonret)
	{
		uint8_t b1, b2;

		//读取文件头
		if (!m_bufstream->read_data(b1))
			return false;
		if (b1 != 0xac)
		{
			switch (b1) {
			case 0x50:
				printf("RMI Call - 0x50 \n");
				break;
			case 0x51:
				printf("RMI ReturnData - 0x51 \n");
				break;
			case 0x52:
				printf("RMI Ping - 0x52 \n");
				break;
			case 0x53:
				printf("RMI PingAck - 0x53 \n");
				break;
			case 0x54:
				printf("RMI DgcAck - 0x54 \n");
				break;
			default:
				printf("Unknown RMI packet type - 0x%x \n" + b1);
				break;
			}

			//不是0xac开头的 再读取一次
			if (!m_bufstream->read_data(b1))
				return false;
		}
		if (!m_bufstream->read_data(b2))
			return false;
		//校验文件头
		printf("STREAM_MAGIC - %x %x\n", b1, b2);
		if (b1 != 0xac || b2 != 0xed)
		{
			printf("Invalid STREAM_MAGIC, should be ac ed \n");
			return false;
		}

		//校验版本
		if (!m_bufstream->read_data(b1))
			return false;
		if (!m_bufstream->read_data(b2))
			return false;
		printf("STREAM_VERSION - %x %x\n", b1, b2);
		if (b1 != 0x00 || b2 != 0x05)
		{
			printf("Invalid STREAM_VERSION, should be 00 05 \n");
			return false;
		}

		//解析内容了
		int index = 0;
		while (true)
		{
			Json::Value value;
			if (!readContentElement(value))
			{
				if (!value.isNull())
				{
					if (index == 0)
						jsonret = value;
					else
						jsonret[index] = value;

					return false;
				}
			}

			if (m_bufstream->eof())
				break;

			//后面还有
			jsonret[index] = value;
			index++;
		}

		return true;
	}
};



/*
//实例1 普通的对象 使用_data
{
	"_data":
	{
		"B_points": 0,
		"account_desc": "E会员",
		"account_level": 5,
		"android_url": "",
		"auth_token": "GgMBu55DmpL8hm7HNRsg",
		"avatar": "https://ugc.bthhotels.com/avatar/images/default_avatar.png!a160",
		"balance": 0,
		"birth": "1995/01/12",
		"btn_text": "",
		"can_update_avatar": false,
		"carbon_points": 0,
		"card_balance": "0",
		"card_code": "",
		"code": "100000138749707",
		"ctf_code": "412702199601028052",
		"ctf_type": "ID",
		"desc": "",
		"down_days_left": 0,
		"down_expire_date": "2023-04-08",
		"email": "",
		"gift_switch": true,
		"growth_value": 0,
		"keep_level_growth_value": 0,
		"keep_level_score": "",
		"level_up_growth_value": 1000,
		"lvl_exp_text": "",
		"name": "张三",
		"new_balance": "0",
		"new_red_packet": "0",
		"next_account_desc": "银会员",
		"next_level_nights": 3,
		"nights": 0,
		"phone": "136****7271",
		"points": 0,
		"red_packet": 0,
		"score_speed_times": 1.0,
		"tags": "[\"SL01\",\"E06\"]",
		"title": "",
		"user_markers": "[]"
	},
	"_desc":
	{
		"annotation": null,
		"classname": "com.ziipin.homeinn.model.UserInfo",
		"fields": [
		{
			"name": "B_points",
			"type": 73
		},
		{
			"name": "account_level",
			"type": 73
		},
		{
			"name": "balance",
			"type": 73
		},
		{
			"name": "can_update_avatar",
			"type": 90
		},
		{
			"name": "carbon_points",
			"type": 73
		},
		{
			"name": "down_days_left",
			"type": 73
		},
		{
			"name": "gift_switch",
			"type": 90
		},
		{
			"name": "growth_value",
			"type": 73
		},
		{
			"name": "keep_level_growth_value",
			"type": 73
		},
		{
			"name": "level_up_growth_value",
			"type": 73
		},
		{
			"name": "next_level_nights",
			"type": 73
		},
		{
			"name": "nights",
			"type": 73
		},
		{
			"name": "points",
			"type": 73
		},
		{
			"name": "red_packet",
			"type": 73
		},
		{
			"name": "score_speed_times",
			"type": 70
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "account_desc",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "android_url",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "auth_token",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "avatar",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "birth",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "btn_text",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "card_balance",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "card_code",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "code",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "ctf_code",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "ctf_type",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "desc",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "down_expire_date",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "email",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "keep_level_score",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "lvl_exp_text",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "name",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "new_balance",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "new_red_packet",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "next_account_desc",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "phone",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "tags",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "title",
			"type": 76
		},
		{
			"classname": "Ljava/lang/String;",
			"name": "user_markers",
			"type": 76
		}],
		"flags": 2,
		"superclass": 0,
		"uid": "fb74abdfc6ffaf03"
	}
}



实例2:hashmap类的解析,看_hashmap字段
{
	"_block": [
		"0000000800000005",
		{
			"_data": {
				"value": 98305
			},
			"_desc": {
				"annotation": null,
				"classname": "java.lang.Integer",
				"fields": [
					{
						"name": "value",
						"type": 73
					}
				],
				"flags": 2,
				"superclass": {
					"annotation": null,
					"classname": "java.lang.Number",
					"fields": [],
					"flags": 2,
					"superclass": 0,
					"uid": "86ac951d0b94e08b"
				},
				"uid": "12e2a0a4f7818738"
			},
			"_super": {
				"_desc": {
					"annotation": null,
					"classname": "java.lang.Number",
					"fields": [],
					"flags": 2,
					"superclass": 0,
					"uid": "86ac951d0b94e08b"
				}
			}
		},
		{
			"_data": {
				"value": true
			},
			"_desc": {
				"annotation": null,
				"classname": "java.lang.Boolean",
				"fields": [
					{
						"name": "value",
						"type": 90
					}
				],
				"flags": 2,
				"superclass": 0,
				"uid": "cd207280d59cfaee"
			}
		},
		{
			"_data": {
				"value": 256
			},
			"_desc": {
				"annotation": null,
				"classname": "java.lang.Integer",
				"fields": [
					{
						"name": "value",
						"type": 73
					}
				],
				"flags": 2,
				"superclass": {
					"annotation": null,
					"classname": "java.lang.Number",
					"fields": [],
					"flags": 2,
					"superclass": 0,
					"uid": "86ac951d0b94e08b"
				},
				"uid": "12e2a0a4f7818738"
			},
			"_super": {
				"_desc": {
					"annotation": null,
					"classname": "java.lang.Number",
					"fields": [],
					"flags": 2,
					"superclass": 0,
					"uid": "86ac951d0b94e08b"
				}
			}
		},
		"A86880902494769",
		{
			"_data": {
				"value": 259
			},
			"_desc": {
				"annotation": null,
				"classname": "java.lang.Integer",
				"fields": [
					{
						"name": "value",
						"type": 73
					}
				],
				"flags": 2,
				"superclass": {
					"annotation": null,
					"classname": "java.lang.Number",
					"fields": [],
					"flags": 2,
					"superclass": 0,
					"uid": "86ac951d0b94e08b"
				},
				"uid": "12e2a0a4f7818738"
			},
			"_super": {
				"_desc": {
					"annotation": null,
					"classname": "java.lang.Number",
					"fields": [],
					"flags": 2,
					"superclass": 0,
					"uid": "86ac951d0b94e08b"
				}
			}
		},
		"OPPOOPPO R7sPlus: fp asimd evtstrm aes pmull sha1 sha2 crc32: AArch64 Processor rev 4 (aarch64): 8: Qualcomm Technologies, Inc MSM8939: null",
		{
			"_data": {
				"value": 94209
			},
			"_desc": {
				"annotation": null,
				"classname": "java.lang.Integer",
				"fields": [
					{
						"name": "value",
						"type": 73
					}
				],
				"flags": 2,
				"superclass": {
					"annotation": null,
					"classname": "java.lang.Number",
					"fields": [],
					"flags": 2,
					"superclass": 0,
					"uid": "86ac951d0b94e08b"
				},
				"uid": "12e2a0a4f7818738"
			},
			"_super": {
				"_desc": {
					"annotation": null,
					"classname": "java.lang.Number",
					"fields": [],
					"flags": 2,
					"superclass": 0,
					"uid": "86ac951d0b94e08b"
				}
			}
		},
		{
			"_data": {
				"value": 0
			},
			"_desc": {
				"annotation": null,
				"classname": "java.lang.Integer",
				"fields": [
					{
						"name": "value",
						"type": 73
					}
				],
				"flags": 2,
				"superclass": {
					"annotation": null,
					"classname": "java.lang.Number",
					"fields": [],
					"flags": 2,
					"superclass": 0,
					"uid": "86ac951d0b94e08b"
				},
				"uid": "12e2a0a4f7818738"
			},
			"_super": {
				"_desc": {
					"annotation": null,
					"classname": "java.lang.Number",
					"fields": [],
					"flags": 2,
					"superclass": 0,
					"uid": "86ac951d0b94e08b"
				}
			}
		},
		{
			"_data": {
				"value": 258
			},
			"_desc": {
				"annotation": null,
				"classname": "java.lang.Integer",
				"fields": [
					{
						"name": "value",
						"type": 73
					}
				],
				"flags": 2,
				"superclass": {
					"annotation": null,
					"classname": "java.lang.Number",
					"fields": [],
					"flags": 2,
					"superclass": 0,
					"uid": "86ac951d0b94e08b"
				},
				"uid": "12e2a0a4f7818738"
			},
			"_super": {
				"_desc": {
					"annotation": null,
					"classname": "java.lang.Number",
					"fields": [],
					"flags": 2,
					"superclass": 0,
					"uid": "86ac951d0b94e08b"
				}
			}
		},
		"868809024947694"
	],
	"_data": {
		"loadFactor": 0.75
	},
	"_desc": {
		"annotation": null,
		"classname": "java.util.HashMap",
		"fields": [
			{
				"name": "loadFactor",
				"type": 70
			}
		],
		"flags": 3,
		"superclass": 0,
		"uid": "0507dac1c31660d1"
	},
	"_hashmap": [
		{
			"98305": true
		},
		{
			"256": "A86880902494769"
		},
		{
			"259": "OPPOOPPO R7sPlus: fp asimd evtstrm aes pmull sha1 sha2 crc32: AArch64 Processor rev 4 (aarch64): 8: Qualcomm Technologies, Inc MSM8939: null"
		},
		{
			"94209": 0
		},
		{
			"258": "868809024947694"
		}
	]
}


*/


评论列表:

发表评论:

验证码