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 @@ +/**************************************************************************** +* * +* asm-xml.h * +* * +* Copyright (C) 2007-08 Marc Kerbiquet * +* * +****************************************************************************/ + +#ifdef WIN32 + #define ACC __cdecl +#else + #define ACC +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +//----------------------------------------------------------------------------- +// Error Codes +//----------------------------------------------------------------------------- +#define RC_OK 0 // everything is ok +#define RC_MEMORY 1 // out of memory + +#define RC_EMPTY_NAME 10 // name empty or not defined +#define RC_ATTR_DEFINED 11 // attribute already defined +#define RC_ELEM_DEFINED 12 // element already defined +#define RC_SCHEMA_EMPTY 13 // schema does not contains a document +#define RC_DOCUMENT_DEFINED 14 // schema contains more than one document +#define RC_UNDEFINED_CLASS 15 // can't find collection in reference +#define RC_UNDEFINED_GROUP 16 // can't find a group in include +#define RC_INVALID_ID 17 // id is not a valid number +#define RC_INVALID_IGNORE 18 // ignore is not 'yes' or 'no' + +#define RC_INVALID_ENTITY_REFERENCE 20 // must be amp, quot, lt, gt, or apos +#define RC_UNEXPECTED_END 21 // found last char too early +#define RC_INVALID_CHAR 22 // wrong char +#define RC_OVERFLOW 23 // number to big in char reference +#define RC_NO_START_TAG 24 // xml does not start with a tag +#define RC_TAG_MISMATCH 25 // invalid close tag +#define RC_INVALID_TAG 26 // invalid root element +#define RC_INVALID_ATTRIBUTE 27 // unknown attribute +#define RC_INVALID_PI 28 // invalid processing instruction ( has been defined in schema; + // use ax_getElement() to retrieve it. + const char* limit ; // the end of the value +}; + +struct AXElement +{ + int id ; // the class of the element + AXElement* nextSibling ; // the next sibling element + AXElement* firstChild ; // the first child element + AXElement* lastChild ; // the last child element + AXAttribute reserved ; // do not use + AXAttribute attributes[1] ; // the array of attributes - there is + // no bound checking in C +}; + +struct AXParseContext +{ + void* base ; + void* limit ; + void* chunks ; + int chunkSize ; + int errorCode ; + const char* source ; + const char* current ; + int line ; + int column ; + AXElement* root ; + AXAttribute version ; + AXAttribute encoding ; + int strict ; + int reserved1 ; + AXElement reserved2 ; +}; + +//----------------------------------------------------------------------------- +// Functions +//----------------------------------------------------------------------------- + +extern +void ACC ax_initialize (void* mallocFun, + void* freeFun); +extern +int ACC ax_initializeParser (AXParseContext* context, + unsigned int chunkSize); +extern +int ACC ax_releaseParser (AXParseContext* context); +extern +AXElement* ACC ax_parse (AXParseContext* context, + const char* source, + AXElementClass* type, + int strict); +extern +int ACC ax_initializeClassParser (AXClassContext* context); +extern +int ACC ax_releaseClassParser (AXClassContext* context); +extern +AXElementClass* ACC ax_classFromElement (AXElement* e, + AXClassContext* context); +extern +AXElementClass* ACC ax_classFromString (const char* source, + AXClassContext* context); + +#define ax_getElement(element, index) ((AXElement*)element->attributes[index].begin) +#define ax_getAttribute(element, index) (&element->attributes[index]) + + +#ifdef __cplusplus +} +#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 @@ + + + + + + + Senator Herpies + 12341241251 + + \ 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 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Friend List Parser +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "asm-xml.h" + +static const int chunkSize = 16*1024*1024; // 16Mk +static const char schemaFilename[] = "schema.xml"; +static const char xmlFilename[] = "friends.xml"; + +char buffer[65536]; + +/////////////////////////////////////////////////////////////////////////////// +// Print an attribute / text value +/////////////////////////////////////////////////////////////////////////////// +const char* asString(AXAttribute* attr) +{ + const char* start = attr->begin; + const char* limit = attr->limit; + size_t size = limit - start; + memcpy(buffer, start, size); + buffer[size] = 0; + return buffer; +} + +/////////////////////////////////////////////////////////////////////////////// +// Print an error code from the parser +/////////////////////////////////////////////////////////////////////////////// +void printAsmXmlError(AXParseContext* context) +{ + fprintf(stderr, "Error (%d,%d): %d\n", context->line, context->column, context->errorCode); +} + +/////////////////////////////////////////////////////////////////////////////// +// Read Schema Definition +/////////////////////////////////////////////////////////////////////////////// +AXElementClass* readClass(const char* filename, AXClassContext* classContext) +{ + FILE* f; + size_t size; + + f = fopen(filename, "rb"); + if( f == NULL ) + { + fprintf(stderr, "can't open schema '%s'\n", filename); + return NULL; + } + size = fread(buffer, 1, 65535, f); + buffer[size] = 0; + fclose(f); + + // Parse the string and build the class + return ax_classFromString(buffer, classContext); +} + +/////////////////////////////////////////////////////////////////////////////// +// Read Document +/////////////////////////////////////////////////////////////////////////////// +AXElement* readDocument(const char* filename, + AXParseContext* parseContext, + AXElementClass* clazz) +{ + FILE* f; + size_t size; + + f = fopen(filename, "rb"); + if( f == NULL ) + { + fprintf(stderr, "can't open file '%s'\n", filename); + return NULL; + } + size = fread(buffer, 1, 65535, f); + buffer[size] = 0; + fclose(f); + + // Parse the string and build the class + return ax_parse(parseContext, buffer, clazz, 1); +} + +/////////////////////////////////////////////////////////////////////////////// +// main +/////////////////////////////////////////////////////////////////////////////// +int main(int argc, char *argv[]) +{ + int res; + AXClassContext classContext; + AXParseContext parseContext; + AXElementClass* friendClass; + AXElement* friends; + AXElement* friend; + + // Initialize the AsmXml library + // + // Pass the malloc() and free() functions + // + ax_initialize(malloc, free); + + // Initialize the class context + // + // It can store one or more classes. Classes read with this + // context are kept in memory as long as it is not released. + // + res = ax_initializeClassParser(&classContext); + // An error while initialization means that allocation failed. + // It should never happen since it allocates only 4K. + if( res != 0 ) + return 1; + + // Read the schema and compile it + // + friendClass = readClass(schemaFilename, &classContext); + if( friendClass == NULL ) + return 1; + + // Initialize the parser + // + // Documents read with this parser will stay in memory as long as + // the parser is not released. + // + // The choice of the chunk size is very important since the + // performance can be affected by this value. The parser allocates + // memory by chunks to reduce calls to malloc that can be very slow. + // The ideal value is around 50% of the source XML to process. + // + res = ax_initializeParser(&parseContext, chunkSize); + // An error while initialization means that initial allocation failed. + if( res != 0 ) + return 1; + + // Read the file and parse it + // + friends = readDocument(xmlFilename, &parseContext, friendClass); + if( friends == NULL ) + { + printAsmXmlError(&parseContext); + return 1; + } + + // Enumerate child elements + friend = friends->firstChild; + while( friend ) + { + printf("================================\n"); + printf("Friend ID: %s\n", asString(&friend->attributes[0])); + printf("Name: %s\n", asString(&friend->attributes[1])); + printf("UserID: %s\n", asString(&friend->attributes[2])); + friend = friend->nextSibling; + printf("================================\n"); + } + + // Release the document and its class + ax_releaseParser(&parseContext); + ax_releaseClassParser(&classContext); + return 0; +} diff --git a/core/XML_Parser/parser.obj b/core/XML_Parser/parser.obj new file mode 100644 index 00000000..8f61851f Binary files /dev/null and b/core/XML_Parser/parser.obj differ