// ECodeParser.cpp: 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "common.h"
#include "krnln.h"
#include "ECodeParser.h"

EXPORT ECode* ECodeParser_Create(LPCSTR eroot)
{
	return new ECode(eroot);
}

EXPORT void ECodeParser_Destroy(ECode* parser)
{
	delete parser;
}

EXPORT void ECodeParser_AddEvent(ECode* parser, LPCSTR name, EVENT e)
{
	parser->AddEvent(name, e);
}

EXPORT EInfo* ECodeParser_Parse(ECode* parser, LPBYTE data, size_t size, BOOL enc)
{
	return parser->Parse(data, size, enc);
}

EXPORT LPBYTE ECodeParser_GetDerived(ECode* parser, ETAG tag)
{
	return parser->GetDerived(tag);
}

EXPORT EBase* ECodeParser_FindEBase(ECode* parser, ETAG tag)
{
	return parser->FindEBase(tag);
}

EXPORT LPSTR ECodeParser_EMethod2Code(ECode* parser, ETAG tag)
{
	return parser->EMethod2Code(tag);
}
EXPORT LPSTR ECodeParser_EMethodCode2Code(ECode* parser, ETAG tag)
{
	return parser->EMethodCode2Code(tag);
}

EXPORT HWND ECodeParser_EForm2Window(ECode* parser, ETAG tag)
{
	return parser->EForm2Window(tag);
}

EXPORT ESection_Program_Assembly* getMethod(ECode* parser, ETAG tag)
{
	return parser->getMethod(tag);
}



EXPORT LPBYTE Ptr2Arr(vector<BYTE>* v, int size)
{
	LPBYTE ptr = v->begin()._Ptr;
	int len = v->size();
	int count = len / size;
	LPBYTE data = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, count * 4 + 8);
	if (!data)return 0;
	LPINT c = (LPINT)data;
	*c = 1;
	c++;
	*c = count;
	c++;
	for (int i = 0; i < count; i++, c++, ptr += size)
		*c = (int)ptr;
	return data;
}

EXPORT LPBYTE Ptr2Bin(vector<BYTE>* v)
{
	LPBYTE ptr = v->begin()._Ptr;
	int len = v->size();
	LPBYTE data = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, len + 8);
	if (!data)return 0;
	*((LPINT)data) = len;
	memcpy(data + 8, ptr, len);
	return data;
}



// 使用 LocalAlloc来申请内存,并把 s 写入内存中, 返回这个内存地址,调用方不使用时需要调用 LocalFree() 释放
EXPORT LPSTR Ptr2Str(string* s)
{
	if (s->empty())
		return NULL;
	int len = s->size();
	LPSTR b = (LPSTR)LocalAlloc(LMEM_ZEROINIT, len + 1);
	if (!b)return 0;
	s->_Copy_s(b, len + 1, len);
	return b;
}


EXPORT void FreePtr(LPVOID ptr)
{
	LocalFree(ptr);
}

// 获取信息,并返回数据, 包括用户配置,加载的模块,加载的支持库,参数为保存到的文件路径
EXPORT LPSTR getSysInfo(ECode* parser)
{
	string s = parser->getSysInfo();

	return Ptr2Str(&s);
}

// 取dll命令信息
EXPORT LPSTR getDllInfo(ECode* parser)
{
	string s = parser->getDllInfo();
	return Ptr2Str(&s);
}

// 取定义的数据类型
EXPORT LPSTR getDataType(ECode* parser)
{
	string s = parser->getDataType();
	return Ptr2Str(&s);
}

// 取全局变量
EXPORT LPSTR getGlobal(ECode* parser)
{
	string s = parser->getGlobal();
	return Ptr2Str(&s);
}

// 取程序集,类,窗口程序集
EXPORT LPSTR getAssemblies(ECode* parser)
{
	vector<string> strs = parser->getAssemblies();
	string ret;
	for (auto i = strs.begin(); i < strs.end(); i++)
	{
		i++;	// 第一个记录程序集类型,跳过
		ret += *i;
	}
	return Ptr2Str(&ret);
}

EXPORT void FreeEBase(EBase* ptr)
{
	delete ptr;
}

ECodeParser::ECodeParser(LPCSTR eroot)
{
	this->_eroot = eroot;
}

ECodeParser::~ECodeParser()
{

}

void ECodeParser::AddEvent(LPCSTR name, EVENT e)
{
	if (strcmp(name, EVENT_INFO) == 0)
		this->_info.push_back(e);
	else if (strcmp(name, EVENT_LIB) == 0)
		this->_lib.push_back(e);
	else if (strcmp(name, EVENT_EC) == 0)
		this->_ec.push_back(e);
	else if (strcmp(name, EVENT_WINDOW) == 0)
		this->_window.push_back(e);
	else if (strcmp(name, EVENT_CLASS) == 0)
		this->_class.push_back(e);
	else if (strcmp(name, EVENT_ASSEMBLY) == 0)
		this->_assembly.push_back(e);
	else if (strcmp(name, EVENT_METHOD) == 0)
		this->_method.push_back(e);
	else if (strcmp(name, EVENT_STRUCT) == 0)
		this->_struct.push_back(e);
	else if (strcmp(name, EVENT_DLL) == 0)
		this->_dll.push_back(e);
	else if (strcmp(name, EVENT_GLOBAL) == 0)
		this->_global.push_back(e);
	else if (strcmp(name, EVENT_CONST) == 0)
		this->_const.push_back(e);
	else if (strcmp(name, EVENT_RESOURCE) == 0)
		this->_resource.push_back(e);
	else if (strcmp(name, EVENT_END) == 0)
		this->_end.push_back(e);
}

void ECodeParser::CallEvent(LPCSTR name, LPVOID obj)
{
	vector<EVENT>* arr;
	if (strcmp(name, EVENT_INFO) == 0)
		arr = &this->_info;
	else if (strcmp(name, EVENT_LIB) == 0)
		arr = &this->_lib;
	else if (strcmp(name, EVENT_EC) == 0)
		arr = &this->_ec;
	else if (strcmp(name, EVENT_WINDOW) == 0)
		arr = &this->_window;
	else if (strcmp(name, EVENT_CLASS) == 0)
		arr = &this->_class;
	else if (strcmp(name, EVENT_ASSEMBLY) == 0)
		arr = &this->_assembly;
	else if (strcmp(name, EVENT_METHOD) == 0)
		arr = &this->_method;
	else if (strcmp(name, EVENT_STRUCT) == 0)
		arr = &this->_struct;
	else if (strcmp(name, EVENT_DLL) == 0)
		arr = &this->_dll;
	else if (strcmp(name, EVENT_GLOBAL) == 0)
		arr = &this->_global;
	else if (strcmp(name, EVENT_CONST) == 0)
		arr = &this->_const;
	else if (strcmp(name, EVENT_RESOURCE) == 0)
		arr = &this->_resource;
	else if (strcmp(name, EVENT_END) == 0)
		arr = &this->_end;
	else
		return;
	for (EVENT e : *arr)
		e(obj);
}

