⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlfile.cpp.svn-base

📁 wince c++ 下 开发的 rss 阅读器源代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/**
 *  XMLFile.cpp
 *
 *  Copyright (C) 2008  David Andrs <pda@jasnapaka.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifdef PRSSR_APP
	#include "../StdAfx.h"
	#include "../prssr.h"
#endif

#ifdef PRSSR_TODAY
	#include "..\prssrtoday\StdAfx.h"
#endif

#include "XMLFile.h"
#include "../../prssrenc/codepages.h"
#include "../misc.h"
#include "../../share/str.h"

#ifdef MYDEBUG
#undef THIS_FILE
static TCHAR THIS_FILE[] = _T(__FILE__);
#include "../debug/crtdbg.h"
#define new MYDEBUG_NEW
#endif

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// XML default encoding
static char *DefaultEncoding = "utf-8";

static void XMLCALL
startElement(void *userData, const char *name, const char **atts) {
	CXmlFile *xml = (CXmlFile *) userData;
	xml->OnStartElement(name, atts);
}

static void XMLCALL
endElement(void *userData, const char *name) {
	CXmlFile *xml = (CXmlFile *) userData;
	xml->OnEndElement(name);
}

static void XMLCALL
charDataHandler(void *userData, const XML_Char *s, int len) {
	CXmlFile *xml = (CXmlFile *) userData;
	xml->OnCharacterData(s, len);
}

//
// Codepage convert
//

static int XMLCALL
utf8EncodingConvert(void *data, const char *p) {
//	LOG0(1, "utf8EncodingConvert");

	unsigned short c = '?';

	BYTE *a = (BYTE *) p;
//	LOG1(1, "a = %x", a[0]);

	if (a[0] < 0xc0)
		c = a[0];
	else if (a[0] < 0xe0)
		MultiByteToWideChar(CP_UTF8, 0, p, 2, &c, 1);
	else if (a[0] < 0xf0)
		MultiByteToWideChar(CP_UTF8, 0, p, 3, &c, 1);
	else if (a[0] <= 0xf4)
		MultiByteToWideChar(CP_UTF8, 0, p, 4, &c, 1);
	else
		c = a[0];

	return c;
}


static int XMLCALL
unknownEncodingConvert(void *data, const char *p) {
//	LOG0(1, "unknownEncodingConvert");

	unsigned short c;
	if (MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, p, 1, &c, 1) == 1)
		return c;
	return '?';
}

static int XMLCALL
big5EncodingConvert(void *data, const char *p) {
	int c;

	BYTE *cs = (BYTE *) p;
	if (cs[0] < 0x80) {
		// single byte
		c = cs[0];
	}
	else {
		// two bytes
		int idx1 = cs[0] - 0xA1;
		if (cs[1] >= 0x40 && cs[1] <= 0x7E) {
			int idx2 = cs[1] - 0x40;
			c = cpBig5_1[(idx1 * 0x3F) + idx2];
		}
		else if (cs[1] >= 0xA1 && cs[1] <= 0xFE) {
			int idx2 = cs[1] - 0xA1;
			c = cpBig5_2[(idx1 * 0x5E) + idx2];
		}
		else
			c = '?';
	}

	return c;
}

static int XMLCALL
eucJpEncodingConvert(void *data, const char *p) {
	int c;

	BYTE *cs = (BYTE *) p;
	if (cs[0] < 0xA1 || cs[0] == 0xFF) {
		// single byte
		c = cs[0];
	}
	else if (cs[0] == 0x8E) {
		c = 0xFF61 + (cs[1] - 0xA1);
	}
	else {
		// two bytes
		if (cs[0] >= 0xA1 && cs[0] <= 0xFE &&
			cs[1] >= 0xA1 && cs[1] <= 0xFE)
		{
			int idx1 = cs[0] - 0xA1;
			int idx2 = cs[1] - 0xA1;
			c = cpEUC_JP[(idx1 * 0x5E) + idx2];
		}
		else {
			c = '?';
		}
	}

	return c;
}

static int XMLCALL
eucKrEncodingConvert(void *data, const char *p) {
	int c = -1;

	BYTE *cs = (BYTE *) p;
	if (cs[0] <= 0x7E || cs[0] == 0xFF) {
		// single byte
		c = cs[0];
	}
	else if (cs[0] >= 0x81 && cs[0] <= 0xFE) {
		// two bytes
		int idx1 = cs[0] - 0x81;
		if (cs[1] >= 0x41 && cs[1] <= 0x5A) {
			int idx2 = cs[1] - 0x41;
			c = cpEUC_KR1[(idx1 * 0x7E) + idx2];
		}
		else if (cs[1] >= 0x61 && cs[1] <= 0x7A) {
			int idx2 = cs[1] - 0x61;
			c = cpEUC_KR2[(idx1 * 0x7E) + idx2];
		}
		else if (cs[1] >= 0x81 && cs[1] <= 0xFE) {
			int idx2 = cs[1] - 0x81;
			c = cpEUC_KR3[(idx1 * 0x7E) + idx2];
		}
	}

	return c;
}

static int XMLCALL
gbkEncodingConvert(void *data, const char *p) {
	int c;

	BYTE *cs = (BYTE *) p;
	if (cs[0] < 0x80) 					// single byte
		c = cs[0];
	else if (cs[0] == 0x80)
		c = 0x20AC;						// euro sign
	else {
		// two bytes (the first is the index of the subtable, the second is the character inside the subtable)
		int idx = ((cs[0] - 0x81) * 0xC0) + (cs[1] - 0x40);			// size of the subtable is 0x0C, each subtable starts with char 0x40
		c = cpGBK[idx];
	}

	return c;
}

static int XMLCALL
unknownEncoding(void *userData, const XML_Char *name, XML_Encoding *info) {
	LOG1(7, "unknownEncoding(, '%s', )", name);

	CXmlFile *xml = (CXmlFile *) userData;

	char *encoding = xml->Encoding;
	int i;

	if (strcmp(encoding, "big5") == 0) {
		// first 0x80 bytes are single byte
		for (i = 0; i < 0x80; i++) info->map[i] = i;
		// the rest is 2-byte
		for (i = 0x80; i <= 0xFF; i++) info->map[i] = -2;
		info->convert = big5EncodingConvert;
	}
	else if (strncmp(encoding, "euc-jp", 6) == 0) {
		// first 0x80 bytes are single byte
		for (i = 0; i <= 0x8D; i++) info->map[i] = i;
		info->map[0x8E] = -2;
		info->map[0x8F] = -3;
		for (i = 0x90; i <= 0x9F; i++) info->map[i] = i;
		info->map[0xA0] = -1;
		// the rest is 2-byte
		for (i = 0xA1; i <= 0xFE; i++) info->map[i] = -2;
		info->map[0xFF] = -1;
		info->convert = eucJpEncodingConvert;
	}
	else if (strncmp(encoding, "euc-kr", 6) == 0 ||
		strncmp(encoding, "ks_c_5601-1987", 14) == 0)
	{
		// first 0x80 bytes are single byte
		for (i = 0; i <= 0x7E; i++) info->map[i] = i;
		info->map[0x7F] = -1;
		info->map[0x80] = -1;
		for (i = 0x81; i <= 0xFE; i++) info->map[i] = -2;
		info->map[0xFF] = -1;
		info->convert = eucKrEncodingConvert;
	}
	else if (strncmp(encoding, "gb", 2) == 0) {	// gbk encoding
		// first 0x80 bytes are single byte
		for (i = 0x00; i <= 0x80; i++) info->map[i] = i;
		for (i = 0x81; i <= 0xFF; i++) info->map[i] = -2;
		info->convert = gbkEncodingConvert;
	}
	else if (strcmp(encoding, "utf-8") == 0) {
		for (i = 0; i < 0xc0; i++) info->map[i] = i;
		for (i = 0xc0; i <  0xe0; i++) info->map[i] = -2;
		for (i = 0xe0; i <  0xf0; i++) info->map[i] = -3;
		for (i = 0xf0; i <= 0xf4; i++) info->map[i] = -4;
		for (i = 0xf5; i <= 0xff; i++) info->map[i] = i;
		info->convert = utf8EncodingConvert;
	}
	else {
		WORD *map;
		if (strcmp(encoding, "iso-8859-2") == 0) map = cpISO_8859_2;
		else if (strcmp(encoding, "iso-8859-3") == 0) map = cpISO_8859_3;
		else if (strcmp(encoding, "iso-8859-4") == 0) map = cpISO_8859_4;
		else if (strcmp(encoding, "iso-8859-5") == 0) map = cpISO_8859_5;
		else if (strcmp(encoding, "iso-8859-6") == 0) map = cpISO_8859_6;
		else if (strcmp(encoding, "iso-8859-7") == 0) map = cpISO_8859_7;
		else if (strcmp(encoding, "iso-8859-8") == 0) map = cpISO_8859_8;
		else if (strcmp(encoding, "iso-8859-9") == 0) map = cpISO_8859_9;
		else if (strcmp(encoding, "iso-8859-10") == 0) map = cpISO_8859_10;
		else if (strcmp(encoding, "iso-8859-11") == 0) map = cpISO_8859_11;
		else if (strcmp(encoding, "iso-8859-13") == 0) map = cpISO_8859_13;
		else if (strcmp(encoding, "iso-8859-14") == 0) map = cpISO_8859_14;
		else if (strcmp(encoding, "iso-8859-15") == 0) map = cpISO_8859_15;
		else if (strcmp(encoding, "iso-8859-16") == 0) map = cpISO_8859_16;
		else if (strcmp(encoding, "windows-1250") == 0) map = cpCP1250;
		else if (strcmp(encoding, "windows-1251") == 0) map = cpCP1251;
		else if (strcmp(encoding, "windows-1252") == 0) map = cpCP1252;
		else if (strcmp(encoding, "windows-1253") == 0) map = cpCP1253;
		else if (strcmp(encoding, "windows-1254") == 0) map = cpCP1254;
		else if (strcmp(encoding, "windows-1255") == 0) map = cpCP1255;
		else if (strcmp(encoding, "windows-1256") == 0) map = cpCP1256;
		else if (strcmp(encoding, "windows-1257") == 0) map = cpCP1257;
		else if (strcmp(encoding, "windows-1258") == 0) map = cpCP1258;
		else if (strcmp(encoding, "koi8-r") == 0) map = cpKOI8_R;
		else map = cpCP1252;

		for (i = 0; i < 256; i++)
			info->map[i] = map[i];
		info->convert = unknownEncodingConvert;
	}

//	LOG1(1, "-- %s", encoding);

	return XML_STATUS_OK;
}

static void XMLCALL
declHandler(void *userData, const XML_Char *version, const XML_Char *encoding, int standalone) {
	CXmlFile *xml = (CXmlFile *) userData;
	xml->OnDeclaration(version, encoding, standalone);
}

/*static void XMLCALL
defaultHandler(void *userData, const XML_Char *s, int len) {
	CXmlFile *xml = (CXmlFile *) userData;
	xml->OnDefault(s, len);
}
*/

