diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/XML_Parser/asm-xml.h.h | 162 | ||||
-rw-r--r-- | core/XML_Parser/friends.xml | 10 | ||||
-rw-r--r-- | core/XML_Parser/main.c | 160 | ||||
-rw-r--r-- | core/XML_Parser/parser.obj | bin | 0 -> 19421 bytes |
4 files changed, 332 insertions, 0 deletions
diff --git a/core/XML_Parser/asm-xml.h.h b/core/XML_Parser/asm-xml.h.h new file mode 100644 index 00000000..38dcb639 --- /dev/null +++ b/core/XML_Parser/asm-xml.h.h | |||
@@ -0,0 +1,162 @@ | |||
1 | /**************************************************************************** | ||
2 | * * | ||
3 | * asm-xml.h * | ||
4 | * * | ||
5 | * Copyright (C) 2007-08 Marc Kerbiquet * | ||
6 | * * | ||
7 | ****************************************************************************/ | ||
8 | |||
9 | #ifdef WIN32 | ||
10 | #define ACC __cdecl | ||
11 | #else | ||
12 | #define ACC | ||
13 | #endif | ||
14 | |||
15 | #ifdef __cplusplus | ||
16 | extern "C" { | ||
17 | #endif | ||
18 | |||
19 | //----------------------------------------------------------------------------- | ||
20 | // Error Codes | ||
21 | //----------------------------------------------------------------------------- | ||
22 | #define RC_OK 0 // everything is ok | ||
23 | #define RC_MEMORY 1 // out of memory | ||
24 | |||
25 | #define RC_EMPTY_NAME 10 // name empty or not defined | ||
26 | #define RC_ATTR_DEFINED 11 // attribute already defined | ||
27 | #define RC_ELEM_DEFINED 12 // element already defined | ||
28 | #define RC_SCHEMA_EMPTY 13 // schema does not contains a document | ||
29 | #define RC_DOCUMENT_DEFINED 14 // schema contains more than one document | ||
30 | #define RC_UNDEFINED_CLASS 15 // can't find collection in reference | ||
31 | #define RC_UNDEFINED_GROUP 16 // can't find a group in include | ||
32 | #define RC_INVALID_ID 17 // id is not a valid number | ||
33 | #define RC_INVALID_IGNORE 18 // ignore is not 'yes' or 'no' | ||
34 | |||
35 | #define RC_INVALID_ENTITY_REFERENCE 20 // must be amp, quot, lt, gt, or apos | ||
36 | #define RC_UNEXPECTED_END 21 // found last char too early | ||
37 | #define RC_INVALID_CHAR 22 // wrong char | ||
38 | #define RC_OVERFLOW 23 // number to big in char reference | ||
39 | #define RC_NO_START_TAG 24 // xml does not start with a tag | ||
40 | #define RC_TAG_MISMATCH 25 // invalid close tag | ||
41 | #define RC_INVALID_TAG 26 // invalid root element | ||
42 | #define RC_INVALID_ATTRIBUTE 27 // unknown attribute | ||
43 | #define RC_INVALID_PI 28 // invalid processing instruction (<?xml) | ||
44 | #define RC_INVALID_DOCTYPE 29 // duplicate doctype or after main element | ||
45 | #define RC_VERSION_EXPECTED 30 // version is missing in xml declaration | ||
46 | |||
47 | //----------------------------------------------------------------------------- | ||
48 | // Structures | ||
49 | //----------------------------------------------------------------------------- | ||
50 | typedef struct AXElement AXElement ; | ||
51 | typedef struct AXAttribute AXAttribute ; | ||
52 | typedef struct AXElementClass AXElementClass ; | ||
53 | typedef struct AXParseContext AXParseContext ; | ||
54 | typedef struct AXClassContext AXClassContext ; | ||
55 | |||
56 | struct AXElementClass | ||
57 | { | ||
58 | int offset ; // Offset of the element in attribute list | ||
59 | char* name ; // Name of the element (not zero terminated) | ||
60 | char* nameLimit ; // End of the name of the element | ||
61 | unsigned int size ; // size in bytes of an element of this class | ||
62 | unsigned int id ; // container, text or mixed | ||
63 | unsigned int type ; // container, text or mixed | ||
64 | unsigned int propertyCount ; // number of attributes and text elements | ||
65 | unsigned int childCount ; // number of child classes | ||
66 | int* attributes ; // (internal) attribute map | ||
67 | int* elements ; // (internal) element map | ||
68 | AXElementClass** children ; // The list of child classes. | ||
69 | // The order is the one defined in the class | ||
70 | // definition file. | ||
71 | int reserved ; | ||
72 | void* reserved2 ; | ||
73 | }; | ||
74 | |||
75 | struct AXClassContext | ||
76 | { | ||
77 | void* base ; | ||
78 | void* limit ; | ||
79 | void* chunks ; | ||
80 | int chunkSize ; | ||
81 | int errorCode ; | ||
82 | int line ; | ||
83 | int column ; | ||
84 | AXElementClass** classes ; // all global classes | ||
85 | AXElementClass* rootClass ; // the root class | ||
86 | AXElement* rootElement ; | ||
87 | }; | ||
88 | |||
89 | struct AXAttribute | ||
90 | { | ||
91 | const char* begin ; // the value (not zero terminated) | ||
92 | // This slot can also contain an element if | ||
93 | // a <element> has been defined in schema; | ||
94 | // use ax_getElement() to retrieve it. | ||
95 | const char* limit ; // the end of the value | ||
96 | }; | ||
97 | |||
98 | struct AXElement | ||
99 | { | ||
100 | int id ; // the class of the element | ||
101 | AXElement* nextSibling ; // the next sibling element | ||
102 | AXElement* firstChild ; // the first child element | ||
103 | AXElement* lastChild ; // the last child element | ||
104 | AXAttribute reserved ; // do not use | ||
105 | AXAttribute attributes[1] ; // the array of attributes - there is | ||
106 | // no bound checking in C | ||
107 | }; | ||
108 | |||
109 | struct AXParseContext | ||
110 | { | ||
111 | void* base ; | ||
112 | void* limit ; | ||
113 | void* chunks ; | ||
114 | int chunkSize ; | ||
115 | int errorCode ; | ||
116 | const char* source ; | ||
117 | const char* current ; | ||
118 | int line ; | ||
119 | int column ; | ||
120 | AXElement* root ; | ||
121 | AXAttribute version ; | ||
122 | AXAttribute encoding ; | ||
123 | int strict ; | ||
124 | int reserved1 ; | ||
125 | AXElement reserved2 ; | ||
126 | }; | ||
127 | |||
128 | //----------------------------------------------------------------------------- | ||
129 | // Functions | ||
130 | //----------------------------------------------------------------------------- | ||
131 | |||
132 | extern | ||
133 | void ACC ax_initialize (void* mallocFun, | ||
134 | void* freeFun); | ||
135 | extern | ||
136 | int ACC ax_initializeParser (AXParseContext* context, | ||
137 | unsigned int chunkSize); | ||
138 | extern | ||
139 | int ACC ax_releaseParser (AXParseContext* context); | ||
140 | extern | ||
141 | AXElement* ACC ax_parse (AXParseContext* context, | ||
142 | const char* source, | ||
143 | AXElementClass* type, | ||
144 | int strict); | ||
145 | extern | ||
146 | int ACC ax_initializeClassParser (AXClassContext* context); | ||
147 | extern | ||
148 | int ACC ax_releaseClassParser (AXClassContext* context); | ||
149 | extern | ||
150 | AXElementClass* ACC ax_classFromElement (AXElement* e, | ||
151 | AXClassContext* context); | ||
152 | extern | ||
153 | AXElementClass* ACC ax_classFromString (const char* source, | ||
154 | AXClassContext* context); | ||
155 | |||
156 | #define ax_getElement(element, index) ((AXElement*)element->attributes[index].begin) | ||
157 | #define ax_getAttribute(element, index) (&element->attributes[index]) | ||
158 | |||
159 | |||
160 | #ifdef __cplusplus | ||
161 | } | ||
162 | #endif | ||
diff --git a/core/XML_Parser/friends.xml b/core/XML_Parser/friends.xml new file mode 100644 index 00000000..edcb1407 --- /dev/null +++ b/core/XML_Parser/friends.xml | |||
@@ -0,0 +1,10 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | ||
2 | |||
3 | <!-- List of friends --> | ||
4 | |||
5 | <friends> | ||
6 | <friend id="001"> | ||
7 | <name>Senator Herpies</name> | ||
8 | <userID>12341241251</userID> | ||
9 | </friend> | ||
10 | </friends> \ No newline at end of file | ||
diff --git a/core/XML_Parser/main.c b/core/XML_Parser/main.c new file mode 100644 index 00000000..28e8ba60 --- /dev/null +++ b/core/XML_Parser/main.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[] = "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 | } | ||
diff --git a/core/XML_Parser/parser.obj b/core/XML_Parser/parser.obj new file mode 100644 index 00000000..8f61851f --- /dev/null +++ b/core/XML_Parser/parser.obj | |||
Binary files differ | |||