// 解析源码
// data	= 易语言源码数据,.e实际数据
// size	= .e文件的尺寸
// enc = 是否分析的为源码，如果是源码，则使用假。如果分析的为剪辑版的数据，则需要设置为真。
EInfo* ECodeParser::Parse(LPBYTE data, size_t size, BOOL enc)
{
	this->_inherit.clear();
	this->_einfo = EInfo();
	LPBYTE ptr = NULL;
	long long offset = sizeof(EFile_Header);


	bool isai = true;

	EFile_Header header;
	memcpy(&header, data, sizeof(EFile_Header));
	if (!arrcmp(header.Magic1, Magic1, 4) || !arrcmp(header.Magic2, Magic2, 4))
		goto end;
	while (offset < size)
	{
		ESection_Header sh = GetData<ESection_Header>(data, offset);
		if (!arrcmp(sh.Magic, Magic_Section, 4))
			goto end;
		ESection_Info si = GetData<ESection_Info>(data, offset);
		if (!arrcmp(si.Key, KEY, 4))
			Decode_Str(si.Name, si.Key);
		LPSTR Block_Name = (LPSTR)si.Name;
		OutputDebugString(Block_Name);
		OutputDebugString("\n");
		if (enc)
		{
			long long t = offset + si.DataLength - 1;
			Byte<4> b = GetData<Byte<4>>(data, t);
			if (arrcmp(b.value, Magic_Section, 4))
				si.DataLength--;
			else
				si.DataLength++;
		}
		if (strcmp(Block_Name, "") == 0) break;
		else if (strcmp(Block_Name, "系统信息段") == 0)
		{
			long long t = offset;
			this->_einfo.SystemInfo = GetData<ESection_SystemInfo>(data, t);
		}
		else if (strcmp(Block_Name, "用户信息段") == 0)
			this->GetUserInfo(data + offset, &this->_einfo.UserInfo);
		else if (strcmp(Block_Name, "程序资源段") == 0)
			this->GetResources(data + offset, &this->_einfo.Resources);
		else if (strcmp(Block_Name, "程序段") == 0)
		{
			if (isai)
			{
				if (enc)
					this->GetLibraries2(data + offset, this->_einfo.TagStatus.Tags, &this->_einfo.Program);
				else
					this->GetLibraries(data + offset, this->_einfo.TagStatus.Tags, &this->_einfo.Program);
			}
			else
				ptr = data + offset;
		}
		else if (strcmp(Block_Name, "辅助信息段2") == 0)
		{
			UINT len = si.DataLength;
			size_t count = len / sizeof(ESection_TagStatus);
			long long t = offset;
			this->_einfo.TagStatus.Tags.resize(count);
			for (size_t i = 0; i < count; i++)
				this->_einfo.TagStatus.Tags.at(i) = GetData<ESection_TagStatus>(data, t);
			isai = true;
			if (ptr != NULL)
			{
				if (enc)
					this->GetLibraries2(ptr, this->_einfo.TagStatus.Tags, &this->_einfo.Program);
				else
					this->GetLibraries(ptr, this->_einfo.TagStatus.Tags, &this->_einfo.Program);
				ptr = NULL;
			}
		}
		else if (strcmp(Block_Name, "易模块记录段") == 0)
			GetECList(data + offset, &this->_einfo.ECList);
		else if (strcmp(Block_Name, "辅助信息段1") == 0)
		{
			UINT len = si.DataLength;
			size_t count = len / sizeof(ESection_UnitInfo);
			long long t = offset;
			this->_einfo.UnitInfo.UnitInfos.resize(count);
			for (size_t i = 0; i < count; i++)
				this->_einfo.UnitInfo.UnitInfos.at(i) = GetData<ESection_UnitInfo>(data, t);
		}
		else if (strcmp(Block_Name, "辅助信息段3") == 0)
		{
			UINT len = si.DataLength;

			/*
			附加外部文件数量  int 4
			附加文件的字节长度 int 4
			附加文件的名称字节集 char*
			*/

		}
		offset += si.DataLength;
	}
end:
	if (ptr != NULL)
	{
		if (enc)
			this->GetLibraries2(ptr, this->_einfo.TagStatus.Tags, &this->_einfo.Program);
		else
			this->GetLibraries(ptr, this->_einfo.TagStatus.Tags, &this->_einfo.Program);
	}
	this->CallEvent(EVENT_END, NULL);
	return &this->_einfo;
}

LPBYTE ECodeParser::GetDerived(ETAG tag)
{
	vector<UINT> list;
	this->EnumDerived(list, tag);
	UINT len = list.size() * sizeof(UINT);
	LPBYTE data = (LPBYTE)LocalAlloc(LMEM_ZEROINIT, len + 8);
	if (!data)return 0;
	LPUINT ptr = list.begin()._Ptr;
	memcpy(data + 8, ptr, len);
	*((LPINT)data) = 1;
	*(((LPINT)data) + 1) = list.size();
	return data;
}

EBase* ECodeParser::FindEBase(ETAG tag)
{
	EBase* base = NULL;
	switch (tag.Type2)
	{
	case Class:
	case StaticClass:
	{
		base = FindInfo(this->_einfo.Program.Assemblies, tag);
		break;
	}
	case Dll:
	{
		base = FindInfo(this->_einfo.Program.Dlls, tag);
		break;
	}
	case Struct:
	{
		base = FindInfo(this->_einfo.Program.Structs, tag);
		break;
	}
	case Method:
	{
		//base = FindInfo(this->_einfo.Program.Methods, tag);
		auto iter = this->_einfo.Program.Methods_map.find((UINT)tag);
		if (iter != this->_einfo.Program.Methods_map.end())
		{
			base = (EBase*)&(this->_einfo.Program.Methods.at(iter->second));
		}

		break;
	}
	case GlobalField:
	{
		base = FindInfo(this->_einfo.Program.GlobalVariables, tag);
		break;
	}
	case Const:
	{
		base = FindInfo(this->_einfo.Resources.Constants.Const, tag);
		break;
	}
	case Image:
	case Music:
	{
		base = FindInfo(this->_einfo.Resources.Constants.Data, tag);
		break;
	}
	case Window:
	{
		base = FindInfo(this->_einfo.Resources.Forms, tag);
		break;
	}
	}
	return base;
}
LPSTR ECodeParser::EMethodCode2Code(ETAG tag)
{
	ESection_Program_Method* method = FindInfo(this->_einfo.Program.Methods, tag);
	if (method != NULL)
	{
		string code = "";
		code.append(this->Code2Str(*method));
		return Ptr2Str(&code);
	}
	return NULL;
}

// 把ESection_Program_Method转换成子程序文本代码,包括子程序头,参数,变量,代码
// 返回 LocalAlloc() 申请的内存字符串,调用方不使用时需要调用 LocalFree() 释放
LPSTR ECodeParser::EMethod2Code(ETAG tag)
{
	ESection_Program_Method* method = FindInfo(this->_einfo.Program.Methods, tag);
	if (method != NULL)
	{
		string code;
		code.append(".子程序 ");
		code.append(method->Name);
		code.append(", ");
		code.append(this->Type2Name(method->ReturnType));
		code.append(", ");
		if (method->Attributes & EMethodAttr::M_Public)
			code.append("公开");
		code.append(", ");
		code.append(method->Remark);
		code.append("\n");
		for (ESection_Variable& item : method->Parameters)
		{
			code.append(".参数 ");
			code.append(item.Name);
			code.append(", ");
			code.append(this->Type2Name(item.DataType));
			code.append(", ");
			bool hasAttr = false;
			if (item.Attributes & EVariableAttr::V_Out)
			{
				code.append("参考");
				hasAttr = true;
			}
			if (item.Attributes & EVariableAttr::V_Optional)
			{
				code.append(hasAttr ? " 可空" : "可空");
				hasAttr = true;
			}
			if (item.Attributes & EVariableAttr::V_Array)
				code.append(hasAttr ? " 数组" : "数组");
			code.append(", ");
			code.append(item.Remark);
			code.append("\n");
		}
		for (ESection_Variable& item : method->Variables)
		{
			code.append(".局部变量 ");
			code.append(item.Name);
			code.append(", ");
			code.append(this->Type2Name(item.DataType));
			code.append(", ");
			if (item.Attributes & EVariableAttr::V_Static)
				code.append("静态");
			code.append(", ");
			if (item.ArrayInfo.Dimension > 0 && item.ArrayInfo.Subscript.size() > 0)
			{
				code.append("\"");
				bool first = true;
				for (UINT item : item.ArrayInfo.Subscript)
				{
					if (first)
						first = false;
					else
						code.append(",");
					code.append(to_string(item));
				}
				code.append("\"");
			}
			code.append(", ");
			code.append(item.Remark);
			code.append("\n");
		}
		code.append("\n");
		code.append(this->Code2Str(*method));
		return Ptr2Str(&code);
	}
	return NULL;
}

HWND ECodeParser::EForm2Window(ETAG tag)
{
	ESection_Resources_Form* form = FindInfo(this->_einfo.Resources.Forms, tag);
	if (form != NULL)
	{
		HUNIT window = NULL;
		HWND hParentWnd = NULL;
		for (ESection_Resources_FormElement& item : form->Elements)
		{
			PLIB_DATA_TYPE_INFO info = this->FindLibDataType(item.Type.LibID - 1, item.Type.ID - 1);
			if (info != NULL)
			{
				PFN_CREATE_UNIT createUnit = (PFN_CREATE_UNIT)info->m_pfnGetInterface(ITF_CREATE_UNIT);
				HUNIT hUnit = createUnit(item.Data.begin()._Ptr, item.Data.size(), CNV_NULL, hParentWnd, 0, 0, item.Left, item.Top, item.Width, item.Height, form->Tag, item.Tag, 0, FALSE);
				if (hUnit != NULL)
				{
					HWND hWnd = *(HWND*)(hUnit + 28);
					if (window == NULL)
					{
						window = hUnit;
						hParentWnd = hWnd;
					}
					ShowWindow(hWnd, item.Status & EElementStatus::E_Visible ? SW_SHOWNA : SW_HIDE);
				}
				else if (window == NULL)
					break;
			}
		}
		return hParentWnd;
	}
	return NULL;
}

void ECodeParser::AddDerived(ETAG key, ETAG value)
{
	if (key != NULL)
		this->_inherit[key].push_back(value);
}

void ECodeParser::EnumDerived(vector<UINT>& list, ETAG tag)
{
	if (tag != NULL)
	{
		for (UINT item : this->_inherit[tag])
		{
			if (find(list.begin(), list.end(), item) == list.end())
			{
				list.push_back(item);
				this->EnumDerived(list, item);
			}
		}
	}
}

// 获取支持库的 GetNewInf() 接口返回的值
PLIB_INFO ECodeParser::FindLibInfo(string& libName)
{
	PLIB_INFO info = NULL;
	map<string, PLIB_INFO>::iterator it = this->_libInfo.find(libName);
	if (it == this->_libInfo.end())
	{
		string modName = libName + ".fne";
		HMODULE mod;
		if (this->_eroot.empty())
			mod = GetModuleHandle(modName.c_str());
		else
		{
			string modPath = this->_eroot + "lib\\" + modName;
			if (libName == "krnln")
			{
				char buffer[MAX_PATH];
				GetTempPath(MAX_PATH, buffer);
				string tmpPath = buffer;
				tmpPath += modName;
				CopyFile(modName.c_str(), tmpPath.c_str(), TRUE);
				modName = tmpPath;
			}
			mod = LoadLibrary(modPath.c_str());
		}
		if (mod != NULL)
		{
			PFN_GET_LIB_INFO getLibInfo = (PFN_GET_LIB_INFO)GetProcAddress(mod, "GetNewInf");
			if (getLibInfo != NULL)
			{
				info = getLibInfo();
				if (info != NULL)
					this->_libInfo.insert(pair<string, PLIB_INFO>(libName, info));
			}
		}
	}
	else
		info = it->second;
	return info;
}

PCMD_INFO ECodeParser::FindLibCmd(USHORT libID, UINT id)
{
	PCMD_INFO cmdInfo = NULL;
	if (libID < this->_einfo.Program.Libraries.size())
	{
		ESection_Library& lib = this->_einfo.Program.Libraries[libID];
		PLIB_INFO info = FindLibInfo(lib.FileName);
		if (info != NULL)
		{
			if (id < info->m_nCmdCount)
				cmdInfo = info->m_pBeginCmdInfo + id;
		}
	}
	return cmdInfo;
}

PLIB_DATA_TYPE_INFO ECodeParser::FindLibDataType(USHORT libID, USHORT id)
{
	PLIB_DATA_TYPE_INFO dataTypeInfo = NULL;
	if (libID < this->_einfo.Program.Libraries.size())
	{
		ESection_Library& lib = this->_einfo.Program.Libraries[libID];
		PLIB_INFO info = FindLibInfo(lib.FileName);
		if (info != NULL)
		{
			if (id < info->m_nDataTypeCount)
				dataTypeInfo = info->m_pDataType + id;
		}
	}
	return dataTypeInfo;
}

PLIB_CONST_INFO ECodeParser::FindLibConst(USHORT libID, USHORT id)
{
	PLIB_CONST_INFO constInfo = NULL;
	if (libID < this->_einfo.Program.Libraries.size())
	{
		ESection_Library& lib = this->_einfo.Program.Libraries[libID];
		PLIB_INFO info = FindLibInfo(lib.FileName);
		if (info != NULL)
		{
			if (id < info->m_nLibConstCount)
				constInfo = info->m_pLibConst + id;
		}
	}
	return constInfo;
}

string ECodeParser::CustomType2Name(ETAG type)
{
	string name;
	switch (type.Type2)
	{
	case StaticClass:
	case Class:
	{
		ESection_Program_Assembly* info = FindInfo(this->_einfo.Program.Assemblies, type);
		if (info != NULL)
			name = info->Name;
		break;
	}
	case Struct:
	{
		ESection_Program_Assembly* info = FindInfo(this->_einfo.Program.Structs, type);
		if (info != NULL)
			name = info->Name;
		break;
	}
	default:
	{
		LIBTAG libType = (LIBTAG)type;
		PLIB_DATA_TYPE_INFO info = FindLibDataType(libType.LibID - 1, libType.ID - 1);
		if (info != NULL)
			name = info->m_szName;
		break;
	}
	}
	return name;
}

string ECodeParser::Type2Name(DataType type)
{
	string name;
	switch (type)
	{
	case EDT_VOID:
		break;
	case EDT_ALL:
		name = "通用型";
		break;
	case EDT_BYTE:
		name = "字节型";
		break;
	case EDT_SHORT:
		name = "短整数型";
		break;
	case EDT_INT:
		name = "整数型";
		break;
	case EDT_LONG:
		name = "长整数型";
		break;
	case EDT_FLOAT:
		name = "小数型";
		break;
	case EDT_DOUBLE:
		name = "双精度小数型";
		break;
	case EDT_BOOL:
		name = "逻辑型";
		break;
	case EDT_DATETIME:
		name = "日期时间型";
		break;
	case EDT_TEXT:
		name = "文本型";
		break;
	case EDT_BIN:
		name = "字节集";
		break;
	case EDT_SUBPTR:
		name = "子程序指针";
		break;
	default:
		name = CustomType2Name(type);
		break;
	}
	return name;
}

string ECodeParser::Var2Name(ETAG tag, ESection_Program_Method& method)
{
	string name;
	switch (tag.Type2)
	{
	case Variable:
	{
		ESection_Variable* var = FindInfo<ESection_Variable>(method.Parameters, tag);
		if (var == NULL)
			var = FindInfo<ESection_Variable>(method.Variables, tag);
		if (var != NULL)
			name = var->Name;
		break;
	}
	case Field:
	{
		ESection_Program_Assembly* info = FindInfo(this->_einfo.Program.Assemblies, method.Class);
		if (info != NULL)
		{
			ESection_Variable* var = info->FindField(tag);
			if (var != NULL)
				name = var->Name;
		}
		break;
	}
	case GlobalField:
	{
		ESection_Variable* var = FindInfo(this->_einfo.Program.GlobalVariables, tag);
		if (var != NULL)
			name = var->Name;
		break;
	}
	case Window:
	{
		ESection_Resources_Form* form = FindInfo(this->_einfo.Resources.Forms, tag);
		if (form != NULL)
			name = form->Name;
		break;
	}
	case Element:
	{
		//如果是一个窗口元素，也就是窗口里面的组件，则需要单独的进行寻找，得到其名字。
		for (ESection_Resources_Form& varForm : this->_einfo.Resources.Forms)
		{
			for (ESection_Resources_FormElement& var : varForm.Elements)
			{
				if (static_cast<EBase>(var).Tag == tag)
				{
					ESection_Resources_FormElement* FormElement = &var;
					if (FormElement != NULL)
						name = FormElement->Name;
					break;
				}
			}
		}

		break;
	}
	default:
		break;
	}
	return name;
}

string ECodeParser::Method2Name(ETAG tag, short libID)
{
	string name;
	switch (libID)
	{
	case CUSTOM:
	{
		ESection_Program_Method* info = FindInfo(this->_einfo.Program.Methods, tag);
		if (info != NULL)
			name = info->Name;
		break;
	}
	case DLL:
	{
		ESection_Program_Dll* info = FindInfo(this->_einfo.Program.Dlls, tag);
		if (info != NULL)
			name = info->Name;
		break;
	}
	case REMARK:
		break;
	default:
	{
		PCMD_INFO info = FindLibCmd((USHORT)libID, tag);
		if (info != NULL)
			name = info->m_szName;
		break;
	}
	}
	return name;
}

string ECodeParser::Const2Name(ETAG tag)
{
	string name;
	switch (tag.Type2)
	{
	case Const:
	{
		ESection_Resources_Const* info = FindInfo(this->_einfo.Resources.Constants.Const, tag);
		if (info != NULL)
			name = info->Name;
		break;
	}
	case Image:
	case Music:
	{
		ESection_Resources_Data* info = FindInfo(this->_einfo.Resources.Constants.Data, tag);
		if (info != NULL)
			name = info->Name;
		break;
	}
	default:
		break;
	}
	return name;
}

string ECodeParser::LibConst2Name(LIBCONST libConst)
{
	string name;
	PLIB_CONST_INFO info = FindLibConst(libConst.LibID - 1, libConst.ID - 1);
	if (info != NULL)
		name = info->m_szName;
	return name;
}

string ECodeParser::LibConstStruct2Name(LIBCONSTSTRUCT libConst)
{
	string name;
	PLIB_DATA_TYPE_INFO info = FindLibDataType(libConst.LibType.LibID - 1, libConst.LibType.ID - 1);
	if (info != NULL)
	{
		name.append(info->m_szName);
		name.append(".");
		if (libConst.Index > 0 && libConst.Index <= info->m_nElementCount)
			name.append(info->m_pElementBegin[libConst.Index - 1].m_szName);
	}
	return name;
}

string ECodeParser::DateTime2Str(double dt)
{
	string codeStr;
	SYSTEMTIME t;
	VariantTimeToSystemTime(dt, &t);
	if (t.wSecond != 0)
		codeStr = to_string(t.wSecond) + "秒";
	if (t.wMinute != 0)
		codeStr.insert(0, to_string(t.wMinute) + "分");
	if (t.wHour != 0)
		codeStr.insert(0, to_string(t.wHour) + "时");
	codeStr.insert(0, to_string(t.wDay) + "日");
	codeStr.insert(0, to_string(t.wMonth) + "月");
	codeStr.insert(0, to_string(t.wYear) + "年");
	codeStr.insert(0, "[");
	codeStr.append("]");
	return codeStr;
}

string ECodeParser::Num2Str(double num)
{
	string codeStr;
	const double eps = 1e-10;
	int i = (int)num;
	if (num - i < eps)
		codeStr = to_string(i);
	else
		codeStr = to_string(num);
	return codeStr;
}

string ECodeParser::FormatMethodCode(ETAG tag, short libID, vector<string>& params)
{
	string codeStr;
	if (libID == 0)
	{
#define OPERATOR(p, op) codeStr.append(p[0] + " "#op" " + p[1])
		switch ((krnln_method)(UINT)tag)
		{
		case 求余数:
			OPERATOR(params, ％);
			break;
		case 相加:
			OPERATOR(params, ＋);
			break;
		case 相减:
			OPERATOR(params, －);
			break;
		case 负:
			codeStr.append("－" + params[0]);
			break;
		case 相乘:
			OPERATOR(params, ×);
			break;
		case 相除:
			OPERATOR(params, ÷);
			break;
		case 整除:
			OPERATOR(params, ＼);
			break;
		case 等于:
			OPERATOR(params, ＝);
			break;
		case 不等于:
			OPERATOR(params, ≠);
			break;
		case 小于:
			OPERATOR(params, ＜);
			break;
		case 大于:
			OPERATOR(params, ＞);
			break;
		case 小于或等于:
			OPERATOR(params, ≤);
			break;
		case 大于或等于:
			OPERATOR(params, ≥);
			break;
		case 近似等于:
			OPERATOR(params, ≈);
			break;
		case 并且:
			OPERATOR(params, 且);
			break;
		case 或者:
			OPERATOR(params, 或);
			break;
		case 赋值:
			OPERATOR(params, ＝);
			break;
		default:
			goto defaultFormat;
		}
	}
	else if (libID == REMARK)
	{

	}
	else
	{
	defaultFormat:
		codeStr.append(this->Method2Name(tag, libID));
		codeStr.append(" (");
		codeStr.append(join(params, ", "));
		codeStr.append(")");
	}
	return codeStr;
}

string ECodeParser::Var2Str(ESection_Program_Method& method, LPBYTE& code, LPBYTE end)
{
	ETAG tag = GetData<ETAG>(code);
	string codeStr = this->Var2Name(tag, method);
	do
	{
		ECode_Type type = GetData<ECode_Type>(code);
		switch (type)
		{
		case ECode_Type::ParameterEnd:
			goto varend;
		case ECode_Type::ArrayBegin:
			codeStr.append(" [");
			switch (GetData<ECode_Type>(code))
			{
			case ECode_Type::NumberIndex:
				codeStr.append(to_string(GetData<int>(code)));
				break;
			case ECode_Type::ParameterBegin:
				codeStr.append(Var2Str(method, code, end));
				break;
			case ECode_Type::Method:
				codeStr.append(Call2Str(method, code, end));
				break;
			}
			codeStr.append("]");
			break;
		case ECode_Type::Field:
		{
			codeStr.append(".");
			EKeyValPair kv = GetData<EKeyValPair>(code);
			switch (kv.Key.Type2)
			{
			case Struct:
			{
				ESection_Program_Assembly* info = FindInfo(this->_einfo.Program.Structs, kv.Key);
				if (info != NULL)
				{
					ESection_Variable* var = info->FindField(kv.Value);
					if (var != NULL)
						codeStr.append(var->Name);
				}
				break;
			}
			case Window:
			{
				ESection_Resources_Form* form = FindInfo(this->_einfo.Resources.Forms, kv.Key);
				if (form != NULL)
				{
					ESection_Resources_FormElement* element = FindInfo(form->Elements, kv.Value);
					if (element != NULL)
					{
						codeStr.append(element->Name);
					}
					else
					{
						//PLIB_DATA_TYPE_INFO info = FindLibDataType(kv.Key.ID - 1, kv.Key.Type1 - 1);
						LIBTAG libType = (LIBTAG)kv.Key;
						PLIB_DATA_TYPE_INFO info = FindLibDataType(libType.LibID - 1, kv.Key.Type1 - 1);
						if (info != NULL)
						{
							UNIT_PROPERTY* prop = (UNIT_PROPERTY*)(info->m_pPropertyBegin + kv.Value.ID - 1);
							codeStr.append(prop->m_szName);
						}
					}
				}
				break;
			}
			default:
			{
				if (tag.Type2 == ETYPE::Window || tag.Type2 == ETYPE::Element)
				{
					//如果解析出来的本属性是一个window或者 Element , 则需要根据id到支持库中查找对应的内容文本。
					LIBTAG libType = (LIBTAG)kv.Key;
					PLIB_DATA_TYPE_INFO info = FindLibDataType(libType.LibID - 1, libType.ID - 1);
					if (info != NULL)
					{
						UNIT_PROPERTY* prop = (UNIT_PROPERTY*)(info->m_pPropertyBegin + kv.Value.ID - 1);
						codeStr.append(prop->m_szName);
					}
					break;

				}
				else
				{
					LIBTAG libType = (LIBTAG)kv.Key;
					PLIB_DATA_TYPE_INFO info = FindLibDataType(libType.LibID - 1, libType.ID - 1);
					if (info != NULL)
						codeStr.append(info->m_szName);
					break;
				}
			}
			}
			break;
		}
		}
	} while (code < end);
varend:;
	return codeStr;
}

// 子程序调用命令解析
string ECodeParser::Call2Str(ESection_Program_Method& method, LPBYTE& code, LPBYTE end)
{
	string codeStr;
	UINT etag = GetData<UINT>(code);
	short LibID = GetData<short>(code);
	UINT len;
	USHORT tag = GetData<USHORT>(code);
	GetNoZeroString(code, &codeStr, true);
	string remark;
	GetNoZeroString(code, &remark);
	ECode_Type head = GetData<ECode_Type>(code);
	if (head == ECode_Type::ParameterBegin)
		codeStr.append(this->Var2Str(method, code, end));
	if (head == ECode_Type::ParamBegin || head == ECode_Type::ParameterBegin)	// 参数开始
	{
		vector<string> paramList;
		do
		{
			string paramStr;
			ECode_Type t = GetData<ECode_Type>(code);
			switch (t)
			{
			case ECode_Type::NullParam:
				break;
			case ECode_Type::NumberConst:
				paramStr = this->Num2Str(GetData<double>(code));
				break;
			case ECode_Type::DatetimeConst:
				paramStr = this->DateTime2Str(GetData<double>(code));
				break;
			case ECode_Type::BoolConst:
				paramStr = GetData<short>(code) == 0 ? "假" : "真";
				break;
			case ECode_Type::StringConst:
				paramStr = "“";
				GetNoZeroString(code, &paramStr, true);
				paramStr += "”";
				break;
			case ECode_Type::Variable:
				if (GetData<ECode_Type>(code) == ECode_Type::ParameterBegin)
					paramStr = this->Var2Str(method, code, end);
				break;
			case ECode_Type::BinConst:
			{
				paramStr = "{ ";
				bool first = true;
				do
				{
					switch (GetData<ECode_Type>(code))
					{
					case ECode_Type::NumberConst:
						if (first)
							first = false;
						else
							paramStr.append(", ");
						paramStr.append(this->Num2Str(GetData<double>(code)));
						break;
					case ECode_Type::BinEnd:
						goto binend;
					}
				} while (code < end);
			binend:
				paramStr.append(" }");
				break;
			}
			case ECode_Type::Method:
				paramStr = this->Call2Str(method, code, end);
				break;
			case ECode_Type::ParamEnd:
				goto paramend;
			case ECode_Type::Const:
				paramStr = "#" + this->Const2Name(GetData<ETAG>(code));
				break;
			case ECode_Type::n4:
				code += sizeof(ETAG);
				break;
			case ECode_Type::LibConst:
				paramStr = "#" + this->LibConst2Name(GetData<LIBCONST>(code));
				break;
			case ECode_Type::LibConstStruct:
				paramStr = "#" + this->LibConstStruct2Name(GetData<LIBCONSTSTRUCT>(code));
				break;
			default:
				continue;
			}
			paramList.push_back(paramStr);
		} while (code < end);
	paramend:
		if (tag == 0)
			codeStr.append(this->FormatMethodCode(etag, LibID, paramList));
	}
	if (remark.empty() == false)
	{
		codeStr.append(LibID == REMARK ? "' " : "  ' ");
		codeStr.append(remark);
	}
	if (remark.empty() && codeStr.empty())
	{
		int a = 0;//空行!?
	}
	return codeStr;
}

// 把数据转换成文本的代码,代码块,不包含子程序头和参数变量
string ECodeParser::Code2Str(ESection_Program_Method& method)
{
	string codeStr;
	LPBYTE begin = method.Code.cbegin()._Ptr;
	LPBYTE end = method.Code.cend()._Ptr;
	LPBYTE ptr = begin;
	int level = 0;
#define INDENT(level) codeStr.append((level) * 4, ' ')
	while (ptr < end)
	{
		const  char* str = codeStr.c_str();
		OutputDebugStringA(str);
		if (codeStr.find("公提取数据") != -1)
		{
			int c = 3;
		}
		BYTE bt = GetData<BYTE>(ptr);
		//printf("byte:%d\n", bt);
		switch (bt)
		{
		case Call:
			INDENT(level);
			codeStr.append(this->Call2Str(method, ptr, end));
			break;
		case If:
			INDENT(level);
			codeStr.append(".");
			codeStr.append(this->Call2Str(method, ptr, end));
			level++;
			break;
		case IfEnd:
			level--;
			INDENT(level);
			codeStr.append(".如果真结束");
			break;
		case Ife:
			INDENT(level);
			codeStr.append(".");
			codeStr.append(this->Call2Str(method, ptr, end));
			level++;
			break;
		case IfeElse:
			INDENT(level - 1);
			codeStr.append(".否则");
			break;
		case IfeEnd:
			level--;
			INDENT(level);
			codeStr.append(".如果结束");
			break;
		case SwitchBegin:
			INDENT(level);
			if (GetData<BYTE>(ptr) == Switch)
			{
				codeStr.append(".判断开始");
				codeStr.append(this->Call2Str(method, ptr, end).erase(0, 4));
			}
			level++;
			break;
		case Switch:
			INDENT(level - 1);
			codeStr.append(".");
			codeStr.append(this->Call2Str(method, ptr, end));
			break;
		case SwitchDefault:
			INDENT(level - 1);
			codeStr.append(".默认");
			break;
		case SwitchEnd:
			level--;
			INDENT(level);
			codeStr.append(".判断结束");
			break;
		case LoopBegin:
			INDENT(level);
			codeStr.append(".");
			codeStr.append(this->Call2Str(method, ptr, end));
			level++;
			break;
		case LoopEnd:
			level--;
			INDENT(level);
			codeStr.append(".");
			codeStr.append(this->Call2Str(method, ptr, end));
			break;
		default:
			continue;
		}
		codeStr.append("\n");
	}
	return codeStr;
}

// 获取变量/参数/成员数据,包括名字,数据类型,备注,属性
void ECodeParser::GetVariables(LPBYTE& pointer, vector<ESection_Variable>* result)
{
	UINT count = GetData<UINT>(pointer);
	UINT length = GetData<UINT>(pointer);
	LPBYTE oldptr = pointer + length;
	if (result != NULL)
	{
		result->resize(count);
		ETAG* tags = new ETAG[count];
		LPBYTE* os = new LPBYTE[count];
		for (size_t i = 0; i < count; i++)
			tags[i] = GetData<ETAG>(pointer);
		LPBYTE mptr = pointer + count * sizeof(UINT);
		for (size_t i = 0; i < count; i++)
			os[i] = mptr + GetData<UINT>(pointer);
		for (size_t i = 0; i < count; i++)
		{
			ESection_Variable& sv = result->at(i);
			pointer = os[i];
			UINT size = GetData<UINT>(pointer);
			sv.Tag = tags[i];
			sv.DataType = GetData<DataType>(pointer);
			sv.Attributes = GetData<EVariableAttr>(pointer);
			sv.ArrayInfo.Dimension = GetData<BYTE>(pointer);
			for (size_t n = 0; n < sv.ArrayInfo.Dimension; n++)
				sv.ArrayInfo.Subscript.push_back(GetData<UINT>(pointer));
			GetAutoString(pointer, &sv.Name);
			GetAutoString(pointer, &sv.Remark);
			if (sv.Tag.Type2 == ETYPE::GlobalField && sv.Name.size())
				this->CallEvent(EVENT_GLOBAL, &sv);
		}
		delete[] tags;
		delete[] os;
	}
	pointer = oldptr;
}

// 获取程序集
void ECodeParser::GetAssemblies(LPBYTE& pointer, vector<ESection_TagStatus>& tagstatus, vector<ESection_Program_Assembly>* result, vector<ESection_Program_Assembly>* refer, bool isclass)
{
	UINT length = GetData<UINT>(pointer) / 2;
	size_t count = length / sizeof(ETAG);
	ETAG* tags = new ETAG[count];
	for (size_t i = 0; i < count; i++)
		tags[i] = GetData<ETAG>(pointer);
	pointer += length;
	result->resize(count);
	for (size_t i = 0; i < count; i++)
	{
		ESection_Program_Assembly& spa = result->at(i);
		spa.Tag = tags[i];
		if (spa.Tag.Type2 == ETYPE::WindowClass)
		{
			spa.Base = GetData<ETAG>(pointer);
			pointer += 4;
		}
		else
		{
			spa.Status = GetData<ETagStatus>(pointer);
			if (isclass)
				spa.Base = GetData<ETAG>(pointer);
		}
		GetString(pointer, &spa.Name);
		GetString(pointer, &spa.Remark);
		if (isclass)
		{
			length = GetData<UINT>(pointer);
			size_t size = length / sizeof(ETAG);
			for (size_t n = 0; n < size; n++)
				spa.Methods.push_back(GetData<ETAG>(pointer));
		}
		GetVariables(pointer, &spa.Variables);
		if (refer != NULL)
		{
			if ((spa.Status & ETagStatus::C_Extern) == ETagStatus::C_Extern)
			{
			referadd:
				refer->push_back(spa);
			}
			else
			{
				ESection_TagStatus* status = FindInfo(tagstatus, spa.Tag);
				if (status != NULL && (status->Status & ETagStatus::C_Extern) == ETagStatus::C_Extern)
					goto referadd;
				else goto add;
			}
		}
		else
		{
		add:
			switch (spa.Tag.Type2)
			{
			case ETYPE::Class:
				this->AddDerived(spa.Base, spa.Tag);
				if (spa.Name.size())
					this->CallEvent(EVENT_CLASS, &spa);
				break;
			case ETYPE::Struct:
				if (spa.Name.size())
					this->CallEvent(EVENT_STRUCT, &spa);
			default:
				this->CallEvent(EVENT_ASSEMBLY, &spa);
				break;
			}
		}
	}
	delete[] tags;
}

// 取子程序数据,包括dll名,调用的库,调用的名字,备注,参数
//void ECodeParser::GetMethods(LPBYTE& pointer, vector<ESection_Program_Method>* result, vector<ESection_Program_Method>* refer, bool callback)
void ECodeParser::GetMethods(LPBYTE& pointer, vector<ESection_Program_Method>* result, map<UINT, int>* methods_map, vector<ESection_Program_Method>* refer, bool callback)
{
	UINT length = GetData<UINT>(pointer) / 2;
	size_t count = length / sizeof(ETAG);
	ETAG* tags = new ETAG[count];
	for (size_t i = 0; i < count; i++)
		tags[i] = GetData<ETAG>(pointer);
	pointer += length;
	result->resize(count);
	//methods_map->clear();
	for (size_t i = 0; i < count; i++)
	{
		ESection_Program_Method& spm = result->at(i);
		spm.Tag = tags[i];
		methods_map->insert(pair<UINT, int>((UINT)spm.Tag, (int)i));
		spm.Class = GetData<ETAG>(pointer);
		spm.Attributes = GetData<EMethodAttr>(pointer);
		spm.ReturnType = GetData<DataType>(pointer);
		GetString(pointer, &spm.Name);
		GetString(pointer, &spm.Remark);
		GetVariables(pointer, &spm.Variables);
		GetVariables(pointer, &spm.Parameters);
		GetBytes(pointer, &spm.RowOffset);
		GetBytes(pointer, &spm.FlowOffset);
		GetBytes(pointer, &spm.MethodOffset);
		GetBytes(pointer, &spm.VariableOffset);
		GetBytes(pointer, &spm.ParameterOffset);
		GetBytes(pointer, &spm.Code);
		if (refer != NULL && (spm.Attributes & EMethodAttr::M_Extern) == EMethodAttr::M_Extern)
			refer->push_back(spm);
		else
		{
			if (callback && spm.Name.size())
				this->CallEvent(EVENT_METHOD, &spm);
		}
	}
	delete[] tags;
}

// 取DLL数据,包括dll名,调用的库,调用的名字,备注,参数
void ECodeParser::GetDlls(LPBYTE& pointer, vector<ESection_Program_Dll>* result)
{
	UINT length = GetData<UINT>(pointer) / 2;
	size_t count = length / sizeof(ETAG);
	ETAG* tags = new ETAG[count];
	for (size_t i = 0; i < count; i++)
		tags[i] = GetData<ETAG>(pointer);
	pointer += length;
	result->resize(count);
	for (size_t i = 0; i < count; i++)
	{
		ESection_Program_Dll& spd = result->at(i);
		spd.Tag = tags[i];
		spd.Status = GetData<ETagStatus>(pointer);
		spd.ReturnType = GetData<DataType>(pointer);
		GetString(pointer, &spd.ShowName);
		GetString(pointer, &spd.Remark);
		GetString(pointer, &spd.Lib);
		GetString(pointer, &spd.Name);
		GetVariables(pointer, &spd.Parameters);
		if (spd.ShowName.size())
			this->CallEvent(EVENT_DLL, &spd);
	}
	delete[] tags;
}

void ECodeParser::GetElements(LPBYTE& pointer, vector<ESection_Resources_FormElement>* result)
{
	UINT count = GetData<UINT>(pointer);
	UINT length = GetData<UINT>(pointer);
	LPBYTE oldptr = pointer + length;
	if (result != NULL)
	{
		ETAG* tags = new ETAG[count];
		LPBYTE* os = new byte * [count];
		for (size_t i = 0; i < count; i++)
			tags[i] = GetData<ETAG>(pointer);
		LPBYTE mptr = pointer + count * sizeof(UINT);
		for (size_t i = 0; i < count; i++)
			os[i] = mptr + GetData<UINT>(pointer);
		result->resize(count);
		for (size_t i = 0; i < count; i++)
		{
			ESection_Resources_FormElement& sre = result->at(i);
			pointer = os[i];
			UINT size = GetData<UINT>(pointer);
			LPBYTE end = pointer + size;
			sre.Tag = tags[i];
			sre.Type = GetData<LIBTAG>(pointer);
			pointer += 20;
			GetAutoString(pointer, &sre.Name);
			GetAutoString(pointer, &sre.Remark);
			pointer += 4;
			sre.Left = GetData<UINT>(pointer);
			sre.Top = GetData<UINT>(pointer);
			sre.Width = GetData<UINT>(pointer);
			sre.Height = GetData<UINT>(pointer);
			pointer += 12;
			GetBytes(pointer, &sre.Cursor);
			GetAutoString(pointer, &sre.Mark);
			pointer += 4;
			sre.Status = GetData<EElementStatus>(pointer);
			pointer += 4;
			size = GetData<UINT>(pointer);
			for (size_t i = 0; i < size; i++)
				sre.Events.push_back(GetData<EKeyValPair>(pointer));
			pointer += 20;
			GetBytes(pointer, end - pointer, &sre.Data);
		}
		delete[] tags;
		delete[] os;
	}
	pointer = oldptr;
}

// 获取窗口数据
void ECodeParser::GetForms(LPBYTE& pointer, vector<ESection_Resources_Form>* result, bool jump)
{
	UINT length = GetData<UINT>(pointer) / 2;
	size_t count = length / sizeof(ETAG);
	ETAG* tags = new ETAG[count];
	for (size_t i = 0; i < count; i++)
		tags[i] = GetData<ETAG>(pointer);
	pointer += length;
	result->resize(count);
	for (size_t i = 0; i < count; i++)
	{
		ESection_Resources_Form& srf = result->at(i);
		srf.Tag = tags[i];
		pointer += 4;
		srf.Class = GetData<ETAG>(pointer);
		GetString(pointer, &srf.Name);
		GetString(pointer, &srf.Remark);
		if (jump)
			GetElements(pointer, NULL);
		else
			GetElements(pointer, &srf.Elements);
		if (srf.Name.size())
			this->CallEvent(EVENT_WINDOW, &srf);
	}
	delete[] tags;
}

