📄 xmlfile.cpp.svn-base
字号:
/**
* 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 + -