diff options
Diffstat (limited to 'messenger/XML_Parser/friends_parser.c')
-rw-r--r-- | messenger/XML_Parser/friends_parser.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/messenger/XML_Parser/friends_parser.c b/messenger/XML_Parser/friends_parser.c new file mode 100644 index 00000000..c17d0868 --- /dev/null +++ b/messenger/XML_Parser/friends_parser.c | |||
@@ -0,0 +1,160 @@ | |||
1 | /////////////////////////////////////////////////////////////////////////////// | ||
2 | // | ||
3 | // Friend List Parser | ||
4 | // | ||
5 | /////////////////////////////////////////////////////////////////////////////// | ||
6 | |||
7 | #include <stdio.h> | ||
8 | #include <stdlib.h> | ||
9 | #include <string.h> | ||
10 | #include "asm-xml.h" | ||
11 | |||
12 | static const int chunkSize = 16*1024*1024; // 16Mk | ||
13 | static const char schemaFilename[] = "friends_schema.xml"; | ||
14 | static const char xmlFilename[] = "friends.xml"; | ||
15 | |||
16 | char buffer[65536]; | ||
17 | |||
18 | /////////////////////////////////////////////////////////////////////////////// | ||
19 | // Print an attribute / text value | ||
20 | /////////////////////////////////////////////////////////////////////////////// | ||
21 | const char* asString(AXAttribute* attr) | ||
22 | { | ||
23 | const char* start = attr->begin; | ||
24 | const char* limit = attr->limit; | ||
25 | size_t size = limit - start; | ||
26 | memcpy(buffer, start, size); | ||
27 | buffer[size] = 0; | ||
28 | return buffer; | ||
29 | } | ||
30 | |||
31 | /////////////////////////////////////////////////////////////////////////////// | ||
32 | // Print an error code from the parser | ||
33 | /////////////////////////////////////////////////////////////////////////////// | ||
34 | void printAsmXmlError(AXParseContext* context) | ||
35 | { | ||
36 | fprintf(stderr, "Error (%d,%d): %d\n", context->line, context->column, context->errorCode); | ||
37 | } | ||
38 | |||
39 | /////////////////////////////////////////////////////////////////////////////// | ||
40 | // Read Schema Definition | ||
41 | /////////////////////////////////////////////////////////////////////////////// | ||
42 | AXElementClass* readClass(const char* filename, AXClassContext* classContext) | ||
43 | { | ||
44 | FILE* f; | ||
45 | size_t size; | ||
46 | |||
47 | f = fopen(filename, "rb"); | ||
48 | if( f == NULL ) | ||
49 | { | ||
50 | fprintf(stderr, "can't open schema '%s'\n", filename); | ||
51 | return NULL; | ||
52 | } | ||
53 | size = fread(buffer, 1, 65535, f); | ||
54 | buffer[size] = 0; | ||
55 | fclose(f); | ||
56 | |||
57 | // Parse the string and build the class | ||
58 | return ax_classFromString(buffer, classContext); | ||
59 | } | ||
60 | |||
61 | /////////////////////////////////////////////////////////////////////////////// | ||
62 | // Read Document | ||
63 | /////////////////////////////////////////////////////////////////////////////// | ||
64 | AXElement* readDocument(const char* filename, | ||
65 | AXParseContext* parseContext, | ||
66 | AXElementClass* clazz) | ||
67 | { | ||
68 | FILE* f; | ||
69 | size_t size; | ||
70 | |||
71 | f = fopen(filename, "rb"); | ||
72 | if( f == NULL ) | ||
73 | { | ||
74 | fprintf(stderr, "can't open file '%s'\n", filename); | ||
75 | return NULL; | ||
76 | } | ||
77 | size = fread(buffer, 1, 65535, f); | ||
78 | buffer[size] = 0; | ||
79 | fclose(f); | ||
80 | |||
81 | // Parse the string and build the class | ||
82 | return ax_parse(parseContext, buffer, clazz, 1); | ||
83 | } | ||
84 | |||
85 | /////////////////////////////////////////////////////////////////////////////// | ||
86 | // main | ||
87 | /////////////////////////////////////////////////////////////////////////////// | ||
88 | int main(int argc, char *argv[]) | ||
89 | { | ||
90 | int res; | ||
91 | AXClassContext classContext; | ||
92 | AXParseContext parseContext; | ||
93 | AXElementClass* friendClass; | ||
94 | AXElement* friends; | ||
95 | AXElement* friend; | ||
96 | |||
97 | // Initialize the AsmXml library | ||
98 | // | ||
99 | // Pass the malloc() and free() functions | ||
100 | // | ||
101 | ax_initialize(malloc, free); | ||
102 | |||
103 | // Initialize the class context | ||
104 | // | ||
105 | // It can store one or more classes. Classes read with this | ||
106 | // context are kept in memory as long as it is not released. | ||
107 | // | ||
108 | res = ax_initializeClassParser(&classContext); | ||
109 | // An error while initialization means that allocation failed. | ||
110 | // It should never happen since it allocates only 4K. | ||
111 | if( res != 0 ) | ||
112 | return 1; | ||
113 | |||
114 | // Read the schema and compile it | ||
115 | // | ||
116 | friendClass = readClass(schemaFilename, &classContext); | ||
117 | if( friendClass == NULL ) | ||
118 | return 1; | ||
119 | |||
120 | // Initialize the parser | ||
121 | // | ||
122 | // Documents read with this parser will stay in memory as long as | ||
123 | // the parser is not released. | ||
124 | // | ||
125 | // The choice of the chunk size is very important since the | ||
126 | // performance can be affected by this value. The parser allocates | ||
127 | // memory by chunks to reduce calls to malloc that can be very slow. | ||
128 | // The ideal value is around 50% of the source XML to process. | ||
129 | // | ||
130 | res = ax_initializeParser(&parseContext, chunkSize); | ||
131 | // An error while initialization means that initial allocation failed. | ||
132 | if( res != 0 ) | ||
133 | return 1; | ||
134 | |||
135 | // Read the file and parse it | ||
136 | // | ||
137 | friends = readDocument(xmlFilename, &parseContext, friendClass); | ||
138 | if( friends == NULL ) | ||
139 | { | ||
140 | printAsmXmlError(&parseContext); | ||
141 | return 1; | ||
142 | } | ||
143 | |||
144 | // Enumerate child elements | ||
145 | friend = friends->firstChild; | ||
146 | while( friend ) | ||
147 | { | ||
148 | printf("================================\n"); | ||
149 | printf("Friend ID: %s\n", asString(&friend->attributes[0])); | ||
150 | printf("Name: %s\n", asString(&friend->attributes[1])); | ||
151 | printf("UserID: %s\n", asString(&friend->attributes[2])); | ||
152 | friend = friend->nextSibling; | ||
153 | printf("================================\n"); | ||
154 | } | ||
155 | |||
156 | // Release the document and its class | ||
157 | ax_releaseParser(&parseContext); | ||
158 | ax_releaseClassParser(&classContext); | ||
159 | return 0; | ||
160 | } | ||