// 获取常量数据
void ECodeParser::GetConst(LPBYTE& pointer, ESection_ResourcesConst* result)
{
	UINT count = GetData<UINT>(pointer);
	UINT length = GetData<UINT>(pointer);
	LPBYTE oldptr = pointer + length;
	ETAG* tags = new ETAG[count];
	LPBYTE* os = new byte * [count];
	for (size_t i = 0; i < count; i++)
		tags[i] = GetData<ETAG>(pointer);
	LPBYTE mptr = pointer + count * sizeof(UINT);
	for (size_t i = 0; i < count; i++)
		os[i] = mptr + GetData<UINT>(pointer);
	result->Const.reserve(count);
	result->Data.reserve(count);
	for (size_t i = 0; i < count; i++)
	{
		ETAG tag = tags[i];
		pointer = os[i];
		GetData<UINT>(pointer);
		switch (tag.Type2)
		{
		case ETYPE::Const:
		{
			size_t n = result->Const.size();
			result->Const.resize(n + 1);
			ESection_Resources_Const& srb = result->Const.at(n);
			srb.Tag = tag;
			srb.Attr = GetData<EConstAttr>(pointer);
			GetAutoString(pointer, &srb.Name);
			GetAutoString(pointer, &srb.Remark);
			srb.Type = GetData<EConstType>(pointer);
			switch (srb.Type)
			{
			case CT_Number:
			case CT_DateTime:
				GetBytes(pointer, 8, &srb.Data);
				break;
			case CT_Bool:
				GetBytes(pointer, 4, &srb.Data);
				break;
			case CT_Text:
				GetBytes(pointer, &srb.Data);
				break;
			}
			if (srb.Name.size())
				this->CallEvent(EVENT_CONST, &srb);
			break;
		}
		case ETYPE::Image:
		case ETYPE::Music:
		{
			size_t n = result->Data.size();
			result->Data.resize(n + 1);
			ESection_Resources_Data& srb = result->Data.at(n);
			srb.Tag = tag;
			srb.Attr = GetData<EConstAttr>(pointer);
			GetAutoString(pointer, &srb.Name);
			GetAutoString(pointer, &srb.Remark);
			GetBytes(pointer, &srb.Data);
			if (srb.Name.size())
				this->CallEvent(EVENT_RESOURCE, &srb);
			break;
		}
		}
	}
	delete[] tags;
	delete[] os;
	pointer = oldptr;
}

// 获取用户段, 在易语言 程序->配置 里的数据
void ECodeParser::GetUserInfo(LPBYTE pointer, ESection_UserInfo* result)
{
	GetString(pointer, &result->ProjectName);
	GetString(pointer, &result->Remark);
	GetString(pointer, &result->Author);
	GetString(pointer, &result->ZipCode);
	GetString(pointer, &result->Address);
	GetString(pointer, &result->Phone);
	GetString(pointer, &result->Fax);
	GetString(pointer, &result->Email);
	GetString(pointer, &result->HomePage);
	GetString(pointer, &result->Copyright);
	result->Major = GetData<UINT>(pointer);
	result->Minor = GetData<UINT>(pointer);
	result->Build = GetData<UINT>(pointer);
	result->Revision = GetData<UINT>(pointer);
	GetString(pointer, NULL);
	result->PluginName = (char*)pointer;
	this->CallEvent(EVENT_INFO, result);
}

// 获取源码程序段的信息,由 Parse() 调用
void ECodeParser::GetLibraries(LPBYTE pointer, vector<ESection_TagStatus>& tagstatus, ESection_Program* result)
{
	pointer += sizeof(UINT);
	pointer += sizeof(UINT);
	GetBytes(pointer, NULL);
	GetBytes(pointer, NULL);
	GetBytes(pointer, NULL);
	USHORT len = GetData<USHORT>(pointer);
	//pointer + 22

	string lib;
	result->Libraries.resize(len);
	for (size_t i = 0; i < len; i++)
	{

		GetString(pointer, &lib);

		//pointer += strLen

		vector<string> arr = split(lib, SP);
		ESection_Library& info = result->Libraries.at(i);
		info.FileName = arr[0];
		info.Guid = arr[1];
		info.Major = atoi(arr[2].c_str());
		info.Minor = atoi(arr[3].c_str());
		info.Name = arr[4];
		this->CallEvent(EVENT_LIB, &info);
	}
	int flag = GetData<int>(pointer);
	pointer += sizeof(UINT);
	if ((flag & 1) != 0) pointer += 16;
	GetBytes(pointer, NULL);
	GetBytes(pointer, NULL);
	GetAssemblies(pointer, tagstatus, &result->Assemblies);
	GetMethods(pointer, &result->Methods, &result->Methods_map);
	GetVariables(pointer, &result->GlobalVariables);
	GetAssemblies(pointer, tagstatus, &result->Structs, NULL, false);
	GetDlls(pointer, &result->Dlls);
}

// 获取剪辑版源码的信息,由 Parse() 调用
void ECodeParser::GetLibraries2(LPBYTE pointer, vector<ESection_TagStatus>& tagstatus, ESection_Program* result)
{
	pointer += sizeof(UINT);
	pointer += sizeof(UINT);
	GetBytes(pointer, NULL);
	pointer += 8;
	GetBytes(pointer, NULL);
	pointer += 8;
	USHORT len = GetData<USHORT>(pointer);
	string lib;
	result->Libraries.resize(len);
	for (size_t i = 0; i < len; i++)
	{
		GetString(pointer, &lib);
		vector<string> arr = split(lib, SP);
		ESection_Library& info = result->Libraries.at(i);
		info.FileName = arr[0];
		info.Guid = arr[1];
		info.Major = atoi(arr[2].c_str());
		info.Minor = atoi(arr[3].c_str());
		info.Name = arr[4];
		this->CallEvent(EVENT_LIB, &info);
	}
	GetBytes(pointer, NULL);
	GetBytes(pointer, NULL);
	pointer += 16;
	GetMethods(pointer, &result->Methods, &result->Methods_map, NULL, false);
	GetDlls(pointer, &result->Dlls);
	GetVariables(pointer, &result->GlobalVariables);
	GetAssemblies(pointer, tagstatus, &result->Assemblies);
	for (ESection_Program_Method& item : result->Methods)
		if (item.Name.size())
			this->CallEvent(EVENT_METHOD, &item);
	GetAssemblies(pointer, tagstatus, &result->Structs, NULL, false);
}

void ECodeParser::GetECList(LPBYTE pointer, ESection_ECList* result)
{
	UINT count = GetData<UINT>(pointer);
	result->List.resize(count);
	for (size_t i = 0; i < count; i++)
	{
		ESection_ECList_Info& info = result->List.at(i);
		pointer += 20;
		GetString(pointer, &info.Name);
		GetString(pointer, &info.Path);
		GetBytes(pointer, NULL);
		GetBytes(pointer, NULL);
		this->CallEvent(EVENT_EC, &info);
	}
}

//  获取程序资源段,包括窗口,资源,常量
void ECodeParser::GetResources(LPBYTE pointer, ESection_Resources* result)
{
	//如果是模块就设置为真
	GetForms(pointer, &result->Forms, true);//设置为false才能正常读取窗口里面的Element
	GetConst(pointer, &result->Constants);
}