summaryrefslogtreecommitdiffstats
path: root/Src/plist/loader.cpp
blob: c367559301dd2f8f3ae37479d1cd9e2f63db4988 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//------------------------------------------------------------------------
//
// iTunes XML Library Reader
// Copyright (C) 2003-2011 Nullsoft, Inc.
//
//------------------------------------------------------------------------

#include "loader.h"
#include <windows.h>
#include <commdlg.h>
#include <bfc/string/stringdict.h>


#define ATTRIB_TRUE  256
#define ATTRIB_FALSE 257

//------------------------------------------------------------------------
// xml tags
//------------------------------------------------------------------------
BEGIN_STRINGDICTIONARY(_itunestypes)
SDI(L"key", PLISTDATA_KEY);
SDI(L"dict", PLISTDATA_DICT);
SDI(L"integer", PLISTDATA_INTEGER);
SDI(L"string", PLISTDATA_STRING);
SDI(L"date", PLISTDATA_DATE);
SDI(L"array", PLISTDATA_ARRAY);
SDI(L"data", PLISTDATA_RAW);
SDI(L"true", ATTRIB_TRUE);
SDI(L"false", ATTRIB_FALSE);
END_STRINGDICTIONARY(_itunestypes, itunestypes)

//------------------------------------------------------------------------
plistLoader::plistLoader() : plistKey(L"root")
{
	m_context.push(this);
}

//------------------------------------------------------------------------
plistLoader::~plistLoader() 
{
}


//------------------------------------------------------------------------
// element opens (or singleton), push new key/dictionary/array, handle value singletons (true/false), defer job to closing tag for other data types
//------------------------------------------------------------------------
void plistLoader::xmlReaderOnStartElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params) {
	m_cdata = 0;
	int a = itunestypes.getId(xmltag);
	switch (a) {
		case PLISTDATA_KEY:
			m_cdata = L"";
			m_context.push(new plistKey());
			m_dict.top()->addKey((plistKey *)m_context.top());
			break;
		case PLISTDATA_DICT:
			{
				m_dict.push(new plistDict());
				plistData *contextTop = m_context.top();
				contextTop->setData(static_cast<plistDict *>(m_dict.top()));
			}
			break;
		case PLISTDATA_ARRAY: 
			{
				plistArray *new_array = new plistArray;
				plistData *contextTop = m_context.top();
				contextTop->setData(new_array);
				m_context.push(new_array);
				m_dict.push(new_array);
				break;
			}
		case PLISTDATA_STRING:
			break;
		case PLISTDATA_INTEGER:
			break;
		case PLISTDATA_DATE:
			break;
		case PLISTDATA_RAW:
			break;
		case PLISTDATA_REAL:
			break;
		case ATTRIB_TRUE: {
			m_context.top()->setData(new plistBoolean(true));
			if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
			break;
		}
		case ATTRIB_FALSE: {
			m_context.top()->setData(new plistBoolean(false));
			if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
			break;
		}
	}
}

//------------------------------------------------------------------------
// element closes, set data for last key/array, pop key/array/dictionary from stack
//------------------------------------------------------------------------
void plistLoader::xmlReaderOnEndElementCallback(const wchar_t *xmlpath, const wchar_t *xmltag) {
	int a = itunestypes.getId(xmltag);
	switch (a) {
		case PLISTDATA_KEY:
			ASSERT(m_context.top()->getType() == PLISTDATA_KEY);
			((plistKey*)m_context.top())->setName(m_cdata);
			break;
		case PLISTDATA_DICT:
			if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
			m_dict.pop();
			break;
		case PLISTDATA_ARRAY: {
			/*if (m_context.top()->getType() == PLISTDATA_KEY)*/ m_context.pop();
			//ASSERT(m_context.top()->getType() == PLISTDATA_ARRAY);
			//plistArray *a = (plistArray *)m_context.top();
			//m_context.pop();
			//m_context.top()->setData(a);
			m_dict.pop();
			break;
		}
		case PLISTDATA_STRING: {
			plistString *s = new plistString(m_cdata);
			m_context.top()->setData(s);
			if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
			break;
		}
		case PLISTDATA_INTEGER: {
			plistInteger *i = new plistInteger();
			i->setString(m_cdata);
			m_context.top()->setData(i);
			if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
			break;
		}
		case PLISTDATA_REAL: {
			plistReal *r = new plistReal();
			r->setString(m_cdata);
			m_context.top()->setData(r);
			if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
			break;
		}
		case PLISTDATA_DATE: {
			plistDate *d = new plistDate();
			d->setString(m_cdata);
			m_context.top()->setData(d);
			if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
			break;
		}
		case PLISTDATA_RAW: {
			plistRaw *r = new plistRaw();
			r->setString(m_cdata);
			m_context.top()->setData(r);
			if (m_context.top()->getType() == PLISTDATA_KEY) m_context.pop();
			break;
		}
	}
	m_cdata = 0;
}

//------------------------------------------------------------------------
// record c_data
//------------------------------------------------------------------------
void plistLoader::xmlReaderOnCharacterDataCallback(const wchar_t *xmlpath, const wchar_t *xmltag, const wchar_t *str) {
	m_cdata += str;
}

#define CBCLASS plistLoader
START_DISPATCH;
VCB(ONSTARTELEMENT, xmlReaderOnStartElementCallback)
VCB(ONCHARDATA, xmlReaderOnCharacterDataCallback)
VCB(ONENDELEMENT, xmlReaderOnEndElementCallback)
END_DISPATCH;
#undef CBCLASS