1 /*
2  * Martian: Motor para creaci�n de videojuegos con SDL y OpenGL
3  * Copyright (C) 2007  Javier P�rez Pacheco
4  *
5  * Este motor tiene licencia Creative Commons y se permite
6  * su modificacion y utilizacion libremente siempre y cuando se
7  * cite al autor original y se comparta con la misma licencia.
8  * No se permite su uso comercial.
9  *
10  * Para mas informacion visite la web:
11  * http://creativecommons.org/licenses/by-nc-sa/2.0/es/
12  *
13  * PROGRAMADOR
14  * Javier P�rez Pacheco
15  * Cadiz (Spain)
16  * javielinux@gmail.com
17  *
18  */
19  #include "hash.h"
20 
21 namespace Martian {
22 
23 	/*****************************
24 	**
25 	** CLASE Hash
26 	**
27 	******************************/
28 	string Hash::pathData = "";
29 
Hash(string file,bool fromConfDirectory)30 	Hash::Hash(string file, bool fromConfDirectory) {
31         cursor =  0;
32 		if (fromConfDirectory) {
33         	loadFromConfDirectory(file);
34 		} else {
35 			loadFromDataDirectory(file);
36 		}
37 	}
38 
setValue(string name,string value)39 	bool Hash::setValue ( string name, string value ) {
40 		int i;
41 		for (i=0; i<(int)items.size(); i++) {
42 			if (items[i].name == name) {
43                 items[i].value = value;
44 				return true;
45 			}
46 		}
47 		return false;
48 	}
49 
getValue(string name)50 	string Hash::getValue ( string name ) {
51 		int i;
52 		for (i=0; i<(int)items.size(); i++) {
53 			if (items[i].name == name) {
54 				return items[i].value;
55 			}
56 		}
57 		printf("%s don't find\n", name.c_str());
58 		return "";
59 	}
60 
getValueToInt(string name)61 	int Hash::getValueToInt(string name) {
62 		int i;
63 		for (i=0; i<(int)items.size(); i++) {
64 			if (items[i].name == name) {
65 				return atoi(items[i].value.c_str());
66 			}
67 		}
68 		printf("%s don't find\n", name.c_str());
69 		return -1;
70 	}
71 
addItem(string name,string value)72 	void Hash::addItem(string name, string value) {
73 
74 		int i;
75 		bool isName = false;
76 		for (i=0; i<(int)items.size(); i++) {
77 			if (items[i].name == name) {
78 				isName = true;
79 			}
80 		}
81         if (isName) {
82             setValue(name, value);
83         } else {
84             Item i;
85 		    i.name = name;
86             i.value = value;
87             items.push_back(i);
88        }
89 	}
90 
loadFromConfDirectory(string f)91 	void Hash::loadFromConfDirectory(string f) {
92 		if (Hash::pathData=="") {
93 			char *directory = NULL;
94 			char tmp_dir[128];
95 			if (getenv("HOME") != NULL) {
96 				directory = getenv("HOME");
97 				sprintf (tmp_dir, "mkdir %s/.%s", directory, CONFIG_DIR_UNIX);
98 				system(tmp_dir);
99 				sprintf (directory, "%s/.%s/", directory, CONFIG_DIR_UNIX);
100 			} else {
101 				directory = "./data/";
102 			}
103 			Hash::pathData = directory;
104 		}
105         file = Hash::pathData + f;
106 
107         FILE *c = fopen((char*)file.c_str(), "r");
108         if(!c) save();
109         parseHashXML((char*)file.c_str(), this);
110     }
111 
loadFromDataDirectory(string f)112 	void Hash::loadFromDataDirectory(string f) {
113         file = string(DATA_DIR) + f;
114 
115         FILE *c = fopen((char*)file.c_str(), "r");
116         if(!c) save();
117         parseHashXML((char*)file.c_str(), this);
118     }
119 
save()120 	bool Hash::save() {
121 
122 		FILE *f;
123 		f = fopen((char*)file.c_str(), "w+");
124 
125 		char tmp_val[128];
126 
127 		sprintf (tmp_val, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<items>\n");
128 		fwrite(tmp_val, strlen(tmp_val), 1, f);
129 
130 		int i;
131 		for (i=0; i<(int)items.size(); i++) {
132 			sprintf (tmp_val, "\t<item name=\"%s\" value=\"%s\" />\n", items[i].name.c_str(), items[i].value.c_str());
133 			fwrite(tmp_val, strlen(tmp_val), 1, f);
134 		}
135 
136 		sprintf (tmp_val, "</items>\n");
137 		fwrite(tmp_val, strlen(tmp_val), 1, f);
138 
139 		fclose(f);
140 
141 		return true;
142 	}
143 
144 
145 	/*****************************
146 	**
147 	** XML
148 	**
149 	******************************/
150 
startHashXML(void * userData,const char * el,const char ** attr)151 	static void startHashXML(void *userData, const char *el, const char **attr) {
152 		int i;
153 		ItemXML* data = (ItemXML*)userData;
154 
155 		if (strcmp(el, "item") == 0) {
156             string n, v;
157 			for (i = 0; attr[i]; i += 2) {
158 				if (strcmp(attr[i], "name") == 0) {
159 					n = attr[i+1];
160 				}
161 				if (strcmp(attr[i], "value") == 0) {
162 					v = attr[i+1];
163 				}
164 			}
165 			data->hash->addItem(n, v);
166 		}
167 
168 	}
169 
endHashXML(void * userData,const char * el)170 	static void endHashXML(void *userData, const char *el)
171 	{
172 		//ItemXML* data = (ItemXML*)userData;
173 
174 	}
175 
parseHashXML(char fileXML[128],Hash * h)176 	void parseHashXML(char fileXML[128], Hash *h) {
177 		char buffer[8192];
178 		int done;
179 
180 		ItemXML data;
181 		data.hash = h;
182 
183 		XML_Parser p = XML_ParserCreate("ISO-8859-1");
184 		if (! p) {
185 			printf("It could not have sufficient memory parser\n");
186 		}
187 
188 		XML_SetUserData(p, &data);
189 		XML_SetElementHandler(p, startHashXML, endHashXML);
190 
191 		FILE *file = fopen(fileXML, "r");
192 		if(!file)
193 			printf("Error opening file XML: %s\n", fileXML);
194 
195 		do
196 		{
197 			size_t len = fread(buffer, 1, sizeof(buffer), file);
198 			done = len < sizeof(buffer);
199 			if(!XML_Parse(p, buffer, len, done)){
200 				printf("Error making the parse\n");
201 			}
202 				//parse_error(&data, XML_ErrorString(XML_GetErrorCode(data.parser)));
203 		}
204 		while(!done);
205 		fclose(file);
206 	}
207 
208 }
209