//////////////////////////////////////////////////////////////////////


CXmlAttr::CXmlAttr() {
}

CXmlAttr::CXmlAttr(const CString &name, const CString &value) {
	Name = name;
	Value = value;
}

CXmlAttr::CXmlAttr(const CString &name, int value) {
	Name = name;
	Value.Format(_T("%d"), value);
}

CXmlAttr::~CXmlAttr() {
}

//////////////////////////////////////////////////////////////////////

CXmlNode::CXmlNode(EType type, CXmlNode *parent) {
	Type = type;
	Parent = parent;
}

CXmlNode::CXmlNode(EType type, CXmlNode *parent, const CString &name) {
	Type = type;
	Parent = parent;
	Text = name;
}

CXmlNode::CXmlNode(EType type, CXmlNode *parent, const CString &name, CList<CXmlAttr*, CXmlAttr*> &attrList) {
	Type = type;
	Parent = parent;
	Text = name;
	POSITION pos = attrList.GetHeadPosition();
	while (pos != NULL) {
		CXmlAttr *a = attrList.GetNext(pos);
		Attrs.AddTail(a);
	}
}

CXmlNode::~CXmlNode() {
	// delete attributes
	while (!Attrs.IsEmpty())
		delete Attrs.RemoveHead();
	// delete childs
	while (!Childs.IsEmpty())
		delete Childs.RemoveHead();
}

BOOL CXmlNode::AddChild(CXmlNode *child) {
	Childs.AddTail(child);
	return TRUE;
}

CString CXmlNode::GetName() {
	if (Type == Tag)
		return Text;
	else
		return _T("");
}

CString CXmlNode::GetValue() {
	if (!Childs.IsEmpty()) {
		CXmlNode *node = Childs.GetHead();
		if (node->Type == Data) {
			CString text = node->Text;
			text.TrimLeft();
			text.TrimRight();
			return text;
		}
		else
			return _T("");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -