110152Satgutier@umich.edu/** 210152Satgutier@umich.edu **************************************************************************** 310152Satgutier@umich.edu * <P> XML.c - implementation file for basic XML parser written in ANSI C++ 410152Satgutier@umich.edu * for portability. It works by using recursion and a node tree for breaking 510152Satgutier@umich.edu * down the elements of an XML document. </P> 610152Satgutier@umich.edu * 710152Satgutier@umich.edu * @version V2.41 810152Satgutier@umich.edu * @author Frank Vanden Berghen 910152Satgutier@umich.edu * 1010152Satgutier@umich.edu * NOTE: 1110152Satgutier@umich.edu * 1210152Satgutier@umich.edu * If you add "#define STRICT_PARSING", on the first line of this file 1310152Satgutier@umich.edu * the parser will see the following XML-stream: 1410152Satgutier@umich.edu * <a><b>some text</b><b>other text </a> 1510152Satgutier@umich.edu * as an error. Otherwise, this tring will be equivalent to: 1610152Satgutier@umich.edu * <a><b>some text</b><b>other text</b></a> 1710152Satgutier@umich.edu * 1810152Satgutier@umich.edu * NOTE: 1910152Satgutier@umich.edu * 2010152Satgutier@umich.edu * If you add "#define APPROXIMATE_PARSING" on the first line of this file 2110152Satgutier@umich.edu * the parser will see the following XML-stream: 2210152Satgutier@umich.edu * <data name="n1"> 2310152Satgutier@umich.edu * <data name="n2"> 2410152Satgutier@umich.edu * <data name="n3" /> 2510152Satgutier@umich.edu * as equivalent to the following XML-stream: 2610152Satgutier@umich.edu * <data name="n1" /> 2710152Satgutier@umich.edu * <data name="n2" /> 2810152Satgutier@umich.edu * <data name="n3" /> 2910152Satgutier@umich.edu * This can be useful for badly-formed XML-streams but prevent the use 3010152Satgutier@umich.edu * of the following XML-stream (problem is: tags at contiguous levels 3110152Satgutier@umich.edu * have the same names): 3210152Satgutier@umich.edu * <data name="n1"> 3310152Satgutier@umich.edu * <data name="n2"> 3410152Satgutier@umich.edu * <data name="n3" /> 3510152Satgutier@umich.edu * </data> 3610152Satgutier@umich.edu * </data> 3710152Satgutier@umich.edu * 3810152Satgutier@umich.edu * NOTE: 3910152Satgutier@umich.edu * 4010152Satgutier@umich.edu * If you add "#define _XMLPARSER_NO_MESSAGEBOX_" on the first line of this file 4110152Satgutier@umich.edu * the "openFileHelper" function will always display error messages inside the 4210152Satgutier@umich.edu * console instead of inside a message-box-window. Message-box-windows are 4310152Satgutier@umich.edu * available on windows 9x/NT/2000/XP/Vista only. 4410152Satgutier@umich.edu * 4510152Satgutier@umich.edu * The following license terms for the "XMLParser library from Business-Insight" apply to projects 4610152Satgutier@umich.edu * that are in some way related to 4710152Satgutier@umich.edu * the "mcpat project", including applications 4810152Satgutier@umich.edu * using "mcpat project" and tools developed 4910152Satgutier@umich.edu * for enhancing "mcpat project". All other projects 5010152Satgutier@umich.edu * (not related to "mcpat project") have to use the "XMLParser library from Business-Insight" 5110152Satgutier@umich.edu * code under the Aladdin Free Public License (AFPL) 5210152Satgutier@umich.edu * See the file "AFPL-license.txt" for more informations about the AFPL license. 5310152Satgutier@umich.edu * (see http://www.artifex.com/downloads/doc/Public.htm for detailed AFPL terms) 5410152Satgutier@umich.edu * 5510152Satgutier@umich.edu * Redistribution and use of the "XMLParser library from Business-Insight" in source and binary forms, with or without 5610152Satgutier@umich.edu * modification, are permitted provided that the following conditions are met: 5710152Satgutier@umich.edu * * Redistributions of source code must retain the above copyright 5810152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer. 5910152Satgutier@umich.edu * * Redistributions in binary form must reproduce the above copyright 6010152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer in the 6110152Satgutier@umich.edu * documentation and/or other materials provided with the distribution. 6210152Satgutier@umich.edu * * Neither the name of Frank Vanden Berghen nor the 6310152Satgutier@umich.edu * names of its contributors may be used to endorse or promote products 6410152Satgutier@umich.edu * derived from this software without specific prior written permission. 6510152Satgutier@umich.edu * 6610152Satgutier@umich.edu * THIS SOFTWARE IS PROVIDED BY Business-Insight ``AS IS'' AND ANY 6710152Satgutier@umich.edu * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 6810152Satgutier@umich.edu * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 6910152Satgutier@umich.edu * DISCLAIMED. IN NO EVENT SHALL Business-Insight BE LIABLE FOR ANY 7010152Satgutier@umich.edu * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 7110152Satgutier@umich.edu * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 7210152Satgutier@umich.edu * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 7310152Satgutier@umich.edu * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 7410152Satgutier@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 7510152Satgutier@umich.edu * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 7610152Satgutier@umich.edu * 7710152Satgutier@umich.edu * Copyright (c) 2002, Business-Insight 7810234Syasuko.eckert@amd.com * Copyright (c) 2010-2013 Advanced Micro Devices, Inc. 7910152Satgutier@umich.edu * <a href="http://www.Business-Insight.com">Business-Insight</a> 8010152Satgutier@umich.edu * All rights reserved. 8110152Satgutier@umich.edu * 8210152Satgutier@umich.edu **************************************************************************** 8310152Satgutier@umich.edu */ 8410152Satgutier@umich.edu#ifndef _CRT_SECURE_NO_DEPRECATE 8510152Satgutier@umich.edu#define _CRT_SECURE_NO_DEPRECATE 8610152Satgutier@umich.edu#endif 8710152Satgutier@umich.edu#include "xmlParser.h" 8810152Satgutier@umich.edu#ifdef _XMLWINDOWS 8910152Satgutier@umich.edu//#ifdef _DEBUG 9010152Satgutier@umich.edu//#define _CRTDBG_MAP_ALLOC 9110152Satgutier@umich.edu//#include <crtdbg.h> 9210152Satgutier@umich.edu//#endif 9310152Satgutier@umich.edu#define WIN32_LEAN_AND_MEAN 9410152Satgutier@umich.edu#include <Windows.h> // to have IsTextUnicode, MultiByteToWideChar, WideCharToMultiByte to handle unicode files 9510234Syasuko.eckert@amd.com// to have "MessageBoxA" to display error messages for openFilHelper 9610152Satgutier@umich.edu#endif 9710152Satgutier@umich.edu 9810152Satgutier@umich.edu#include <memory.h> 9910152Satgutier@umich.edu 10010152Satgutier@umich.edu#include <cassert> 10110152Satgutier@umich.edu#include <cstdio> 10210152Satgutier@umich.edu#include <cstdlib> 10310152Satgutier@umich.edu#include <cstring> 10410152Satgutier@umich.edu 10510234Syasuko.eckert@amd.comXMLCSTR XMLNode::getVersion() { 10610234Syasuko.eckert@amd.com return _CXML("v2.39"); 10710234Syasuko.eckert@amd.com} 10810234Syasuko.eckert@amd.comvoid freeXMLString(XMLSTR t) { 10910234Syasuko.eckert@amd.com if (t)free(t); 11010234Syasuko.eckert@amd.com} 11110152Satgutier@umich.edu 11210152Satgutier@umich.edustatic XMLNode::XMLCharEncoding characterEncoding=XMLNode::char_encoding_UTF8; 11310152Satgutier@umich.edustatic char guessWideCharChars=1, dropWhiteSpace=1, removeCommentsInMiddleOfText=1; 11410152Satgutier@umich.edu 11510234Syasuko.eckert@amd.cominline int mmin( const int t1, const int t2 ) { 11610234Syasuko.eckert@amd.com return t1 < t2 ? t1 : t2; 11710234Syasuko.eckert@amd.com} 11810152Satgutier@umich.edu 11910152Satgutier@umich.edu// You can modify the initialization of the variable "XMLClearTags" below 12010152Satgutier@umich.edu// to change the clearTags that are currently recognized by the library. 12110152Satgutier@umich.edu// The number on the second columns is the length of the string inside the 12210152Satgutier@umich.edu// first column. The "<!DOCTYPE" declaration must be the second in the list. 12310152Satgutier@umich.edu// The "<!--" declaration must be the third in the list. 12410234Syasuko.eckert@amd.comtypedef struct { 12510234Syasuko.eckert@amd.com XMLCSTR lpszOpen; 12610234Syasuko.eckert@amd.com int openTagLen; 12710234Syasuko.eckert@amd.com XMLCSTR lpszClose; 12810234Syasuko.eckert@amd.com} ALLXMLClearTag; 12910234Syasuko.eckert@amd.comstatic ALLXMLClearTag XMLClearTags[] = { 13010234Syasuko.eckert@amd.com { _CXML("<![CDATA["), 9, _CXML("]]>") }, 13110234Syasuko.eckert@amd.com { _CXML("<!DOCTYPE"), 9, _CXML(">") }, 13210234Syasuko.eckert@amd.com { _CXML("<!--") , 4, _CXML("-->") }, 13310234Syasuko.eckert@amd.com { _CXML("<PRE>") , 5, _CXML("</PRE>") }, 13410152Satgutier@umich.edu// { _CXML("<Script>") ,8, _CXML("</Script>")}, 13510234Syasuko.eckert@amd.com { NULL , 0, NULL } 13610152Satgutier@umich.edu}; 13710152Satgutier@umich.edu 13810152Satgutier@umich.edu// You can modify the initialization of the variable "XMLEntities" below 13910152Satgutier@umich.edu// to change the character entities that are currently recognized by the library. 14010152Satgutier@umich.edu// The number on the second columns is the length of the string inside the 14110152Satgutier@umich.edu// first column. Additionally, the syntaxes " " and " " are recognized. 14210234Syasuko.eckert@amd.comtypedef struct { 14310234Syasuko.eckert@amd.com XMLCSTR s; 14410234Syasuko.eckert@amd.com int l; 14510234Syasuko.eckert@amd.com XMLCHAR c; 14610234Syasuko.eckert@amd.com} XMLCharacterEntity; 14710234Syasuko.eckert@amd.comstatic XMLCharacterEntity XMLEntities[] = { 14810152Satgutier@umich.edu { _CXML("&" ), 5, _CXML('&' )}, 14910152Satgutier@umich.edu { _CXML("<" ), 4, _CXML('<' )}, 15010152Satgutier@umich.edu { _CXML(">" ), 4, _CXML('>' )}, 15110152Satgutier@umich.edu { _CXML("""), 6, _CXML('\"')}, 15210152Satgutier@umich.edu { _CXML("'"), 6, _CXML('\'')}, 15310152Satgutier@umich.edu { NULL , 0, '\0' } 15410152Satgutier@umich.edu}; 15510152Satgutier@umich.edu 15610152Satgutier@umich.edu// When rendering the XMLNode to a string (using the "createXMLString" function), 15710152Satgutier@umich.edu// you can ask for a beautiful formatting. This formatting is using the 15810152Satgutier@umich.edu// following indentation character: 15910152Satgutier@umich.edu#define INDENTCHAR _CXML('\t') 16010152Satgutier@umich.edu 16110152Satgutier@umich.edu// The following function parses the XML errors into a user friendly string. 16210152Satgutier@umich.edu// You can edit this to change the output language of the library to something else. 16310234Syasuko.eckert@amd.comXMLCSTR XMLNode::getError(XMLError xerror) { 16410234Syasuko.eckert@amd.com switch (xerror) { 16510234Syasuko.eckert@amd.com case eXMLErrorNone: 16610234Syasuko.eckert@amd.com return _CXML("No error"); 16710234Syasuko.eckert@amd.com case eXMLErrorMissingEndTag: 16810234Syasuko.eckert@amd.com return _CXML("Warning: Unmatched end tag"); 16910234Syasuko.eckert@amd.com case eXMLErrorNoXMLTagFound: 17010234Syasuko.eckert@amd.com return _CXML("Warning: No XML tag found"); 17110234Syasuko.eckert@amd.com case eXMLErrorEmpty: 17210234Syasuko.eckert@amd.com return _CXML("Error: No XML data"); 17310234Syasuko.eckert@amd.com case eXMLErrorMissingTagName: 17410234Syasuko.eckert@amd.com return _CXML("Error: Missing start tag name"); 17510234Syasuko.eckert@amd.com case eXMLErrorMissingEndTagName: 17610234Syasuko.eckert@amd.com return _CXML("Error: Missing end tag name"); 17710234Syasuko.eckert@amd.com case eXMLErrorUnmatchedEndTag: 17810234Syasuko.eckert@amd.com return _CXML("Error: Unmatched end tag"); 17910234Syasuko.eckert@amd.com case eXMLErrorUnmatchedEndClearTag: 18010234Syasuko.eckert@amd.com return _CXML("Error: Unmatched clear tag end"); 18110234Syasuko.eckert@amd.com case eXMLErrorUnexpectedToken: 18210234Syasuko.eckert@amd.com return _CXML("Error: Unexpected token found"); 18310234Syasuko.eckert@amd.com case eXMLErrorNoElements: 18410234Syasuko.eckert@amd.com return _CXML("Error: No elements found"); 18510234Syasuko.eckert@amd.com case eXMLErrorFileNotFound: 18610234Syasuko.eckert@amd.com return _CXML("Error: File not found"); 18710234Syasuko.eckert@amd.com case eXMLErrorFirstTagNotFound: 18810234Syasuko.eckert@amd.com return _CXML("Error: First Tag not found"); 18910234Syasuko.eckert@amd.com case eXMLErrorUnknownCharacterEntity: 19010234Syasuko.eckert@amd.com return _CXML("Error: Unknown character entity"); 19110234Syasuko.eckert@amd.com case eXMLErrorCharacterCodeAbove255: 19210234Syasuko.eckert@amd.com return _CXML("Error: Character code above 255 is forbidden in MultiByte char mode."); 19310234Syasuko.eckert@amd.com case eXMLErrorCharConversionError: 19410234Syasuko.eckert@amd.com return _CXML("Error: unable to convert between WideChar and MultiByte chars"); 19510234Syasuko.eckert@amd.com case eXMLErrorCannotOpenWriteFile: 19610234Syasuko.eckert@amd.com return _CXML("Error: unable to open file for writing"); 19710234Syasuko.eckert@amd.com case eXMLErrorCannotWriteFile: 19810234Syasuko.eckert@amd.com return _CXML("Error: cannot write into file"); 19910152Satgutier@umich.edu 20010234Syasuko.eckert@amd.com case eXMLErrorBase64DataSizeIsNotMultipleOf4: 20110234Syasuko.eckert@amd.com return _CXML("Warning: Base64-string length is not a multiple of 4"); 20210234Syasuko.eckert@amd.com case eXMLErrorBase64DecodeTruncatedData: 20310234Syasuko.eckert@amd.com return _CXML("Warning: Base64-string is truncated"); 20410234Syasuko.eckert@amd.com case eXMLErrorBase64DecodeIllegalCharacter: 20510234Syasuko.eckert@amd.com return _CXML("Error: Base64-string contains an illegal character"); 20610234Syasuko.eckert@amd.com case eXMLErrorBase64DecodeBufferTooSmall: 20710234Syasuko.eckert@amd.com return _CXML("Error: Base64 decode output buffer is too small"); 20810152Satgutier@umich.edu }; 20910152Satgutier@umich.edu return _CXML("Unknown"); 21010152Satgutier@umich.edu} 21110152Satgutier@umich.edu 21210152Satgutier@umich.edu///////////////////////////////////////////////////////////////////////// 21310152Satgutier@umich.edu// Here start the abstraction layer to be OS-independent // 21410152Satgutier@umich.edu///////////////////////////////////////////////////////////////////////// 21510152Satgutier@umich.edu 21610152Satgutier@umich.edu// Here is an abstraction layer to access some common string manipulation functions. 21710152Satgutier@umich.edu// The abstraction layer is currently working for gcc, Microsoft Visual Studio 6.0, 21810152Satgutier@umich.edu// Microsoft Visual Studio .NET, CC (sun compiler) and Borland C++. 21910152Satgutier@umich.edu// If you plan to "port" the library to a new system/compiler, all you have to do is 22010152Satgutier@umich.edu// to edit the following lines. 22110152Satgutier@umich.edu#ifdef XML_NO_WIDE_CHAR 22210234Syasuko.eckert@amd.comchar myIsTextWideChar(const void *b, int len) { 22310234Syasuko.eckert@amd.com return FALSE; 22410234Syasuko.eckert@amd.com} 22510152Satgutier@umich.edu#else 22610234Syasuko.eckert@amd.com#if defined (UNDER_CE) || !defined(_XMLWINDOWS) 22710234Syasuko.eckert@amd.com// inspired by the Wine API: RtlIsTextUnicode 22810234Syasuko.eckert@amd.comchar myIsTextWideChar(const void *b, int len) { 22910152Satgutier@umich.edu#ifdef sun 23010234Syasuko.eckert@amd.com // for SPARC processors: wchar_t* buffers must always be alligned, otherwise it's a char* buffer. 23110234Syasuko.eckert@amd.com if ((((unsigned long)b)%sizeof(wchar_t))!=0) return FALSE; 23210152Satgutier@umich.edu#endif 23310234Syasuko.eckert@amd.com const wchar_t *s = (const wchar_t*)b; 23410152Satgutier@umich.edu 23510234Syasuko.eckert@amd.com // buffer too small: 23610234Syasuko.eckert@amd.com if (len < (int)sizeof(wchar_t)) return FALSE; 23710152Satgutier@umich.edu 23810234Syasuko.eckert@amd.com // odd length test 23910234Syasuko.eckert@amd.com if (len&1) return FALSE; 24010152Satgutier@umich.edu 24110234Syasuko.eckert@amd.com /* only checks the first 256 characters */ 24210234Syasuko.eckert@amd.com len = mmin(256, len / sizeof(wchar_t)); 24310152Satgutier@umich.edu 24410234Syasuko.eckert@amd.com // Check for the special byte order: 24510234Syasuko.eckert@amd.com if (*((unsigned short*)s) == 0xFFFE) return TRUE; // IS_TEXT_UNICODE_REVERSE_SIGNATURE; 24610234Syasuko.eckert@amd.com if (*((unsigned short*)s) == 0xFEFF) return TRUE; // IS_TEXT_UNICODE_SIGNATURE 24710152Satgutier@umich.edu 24810234Syasuko.eckert@amd.com // checks for ASCII characters in the UNICODE stream 24910234Syasuko.eckert@amd.com int i, stats=0; 25010234Syasuko.eckert@amd.com for (i=0; i<len; i++) if (s[i]<=(unsigned short)255) stats++; 25110234Syasuko.eckert@amd.com if (stats>len/2) return TRUE; 25210152Satgutier@umich.edu 25310234Syasuko.eckert@amd.com // Check for UNICODE NULL chars 25410234Syasuko.eckert@amd.com for (i=0; i<len; i++) if (!s[i]) return TRUE; 25510152Satgutier@umich.edu 25610234Syasuko.eckert@amd.com return FALSE; 25710234Syasuko.eckert@amd.com} 25810234Syasuko.eckert@amd.com#else 25910234Syasuko.eckert@amd.comchar myIsTextWideChar(const void *b, int l) { 26010234Syasuko.eckert@amd.com return (char)IsTextUnicode((CONST LPVOID)b, l, NULL); 26110234Syasuko.eckert@amd.com}; 26210234Syasuko.eckert@amd.com#endif 26310152Satgutier@umich.edu#endif 26410152Satgutier@umich.edu 26510152Satgutier@umich.edu#ifdef _XMLWINDOWS 26610152Satgutier@umich.edu// for Microsoft Visual Studio 6.0 and Microsoft Visual Studio .NET and Borland C++ Builder 6.0 26710234Syasuko.eckert@amd.com#ifdef _XMLWIDECHAR 26810234Syasuko.eckert@amd.comwchar_t *myMultiByteToWideChar(const char *s, XMLNode::XMLCharEncoding ce) { 26910234Syasuko.eckert@amd.com int i; 27010234Syasuko.eckert@amd.com if (ce == XMLNode::char_encoding_UTF8) { 27110234Syasuko.eckert@amd.com i = (int)MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0); 27210234Syasuko.eckert@amd.com } else { 27310234Syasuko.eckert@amd.com i = (int)MultiByteToWideChar(CP_ACP , MB_PRECOMPOSED, s, -1, NULL, 0); 27410234Syasuko.eckert@amd.com } 27510234Syasuko.eckert@amd.com if (i < 0) { 27610234Syasuko.eckert@amd.com return NULL; 27710234Syasuko.eckert@amd.com } 27810234Syasuko.eckert@amd.com wchar_t *d = (wchar_t *)malloc((i + 1) * sizeof(XMLCHAR)); 27910234Syasuko.eckert@amd.com if (ce == XMLNode::char_encoding_UTF8) { 28010234Syasuko.eckert@amd.com i = (int)MultiByteToWideChar(CP_UTF8, 0, s, -1, d, i); 28110234Syasuko.eckert@amd.com } else { 28210234Syasuko.eckert@amd.com i = (int)MultiByteToWideChar(CP_ACP , MB_PRECOMPOSED, s, -1, d, i); 28310234Syasuko.eckert@amd.com } 28410234Syasuko.eckert@amd.com d[i] = 0; 28510234Syasuko.eckert@amd.com return d; 28610234Syasuko.eckert@amd.com} 28710234Syasuko.eckert@amd.comstatic inline FILE *xfopen(XMLCSTR filename, XMLCSTR mode) { 28810234Syasuko.eckert@amd.com return _wfopen(filename, mode); 28910234Syasuko.eckert@amd.com} 29010234Syasuko.eckert@amd.comstatic inline int xstrlen(XMLCSTR c) { 29110234Syasuko.eckert@amd.com return (int)wcslen(c); 29210234Syasuko.eckert@amd.com} 29310234Syasuko.eckert@amd.comstatic inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { 29410234Syasuko.eckert@amd.com return _wcsnicmp(c1, c2, l); 29510234Syasuko.eckert@amd.com} 29610234Syasuko.eckert@amd.comstatic inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { 29710234Syasuko.eckert@amd.com return wcsncmp(c1, c2, l); 29810234Syasuko.eckert@amd.com} 29910234Syasuko.eckert@amd.comstatic inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { 30010234Syasuko.eckert@amd.com return _wcsicmp(c1, c2); 30110234Syasuko.eckert@amd.com} 30210234Syasuko.eckert@amd.comstatic inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { 30310234Syasuko.eckert@amd.com return (XMLSTR)wcsstr(c1, c2); 30410234Syasuko.eckert@amd.com} 30510234Syasuko.eckert@amd.comstatic inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { 30610234Syasuko.eckert@amd.com return (XMLSTR)wcscpy(c1, c2); 30710234Syasuko.eckert@amd.com} 30810234Syasuko.eckert@amd.com#else 30910234Syasuko.eckert@amd.comchar *myWideCharToMultiByte(const wchar_t *s) { 31010234Syasuko.eckert@amd.com UINT codePage = CP_ACP; 31110234Syasuko.eckert@amd.com if (characterEncoding == XMLNode::char_encoding_UTF8) codePage = CP_UTF8; 31210234Syasuko.eckert@amd.com int i = (int)WideCharToMultiByte(codePage, // code page 31310234Syasuko.eckert@amd.com 0, // performance and mapping flags 31410234Syasuko.eckert@amd.com s, // wide-character string 31510234Syasuko.eckert@amd.com -1, // number of chars in string 31610234Syasuko.eckert@amd.com NULL, // buffer for new string 31710234Syasuko.eckert@amd.com 0, // size of buffer 31810234Syasuko.eckert@amd.com NULL, // default for unmappable chars 31910234Syasuko.eckert@amd.com NULL // set when default char used 32010234Syasuko.eckert@amd.com ); 32110234Syasuko.eckert@amd.com if (i<0) return NULL; 32210234Syasuko.eckert@amd.com char *d=(char*)malloc(i+1); 32310234Syasuko.eckert@amd.com WideCharToMultiByte(codePage, // code page 32410234Syasuko.eckert@amd.com 0, // performance and mapping flags 32510234Syasuko.eckert@amd.com s, // wide-character string 32610234Syasuko.eckert@amd.com -1, // number of chars in string 32710234Syasuko.eckert@amd.com d, // buffer for new string 32810234Syasuko.eckert@amd.com i, // size of buffer 32910234Syasuko.eckert@amd.com NULL, // default for unmappable chars 33010234Syasuko.eckert@amd.com NULL // set when default char used 33110234Syasuko.eckert@amd.com ); 33210234Syasuko.eckert@amd.com d[i] = 0; 33310234Syasuko.eckert@amd.com return d; 33410234Syasuko.eckert@amd.com} 33510234Syasuko.eckert@amd.comstatic inline FILE *xfopen(XMLCSTR filename, XMLCSTR mode) { 33610234Syasuko.eckert@amd.com return fopen(filename, mode); 33710234Syasuko.eckert@amd.com} 33810234Syasuko.eckert@amd.comstatic inline int xstrlen(XMLCSTR c) { 33910234Syasuko.eckert@amd.com return (int)strlen(c); 34010234Syasuko.eckert@amd.com} 34110234Syasuko.eckert@amd.com#ifdef __BORLANDC__ 34210234Syasuko.eckert@amd.comstatic inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { 34310234Syasuko.eckert@amd.com return strnicmp(c1, c2, l); 34410234Syasuko.eckert@amd.com} 34510234Syasuko.eckert@amd.comstatic inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { 34610234Syasuko.eckert@amd.com return stricmp(c1, c2); 34710234Syasuko.eckert@amd.com} 34810234Syasuko.eckert@amd.com#else 34910234Syasuko.eckert@amd.comstatic inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { 35010234Syasuko.eckert@amd.com return _strnicmp(c1, c2, l); 35110234Syasuko.eckert@amd.com} 35210234Syasuko.eckert@amd.comstatic inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { 35310234Syasuko.eckert@amd.com return _stricmp(c1, c2); 35410234Syasuko.eckert@amd.com} 35510234Syasuko.eckert@amd.com#endif 35610234Syasuko.eckert@amd.comstatic inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { 35710234Syasuko.eckert@amd.com return strncmp(c1, c2, l); 35810234Syasuko.eckert@amd.com} 35910234Syasuko.eckert@amd.comstatic inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { 36010234Syasuko.eckert@amd.com return (XMLSTR)strstr(c1, c2); 36110234Syasuko.eckert@amd.com} 36210234Syasuko.eckert@amd.comstatic inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { 36310234Syasuko.eckert@amd.com return (XMLSTR)strcpy(c1, c2); 36410234Syasuko.eckert@amd.com} 36510234Syasuko.eckert@amd.com#endif 36610152Satgutier@umich.edu#else 36710152Satgutier@umich.edu// for gcc and CC 36810234Syasuko.eckert@amd.com#ifdef XML_NO_WIDE_CHAR 36910234Syasuko.eckert@amd.comchar *myWideCharToMultiByte(const wchar_t *s) { 37010234Syasuko.eckert@amd.com return NULL; 37110234Syasuko.eckert@amd.com} 37210234Syasuko.eckert@amd.com#else 37310234Syasuko.eckert@amd.comchar *myWideCharToMultiByte(const wchar_t *s) { 37410234Syasuko.eckert@amd.com const wchar_t *ss = s; 37510234Syasuko.eckert@amd.com int i = (int)wcsrtombs(NULL, &ss, 0, NULL); 37610234Syasuko.eckert@amd.com if (i < 0) return NULL; 37710234Syasuko.eckert@amd.com char *d = (char *)malloc(i + 1); 37810234Syasuko.eckert@amd.com wcsrtombs(d, &s, i, NULL); 37910234Syasuko.eckert@amd.com d[i] = 0; 38010234Syasuko.eckert@amd.com return d; 38110234Syasuko.eckert@amd.com} 38210234Syasuko.eckert@amd.com#endif 38310234Syasuko.eckert@amd.com#ifdef _XMLWIDECHAR 38410234Syasuko.eckert@amd.comwchar_t *myMultiByteToWideChar(const char *s, XMLNode::XMLCharEncoding ce) { 38510234Syasuko.eckert@amd.com const char *ss = s; 38610234Syasuko.eckert@amd.com int i = (int)mbsrtowcs(NULL, &ss, 0, NULL); 38710234Syasuko.eckert@amd.com if (i < 0) return NULL; 38810234Syasuko.eckert@amd.com wchar_t *d = (wchar_t *)malloc((i + 1) * sizeof(wchar_t)); 38910234Syasuko.eckert@amd.com mbsrtowcs(d, &s, i, NULL); 39010234Syasuko.eckert@amd.com d[i] = 0; 39110234Syasuko.eckert@amd.com return d; 39210234Syasuko.eckert@amd.com} 39310234Syasuko.eckert@amd.comint xstrlen(XMLCSTR c) { 39410234Syasuko.eckert@amd.com return wcslen(c); 39510234Syasuko.eckert@amd.com} 39610234Syasuko.eckert@amd.com#ifdef sun 39710234Syasuko.eckert@amd.com// for CC 39810234Syasuko.eckert@amd.com#include <widec.h> 39910234Syasuko.eckert@amd.comstatic inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { 40010234Syasuko.eckert@amd.com return wsncasecmp(c1, c2, l); 40110234Syasuko.eckert@amd.com} 40210234Syasuko.eckert@amd.comstatic inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { 40310234Syasuko.eckert@amd.com return wsncmp(c1, c2, l); 40410234Syasuko.eckert@amd.com} 40510234Syasuko.eckert@amd.comstatic inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { 40610234Syasuko.eckert@amd.com return wscasecmp(c1, c2); 40710234Syasuko.eckert@amd.com} 40810234Syasuko.eckert@amd.com#else 40910234Syasuko.eckert@amd.com// for gcc 41010234Syasuko.eckert@amd.comstatic inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { 41110234Syasuko.eckert@amd.com return wcsncasecmp(c1, c2, l); 41210234Syasuko.eckert@amd.com} 41310234Syasuko.eckert@amd.comstatic inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { 41410234Syasuko.eckert@amd.com return wcsncmp(c1, c2, l); 41510234Syasuko.eckert@amd.com} 41610234Syasuko.eckert@amd.comstatic inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { 41710234Syasuko.eckert@amd.com return wcscasecmp(c1, c2); 41810234Syasuko.eckert@amd.com} 41910234Syasuko.eckert@amd.com#endif 42010234Syasuko.eckert@amd.comstatic inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { 42110234Syasuko.eckert@amd.com return (XMLSTR)wcsstr(c1, c2); 42210234Syasuko.eckert@amd.com} 42310234Syasuko.eckert@amd.comstatic inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { 42410234Syasuko.eckert@amd.com return (XMLSTR)wcscpy(c1, c2); 42510234Syasuko.eckert@amd.com} 42610234Syasuko.eckert@amd.comstatic inline FILE *xfopen(XMLCSTR filename, XMLCSTR mode) { 42710234Syasuko.eckert@amd.com char *filenameAscii = myWideCharToMultiByte(filename); 42810234Syasuko.eckert@amd.com FILE *f; 42910234Syasuko.eckert@amd.com if (mode[0] == _CXML('r')) f = fopen(filenameAscii, "rb"); 43010234Syasuko.eckert@amd.com else f = fopen(filenameAscii, "wb"); 43110234Syasuko.eckert@amd.com free(filenameAscii); 43210234Syasuko.eckert@amd.com return f; 43310234Syasuko.eckert@amd.com} 43410234Syasuko.eckert@amd.com#else 43510234Syasuko.eckert@amd.comstatic inline FILE *xfopen(XMLCSTR filename, XMLCSTR mode) { 43610234Syasuko.eckert@amd.com return fopen(filename, mode); 43710234Syasuko.eckert@amd.com} 43810234Syasuko.eckert@amd.comstatic inline int xstrlen(XMLCSTR c) { 43910234Syasuko.eckert@amd.com return strlen(c); 44010234Syasuko.eckert@amd.com} 44110234Syasuko.eckert@amd.comstatic inline int xstrnicmp(XMLCSTR c1, XMLCSTR c2, int l) { 44210234Syasuko.eckert@amd.com return strncasecmp(c1, c2, l); 44310234Syasuko.eckert@amd.com} 44410234Syasuko.eckert@amd.comstatic inline int xstrncmp(XMLCSTR c1, XMLCSTR c2, int l) { 44510234Syasuko.eckert@amd.com return strncmp(c1, c2, l); 44610234Syasuko.eckert@amd.com} 44710234Syasuko.eckert@amd.comstatic inline int xstricmp(XMLCSTR c1, XMLCSTR c2) { 44810234Syasuko.eckert@amd.com return strcasecmp(c1, c2); 44910234Syasuko.eckert@amd.com} 45010234Syasuko.eckert@amd.comstatic inline XMLSTR xstrstr(XMLCSTR c1, XMLCSTR c2) { 45110234Syasuko.eckert@amd.com return (XMLSTR)strstr(c1, c2); 45210234Syasuko.eckert@amd.com} 45310234Syasuko.eckert@amd.comstatic inline XMLSTR xstrcpy(XMLSTR c1, XMLCSTR c2) { 45410234Syasuko.eckert@amd.com return (XMLSTR)strcpy(c1, c2); 45510234Syasuko.eckert@amd.com} 45610234Syasuko.eckert@amd.com#endif 45710234Syasuko.eckert@amd.comstatic inline int _strnicmp(const char *c1, const char *c2, int l) { 45810234Syasuko.eckert@amd.com return strncasecmp(c1, c2, l); 45910234Syasuko.eckert@amd.com} 46010152Satgutier@umich.edu#endif 46110152Satgutier@umich.edu 46210152Satgutier@umich.edu 46310152Satgutier@umich.edu/////////////////////////////////////////////////////////////////////////////// 46410152Satgutier@umich.edu// the "xmltoc,xmltob,xmltoi,xmltol,xmltof,xmltoa" functions // 46510152Satgutier@umich.edu/////////////////////////////////////////////////////////////////////////////// 46610152Satgutier@umich.edu// These 6 functions are not used inside the XMLparser. 46710152Satgutier@umich.edu// There are only here as "convenience" functions for the user. 46810152Satgutier@umich.edu// If you don't need them, you can delete them without any trouble. 46910152Satgutier@umich.edu#ifdef _XMLWIDECHAR 47010234Syasuko.eckert@amd.com#ifdef _XMLWINDOWS 47110234Syasuko.eckert@amd.com// for Microsoft Visual Studio 6.0 and Microsoft Visual Studio .NET and Borland C++ Builder 6.0 47210234Syasuko.eckert@amd.comchar xmltob(XMLCSTR t, int v) { 47310234Syasuko.eckert@amd.com if (t && (*t)) return (char)_wtoi(t); 47410234Syasuko.eckert@amd.com return v; 47510234Syasuko.eckert@amd.com} 47610234Syasuko.eckert@amd.comint xmltoi(XMLCSTR t, int v) { 47710234Syasuko.eckert@amd.com if (t && (*t)) return _wtoi(t); 47810234Syasuko.eckert@amd.com return v; 47910234Syasuko.eckert@amd.com} 48010234Syasuko.eckert@amd.comlong xmltol(XMLCSTR t, long v) { 48110234Syasuko.eckert@amd.com if (t && (*t)) return _wtol(t); 48210234Syasuko.eckert@amd.com return v; 48310234Syasuko.eckert@amd.com} 48410234Syasuko.eckert@amd.comdouble xmltof(XMLCSTR t, double v) { 48510234Syasuko.eckert@amd.com if (t && (*t)) wscanf(t, "%f", &v); /*v=_wtof(t);*/ 48610234Syasuko.eckert@amd.com return v; 48710234Syasuko.eckert@amd.com} 48810152Satgutier@umich.edu#else 48910234Syasuko.eckert@amd.com#ifdef sun 49010234Syasuko.eckert@amd.com// for CC 49110234Syasuko.eckert@amd.com#include <widec.h> 49210234Syasuko.eckert@amd.comchar xmltob(XMLCSTR t, int v) { 49310234Syasuko.eckert@amd.com if (t) return (char)wstol(t, NULL, 10); 49410234Syasuko.eckert@amd.com return v; 49510234Syasuko.eckert@amd.com} 49610234Syasuko.eckert@amd.comint xmltoi(XMLCSTR t, int v) { 49710234Syasuko.eckert@amd.com if (t) return (int)wstol(t, NULL, 10); 49810234Syasuko.eckert@amd.com return v; 49910234Syasuko.eckert@amd.com} 50010234Syasuko.eckert@amd.comlong xmltol(XMLCSTR t, long v) { 50110234Syasuko.eckert@amd.com if (t) return wstol(t, NULL, 10); 50210234Syasuko.eckert@amd.com return v; 50310234Syasuko.eckert@amd.com} 50410234Syasuko.eckert@amd.com#else 50510234Syasuko.eckert@amd.com// for gcc 50610234Syasuko.eckert@amd.comchar xmltob(XMLCSTR t, int v) { 50710234Syasuko.eckert@amd.com if (t) return (char)wcstol(t, NULL, 10); 50810234Syasuko.eckert@amd.com return v; 50910234Syasuko.eckert@amd.com} 51010234Syasuko.eckert@amd.comint xmltoi(XMLCSTR t, int v) { 51110234Syasuko.eckert@amd.com if (t) return (int)wcstol(t, NULL, 10); 51210234Syasuko.eckert@amd.com return v; 51310234Syasuko.eckert@amd.com} 51410234Syasuko.eckert@amd.comlong xmltol(XMLCSTR t, long v) { 51510234Syasuko.eckert@amd.com if (t) return wcstol(t, NULL, 10); 51610234Syasuko.eckert@amd.com return v; 51710234Syasuko.eckert@amd.com} 51810152Satgutier@umich.edu#endif 51910234Syasuko.eckert@amd.comdouble xmltof(XMLCSTR t, double v) { 52010234Syasuko.eckert@amd.com if (t && (*t)) wscanf(t, "%f", &v); /*v=_wtof(t);*/ 52110234Syasuko.eckert@amd.com return v; 52210234Syasuko.eckert@amd.com} 52310234Syasuko.eckert@amd.com#endif 52410234Syasuko.eckert@amd.com#else 52510234Syasuko.eckert@amd.comchar xmltob(XMLCSTR t, char v) { 52610234Syasuko.eckert@amd.com if (t && (*t)) return (char)atoi(t); 52710234Syasuko.eckert@amd.com return v; 52810234Syasuko.eckert@amd.com} 52910234Syasuko.eckert@amd.comint xmltoi(XMLCSTR t, int v) { 53010234Syasuko.eckert@amd.com if (t && (*t)) return atoi(t); 53110234Syasuko.eckert@amd.com return v; 53210234Syasuko.eckert@amd.com} 53310234Syasuko.eckert@amd.comlong xmltol(XMLCSTR t, long v) { 53410234Syasuko.eckert@amd.com if (t && (*t)) return atol(t); 53510234Syasuko.eckert@amd.com return v; 53610234Syasuko.eckert@amd.com} 53710234Syasuko.eckert@amd.comdouble xmltof(XMLCSTR t, double v) { 53810234Syasuko.eckert@amd.com if (t && (*t)) return atof(t); 53910234Syasuko.eckert@amd.com return v; 54010234Syasuko.eckert@amd.com} 54110234Syasuko.eckert@amd.com#endif 54210234Syasuko.eckert@amd.comXMLCSTR xmltoa(XMLCSTR t, XMLCSTR v) { 54310234Syasuko.eckert@amd.com if (t) return t; 54410234Syasuko.eckert@amd.com return v; 54510234Syasuko.eckert@amd.com} 54610234Syasuko.eckert@amd.comXMLCHAR xmltoc(XMLCSTR t, XMLCHAR v) { 54710234Syasuko.eckert@amd.com if (t && (*t)) return *t; 54810234Syasuko.eckert@amd.com return v; 54910234Syasuko.eckert@amd.com} 55010152Satgutier@umich.edu 55110152Satgutier@umich.edu///////////////////////////////////////////////////////////////////////// 55210152Satgutier@umich.edu// the "openFileHelper" function // 55310152Satgutier@umich.edu///////////////////////////////////////////////////////////////////////// 55410152Satgutier@umich.edu 55510152Satgutier@umich.edu// Since each application has its own way to report and deal with errors, you should modify & rewrite 55610152Satgutier@umich.edu// the following "openFileHelper" function to get an "error reporting mechanism" tailored to your needs. 55710234Syasuko.eckert@amd.comXMLNode XMLNode::openFileHelper(XMLCSTR filename, XMLCSTR tag) { 55810152Satgutier@umich.edu // guess the value of the global parameter "characterEncoding" 55910152Satgutier@umich.edu // (the guess is based on the first 200 bytes of the file). 56010234Syasuko.eckert@amd.com FILE *f = xfopen(filename, _CXML("rb")); 56110234Syasuko.eckert@amd.com if (f) { 56210152Satgutier@umich.edu char bb[205]; 56310234Syasuko.eckert@amd.com int l = (int)fread(bb, 1, 200, f); 56410234Syasuko.eckert@amd.com setGlobalOptions(guessCharEncoding(bb, l), guessWideCharChars, 56510234Syasuko.eckert@amd.com dropWhiteSpace, removeCommentsInMiddleOfText); 56610152Satgutier@umich.edu fclose(f); 56710152Satgutier@umich.edu } 56810152Satgutier@umich.edu 56910152Satgutier@umich.edu // parse the file 57010152Satgutier@umich.edu XMLResults pResults; 57110234Syasuko.eckert@amd.com XMLNode xnode = XMLNode::parseFile(filename, tag, &pResults); 57210152Satgutier@umich.edu 57310152Satgutier@umich.edu // display error message (if any) 57410234Syasuko.eckert@amd.com if (pResults.error != eXMLErrorNone) { 57510152Satgutier@umich.edu // create message 57610234Syasuko.eckert@amd.com char message[2000], *s1 = (char*)"", *s3 = (char*)""; 57710234Syasuko.eckert@amd.com XMLCSTR s2 = _CXML(""); 57810234Syasuko.eckert@amd.com if (pResults.error == eXMLErrorFirstTagNotFound) { 57910234Syasuko.eckert@amd.com s1 = (char*)"First Tag should be '"; 58010234Syasuko.eckert@amd.com s2 = tag; 58110234Syasuko.eckert@amd.com s3 = (char*)"'.\n"; 58210234Syasuko.eckert@amd.com } 58310152Satgutier@umich.edu sprintf(message, 58410152Satgutier@umich.edu#ifdef _XMLWIDECHAR 58510234Syasuko.eckert@amd.com "XML Parsing error inside file '%S'.\n%S\nAt line %i, column %i.\n%s%S%s" 58610152Satgutier@umich.edu#else 58710234Syasuko.eckert@amd.com "XML Parsing error inside file '%s'.\n%s\nAt line %i, column %i.\n%s%s%s" 58810152Satgutier@umich.edu#endif 58910234Syasuko.eckert@amd.com , filename, XMLNode::getError(pResults.error), pResults.nLine, 59010234Syasuko.eckert@amd.com pResults.nColumn, s1, s2, s3); 59110152Satgutier@umich.edu 59210152Satgutier@umich.edu // display message 59310152Satgutier@umich.edu#if defined(_XMLWINDOWS) && !defined(UNDER_CE) && !defined(_XMLPARSER_NO_MESSAGEBOX_) 59410234Syasuko.eckert@amd.com MessageBoxA(NULL, message, "XML Parsing error", MB_OK | MB_ICONERROR | 59510234Syasuko.eckert@amd.com MB_TOPMOST); 59610152Satgutier@umich.edu#else 59710234Syasuko.eckert@amd.com printf("%s", message); 59810152Satgutier@umich.edu#endif 59910152Satgutier@umich.edu exit(255); 60010152Satgutier@umich.edu } 60110152Satgutier@umich.edu return xnode; 60210152Satgutier@umich.edu} 60310152Satgutier@umich.edu 60410152Satgutier@umich.edu///////////////////////////////////////////////////////////////////////// 60510152Satgutier@umich.edu// Here start the core implementation of the XMLParser library // 60610152Satgutier@umich.edu///////////////////////////////////////////////////////////////////////// 60710152Satgutier@umich.edu 60810152Satgutier@umich.edu// You should normally not change anything below this point. 60910152Satgutier@umich.edu 61010152Satgutier@umich.edu#ifndef _XMLWIDECHAR 61110152Satgutier@umich.edu// If "characterEncoding=ascii" then we assume that all characters have the same length of 1 byte. 61210152Satgutier@umich.edu// If "characterEncoding=UTF8" then the characters have different lengths (from 1 byte to 4 bytes). 61310152Satgutier@umich.edu// If "characterEncoding=ShiftJIS" then the characters have different lengths (from 1 byte to 2 bytes). 61410152Satgutier@umich.edu// This table is used as lookup-table to know the length of a character (in byte) based on the 61510152Satgutier@umich.edu// content of the first byte of the character. 61610152Satgutier@umich.edu// (note: if you modify this, you must always have XML_utf8ByteTable[0]=0 ). 61710234Syasuko.eckert@amd.comstatic const char XML_utf8ByteTable[256] = { 61810152Satgutier@umich.edu // 0 1 2 3 4 5 6 7 8 9 a b c d e f 61910234Syasuko.eckert@amd.com 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x00 62010234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x10 62110234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x20 62210234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x30 62310234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x40 62410234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x50 62510234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x60 62610234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x70 End of ASCII range 62710234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x80 0x80 to 0xc1 invalid 62810234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x90 62910234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0xa0 63010234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0xb0 63110234Syasuko.eckert@amd.com 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0xc0 0xc2 to 0xdf 2 byte 63210234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0xd0 63310234Syasuko.eckert@amd.com 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,// 0xe0 0xe0 to 0xef 3 byte 63410234Syasuko.eckert@amd.com 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid 63510152Satgutier@umich.edu}; 63610234Syasuko.eckert@amd.comstatic const char XML_legacyByteTable[256] = { 63710234Syasuko.eckert@amd.com 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 63810234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 63910234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 64010234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 64110234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 64210234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 64310152Satgutier@umich.edu}; 64410234Syasuko.eckert@amd.comstatic const char XML_sjisByteTable[256] = { 64510152Satgutier@umich.edu // 0 1 2 3 4 5 6 7 8 9 a b c d e f 64610234Syasuko.eckert@amd.com 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x00 64710234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x10 64810234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x20 64910234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x30 65010234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x40 65110234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x50 65210234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x60 65310234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x70 65410234Syasuko.eckert@amd.com 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0x80 0x81 to 0x9F 2 bytes 65510234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0x90 65610234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0xa0 65710234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0xb0 65810234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0xc0 65910234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0xd0 66010234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0xe0 0xe0 to 0xef 2 bytes 66110234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 66210152Satgutier@umich.edu}; 66310234Syasuko.eckert@amd.comstatic const char XML_gb2312ByteTable[256] = { 66410152Satgutier@umich.edu// 0 1 2 3 4 5 6 7 8 9 a b c d e f 66510234Syasuko.eckert@amd.com 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x00 66610234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x10 66710234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x20 66810234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x30 66910234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x40 67010234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x50 67110234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x60 67210234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x70 67310234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x80 67410234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x90 67510234Syasuko.eckert@amd.com 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0xa0 0xa1 to 0xf7 2 bytes 67610234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0xb0 67710234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0xc0 67810234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0xd0 67910234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0xe0 68010234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 // 0xf0 68110152Satgutier@umich.edu}; 68210234Syasuko.eckert@amd.comstatic const char XML_gbk_big5_ByteTable[256] = { 68310152Satgutier@umich.edu // 0 1 2 3 4 5 6 7 8 9 a b c d e f 68410234Syasuko.eckert@amd.com 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x00 68510234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x10 68610234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x20 68710234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x30 68810234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x40 68910234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x50 69010234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x60 69110234Syasuko.eckert@amd.com 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,// 0x70 69210234Syasuko.eckert@amd.com 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0x80 0x81 to 0xfe 2 bytes 69310234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0x90 69410234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0xa0 69510234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0xb0 69610234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0xc0 69710234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0xd0 69810234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,// 0xe0 69910234Syasuko.eckert@amd.com 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 // 0xf0 70010152Satgutier@umich.edu}; 70110234Syasuko.eckert@amd.com// the default is "characterEncoding=XMLNode::encoding_UTF8" 70210234Syasuko.eckert@amd.comstatic const char *XML_ByteTable = (const char *)XML_utf8ByteTable; 70310152Satgutier@umich.edu#endif 70410152Satgutier@umich.edu 70510152Satgutier@umich.edu 70610152Satgutier@umich.eduXMLNode XMLNode::emptyXMLNode; 70710234Syasuko.eckert@amd.comXMLClear XMLNode::emptyXMLClear = { NULL, NULL, NULL}; 70810234Syasuko.eckert@amd.comXMLAttribute XMLNode::emptyXMLAttribute = { NULL, NULL}; 70910152Satgutier@umich.edu 71010152Satgutier@umich.edu// Enumeration used to decipher what type a token is 71110234Syasuko.eckert@amd.comtypedef enum XMLTokenTypeTag { 71210152Satgutier@umich.edu eTokenText = 0, 71310152Satgutier@umich.edu eTokenQuotedText, 71410152Satgutier@umich.edu eTokenTagStart, /* "<" */ 71510152Satgutier@umich.edu eTokenTagEnd, /* "</" */ 71610152Satgutier@umich.edu eTokenCloseTag, /* ">" */ 71710152Satgutier@umich.edu eTokenEquals, /* "=" */ 71810152Satgutier@umich.edu eTokenDeclaration, /* "<?" */ 71910152Satgutier@umich.edu eTokenShortHandClose, /* "/>" */ 72010152Satgutier@umich.edu eTokenClear, 72110152Satgutier@umich.edu eTokenError 72210152Satgutier@umich.edu} XMLTokenType; 72310152Satgutier@umich.edu 72410152Satgutier@umich.edu// Main structure used for parsing XML 72510234Syasuko.eckert@amd.comtypedef struct XML { 72610152Satgutier@umich.edu XMLCSTR lpXML; 72710152Satgutier@umich.edu XMLCSTR lpszText; 72810152Satgutier@umich.edu int nIndex,nIndexMissigEndTag; 72910152Satgutier@umich.edu enum XMLError error; 73010152Satgutier@umich.edu XMLCSTR lpEndTag; 73110152Satgutier@umich.edu int cbEndTag; 73210152Satgutier@umich.edu XMLCSTR lpNewElement; 73310152Satgutier@umich.edu int cbNewElement; 73410152Satgutier@umich.edu int nFirst; 73510152Satgutier@umich.edu} XML; 73610152Satgutier@umich.edu 73710234Syasuko.eckert@amd.comtypedef struct { 73810152Satgutier@umich.edu ALLXMLClearTag *pClr; 73910152Satgutier@umich.edu XMLCSTR pStr; 74010152Satgutier@umich.edu} NextToken; 74110152Satgutier@umich.edu 74210152Satgutier@umich.edu// Enumeration used when parsing attributes 74310234Syasuko.eckert@amd.comtypedef enum Attrib { 74410152Satgutier@umich.edu eAttribName = 0, 74510152Satgutier@umich.edu eAttribEquals, 74610152Satgutier@umich.edu eAttribValue 74710152Satgutier@umich.edu} Attrib; 74810152Satgutier@umich.edu 74910152Satgutier@umich.edu// Enumeration used when parsing elements to dictate whether we are currently 75010152Satgutier@umich.edu// inside a tag 75110234Syasuko.eckert@amd.comtypedef enum Status { 75210152Satgutier@umich.edu eInsideTag = 0, 75310152Satgutier@umich.edu eOutsideTag 75410152Satgutier@umich.edu} Status; 75510152Satgutier@umich.edu 75610234Syasuko.eckert@amd.comXMLError XMLNode::writeToFile(XMLCSTR filename, const char *encoding, char nFormat) const { 75710152Satgutier@umich.edu if (!d) return eXMLErrorNone; 75810234Syasuko.eckert@amd.com FILE *f = xfopen(filename, _CXML("wb")); 75910152Satgutier@umich.edu if (!f) return eXMLErrorCannotOpenWriteFile; 76010152Satgutier@umich.edu#ifdef _XMLWIDECHAR 76110234Syasuko.eckert@amd.com unsigned char h[2] = { 0xFF, 0xFE }; 76210234Syasuko.eckert@amd.com if (!fwrite(h, 2, 1, f)) return eXMLErrorCannotWriteFile; 76310234Syasuko.eckert@amd.com if ((!isDeclaration()) && ((d->lpszName) || 76410234Syasuko.eckert@amd.com (!getChildNode().isDeclaration()))) { 76510234Syasuko.eckert@amd.com if (!fwrite(L"<?xml version=\"1.0\" encoding=\"utf-16\"?>\n", 76610234Syasuko.eckert@amd.com sizeof(wchar_t)*40, 1, f)) 76710152Satgutier@umich.edu return eXMLErrorCannotWriteFile; 76810152Satgutier@umich.edu } 76910152Satgutier@umich.edu#else 77010234Syasuko.eckert@amd.com if ((!isDeclaration()) && ((d->lpszName) || 77110234Syasuko.eckert@amd.com (!getChildNode().isDeclaration()))) { 77210234Syasuko.eckert@amd.com if (characterEncoding == char_encoding_UTF8) { 77310152Satgutier@umich.edu // header so that windows recognize the file as UTF-8: 77410234Syasuko.eckert@amd.com unsigned char h[3] = {0xEF, 0xBB, 0xBF}; 77510234Syasuko.eckert@amd.com if (!fwrite(h, 3, 1, f)) return eXMLErrorCannotWriteFile; 77610234Syasuko.eckert@amd.com encoding = "utf-8"; 77710234Syasuko.eckert@amd.com } else if (characterEncoding == char_encoding_ShiftJIS) 77810234Syasuko.eckert@amd.com encoding = "SHIFT-JIS"; 77910152Satgutier@umich.edu 78010234Syasuko.eckert@amd.com if (!encoding) encoding = "ISO-8859-1"; 78110234Syasuko.eckert@amd.com if (fprintf(f, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", encoding) 78210234Syasuko.eckert@amd.com < 0) 78310234Syasuko.eckert@amd.com return eXMLErrorCannotWriteFile; 78410234Syasuko.eckert@amd.com } else { 78510234Syasuko.eckert@amd.com if (characterEncoding == char_encoding_UTF8) { 78610234Syasuko.eckert@amd.com unsigned char h[3] = {0xEF, 0xBB, 0xBF}; 78710234Syasuko.eckert@amd.com if (!fwrite(h, 3, 1, f)) return eXMLErrorCannotWriteFile; 78810152Satgutier@umich.edu } 78910152Satgutier@umich.edu } 79010152Satgutier@umich.edu#endif 79110152Satgutier@umich.edu int i; 79210234Syasuko.eckert@amd.com XMLSTR t = createXMLString(nFormat, &i); 79310234Syasuko.eckert@amd.com if (!fwrite(t, sizeof(XMLCHAR)*i, 1, f)) return eXMLErrorCannotWriteFile; 79410234Syasuko.eckert@amd.com if (fclose(f) != 0) return eXMLErrorCannotWriteFile; 79510152Satgutier@umich.edu free(t); 79610152Satgutier@umich.edu return eXMLErrorNone; 79710152Satgutier@umich.edu} 79810152Satgutier@umich.edu 79910152Satgutier@umich.edu// Duplicate a given string. 80010234Syasuko.eckert@amd.comXMLSTR stringDup(XMLCSTR lpszData, int cbData) { 80110234Syasuko.eckert@amd.com if (lpszData == NULL) return NULL; 80210152Satgutier@umich.edu 80310152Satgutier@umich.edu XMLSTR lpszNew; 80410234Syasuko.eckert@amd.com if (cbData == -1) cbData = (int)xstrlen(lpszData); 80510234Syasuko.eckert@amd.com lpszNew = (XMLSTR)malloc((cbData + 1) * sizeof(XMLCHAR)); 80610234Syasuko.eckert@amd.com if (lpszNew) { 80710152Satgutier@umich.edu memcpy(lpszNew, lpszData, (cbData) * sizeof(XMLCHAR)); 80810152Satgutier@umich.edu lpszNew[cbData] = (XMLCHAR)NULL; 80910152Satgutier@umich.edu } 81010152Satgutier@umich.edu return lpszNew; 81110152Satgutier@umich.edu} 81210152Satgutier@umich.edu 81310234Syasuko.eckert@amd.comXMLSTR ToXMLStringTool::toXMLUnSafe(XMLSTR dest, XMLCSTR source) { 81410234Syasuko.eckert@amd.com XMLSTR dd = dest; 81510152Satgutier@umich.edu XMLCHAR ch; 81610152Satgutier@umich.edu XMLCharacterEntity *entity; 81710234Syasuko.eckert@amd.com while ((ch = *source)) { 81810234Syasuko.eckert@amd.com entity = XMLEntities; 81910234Syasuko.eckert@amd.com do { 82010234Syasuko.eckert@amd.com if (ch == entity->c) { 82110234Syasuko.eckert@amd.com xstrcpy(dest, entity->s); 82210234Syasuko.eckert@amd.com dest += entity->l; 82310234Syasuko.eckert@amd.com source++; 82410234Syasuko.eckert@amd.com goto out_of_loop1; 82510234Syasuko.eckert@amd.com } 82610152Satgutier@umich.edu entity++; 82710234Syasuko.eckert@amd.com } while (entity->s); 82810152Satgutier@umich.edu#ifdef _XMLWIDECHAR 82910234Syasuko.eckert@amd.com *(dest++) = *(source++); 83010152Satgutier@umich.edu#else 83110234Syasuko.eckert@amd.com switch (XML_ByteTable[(unsigned char)ch]) { 83210234Syasuko.eckert@amd.com case 4: 83310234Syasuko.eckert@amd.com *(dest++) = *(source++); 83410234Syasuko.eckert@amd.com case 3: 83510234Syasuko.eckert@amd.com *(dest++) = *(source++); 83610234Syasuko.eckert@amd.com case 2: 83710234Syasuko.eckert@amd.com *(dest++) = *(source++); 83810234Syasuko.eckert@amd.com case 1: 83910234Syasuko.eckert@amd.com *(dest++) = *(source++); 84010152Satgutier@umich.edu } 84110152Satgutier@umich.edu#endif 84210152Satgutier@umich.eduout_of_loop1: 84310152Satgutier@umich.edu ; 84410152Satgutier@umich.edu } 84510234Syasuko.eckert@amd.com *dest = 0; 84610152Satgutier@umich.edu return dd; 84710152Satgutier@umich.edu} 84810152Satgutier@umich.edu 84910152Satgutier@umich.edu// private (used while rendering): 85010234Syasuko.eckert@amd.comint ToXMLStringTool::lengthXMLString(XMLCSTR source) { 85110234Syasuko.eckert@amd.com int r = 0; 85210152Satgutier@umich.edu XMLCharacterEntity *entity; 85310152Satgutier@umich.edu XMLCHAR ch; 85410234Syasuko.eckert@amd.com while ((ch = *source)) { 85510234Syasuko.eckert@amd.com entity = XMLEntities; 85610234Syasuko.eckert@amd.com do { 85710234Syasuko.eckert@amd.com if (ch == entity->c) { 85810234Syasuko.eckert@amd.com r += entity->l; 85910234Syasuko.eckert@amd.com source++; 86010234Syasuko.eckert@amd.com goto out_of_loop1; 86110234Syasuko.eckert@amd.com } 86210152Satgutier@umich.edu entity++; 86310234Syasuko.eckert@amd.com } while (entity->s); 86410152Satgutier@umich.edu#ifdef _XMLWIDECHAR 86510234Syasuko.eckert@amd.com r++; 86610234Syasuko.eckert@amd.com source++; 86710152Satgutier@umich.edu#else 86810234Syasuko.eckert@amd.com ch = XML_ByteTable[(unsigned char)ch]; 86910234Syasuko.eckert@amd.com r += ch; 87010234Syasuko.eckert@amd.com source += ch; 87110152Satgutier@umich.edu#endif 87210152Satgutier@umich.eduout_of_loop1: 87310152Satgutier@umich.edu ; 87410152Satgutier@umich.edu } 87510152Satgutier@umich.edu return r; 87610152Satgutier@umich.edu} 87710152Satgutier@umich.edu 87810234Syasuko.eckert@amd.comToXMLStringTool::~ToXMLStringTool() { 87910234Syasuko.eckert@amd.com freeBuffer(); 88010234Syasuko.eckert@amd.com} 88110234Syasuko.eckert@amd.comvoid ToXMLStringTool::freeBuffer() { 88210234Syasuko.eckert@amd.com if (buf) free(buf); 88310234Syasuko.eckert@amd.com buf = NULL; 88410234Syasuko.eckert@amd.com buflen = 0; 88510234Syasuko.eckert@amd.com} 88610234Syasuko.eckert@amd.comXMLSTR ToXMLStringTool::toXML(XMLCSTR source) { 88710234Syasuko.eckert@amd.com int l = lengthXMLString(source) + 1; 88810234Syasuko.eckert@amd.com if (l > buflen) { 88910234Syasuko.eckert@amd.com buflen = l; 89010234Syasuko.eckert@amd.com buf = (XMLSTR)realloc(buf, l * sizeof(XMLCHAR)); 89110234Syasuko.eckert@amd.com } 89210234Syasuko.eckert@amd.com return toXMLUnSafe(buf, source); 89310152Satgutier@umich.edu} 89410152Satgutier@umich.edu 89510152Satgutier@umich.edu// private: 89610234Syasuko.eckert@amd.comXMLSTR fromXMLString(XMLCSTR s, int lo, XML *pXML) { 89710152Satgutier@umich.edu // This function is the opposite of the function "toXMLString". It decodes the escape 89810152Satgutier@umich.edu // sequences &, ", ', <, > and replace them by the characters 89910152Satgutier@umich.edu // &,",',<,>. This function is used internally by the XML Parser. All the calls to 90010152Satgutier@umich.edu // the XML library will always gives you back "decoded" strings. 90110152Satgutier@umich.edu // 90210152Satgutier@umich.edu // in: string (s) and length (lo) of string 90310152Satgutier@umich.edu // out: new allocated string converted from xml 90410152Satgutier@umich.edu if (!s) return NULL; 90510152Satgutier@umich.edu 90610234Syasuko.eckert@amd.com int ll = 0, j; 90710152Satgutier@umich.edu XMLSTR d; 90810234Syasuko.eckert@amd.com XMLCSTR ss = s; 90910152Satgutier@umich.edu XMLCharacterEntity *entity; 91010234Syasuko.eckert@amd.com while ((lo > 0) && (*s)) { 91110234Syasuko.eckert@amd.com if (*s == _CXML('&')) { 91210234Syasuko.eckert@amd.com if ((lo > 2) && (s[1] == _CXML('#'))) { 91310234Syasuko.eckert@amd.com s += 2; 91410234Syasuko.eckert@amd.com lo -= 2; 91510234Syasuko.eckert@amd.com if ((*s == _CXML('X')) || (*s == _CXML('x'))) { 91610234Syasuko.eckert@amd.com s++; 91710234Syasuko.eckert@amd.com lo--; 91810234Syasuko.eckert@amd.com } 91910234Syasuko.eckert@amd.com while ((*s) && (*s != _CXML(';')) && ((lo--) > 0)) { 92010234Syasuko.eckert@amd.com s++; 92110234Syasuko.eckert@amd.com } 92210234Syasuko.eckert@amd.com if (*s != _CXML(';')) { 92310234Syasuko.eckert@amd.com pXML->error = eXMLErrorUnknownCharacterEntity; 92410152Satgutier@umich.edu return NULL; 92510152Satgutier@umich.edu } 92610234Syasuko.eckert@amd.com s++; 92710234Syasuko.eckert@amd.com lo--; 92810234Syasuko.eckert@amd.com } else { 92910234Syasuko.eckert@amd.com entity = XMLEntities; 93010234Syasuko.eckert@amd.com do { 93110234Syasuko.eckert@amd.com if ((lo >= entity->l) && 93210234Syasuko.eckert@amd.com (xstrnicmp(s, entity->s, entity->l) == 0)) { 93310234Syasuko.eckert@amd.com s += entity->l; 93410234Syasuko.eckert@amd.com lo -= entity->l; 93510234Syasuko.eckert@amd.com break; 93610234Syasuko.eckert@amd.com } 93710152Satgutier@umich.edu entity++; 93810234Syasuko.eckert@amd.com } while (entity->s); 93910234Syasuko.eckert@amd.com if (!entity->s) { 94010234Syasuko.eckert@amd.com pXML->error = eXMLErrorUnknownCharacterEntity; 94110152Satgutier@umich.edu return NULL; 94210152Satgutier@umich.edu } 94310152Satgutier@umich.edu } 94410234Syasuko.eckert@amd.com } else { 94510152Satgutier@umich.edu#ifdef _XMLWIDECHAR 94610234Syasuko.eckert@amd.com s++; 94710234Syasuko.eckert@amd.com lo--; 94810152Satgutier@umich.edu#else 94910234Syasuko.eckert@amd.com j = XML_ByteTable[(unsigned char)*s]; 95010234Syasuko.eckert@amd.com s += j; 95110234Syasuko.eckert@amd.com lo -= j; 95210234Syasuko.eckert@amd.com ll += j - 1; 95310152Satgutier@umich.edu#endif 95410152Satgutier@umich.edu } 95510152Satgutier@umich.edu ll++; 95610152Satgutier@umich.edu } 95710152Satgutier@umich.edu 95810234Syasuko.eckert@amd.com d = (XMLSTR)malloc((ll + 1) * sizeof(XMLCHAR)); 95910234Syasuko.eckert@amd.com s = d; 96010234Syasuko.eckert@amd.com while (ll-- > 0) { 96110234Syasuko.eckert@amd.com if (*ss == _CXML('&')) { 96210234Syasuko.eckert@amd.com if (ss[1] == _CXML('#')) { 96310234Syasuko.eckert@amd.com ss += 2; 96410234Syasuko.eckert@amd.com j = 0; 96510234Syasuko.eckert@amd.com if ((*ss == _CXML('X')) || (*ss == _CXML('x'))) { 96610152Satgutier@umich.edu ss++; 96710234Syasuko.eckert@amd.com while (*ss != _CXML(';')) { 96810234Syasuko.eckert@amd.com if ((*ss >= _CXML('0')) && (*ss <= _CXML('9'))) { 96910234Syasuko.eckert@amd.com j = (j << 4) + *ss - _CXML('0'); 97010234Syasuko.eckert@amd.com } else if ((*ss >= _CXML('A')) && (*ss <= _CXML('F'))) { 97110234Syasuko.eckert@amd.com j = (j << 4) + *ss - _CXML('A') + 10; 97210234Syasuko.eckert@amd.com } else if ((*ss >= _CXML('a')) && (*ss <= _CXML('f'))) { 97310234Syasuko.eckert@amd.com j = (j << 4) + *ss - _CXML('a') + 10; 97410234Syasuko.eckert@amd.com } else { 97510234Syasuko.eckert@amd.com free((void*)s); 97610234Syasuko.eckert@amd.com pXML->error = eXMLErrorUnknownCharacterEntity; 97710234Syasuko.eckert@amd.com return NULL; 97810234Syasuko.eckert@amd.com } 97910152Satgutier@umich.edu ss++; 98010152Satgutier@umich.edu } 98110234Syasuko.eckert@amd.com } else { 98210234Syasuko.eckert@amd.com while (*ss != _CXML(';')) { 98310234Syasuko.eckert@amd.com if ((*ss >= _CXML('0')) && (*ss <= _CXML('9'))) { 98410234Syasuko.eckert@amd.com j = (j * 10) + *ss - _CXML('0'); 98510234Syasuko.eckert@amd.com } else { 98610234Syasuko.eckert@amd.com free((void*)s); 98710234Syasuko.eckert@amd.com pXML->error = eXMLErrorUnknownCharacterEntity; 98810234Syasuko.eckert@amd.com return NULL; 98910234Syasuko.eckert@amd.com } 99010152Satgutier@umich.edu ss++; 99110152Satgutier@umich.edu } 99210152Satgutier@umich.edu } 99310152Satgutier@umich.edu#ifndef _XMLWIDECHAR 99410234Syasuko.eckert@amd.com if (j > 255) { 99510234Syasuko.eckert@amd.com free((void*)s); 99610234Syasuko.eckert@amd.com pXML->error = eXMLErrorCharacterCodeAbove255; 99710234Syasuko.eckert@amd.com return NULL; 99810234Syasuko.eckert@amd.com } 99910152Satgutier@umich.edu#endif 100010234Syasuko.eckert@amd.com (*d++) = (XMLCHAR)j; 100110234Syasuko.eckert@amd.com ss++; 100210234Syasuko.eckert@amd.com } else { 100310234Syasuko.eckert@amd.com entity = XMLEntities; 100410234Syasuko.eckert@amd.com do { 100510234Syasuko.eckert@amd.com if (xstrnicmp(ss, entity->s, entity->l) == 0) { 100610234Syasuko.eckert@amd.com *(d++) = entity->c; 100710234Syasuko.eckert@amd.com ss += entity->l; 100810234Syasuko.eckert@amd.com break; 100910234Syasuko.eckert@amd.com } 101010152Satgutier@umich.edu entity++; 101110234Syasuko.eckert@amd.com } while (entity->s); 101210152Satgutier@umich.edu } 101310234Syasuko.eckert@amd.com } else { 101410152Satgutier@umich.edu#ifdef _XMLWIDECHAR 101510234Syasuko.eckert@amd.com *(d++) = *(ss++); 101610152Satgutier@umich.edu#else 101710234Syasuko.eckert@amd.com switch (XML_ByteTable[(unsigned char)*ss]) { 101810234Syasuko.eckert@amd.com case 4: 101910234Syasuko.eckert@amd.com *(d++) = *(ss++); 102010234Syasuko.eckert@amd.com ll--; 102110234Syasuko.eckert@amd.com case 3: 102210234Syasuko.eckert@amd.com *(d++) = *(ss++); 102310234Syasuko.eckert@amd.com ll--; 102410234Syasuko.eckert@amd.com case 2: 102510234Syasuko.eckert@amd.com *(d++) = *(ss++); 102610234Syasuko.eckert@amd.com ll--; 102710234Syasuko.eckert@amd.com case 1: 102810234Syasuko.eckert@amd.com *(d++) = *(ss++); 102910152Satgutier@umich.edu } 103010152Satgutier@umich.edu#endif 103110152Satgutier@umich.edu } 103210152Satgutier@umich.edu } 103310234Syasuko.eckert@amd.com *d = 0; 103410152Satgutier@umich.edu return (XMLSTR)s; 103510152Satgutier@umich.edu} 103610152Satgutier@umich.edu 103710152Satgutier@umich.edu#define XML_isSPACECHAR(ch) ((ch==_CXML('\n'))||(ch==_CXML(' '))||(ch== _CXML('\t'))||(ch==_CXML('\r'))) 103810152Satgutier@umich.edu 103910152Satgutier@umich.edu// private: 104010152Satgutier@umich.educhar myTagCompare(XMLCSTR cclose, XMLCSTR copen) 104110152Satgutier@umich.edu// !!!! WARNING strange convention&: 104210152Satgutier@umich.edu// return 0 if equals 104310152Satgutier@umich.edu// return 1 if different 104410152Satgutier@umich.edu{ 104510152Satgutier@umich.edu if (!cclose) return 1; 104610234Syasuko.eckert@amd.com int l = (int)xstrlen(cclose); 104710234Syasuko.eckert@amd.com if (xstrnicmp(cclose, copen, l) != 0) return 1; 104810234Syasuko.eckert@amd.com const XMLCHAR c = copen[l]; 104910234Syasuko.eckert@amd.com if (XML_isSPACECHAR(c) || 105010234Syasuko.eckert@amd.com (c == _CXML('/' )) || 105110234Syasuko.eckert@amd.com (c == _CXML('<' )) || 105210234Syasuko.eckert@amd.com (c == _CXML('>' )) || 105310234Syasuko.eckert@amd.com (c == _CXML('=' ))) return 0; 105410152Satgutier@umich.edu return 1; 105510152Satgutier@umich.edu} 105610152Satgutier@umich.edu 105710152Satgutier@umich.edu// Obtain the next character from the string. 105810234Syasuko.eckert@amd.comstatic inline XMLCHAR getNextChar(XML *pXML) { 105910152Satgutier@umich.edu XMLCHAR ch = pXML->lpXML[pXML->nIndex]; 106010152Satgutier@umich.edu#ifdef _XMLWIDECHAR 106110234Syasuko.eckert@amd.com if (ch != 0) pXML->nIndex++; 106210152Satgutier@umich.edu#else 106310234Syasuko.eckert@amd.com pXML->nIndex += XML_ByteTable[(unsigned char)ch]; 106410152Satgutier@umich.edu#endif 106510152Satgutier@umich.edu return ch; 106610152Satgutier@umich.edu} 106710152Satgutier@umich.edu 106810152Satgutier@umich.edu// Find the next token in a string. 106910152Satgutier@umich.edu// pcbToken contains the number of characters that have been read. 107010234Syasuko.eckert@amd.comstatic NextToken GetNextToken(XML *pXML, int *pcbToken, 107110234Syasuko.eckert@amd.com enum XMLTokenTypeTag *pType) { 107210152Satgutier@umich.edu NextToken result; 107310152Satgutier@umich.edu XMLCHAR ch; 107410152Satgutier@umich.edu XMLCHAR chTemp; 107510234Syasuko.eckert@amd.com int indexStart, nFoundMatch, nIsText = FALSE; 107610234Syasuko.eckert@amd.com result.pClr = NULL; // prevent warning 107710152Satgutier@umich.edu 107810152Satgutier@umich.edu // Find next non-white space character 107910234Syasuko.eckert@amd.com do { 108010234Syasuko.eckert@amd.com indexStart = pXML->nIndex; 108110234Syasuko.eckert@amd.com ch = getNextChar(pXML); 108210234Syasuko.eckert@amd.com } while XML_isSPACECHAR(ch); 108310152Satgutier@umich.edu 108410234Syasuko.eckert@amd.com if (ch) { 108510152Satgutier@umich.edu // Cache the current string pointer 108610152Satgutier@umich.edu result.pStr = &pXML->lpXML[indexStart]; 108710152Satgutier@umich.edu 108810152Satgutier@umich.edu // First check whether the token is in the clear tag list (meaning it 108910152Satgutier@umich.edu // does not need formatting). 109010234Syasuko.eckert@amd.com ALLXMLClearTag *ctag = XMLClearTags; 109110234Syasuko.eckert@amd.com do { 109210234Syasuko.eckert@amd.com if (xstrncmp(ctag->lpszOpen, result.pStr, ctag->openTagLen) == 0) { 109310234Syasuko.eckert@amd.com result.pClr = ctag; 109410234Syasuko.eckert@amd.com pXML->nIndex += ctag->openTagLen - 1; 109510234Syasuko.eckert@amd.com *pType = eTokenClear; 109610152Satgutier@umich.edu return result; 109710152Satgutier@umich.edu } 109810152Satgutier@umich.edu ctag++; 109910234Syasuko.eckert@amd.com } while (ctag->lpszOpen); 110010152Satgutier@umich.edu 110110152Satgutier@umich.edu // If we didn't find a clear tag then check for standard tokens 110210234Syasuko.eckert@amd.com switch (ch) { 110310234Syasuko.eckert@amd.com // Check for quotes 110410152Satgutier@umich.edu case _CXML('\''): 110510152Satgutier@umich.edu case _CXML('\"'): 110610152Satgutier@umich.edu // Type of token 110710152Satgutier@umich.edu *pType = eTokenQuotedText; 110810152Satgutier@umich.edu chTemp = ch; 110910152Satgutier@umich.edu 111010152Satgutier@umich.edu // Set the size 111110152Satgutier@umich.edu nFoundMatch = FALSE; 111210152Satgutier@umich.edu 111310152Satgutier@umich.edu // Search through the string to find a matching quote 111410234Syasuko.eckert@amd.com while ((ch = getNextChar(pXML))) { 111510234Syasuko.eckert@amd.com if (ch == chTemp) { 111610234Syasuko.eckert@amd.com nFoundMatch = TRUE; 111710234Syasuko.eckert@amd.com break; 111810234Syasuko.eckert@amd.com } 111910234Syasuko.eckert@amd.com if (ch == _CXML('<')) { 112010234Syasuko.eckert@amd.com break; 112110234Syasuko.eckert@amd.com } 112210152Satgutier@umich.edu } 112310152Satgutier@umich.edu 112410152Satgutier@umich.edu // If we failed to find a matching quote 112510234Syasuko.eckert@amd.com if (nFoundMatch == FALSE) { 112610234Syasuko.eckert@amd.com pXML->nIndex = indexStart + 1; 112710234Syasuko.eckert@amd.com nIsText = TRUE; 112810152Satgutier@umich.edu break; 112910152Satgutier@umich.edu } 113010152Satgutier@umich.edu 113110152Satgutier@umich.edu// 4.02.2002 113210152Satgutier@umich.edu// if (FindNonWhiteSpace(pXML)) pXML->nIndex--; 113310152Satgutier@umich.edu 113410152Satgutier@umich.edu break; 113510152Satgutier@umich.edu 113610234Syasuko.eckert@amd.com // Equals (used with attribute values) 113710152Satgutier@umich.edu case _CXML('='): 113810152Satgutier@umich.edu *pType = eTokenEquals; 113910152Satgutier@umich.edu break; 114010152Satgutier@umich.edu 114110234Syasuko.eckert@amd.com // Close tag 114210152Satgutier@umich.edu case _CXML('>'): 114310152Satgutier@umich.edu *pType = eTokenCloseTag; 114410152Satgutier@umich.edu break; 114510152Satgutier@umich.edu 114610234Syasuko.eckert@amd.com // Check for tag start and tag end 114710152Satgutier@umich.edu case _CXML('<'): 114810152Satgutier@umich.edu 114910152Satgutier@umich.edu // Peek at the next character to see if we have an end tag '</', 115010152Satgutier@umich.edu // or an xml declaration '<?' 115110152Satgutier@umich.edu chTemp = pXML->lpXML[pXML->nIndex]; 115210152Satgutier@umich.edu 115310152Satgutier@umich.edu // If we have a tag end... 115410234Syasuko.eckert@amd.com if (chTemp == _CXML('/')) { 115510152Satgutier@umich.edu // Set the type and ensure we point at the next character 115610152Satgutier@umich.edu getNextChar(pXML); 115710152Satgutier@umich.edu *pType = eTokenTagEnd; 115810152Satgutier@umich.edu } 115910152Satgutier@umich.edu 116010152Satgutier@umich.edu // If we have an XML declaration tag 116110234Syasuko.eckert@amd.com else if (chTemp == _CXML('?')) { 116210152Satgutier@umich.edu 116310152Satgutier@umich.edu // Set the type and ensure we point at the next character 116410152Satgutier@umich.edu getNextChar(pXML); 116510152Satgutier@umich.edu *pType = eTokenDeclaration; 116610152Satgutier@umich.edu } 116710152Satgutier@umich.edu 116810152Satgutier@umich.edu // Otherwise we must have a start tag 116910234Syasuko.eckert@amd.com else { 117010152Satgutier@umich.edu *pType = eTokenTagStart; 117110152Satgutier@umich.edu } 117210152Satgutier@umich.edu break; 117310152Satgutier@umich.edu 117410234Syasuko.eckert@amd.com // Check to see if we have a short hand type end tag ('/>'). 117510152Satgutier@umich.edu case _CXML('/'): 117610152Satgutier@umich.edu 117710152Satgutier@umich.edu // Peek at the next character to see if we have a short end tag '/>' 117810152Satgutier@umich.edu chTemp = pXML->lpXML[pXML->nIndex]; 117910152Satgutier@umich.edu 118010152Satgutier@umich.edu // If we have a short hand end tag... 118110234Syasuko.eckert@amd.com if (chTemp == _CXML('>')) { 118210152Satgutier@umich.edu // Set the type and ensure we point at the next character 118310152Satgutier@umich.edu getNextChar(pXML); 118410152Satgutier@umich.edu *pType = eTokenShortHandClose; 118510152Satgutier@umich.edu break; 118610152Satgutier@umich.edu } 118710152Satgutier@umich.edu 118810152Satgutier@umich.edu // If we haven't found a short hand closing tag then drop into the 118910152Satgutier@umich.edu // text process 119010152Satgutier@umich.edu 119110234Syasuko.eckert@amd.com // Other characters 119210152Satgutier@umich.edu default: 119310152Satgutier@umich.edu nIsText = TRUE; 119410152Satgutier@umich.edu } 119510152Satgutier@umich.edu 119610152Satgutier@umich.edu // If this is a TEXT node 119710234Syasuko.eckert@amd.com if (nIsText) { 119810152Satgutier@umich.edu // Indicate we are dealing with text 119910152Satgutier@umich.edu *pType = eTokenText; 120010234Syasuko.eckert@amd.com while ((ch = getNextChar(pXML))) { 120110234Syasuko.eckert@amd.com if XML_isSPACECHAR(ch) { 120210234Syasuko.eckert@amd.com indexStart++; 120310234Syasuko.eckert@amd.com break; 120410152Satgutier@umich.edu 120510234Syasuko.eckert@amd.com } else if (ch == _CXML('/')) { 120610152Satgutier@umich.edu // If we find a slash then this maybe text or a short hand end tag 120710152Satgutier@umich.edu // Peek at the next character to see it we have short hand end tag 120810234Syasuko.eckert@amd.com ch = pXML->lpXML[pXML->nIndex]; 120910152Satgutier@umich.edu // If we found a short hand end tag then we need to exit the loop 121010234Syasuko.eckert@amd.com if (ch == _CXML('>')) { 121110234Syasuko.eckert@amd.com pXML->nIndex--; 121210234Syasuko.eckert@amd.com break; 121310234Syasuko.eckert@amd.com } 121410152Satgutier@umich.edu 121510234Syasuko.eckert@amd.com } else if ((ch == _CXML('<')) || (ch == _CXML('>')) || 121610234Syasuko.eckert@amd.com (ch == _CXML('='))) { 121710234Syasuko.eckert@amd.com pXML->nIndex--; 121810234Syasuko.eckert@amd.com break; 121910152Satgutier@umich.edu } 122010152Satgutier@umich.edu } 122110152Satgutier@umich.edu } 122210234Syasuko.eckert@amd.com *pcbToken = pXML->nIndex - indexStart; 122310234Syasuko.eckert@amd.com } else { 122410152Satgutier@umich.edu // If we failed to obtain a valid character 122510152Satgutier@umich.edu *pcbToken = 0; 122610152Satgutier@umich.edu *pType = eTokenError; 122710234Syasuko.eckert@amd.com result.pStr = NULL; 122810152Satgutier@umich.edu } 122910152Satgutier@umich.edu 123010152Satgutier@umich.edu return result; 123110152Satgutier@umich.edu} 123210152Satgutier@umich.edu 123310234Syasuko.eckert@amd.comXMLCSTR XMLNode::updateName_WOSD(XMLSTR lpszName) { 123410234Syasuko.eckert@amd.com if (!d) { 123510234Syasuko.eckert@amd.com free(lpszName); 123610234Syasuko.eckert@amd.com return NULL; 123710234Syasuko.eckert@amd.com } 123810234Syasuko.eckert@amd.com if (d->lpszName && (lpszName != d->lpszName)) free((void*)d->lpszName); 123910234Syasuko.eckert@amd.com d->lpszName = lpszName; 124010152Satgutier@umich.edu return lpszName; 124110152Satgutier@umich.edu} 124210152Satgutier@umich.edu 124310152Satgutier@umich.edu// private: 124410234Syasuko.eckert@amd.comXMLNode::XMLNode(struct XMLNodeDataTag *p) { 124510234Syasuko.eckert@amd.com d = p; 124610234Syasuko.eckert@amd.com (p->ref_count)++; 124710234Syasuko.eckert@amd.com} 124810234Syasuko.eckert@amd.comXMLNode::XMLNode(XMLNodeData *pParent, XMLSTR lpszName, char isDeclaration) { 124910234Syasuko.eckert@amd.com d = (XMLNodeData*)malloc(sizeof(XMLNodeData)); 125010234Syasuko.eckert@amd.com d->ref_count = 1; 125110152Satgutier@umich.edu 125210234Syasuko.eckert@amd.com d->lpszName = NULL; 125310234Syasuko.eckert@amd.com d->nChild = 0; 125410152Satgutier@umich.edu d->nText = 0; 125510152Satgutier@umich.edu d->nClear = 0; 125610152Satgutier@umich.edu d->nAttribute = 0; 125710152Satgutier@umich.edu 125810152Satgutier@umich.edu d->isDeclaration = isDeclaration; 125910152Satgutier@umich.edu 126010152Satgutier@umich.edu d->pParent = pParent; 126110234Syasuko.eckert@amd.com d->pChild = NULL; 126210234Syasuko.eckert@amd.com d->pText = NULL; 126310234Syasuko.eckert@amd.com d->pClear = NULL; 126410234Syasuko.eckert@amd.com d->pAttribute = NULL; 126510234Syasuko.eckert@amd.com d->pOrder = NULL; 126610152Satgutier@umich.edu 126710152Satgutier@umich.edu updateName_WOSD(lpszName); 126810152Satgutier@umich.edu} 126910152Satgutier@umich.edu 127010234Syasuko.eckert@amd.comXMLNode XMLNode::createXMLTopNode_WOSD(XMLSTR lpszName, char isDeclaration) { 127110234Syasuko.eckert@amd.com return XMLNode(NULL, lpszName, isDeclaration); 127210234Syasuko.eckert@amd.com} 127310234Syasuko.eckert@amd.comXMLNode XMLNode::createXMLTopNode(XMLCSTR lpszName, char isDeclaration) { 127410234Syasuko.eckert@amd.com return XMLNode(NULL, stringDup(lpszName), isDeclaration); 127510234Syasuko.eckert@amd.com} 127610152Satgutier@umich.edu 127710152Satgutier@umich.edu#define MEMORYINCREASE 50 127810152Satgutier@umich.edu 127910234Syasuko.eckert@amd.comstatic inline void myFree(void *p) { 128010234Syasuko.eckert@amd.com if (p) free(p); 128110234Syasuko.eckert@amd.com} 128210234Syasuko.eckert@amd.comstatic inline void *myRealloc(void *p, int newsize, int memInc, int sizeofElem) { 128310234Syasuko.eckert@amd.com if (p == NULL) { 128410234Syasuko.eckert@amd.com if (memInc) return malloc(memInc*sizeofElem); 128510234Syasuko.eckert@amd.com return malloc(sizeofElem); 128610234Syasuko.eckert@amd.com } 128710234Syasuko.eckert@amd.com if ((memInc == 0) || ((newsize % memInc) == 0)) { 128810234Syasuko.eckert@amd.com p = realloc(p, (newsize + memInc) * sizeofElem); 128910234Syasuko.eckert@amd.com } 129010152Satgutier@umich.edu// if (!p) 129110152Satgutier@umich.edu// { 129210152Satgutier@umich.edu// printf("XMLParser Error: Not enough memory! Aborting...\n"); exit(220); 129310152Satgutier@umich.edu// } 129410152Satgutier@umich.edu return p; 129510152Satgutier@umich.edu} 129610152Satgutier@umich.edu 129710152Satgutier@umich.edu// private: 129810234Syasuko.eckert@amd.comXMLElementPosition XMLNode::findPosition(XMLNodeData *d, int index, 129910234Syasuko.eckert@amd.com XMLElementType xxtype) { 130010234Syasuko.eckert@amd.com if (index < 0) return -1; 130110234Syasuko.eckert@amd.com int i = 0, j = (int)((index << 2) + xxtype), *o = d->pOrder; 130210234Syasuko.eckert@amd.com while (o[i] != j) i++; 130310234Syasuko.eckert@amd.com return i; 130410152Satgutier@umich.edu} 130510152Satgutier@umich.edu 130610152Satgutier@umich.edu// private: 130710152Satgutier@umich.edu// update "order" information when deleting a content of a XMLNode 130810234Syasuko.eckert@amd.comint XMLNode::removeOrderElement(XMLNodeData *d, XMLElementType t, int index) { 130910234Syasuko.eckert@amd.com int n = d->nChild + d->nText + d->nClear; 131010234Syasuko.eckert@amd.com int *o = d->pOrder; 131110234Syasuko.eckert@amd.com int i = findPosition(d, index, t); 131210234Syasuko.eckert@amd.com memmove(o + i, o + i + 1, (n - i)*sizeof(int)); 131310234Syasuko.eckert@amd.com for (; i < n; i++) 131410234Syasuko.eckert@amd.com if ((o[i]&3) == (int)t) o[i] -= 4; 131510152Satgutier@umich.edu // We should normally do: 131610152Satgutier@umich.edu // d->pOrder=(int)realloc(d->pOrder,n*sizeof(int)); 131710152Satgutier@umich.edu // but we skip reallocation because it's too time consuming. 131810152Satgutier@umich.edu // Anyway, at the end, it will be free'd completely at once. 131910152Satgutier@umich.edu return i; 132010152Satgutier@umich.edu} 132110152Satgutier@umich.edu 132210234Syasuko.eckert@amd.comvoid *XMLNode::addToOrder(int memoryIncrease, int *_pos, int nc, void *p, 132310234Syasuko.eckert@amd.com int size, XMLElementType xtype) { 132410152Satgutier@umich.edu // in: *_pos is the position inside d->pOrder ("-1" means "EndOf") 132510152Satgutier@umich.edu // out: *_pos is the index inside p 132610234Syasuko.eckert@amd.com p = myRealloc(p, (nc + 1), memoryIncrease, size); 132710234Syasuko.eckert@amd.com int n = d->nChild + d->nText + d->nClear; 132810234Syasuko.eckert@amd.com d->pOrder = (int*)myRealloc(d->pOrder, n + 1, memoryIncrease * 3, 132910234Syasuko.eckert@amd.com sizeof(int)); 133010234Syasuko.eckert@amd.com int pos = *_pos, *o = d->pOrder; 133110152Satgutier@umich.edu 133210234Syasuko.eckert@amd.com if ((pos < 0) || (pos >= n)) { 133310234Syasuko.eckert@amd.com *_pos = nc; 133410234Syasuko.eckert@amd.com o[n] = (int)((nc << 2) + xtype); 133510234Syasuko.eckert@amd.com return p; 133610234Syasuko.eckert@amd.com } 133710152Satgutier@umich.edu 133810234Syasuko.eckert@amd.com int i = pos; 133910234Syasuko.eckert@amd.com memmove(o + i + 1, o + i, (n - i)*sizeof(int)); 134010152Satgutier@umich.edu 134110234Syasuko.eckert@amd.com while ((pos < n) && ((o[pos]&3) != (int)xtype)) pos++; 134210234Syasuko.eckert@amd.com if (pos == n) { 134310234Syasuko.eckert@amd.com *_pos = nc; 134410234Syasuko.eckert@amd.com o[n] = (int)((nc << 2) + xtype); 134510234Syasuko.eckert@amd.com return p; 134610234Syasuko.eckert@amd.com } 134710152Satgutier@umich.edu 134810234Syasuko.eckert@amd.com o[i] = o[pos]; 134910234Syasuko.eckert@amd.com for (i = pos + 1; i <= n; i++) if ((o[i]&3) == (int)xtype) o[i] += 4; 135010152Satgutier@umich.edu 135110234Syasuko.eckert@amd.com *_pos = pos = o[pos] >> 2; 135210234Syasuko.eckert@amd.com memmove(((char*)p) + (pos + 1)*size, ((char*)p) + pos*size, (nc - pos)*size); 135310152Satgutier@umich.edu 135410152Satgutier@umich.edu return p; 135510152Satgutier@umich.edu} 135610152Satgutier@umich.edu 135710152Satgutier@umich.edu// Add a child node to the given element. 135810234Syasuko.eckert@amd.comXMLNode XMLNode::addChild_priv(int memoryIncrease, XMLSTR lpszName, 135910234Syasuko.eckert@amd.com char isDeclaration, int pos) { 136010152Satgutier@umich.edu if (!lpszName) return emptyXMLNode; 136110234Syasuko.eckert@amd.com d->pChild = (XMLNode*)addToOrder(memoryIncrease, &pos, d->nChild, 136210234Syasuko.eckert@amd.com d->pChild, sizeof(XMLNode), eNodeChild); 136310234Syasuko.eckert@amd.com d->pChild[pos].d = NULL; 136410234Syasuko.eckert@amd.com d->pChild[pos] = XMLNode(d, lpszName, isDeclaration); 136510152Satgutier@umich.edu d->nChild++; 136610152Satgutier@umich.edu return d->pChild[pos]; 136710152Satgutier@umich.edu} 136810152Satgutier@umich.edu 136910152Satgutier@umich.edu// Add an attribute to an element. 137010234Syasuko.eckert@amd.comXMLAttribute *XMLNode::addAttribute_priv(int memoryIncrease, XMLSTR lpszName, 137110234Syasuko.eckert@amd.com XMLSTR lpszValuev) { 137210152Satgutier@umich.edu if (!lpszName) return &emptyXMLAttribute; 137310234Syasuko.eckert@amd.com if (!d) { 137410234Syasuko.eckert@amd.com myFree(lpszName); 137510234Syasuko.eckert@amd.com myFree(lpszValuev); 137610234Syasuko.eckert@amd.com return &emptyXMLAttribute; 137710234Syasuko.eckert@amd.com } 137810234Syasuko.eckert@amd.com int nc = d->nAttribute; 137910234Syasuko.eckert@amd.com d->pAttribute = (XMLAttribute*)myRealloc(d->pAttribute, (nc + 1), 138010234Syasuko.eckert@amd.com memoryIncrease, 138110234Syasuko.eckert@amd.com sizeof(XMLAttribute)); 138210234Syasuko.eckert@amd.com XMLAttribute *pAttr = d->pAttribute + nc; 138310152Satgutier@umich.edu pAttr->lpszName = lpszName; 138410152Satgutier@umich.edu pAttr->lpszValue = lpszValuev; 138510152Satgutier@umich.edu d->nAttribute++; 138610152Satgutier@umich.edu return pAttr; 138710152Satgutier@umich.edu} 138810152Satgutier@umich.edu 138910152Satgutier@umich.edu// Add text to the element. 139010234Syasuko.eckert@amd.comXMLCSTR XMLNode::addText_priv(int memoryIncrease, XMLSTR lpszValue, int pos) { 139110152Satgutier@umich.edu if (!lpszValue) return NULL; 139210234Syasuko.eckert@amd.com if (!d) { 139310234Syasuko.eckert@amd.com myFree(lpszValue); 139410234Syasuko.eckert@amd.com return NULL; 139510234Syasuko.eckert@amd.com } 139610234Syasuko.eckert@amd.com d->pText = (XMLCSTR*)addToOrder(memoryIncrease, &pos, d->nText, d->pText, 139710234Syasuko.eckert@amd.com sizeof(XMLSTR), eNodeText); 139810234Syasuko.eckert@amd.com d->pText[pos] = lpszValue; 139910152Satgutier@umich.edu d->nText++; 140010152Satgutier@umich.edu return lpszValue; 140110152Satgutier@umich.edu} 140210152Satgutier@umich.edu 140310152Satgutier@umich.edu// Add clear (unformatted) text to the element. 140410234Syasuko.eckert@amd.comXMLClear *XMLNode::addClear_priv(int memoryIncrease, XMLSTR lpszValue, 140510234Syasuko.eckert@amd.com XMLCSTR lpszOpen, XMLCSTR lpszClose, 140610234Syasuko.eckert@amd.com int pos) { 140710152Satgutier@umich.edu if (!lpszValue) return &emptyXMLClear; 140810234Syasuko.eckert@amd.com if (!d) { 140910234Syasuko.eckert@amd.com myFree(lpszValue); 141010234Syasuko.eckert@amd.com return &emptyXMLClear; 141110234Syasuko.eckert@amd.com } 141210234Syasuko.eckert@amd.com d->pClear = (XMLClear *)addToOrder(memoryIncrease, &pos, d->nClear, 141310234Syasuko.eckert@amd.com d->pClear, sizeof(XMLClear), 141410234Syasuko.eckert@amd.com eNodeClear); 141510234Syasuko.eckert@amd.com XMLClear *pNewClear = d->pClear + pos; 141610152Satgutier@umich.edu pNewClear->lpszValue = lpszValue; 141710234Syasuko.eckert@amd.com if (!lpszOpen) lpszOpen = XMLClearTags->lpszOpen; 141810234Syasuko.eckert@amd.com if (!lpszClose) lpszClose = XMLClearTags->lpszClose; 141910152Satgutier@umich.edu pNewClear->lpszOpenTag = lpszOpen; 142010152Satgutier@umich.edu pNewClear->lpszCloseTag = lpszClose; 142110152Satgutier@umich.edu d->nClear++; 142210152Satgutier@umich.edu return pNewClear; 142310152Satgutier@umich.edu} 142410152Satgutier@umich.edu 142510152Satgutier@umich.edu// private: 142610152Satgutier@umich.edu// Parse a clear (unformatted) type node. 142710234Syasuko.eckert@amd.comchar XMLNode::parseClearTag(void *px, void *_pClear) { 142810234Syasuko.eckert@amd.com XML *pXML = (XML *)px; 142910234Syasuko.eckert@amd.com ALLXMLClearTag pClear = *((ALLXMLClearTag*)_pClear); 143010234Syasuko.eckert@amd.com int cbTemp = 0; 143110234Syasuko.eckert@amd.com XMLCSTR lpszTemp = NULL; 143210234Syasuko.eckert@amd.com XMLCSTR lpXML = &pXML->lpXML[pXML->nIndex]; 143310234Syasuko.eckert@amd.com static XMLCSTR docTypeEnd = _CXML("]>"); 143410152Satgutier@umich.edu 143510152Satgutier@umich.edu // Find the closing tag 143610152Satgutier@umich.edu // Seems the <!DOCTYPE need a better treatment so lets handle it 143710234Syasuko.eckert@amd.com if (pClear.lpszOpen == XMLClearTags[1].lpszOpen) { 143810234Syasuko.eckert@amd.com XMLCSTR pCh = lpXML; 143910234Syasuko.eckert@amd.com while (*pCh) { 144010234Syasuko.eckert@amd.com if (*pCh == _CXML('<')) { 144110234Syasuko.eckert@amd.com pClear.lpszClose = docTypeEnd; 144210234Syasuko.eckert@amd.com lpszTemp = xstrstr(lpXML, docTypeEnd); 144310234Syasuko.eckert@amd.com break; 144410234Syasuko.eckert@amd.com } else if (*pCh == _CXML('>')) { 144510234Syasuko.eckert@amd.com lpszTemp = pCh; 144610234Syasuko.eckert@amd.com break; 144710234Syasuko.eckert@amd.com } 144810152Satgutier@umich.edu#ifdef _XMLWIDECHAR 144910152Satgutier@umich.edu pCh++; 145010152Satgutier@umich.edu#else 145110234Syasuko.eckert@amd.com pCh += XML_ByteTable[(unsigned char)(*pCh)]; 145210152Satgutier@umich.edu#endif 145310152Satgutier@umich.edu } 145410234Syasuko.eckert@amd.com } else lpszTemp = xstrstr(lpXML, pClear.lpszClose); 145510152Satgutier@umich.edu 145610234Syasuko.eckert@amd.com if (lpszTemp) { 145710152Satgutier@umich.edu // Cache the size and increment the index 145810152Satgutier@umich.edu cbTemp = (int)(lpszTemp - lpXML); 145910152Satgutier@umich.edu 146010234Syasuko.eckert@amd.com pXML->nIndex += cbTemp + (int)xstrlen(pClear.lpszClose); 146110152Satgutier@umich.edu 146210152Satgutier@umich.edu // Add the clear node to the current element 146310234Syasuko.eckert@amd.com addClear_priv(MEMORYINCREASE, stringDup(lpXML, cbTemp), 146410234Syasuko.eckert@amd.com pClear.lpszOpen, pClear.lpszClose, -1); 146510152Satgutier@umich.edu return 0; 146610152Satgutier@umich.edu } 146710152Satgutier@umich.edu 146810152Satgutier@umich.edu // If we failed to find the end tag 146910152Satgutier@umich.edu pXML->error = eXMLErrorUnmatchedEndClearTag; 147010152Satgutier@umich.edu return 1; 147110152Satgutier@umich.edu} 147210152Satgutier@umich.edu 147310234Syasuko.eckert@amd.comvoid XMLNode::exactMemory(XMLNodeData *d) { 147410234Syasuko.eckert@amd.com if (d->pOrder) { 147510234Syasuko.eckert@amd.com d->pOrder = (int*)realloc(d->pOrder, (d->nChild + d->nText + d->nClear) 147610234Syasuko.eckert@amd.com * sizeof(int)); 147710234Syasuko.eckert@amd.com } 147810234Syasuko.eckert@amd.com if (d->pChild) { 147910234Syasuko.eckert@amd.com d->pChild = (XMLNode*)realloc(d->pChild, d->nChild * sizeof(XMLNode)); 148010234Syasuko.eckert@amd.com } 148110234Syasuko.eckert@amd.com if (d->pAttribute) { 148210234Syasuko.eckert@amd.com d->pAttribute = (XMLAttribute*)realloc(d->pAttribute, d->nAttribute * 148310234Syasuko.eckert@amd.com sizeof(XMLAttribute)); 148410234Syasuko.eckert@amd.com } 148510234Syasuko.eckert@amd.com if (d->pText) { 148610234Syasuko.eckert@amd.com d->pText = (XMLCSTR*)realloc(d->pText, d->nText * sizeof(XMLSTR)); 148710234Syasuko.eckert@amd.com } 148810234Syasuko.eckert@amd.com if (d->pClear) { 148910234Syasuko.eckert@amd.com d->pClear = (XMLClear *)realloc(d->pClear, d->nClear * sizeof(XMLClear)); 149010234Syasuko.eckert@amd.com } 149110152Satgutier@umich.edu} 149210152Satgutier@umich.edu 149310234Syasuko.eckert@amd.comchar XMLNode::maybeAddTxT(void *pa, XMLCSTR tokenPStr) { 149410234Syasuko.eckert@amd.com XML *pXML = (XML *)pa; 149510234Syasuko.eckert@amd.com XMLCSTR lpszText = pXML->lpszText; 149610152Satgutier@umich.edu if (!lpszText) return 0; 149710234Syasuko.eckert@amd.com if (dropWhiteSpace) while (XML_isSPACECHAR(*lpszText) && 149810234Syasuko.eckert@amd.com (lpszText != tokenPStr)) lpszText++; 149910152Satgutier@umich.edu int cbText = (int)(tokenPStr - lpszText); 150010234Syasuko.eckert@amd.com if (!cbText) { 150110234Syasuko.eckert@amd.com pXML->lpszText = NULL; 150210234Syasuko.eckert@amd.com return 0; 150310234Syasuko.eckert@amd.com } 150410234Syasuko.eckert@amd.com if (dropWhiteSpace) { 150510234Syasuko.eckert@amd.com cbText--; 150610234Syasuko.eckert@amd.com while ((cbText) && XML_isSPACECHAR(lpszText[cbText])) cbText--; 150710234Syasuko.eckert@amd.com cbText++; 150810234Syasuko.eckert@amd.com } 150910234Syasuko.eckert@amd.com if (!cbText) { 151010234Syasuko.eckert@amd.com pXML->lpszText = NULL; 151110234Syasuko.eckert@amd.com return 0; 151210234Syasuko.eckert@amd.com } 151310234Syasuko.eckert@amd.com XMLSTR lpt = fromXMLString(lpszText, cbText, pXML); 151410152Satgutier@umich.edu if (!lpt) return 1; 151510234Syasuko.eckert@amd.com pXML->lpszText = NULL; 151610234Syasuko.eckert@amd.com if (removeCommentsInMiddleOfText && d->nText && d->nClear) { 151710152Satgutier@umich.edu // if the previous insertion was a comment (<!-- -->) AND 151810152Satgutier@umich.edu // if the previous previous insertion was a text then, delete the comment and append the text 151910234Syasuko.eckert@amd.com int n = d->nChild + d->nText + d->nClear - 1, *o = d->pOrder; 152010234Syasuko.eckert@amd.com if (((o[n]&3) == eNodeClear) && ((o[n-1]&3) == eNodeText)) { 152110234Syasuko.eckert@amd.com int i = o[n] >> 2; 152210234Syasuko.eckert@amd.com if (d->pClear[i].lpszOpenTag == XMLClearTags[2].lpszOpen) { 152310152Satgutier@umich.edu deleteClear(i); 152410234Syasuko.eckert@amd.com i = o[n-1] >> 2; 152510234Syasuko.eckert@amd.com n = xstrlen(d->pText[i]); 152610234Syasuko.eckert@amd.com int n2 = xstrlen(lpt) + 1; 152710234Syasuko.eckert@amd.com d->pText[i] = (XMLSTR)realloc((void*)d->pText[i], (n + n2) * 152810234Syasuko.eckert@amd.com sizeof(XMLCHAR)); 152910152Satgutier@umich.edu if (!d->pText[i]) return 1; 153010234Syasuko.eckert@amd.com memcpy((void*)(d->pText[i] + n), lpt, n2*sizeof(XMLCHAR)); 153110152Satgutier@umich.edu free(lpt); 153210152Satgutier@umich.edu return 0; 153310152Satgutier@umich.edu } 153410152Satgutier@umich.edu } 153510152Satgutier@umich.edu } 153610234Syasuko.eckert@amd.com addText_priv(MEMORYINCREASE, lpt, -1); 153710152Satgutier@umich.edu return 0; 153810152Satgutier@umich.edu} 153910152Satgutier@umich.edu// private: 154010152Satgutier@umich.edu// Recursively parse an XML element. 154110234Syasuko.eckert@amd.comint XMLNode::ParseXMLElement(void *pa) { 154210234Syasuko.eckert@amd.com XML *pXML = (XML *)pa; 154310152Satgutier@umich.edu int cbToken; 154410152Satgutier@umich.edu enum XMLTokenTypeTag xtype; 154510152Satgutier@umich.edu NextToken token; 154610234Syasuko.eckert@amd.com XMLCSTR lpszTemp = NULL; 154710234Syasuko.eckert@amd.com int cbTemp = 0; 154810152Satgutier@umich.edu char nDeclaration; 154910152Satgutier@umich.edu XMLNode pNew; 155010152Satgutier@umich.edu enum Status status; // inside or outside a tag 155110152Satgutier@umich.edu enum Attrib attrib = eAttribName; 155210152Satgutier@umich.edu 155310152Satgutier@umich.edu assert(pXML); 155410152Satgutier@umich.edu 155510152Satgutier@umich.edu // If this is the first call to the function 155610234Syasuko.eckert@amd.com if (pXML->nFirst) { 155710152Satgutier@umich.edu // Assume we are outside of a tag definition 155810152Satgutier@umich.edu pXML->nFirst = FALSE; 155910152Satgutier@umich.edu status = eOutsideTag; 156010234Syasuko.eckert@amd.com } else { 156110152Satgutier@umich.edu // If this is not the first call then we should only be called when inside a tag. 156210152Satgutier@umich.edu status = eInsideTag; 156310152Satgutier@umich.edu } 156410152Satgutier@umich.edu 156510152Satgutier@umich.edu // Iterate through the tokens in the document 156610234Syasuko.eckert@amd.com for (;;) { 156710152Satgutier@umich.edu // Obtain the next token 156810152Satgutier@umich.edu token = GetNextToken(pXML, &cbToken, &xtype); 156910152Satgutier@umich.edu 157010234Syasuko.eckert@amd.com if (xtype != eTokenError) { 157110152Satgutier@umich.edu // Check the current status 157210234Syasuko.eckert@amd.com switch (status) { 157310152Satgutier@umich.edu 157410234Syasuko.eckert@amd.com // If we are outside of a tag definition 157510152Satgutier@umich.edu case eOutsideTag: 157610152Satgutier@umich.edu 157710152Satgutier@umich.edu // Check what type of token we obtained 157810234Syasuko.eckert@amd.com switch (xtype) { 157910234Syasuko.eckert@amd.com // If we have found text or quoted text 158010152Satgutier@umich.edu case eTokenText: 158110152Satgutier@umich.edu case eTokenCloseTag: /* '>' */ 158210152Satgutier@umich.edu case eTokenShortHandClose: /* '/>' */ 158310152Satgutier@umich.edu case eTokenQuotedText: 158410152Satgutier@umich.edu case eTokenEquals: 158510152Satgutier@umich.edu break; 158610152Satgutier@umich.edu 158710234Syasuko.eckert@amd.com // If we found a start tag '<' and declarations '<?' 158810152Satgutier@umich.edu case eTokenTagStart: 158910152Satgutier@umich.edu case eTokenDeclaration: 159010152Satgutier@umich.edu 159110152Satgutier@umich.edu // Cache whether this new element is a declaration or not 159210152Satgutier@umich.edu nDeclaration = (xtype == eTokenDeclaration); 159310152Satgutier@umich.edu 159410152Satgutier@umich.edu // If we have node text then add this to the element 159510234Syasuko.eckert@amd.com if (maybeAddTxT(pXML, token.pStr)) return FALSE; 159610152Satgutier@umich.edu 159710152Satgutier@umich.edu // Find the name of the tag 159810152Satgutier@umich.edu token = GetNextToken(pXML, &cbToken, &xtype); 159910152Satgutier@umich.edu 160010152Satgutier@umich.edu // Return an error if we couldn't obtain the next token or 160110152Satgutier@umich.edu // it wasnt text 160210234Syasuko.eckert@amd.com if (xtype != eTokenText) { 160310152Satgutier@umich.edu pXML->error = eXMLErrorMissingTagName; 160410152Satgutier@umich.edu return FALSE; 160510152Satgutier@umich.edu } 160610152Satgutier@umich.edu 160710152Satgutier@umich.edu // If we found a new element which is the same as this 160810152Satgutier@umich.edu // element then we need to pass this back to the caller.. 160910152Satgutier@umich.edu 161010152Satgutier@umich.edu#ifdef APPROXIMATE_PARSING 161110152Satgutier@umich.edu if (d->lpszName && 161210234Syasuko.eckert@amd.com myTagCompare(d->lpszName, token.pStr) == 0) { 161310152Satgutier@umich.edu // Indicate to the caller that it needs to create a 161410152Satgutier@umich.edu // new element. 161510152Satgutier@umich.edu pXML->lpNewElement = token.pStr; 161610152Satgutier@umich.edu pXML->cbNewElement = cbToken; 161710152Satgutier@umich.edu return TRUE; 161810152Satgutier@umich.edu } else 161910152Satgutier@umich.edu#endif 162010152Satgutier@umich.edu { 162110152Satgutier@umich.edu // If the name of the new element differs from the name of 162210152Satgutier@umich.edu // the current element we need to add the new element to 162310152Satgutier@umich.edu // the current one and recurse 162410234Syasuko.eckert@amd.com pNew = addChild_priv(MEMORYINCREASE, 162510234Syasuko.eckert@amd.com stringDup(token.pStr, cbToken), 162610234Syasuko.eckert@amd.com nDeclaration, -1); 162710152Satgutier@umich.edu 162810234Syasuko.eckert@amd.com while (!pNew.isEmpty()) { 162910152Satgutier@umich.edu // Callself to process the new node. If we return 163010152Satgutier@umich.edu // FALSE this means we dont have any more 163110152Satgutier@umich.edu // processing to do... 163210152Satgutier@umich.edu 163310152Satgutier@umich.edu if (!pNew.ParseXMLElement(pXML)) return FALSE; 163410234Syasuko.eckert@amd.com else { 163510152Satgutier@umich.edu // If the call to recurse this function 163610152Satgutier@umich.edu // evented in a end tag specified in XML then 163710152Satgutier@umich.edu // we need to unwind the calls to this 163810152Satgutier@umich.edu // function until we find the appropriate node 163910152Satgutier@umich.edu // (the element name and end tag name must 164010152Satgutier@umich.edu // match) 164110234Syasuko.eckert@amd.com if (pXML->cbEndTag) { 164210152Satgutier@umich.edu // If we are back at the root node then we 164310152Satgutier@umich.edu // have an unmatched end tag 164410234Syasuko.eckert@amd.com if (!d->lpszName) { 164510234Syasuko.eckert@amd.com pXML->error = eXMLErrorUnmatchedEndTag; 164610152Satgutier@umich.edu return FALSE; 164710152Satgutier@umich.edu } 164810152Satgutier@umich.edu 164910152Satgutier@umich.edu // If the end tag matches the name of this 165010152Satgutier@umich.edu // element then we only need to unwind 165110152Satgutier@umich.edu // once more... 165210152Satgutier@umich.edu 165310234Syasuko.eckert@amd.com if (myTagCompare(d->lpszName, 165410234Syasuko.eckert@amd.com pXML->lpEndTag) == 0) { 165510152Satgutier@umich.edu pXML->cbEndTag = 0; 165610152Satgutier@umich.edu } 165710152Satgutier@umich.edu 165810152Satgutier@umich.edu return TRUE; 165910234Syasuko.eckert@amd.com } else if (pXML->cbNewElement) { 166010234Syasuko.eckert@amd.com // If the call indicated a new element is to 166110234Syasuko.eckert@amd.com // be created on THIS element. 166210152Satgutier@umich.edu 166310234Syasuko.eckert@amd.com // If the name of this element matches the 166410234Syasuko.eckert@amd.com // name of the element we need to create 166510234Syasuko.eckert@amd.com // then we need to return to the caller 166610234Syasuko.eckert@amd.com // and let it process the element. 166710152Satgutier@umich.edu 166810234Syasuko.eckert@amd.com if (myTagCompare(d->lpszName, 166910234Syasuko.eckert@amd.com pXML->lpNewElement) == 0) { 167010234Syasuko.eckert@amd.com return TRUE; 167110234Syasuko.eckert@amd.com } 167210152Satgutier@umich.edu 167310234Syasuko.eckert@amd.com // Add the new element and recurse 167410234Syasuko.eckert@amd.com pNew = 167510234Syasuko.eckert@amd.com addChild_priv(MEMORYINCREASE, 167610234Syasuko.eckert@amd.com stringDup(pXML-> 167710234Syasuko.eckert@amd.com lpNewElement, 167810234Syasuko.eckert@amd.com pXML-> 167910234Syasuko.eckert@amd.com cbNewElement), 168010234Syasuko.eckert@amd.com 0, -1); 168110234Syasuko.eckert@amd.com pXML->cbNewElement = 0; 168210234Syasuko.eckert@amd.com } else { 168310234Syasuko.eckert@amd.com // If we didn't have a new element to create 168410234Syasuko.eckert@amd.com pNew = emptyXMLNode; 168510152Satgutier@umich.edu 168610234Syasuko.eckert@amd.com } 168710152Satgutier@umich.edu } 168810152Satgutier@umich.edu } 168910152Satgutier@umich.edu } 169010152Satgutier@umich.edu break; 169110152Satgutier@umich.edu 169210234Syasuko.eckert@amd.com // If we found an end tag 169310152Satgutier@umich.edu case eTokenTagEnd: 169410152Satgutier@umich.edu 169510152Satgutier@umich.edu // If we have node text then add this to the element 169610234Syasuko.eckert@amd.com if (maybeAddTxT(pXML, token.pStr)) return FALSE; 169710152Satgutier@umich.edu 169810152Satgutier@umich.edu // Find the name of the end tag 169910152Satgutier@umich.edu token = GetNextToken(pXML, &cbTemp, &xtype); 170010152Satgutier@umich.edu 170110152Satgutier@umich.edu // The end tag should be text 170210234Syasuko.eckert@amd.com if (xtype != eTokenText) { 170310152Satgutier@umich.edu pXML->error = eXMLErrorMissingEndTagName; 170410152Satgutier@umich.edu return FALSE; 170510152Satgutier@umich.edu } 170610152Satgutier@umich.edu lpszTemp = token.pStr; 170710152Satgutier@umich.edu 170810152Satgutier@umich.edu // After the end tag we should find a closing tag 170910152Satgutier@umich.edu token = GetNextToken(pXML, &cbToken, &xtype); 171010234Syasuko.eckert@amd.com if (xtype != eTokenCloseTag) { 171110152Satgutier@umich.edu pXML->error = eXMLErrorMissingEndTagName; 171210152Satgutier@umich.edu return FALSE; 171310152Satgutier@umich.edu } 171410234Syasuko.eckert@amd.com pXML->lpszText = pXML->lpXML + pXML->nIndex; 171510152Satgutier@umich.edu 171610152Satgutier@umich.edu // We need to return to the previous caller. If the name 171710152Satgutier@umich.edu // of the tag cannot be found we need to keep returning to 171810152Satgutier@umich.edu // caller until we find a match 171910152Satgutier@umich.edu if (myTagCompare(d->lpszName, lpszTemp) != 0) 172010152Satgutier@umich.edu#ifdef STRICT_PARSING 172110152Satgutier@umich.edu { 172210234Syasuko.eckert@amd.com pXML->error = eXMLErrorUnmatchedEndTag; 172310234Syasuko.eckert@amd.com pXML->nIndexMissigEndTag = pXML->nIndex; 172410152Satgutier@umich.edu return FALSE; 172510152Satgutier@umich.edu } 172610152Satgutier@umich.edu#else 172710152Satgutier@umich.edu { 172810234Syasuko.eckert@amd.com pXML->error = eXMLErrorMissingEndTag; 172910234Syasuko.eckert@amd.com pXML->nIndexMissigEndTag = pXML->nIndex; 173010152Satgutier@umich.edu pXML->lpEndTag = lpszTemp; 173110152Satgutier@umich.edu pXML->cbEndTag = cbTemp; 173210152Satgutier@umich.edu } 173310152Satgutier@umich.edu#endif 173410152Satgutier@umich.edu 173510152Satgutier@umich.edu // Return to the caller 173610152Satgutier@umich.edu exactMemory(d); 173710152Satgutier@umich.edu return TRUE; 173810152Satgutier@umich.edu 173910234Syasuko.eckert@amd.com // If we found a clear (unformatted) token 174010152Satgutier@umich.edu case eTokenClear: 174110152Satgutier@umich.edu // If we have node text then add this to the element 174210234Syasuko.eckert@amd.com if (maybeAddTxT(pXML, token.pStr)) return FALSE; 174310152Satgutier@umich.edu if (parseClearTag(pXML, token.pClr)) return FALSE; 174410234Syasuko.eckert@amd.com pXML->lpszText = pXML->lpXML + pXML->nIndex; 174510152Satgutier@umich.edu break; 174610152Satgutier@umich.edu 174710152Satgutier@umich.edu default: 174810152Satgutier@umich.edu break; 174910152Satgutier@umich.edu } 175010152Satgutier@umich.edu break; 175110152Satgutier@umich.edu 175210234Syasuko.eckert@amd.com // If we are inside a tag definition we need to search for attributes 175310152Satgutier@umich.edu case eInsideTag: 175410152Satgutier@umich.edu 175510152Satgutier@umich.edu // Check what part of the attribute (name, equals, value) we 175610152Satgutier@umich.edu // are looking for. 175710234Syasuko.eckert@amd.com switch (attrib) { 175810234Syasuko.eckert@amd.com // If we are looking for a new attribute 175910152Satgutier@umich.edu case eAttribName: 176010152Satgutier@umich.edu 176110152Satgutier@umich.edu // Check what the current token type is 176210234Syasuko.eckert@amd.com switch (xtype) { 176310234Syasuko.eckert@amd.com // If the current type is text... 176410234Syasuko.eckert@amd.com // Eg. 'attribute' 176510152Satgutier@umich.edu case eTokenText: 176610152Satgutier@umich.edu // Cache the token then indicate that we are next to 176710152Satgutier@umich.edu // look for the equals 176810152Satgutier@umich.edu lpszTemp = token.pStr; 176910152Satgutier@umich.edu cbTemp = cbToken; 177010152Satgutier@umich.edu attrib = eAttribEquals; 177110152Satgutier@umich.edu break; 177210152Satgutier@umich.edu 177310234Syasuko.eckert@amd.com // If we found a closing tag... 177410234Syasuko.eckert@amd.com // Eg. '>' 177510152Satgutier@umich.edu case eTokenCloseTag: 177610152Satgutier@umich.edu // We are now outside the tag 177710152Satgutier@umich.edu status = eOutsideTag; 177810234Syasuko.eckert@amd.com pXML->lpszText = pXML->lpXML + pXML->nIndex; 177910152Satgutier@umich.edu break; 178010152Satgutier@umich.edu 178110234Syasuko.eckert@amd.com // If we found a short hand '/>' closing tag then we can 178210234Syasuko.eckert@amd.com // return to the caller 178310152Satgutier@umich.edu case eTokenShortHandClose: 178410152Satgutier@umich.edu exactMemory(d); 178510234Syasuko.eckert@amd.com pXML->lpszText = pXML->lpXML + pXML->nIndex; 178610152Satgutier@umich.edu return TRUE; 178710152Satgutier@umich.edu 178810234Syasuko.eckert@amd.com // Errors... 178910152Satgutier@umich.edu case eTokenQuotedText: /* '"SomeText"' */ 179010152Satgutier@umich.edu case eTokenTagStart: /* '<' */ 179110152Satgutier@umich.edu case eTokenTagEnd: /* '</' */ 179210152Satgutier@umich.edu case eTokenEquals: /* '=' */ 179310152Satgutier@umich.edu case eTokenDeclaration: /* '<?' */ 179410152Satgutier@umich.edu case eTokenClear: 179510152Satgutier@umich.edu pXML->error = eXMLErrorUnexpectedToken; 179610152Satgutier@umich.edu return FALSE; 179710234Syasuko.eckert@amd.com default: 179810234Syasuko.eckert@amd.com break; 179910152Satgutier@umich.edu } 180010152Satgutier@umich.edu break; 180110152Satgutier@umich.edu 180210234Syasuko.eckert@amd.com // If we are looking for an equals 180310152Satgutier@umich.edu case eAttribEquals: 180410152Satgutier@umich.edu // Check what the current token type is 180510234Syasuko.eckert@amd.com switch (xtype) { 180610234Syasuko.eckert@amd.com // If the current type is text... 180710234Syasuko.eckert@amd.com // Eg. 'Attribute AnotherAttribute' 180810152Satgutier@umich.edu case eTokenText: 180910152Satgutier@umich.edu // Add the unvalued attribute to the list 181010234Syasuko.eckert@amd.com addAttribute_priv(MEMORYINCREASE, 181110234Syasuko.eckert@amd.com stringDup(lpszTemp, cbTemp), NULL); 181210152Satgutier@umich.edu // Cache the token then indicate. We are next to 181310152Satgutier@umich.edu // look for the equals attribute 181410152Satgutier@umich.edu lpszTemp = token.pStr; 181510152Satgutier@umich.edu cbTemp = cbToken; 181610152Satgutier@umich.edu break; 181710152Satgutier@umich.edu 181810234Syasuko.eckert@amd.com // If we found a closing tag 'Attribute >' or a short hand 181910234Syasuko.eckert@amd.com // closing tag 'Attribute />' 182010152Satgutier@umich.edu case eTokenShortHandClose: 182110152Satgutier@umich.edu case eTokenCloseTag: 182210152Satgutier@umich.edu // If we are a declaration element '<?' then we need 182310152Satgutier@umich.edu // to remove extra closing '?' if it exists 182410234Syasuko.eckert@amd.com pXML->lpszText = pXML->lpXML + pXML->nIndex; 182510152Satgutier@umich.edu 182610152Satgutier@umich.edu if (d->isDeclaration && 182710234Syasuko.eckert@amd.com (lpszTemp[cbTemp-1]) == _CXML('?')) { 182810152Satgutier@umich.edu cbTemp--; 182910234Syasuko.eckert@amd.com if (d->pParent && d->pParent->pParent) { 183010234Syasuko.eckert@amd.com xtype = eTokenShortHandClose; 183110234Syasuko.eckert@amd.com } 183210152Satgutier@umich.edu } 183310152Satgutier@umich.edu 183410234Syasuko.eckert@amd.com if (cbTemp) { 183510152Satgutier@umich.edu // Add the unvalued attribute to the list 183610234Syasuko.eckert@amd.com addAttribute_priv(MEMORYINCREASE, 183710234Syasuko.eckert@amd.com stringDup(lpszTemp, cbTemp), NULL); 183810152Satgutier@umich.edu } 183910152Satgutier@umich.edu 184010152Satgutier@umich.edu // If this is the end of the tag then return to the caller 184110234Syasuko.eckert@amd.com if (xtype == eTokenShortHandClose) { 184210152Satgutier@umich.edu exactMemory(d); 184310152Satgutier@umich.edu return TRUE; 184410152Satgutier@umich.edu } 184510152Satgutier@umich.edu 184610152Satgutier@umich.edu // We are now outside the tag 184710152Satgutier@umich.edu status = eOutsideTag; 184810152Satgutier@umich.edu break; 184910152Satgutier@umich.edu 185010234Syasuko.eckert@amd.com // If we found the equals token... 185110234Syasuko.eckert@amd.com // Eg. 'Attribute =' 185210152Satgutier@umich.edu case eTokenEquals: 185310152Satgutier@umich.edu // Indicate that we next need to search for the value 185410152Satgutier@umich.edu // for the attribute 185510152Satgutier@umich.edu attrib = eAttribValue; 185610152Satgutier@umich.edu break; 185710152Satgutier@umich.edu 185810234Syasuko.eckert@amd.com // Errors... 185910152Satgutier@umich.edu case eTokenQuotedText: /* 'Attribute "InvalidAttr"'*/ 186010152Satgutier@umich.edu case eTokenTagStart: /* 'Attribute <' */ 186110152Satgutier@umich.edu case eTokenTagEnd: /* 'Attribute </' */ 186210152Satgutier@umich.edu case eTokenDeclaration: /* 'Attribute <?' */ 186310152Satgutier@umich.edu case eTokenClear: 186410152Satgutier@umich.edu pXML->error = eXMLErrorUnexpectedToken; 186510152Satgutier@umich.edu return FALSE; 186610234Syasuko.eckert@amd.com default: 186710234Syasuko.eckert@amd.com break; 186810152Satgutier@umich.edu } 186910152Satgutier@umich.edu break; 187010152Satgutier@umich.edu 187110234Syasuko.eckert@amd.com // If we are looking for an attribute value 187210152Satgutier@umich.edu case eAttribValue: 187310152Satgutier@umich.edu // Check what the current token type is 187410234Syasuko.eckert@amd.com switch (xtype) { 187510234Syasuko.eckert@amd.com // If the current type is text or quoted text... 187610234Syasuko.eckert@amd.com // Eg. 'Attribute = "Value"' or 'Attribute = Value' or 187710234Syasuko.eckert@amd.com // 'Attribute = 'Value''. 187810152Satgutier@umich.edu case eTokenText: 187910152Satgutier@umich.edu case eTokenQuotedText: 188010152Satgutier@umich.edu // If we are a declaration element '<?' then we need 188110152Satgutier@umich.edu // to remove extra closing '?' if it exists 188210152Satgutier@umich.edu if (d->isDeclaration && 188310234Syasuko.eckert@amd.com (token.pStr[cbToken-1]) == _CXML('?')) { 188410152Satgutier@umich.edu cbToken--; 188510152Satgutier@umich.edu } 188610152Satgutier@umich.edu 188710234Syasuko.eckert@amd.com if (cbTemp) { 188810152Satgutier@umich.edu // Add the valued attribute to the list 188910234Syasuko.eckert@amd.com if (xtype == eTokenQuotedText) { 189010234Syasuko.eckert@amd.com token.pStr++; 189110234Syasuko.eckert@amd.com cbToken -= 2; 189210234Syasuko.eckert@amd.com } 189310234Syasuko.eckert@amd.com XMLSTR attrVal = (XMLSTR)token.pStr; 189410234Syasuko.eckert@amd.com if (attrVal) { 189510234Syasuko.eckert@amd.com attrVal = fromXMLString(attrVal, cbToken, pXML); 189610152Satgutier@umich.edu if (!attrVal) return FALSE; 189710152Satgutier@umich.edu } 189810234Syasuko.eckert@amd.com addAttribute_priv(MEMORYINCREASE, 189910234Syasuko.eckert@amd.com stringDup(lpszTemp, cbTemp), 190010234Syasuko.eckert@amd.com attrVal); 190110152Satgutier@umich.edu } 190210152Satgutier@umich.edu 190310152Satgutier@umich.edu // Indicate we are searching for a new attribute 190410152Satgutier@umich.edu attrib = eAttribName; 190510152Satgutier@umich.edu break; 190610152Satgutier@umich.edu 190710234Syasuko.eckert@amd.com // Errors... 190810152Satgutier@umich.edu case eTokenTagStart: /* 'Attr = <' */ 190910152Satgutier@umich.edu case eTokenTagEnd: /* 'Attr = </' */ 191010152Satgutier@umich.edu case eTokenCloseTag: /* 'Attr = >' */ 191110152Satgutier@umich.edu case eTokenShortHandClose: /* "Attr = />" */ 191210152Satgutier@umich.edu case eTokenEquals: /* 'Attr = =' */ 191310152Satgutier@umich.edu case eTokenDeclaration: /* 'Attr = <?' */ 191410152Satgutier@umich.edu case eTokenClear: 191510152Satgutier@umich.edu pXML->error = eXMLErrorUnexpectedToken; 191610152Satgutier@umich.edu return FALSE; 191710152Satgutier@umich.edu break; 191810234Syasuko.eckert@amd.com default: 191910234Syasuko.eckert@amd.com break; 192010152Satgutier@umich.edu } 192110152Satgutier@umich.edu } 192210152Satgutier@umich.edu } 192310152Satgutier@umich.edu } 192410152Satgutier@umich.edu // If we failed to obtain the next token 192510234Syasuko.eckert@amd.com else { 192610234Syasuko.eckert@amd.com if ((!d->isDeclaration) && (d->pParent)) { 192710152Satgutier@umich.edu#ifdef STRICT_PARSING 192810234Syasuko.eckert@amd.com pXML->error = eXMLErrorUnmatchedEndTag; 192910152Satgutier@umich.edu#else 193010234Syasuko.eckert@amd.com pXML->error = eXMLErrorMissingEndTag; 193110152Satgutier@umich.edu#endif 193210234Syasuko.eckert@amd.com pXML->nIndexMissigEndTag = pXML->nIndex; 193310152Satgutier@umich.edu } 193410234Syasuko.eckert@amd.com maybeAddTxT(pXML, pXML->lpXML + pXML->nIndex); 193510152Satgutier@umich.edu return FALSE; 193610152Satgutier@umich.edu } 193710152Satgutier@umich.edu } 193810152Satgutier@umich.edu} 193910152Satgutier@umich.edu 194010152Satgutier@umich.edu// Count the number of lines and columns in an XML string. 194110234Syasuko.eckert@amd.comstatic void CountLinesAndColumns(XMLCSTR lpXML, int nUpto, 194210234Syasuko.eckert@amd.com XMLResults *pResults) { 194310152Satgutier@umich.edu XMLCHAR ch; 194410152Satgutier@umich.edu assert(lpXML); 194510152Satgutier@umich.edu assert(pResults); 194610152Satgutier@umich.edu 194710234Syasuko.eckert@amd.com struct XML xml = { lpXML, lpXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, 194810234Syasuko.eckert@amd.com TRUE }; 194910152Satgutier@umich.edu 195010152Satgutier@umich.edu pResults->nLine = 1; 195110152Satgutier@umich.edu pResults->nColumn = 1; 195210234Syasuko.eckert@amd.com while (xml.nIndex < nUpto) { 195310152Satgutier@umich.edu ch = getNextChar(&xml); 195410152Satgutier@umich.edu if (ch != _CXML('\n')) pResults->nColumn++; 195510234Syasuko.eckert@amd.com else { 195610152Satgutier@umich.edu pResults->nLine++; 195710234Syasuko.eckert@amd.com pResults->nColumn = 1; 195810152Satgutier@umich.edu } 195910152Satgutier@umich.edu } 196010152Satgutier@umich.edu} 196110152Satgutier@umich.edu 196210152Satgutier@umich.edu// Parse XML and return the root element. 196310234Syasuko.eckert@amd.comXMLNode XMLNode::parseString(XMLCSTR lpszXML, XMLCSTR tag, 196410234Syasuko.eckert@amd.com XMLResults *pResults) { 196510234Syasuko.eckert@amd.com if (!lpszXML) { 196610234Syasuko.eckert@amd.com if (pResults) { 196710234Syasuko.eckert@amd.com pResults->error = eXMLErrorNoElements; 196810234Syasuko.eckert@amd.com pResults->nLine = 0; 196910234Syasuko.eckert@amd.com pResults->nColumn = 0; 197010152Satgutier@umich.edu } 197110152Satgutier@umich.edu return emptyXMLNode; 197210152Satgutier@umich.edu } 197310152Satgutier@umich.edu 197410234Syasuko.eckert@amd.com XMLNode xnode(NULL, NULL, FALSE); 197510234Syasuko.eckert@amd.com struct XML xml = { lpszXML, lpszXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, 197610234Syasuko.eckert@amd.com TRUE }; 197710152Satgutier@umich.edu 197810152Satgutier@umich.edu // Create header element 197910152Satgutier@umich.edu xnode.ParseXMLElement(&xml); 198010152Satgutier@umich.edu enum XMLError error = xml.error; 198110234Syasuko.eckert@amd.com if (!xnode.nChildNode()) error = eXMLErrorNoXMLTagFound; 198210234Syasuko.eckert@amd.com if ((xnode.nChildNode() == 1) && (xnode.nElement() == 1)) { 198310234Syasuko.eckert@amd.com xnode = xnode.getChildNode(); // skip the empty node 198410234Syasuko.eckert@amd.com } 198510152Satgutier@umich.edu 198610152Satgutier@umich.edu // If no error occurred 198710234Syasuko.eckert@amd.com if ((error == eXMLErrorNone) || (error == eXMLErrorMissingEndTag) || 198810234Syasuko.eckert@amd.com (error == eXMLErrorNoXMLTagFound)) { 198910234Syasuko.eckert@amd.com XMLCSTR name = xnode.getName(); 199010234Syasuko.eckert@amd.com if (tag && (*tag) && ((!name) || (xstricmp(name, tag)))) { 199110234Syasuko.eckert@amd.com xnode = xnode.getChildNode(tag); 199210234Syasuko.eckert@amd.com if (xnode.isEmpty()) { 199310234Syasuko.eckert@amd.com if (pResults) { 199410234Syasuko.eckert@amd.com pResults->error = eXMLErrorFirstTagNotFound; 199510234Syasuko.eckert@amd.com pResults->nLine = 0; 199610234Syasuko.eckert@amd.com pResults->nColumn = 0; 199710152Satgutier@umich.edu } 199810152Satgutier@umich.edu return emptyXMLNode; 199910152Satgutier@umich.edu } 200010152Satgutier@umich.edu } 200110234Syasuko.eckert@amd.com } else { 200210152Satgutier@umich.edu // Cleanup: this will destroy all the nodes 200310152Satgutier@umich.edu xnode = emptyXMLNode; 200410152Satgutier@umich.edu } 200510152Satgutier@umich.edu 200610152Satgutier@umich.edu 200710152Satgutier@umich.edu // If we have been given somewhere to place results 200810234Syasuko.eckert@amd.com if (pResults) { 200910152Satgutier@umich.edu pResults->error = error; 201010152Satgutier@umich.edu 201110152Satgutier@umich.edu // If we have an error 201210234Syasuko.eckert@amd.com if (error != eXMLErrorNone) { 201310234Syasuko.eckert@amd.com if (error == eXMLErrorMissingEndTag) { 201410234Syasuko.eckert@amd.com xml.nIndex = xml.nIndexMissigEndTag; 201510234Syasuko.eckert@amd.com } 201610152Satgutier@umich.edu // Find which line and column it starts on. 201710152Satgutier@umich.edu CountLinesAndColumns(xml.lpXML, xml.nIndex, pResults); 201810152Satgutier@umich.edu } 201910152Satgutier@umich.edu } 202010152Satgutier@umich.edu return xnode; 202110152Satgutier@umich.edu} 202210152Satgutier@umich.edu 202310234Syasuko.eckert@amd.comXMLNode XMLNode::parseFile(XMLCSTR filename, XMLCSTR tag, XMLResults *pResults) { 202410234Syasuko.eckert@amd.com if (pResults) { 202510234Syasuko.eckert@amd.com pResults->nLine = 0; 202610234Syasuko.eckert@amd.com pResults->nColumn = 0; 202710234Syasuko.eckert@amd.com } 202810234Syasuko.eckert@amd.com FILE *f = xfopen(filename, _CXML("rb")); 202910234Syasuko.eckert@amd.com if (f == NULL) { 203010234Syasuko.eckert@amd.com if (pResults) pResults->error = eXMLErrorFileNotFound; 203110234Syasuko.eckert@amd.com return emptyXMLNode; 203210234Syasuko.eckert@amd.com } 203310234Syasuko.eckert@amd.com fseek(f, 0, SEEK_END); 203410234Syasuko.eckert@amd.com int l = ftell(f), headerSz = 0; 203510234Syasuko.eckert@amd.com if (!l) { 203610234Syasuko.eckert@amd.com if (pResults) pResults->error = eXMLErrorEmpty; 203710234Syasuko.eckert@amd.com fclose(f); 203810234Syasuko.eckert@amd.com return emptyXMLNode; 203910234Syasuko.eckert@amd.com } 204010234Syasuko.eckert@amd.com fseek(f, 0, SEEK_SET); 204110234Syasuko.eckert@amd.com unsigned char *buf = (unsigned char*)malloc(l + 4); 204210234Syasuko.eckert@amd.com l = fread(buf, 1, l, f); 204310152Satgutier@umich.edu fclose(f); 204410234Syasuko.eckert@amd.com buf[l] = 0; 204510234Syasuko.eckert@amd.com buf[l+1] = 0; 204610234Syasuko.eckert@amd.com buf[l+2] = 0; 204710234Syasuko.eckert@amd.com buf[l+3] = 0; 204810152Satgutier@umich.edu#ifdef _XMLWIDECHAR 204910234Syasuko.eckert@amd.com if (guessWideCharChars) { 205010234Syasuko.eckert@amd.com if (!myIsTextWideChar(buf, l)) { 205110234Syasuko.eckert@amd.com XMLNode::XMLCharEncoding ce = XMLNode::char_encoding_legacy; 205210234Syasuko.eckert@amd.com if ((buf[0] == 0xef) && (buf[1] == 0xbb) && (buf[2] == 0xbf)) { 205310234Syasuko.eckert@amd.com headerSz = 3; 205410234Syasuko.eckert@amd.com ce = XMLNode::char_encoding_UTF8; 205510234Syasuko.eckert@amd.com } 205610234Syasuko.eckert@amd.com XMLSTR b2 = myMultiByteToWideChar((const char*)(buf + headerSz), ce); 205710234Syasuko.eckert@amd.com free(buf); 205810234Syasuko.eckert@amd.com buf = (unsigned char*)b2; 205910234Syasuko.eckert@amd.com headerSz = 0; 206010234Syasuko.eckert@amd.com } else { 206110234Syasuko.eckert@amd.com if ((buf[0] == 0xef) && (buf[1] == 0xff)) headerSz = 2; 206210234Syasuko.eckert@amd.com if ((buf[0] == 0xff) && (buf[1] == 0xfe)) headerSz = 2; 206310152Satgutier@umich.edu } 206410152Satgutier@umich.edu } 206510152Satgutier@umich.edu#else 206610234Syasuko.eckert@amd.com if (guessWideCharChars) { 206710234Syasuko.eckert@amd.com if (myIsTextWideChar(buf, l)) { 206810234Syasuko.eckert@amd.com if ((buf[0] == 0xef) && (buf[1] == 0xff)) headerSz = 2; 206910234Syasuko.eckert@amd.com if ((buf[0] == 0xff) && (buf[1] == 0xfe)) headerSz = 2; 207010234Syasuko.eckert@amd.com char *b2 = myWideCharToMultiByte((const wchar_t*)(buf + headerSz)); 207110234Syasuko.eckert@amd.com free(buf); 207210234Syasuko.eckert@amd.com buf = (unsigned char*)b2; 207310234Syasuko.eckert@amd.com headerSz = 0; 207410234Syasuko.eckert@amd.com } else { 207510234Syasuko.eckert@amd.com if ((buf[0] == 0xef) && (buf[1] == 0xbb) && (buf[2] == 0xbf)) { 207610234Syasuko.eckert@amd.com headerSz = 3; 207710234Syasuko.eckert@amd.com } 207810152Satgutier@umich.edu } 207910152Satgutier@umich.edu } 208010152Satgutier@umich.edu#endif 208110152Satgutier@umich.edu 208210234Syasuko.eckert@amd.com if (!buf) { 208310234Syasuko.eckert@amd.com if (pResults) pResults->error = eXMLErrorCharConversionError; 208410234Syasuko.eckert@amd.com return emptyXMLNode; 208510234Syasuko.eckert@amd.com } 208610234Syasuko.eckert@amd.com XMLNode x = parseString((XMLSTR)(buf + headerSz), tag, pResults); 208710152Satgutier@umich.edu free(buf); 208810152Satgutier@umich.edu return x; 208910152Satgutier@umich.edu} 209010152Satgutier@umich.edu 209110234Syasuko.eckert@amd.comstatic inline void charmemset(XMLSTR dest, XMLCHAR c, int l) { 209210234Syasuko.eckert@amd.com while (l--) *(dest++) = c; 209310234Syasuko.eckert@amd.com} 209410152Satgutier@umich.edu// private: 209510152Satgutier@umich.edu// Creates an user friendly XML string from a given element with 209610152Satgutier@umich.edu// appropriate white space and carriage returns. 209710152Satgutier@umich.edu// 209810152Satgutier@umich.edu// This recurses through all subnodes then adds contents of the nodes to the 209910152Satgutier@umich.edu// string. 210010234Syasuko.eckert@amd.comint XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, 210110234Syasuko.eckert@amd.com int nFormat) { 210210152Satgutier@umich.edu int nResult = 0; 210310234Syasuko.eckert@amd.com int cb = nFormat < 0 ? 0 : nFormat; 210410152Satgutier@umich.edu int cbElement; 210510234Syasuko.eckert@amd.com int nChildFormat = -1; 210610234Syasuko.eckert@amd.com int nElementI = pEntry->nChild + pEntry->nText + pEntry->nClear; 210710234Syasuko.eckert@amd.com int i, j; 210810234Syasuko.eckert@amd.com if ((nFormat >= 0) && (nElementI == 1) && (pEntry->nText == 1) && 210910234Syasuko.eckert@amd.com (!pEntry->isDeclaration)) { 211010234Syasuko.eckert@amd.com nFormat = -2; 211110234Syasuko.eckert@amd.com } 211210152Satgutier@umich.edu 211310152Satgutier@umich.edu assert(pEntry); 211410152Satgutier@umich.edu 211510152Satgutier@umich.edu#define LENSTR(lpsz) (lpsz ? xstrlen(lpsz) : 0) 211610152Satgutier@umich.edu 211710152Satgutier@umich.edu // If the element has no name then assume this is the head node. 211810152Satgutier@umich.edu cbElement = (int)LENSTR(pEntry->lpszName); 211910152Satgutier@umich.edu 212010234Syasuko.eckert@amd.com if (cbElement) { 212110152Satgutier@umich.edu // "<elementname " 212210234Syasuko.eckert@amd.com if (lpszMarker) { 212310152Satgutier@umich.edu if (cb) charmemset(lpszMarker, INDENTCHAR, cb); 212410152Satgutier@umich.edu nResult = cb; 212510234Syasuko.eckert@amd.com lpszMarker[nResult++] = _CXML('<'); 212610234Syasuko.eckert@amd.com if (pEntry->isDeclaration) lpszMarker[nResult++] = _CXML('?'); 212710152Satgutier@umich.edu xstrcpy(&lpszMarker[nResult], pEntry->lpszName); 212810234Syasuko.eckert@amd.com nResult += cbElement; 212910234Syasuko.eckert@amd.com lpszMarker[nResult++] = _CXML(' '); 213010152Satgutier@umich.edu 213110234Syasuko.eckert@amd.com } else { 213210234Syasuko.eckert@amd.com nResult += cbElement + 2 + cb; 213310152Satgutier@umich.edu if (pEntry->isDeclaration) nResult++; 213410152Satgutier@umich.edu } 213510152Satgutier@umich.edu 213610152Satgutier@umich.edu // Enumerate attributes and add them to the string 213710234Syasuko.eckert@amd.com XMLAttribute *pAttr = pEntry->pAttribute; 213810234Syasuko.eckert@amd.com for (i = 0; i < pEntry->nAttribute; i++) { 213910152Satgutier@umich.edu // "Attrib 214010152Satgutier@umich.edu cb = (int)LENSTR(pAttr->lpszName); 214110234Syasuko.eckert@amd.com if (cb) { 214210152Satgutier@umich.edu if (lpszMarker) xstrcpy(&lpszMarker[nResult], pAttr->lpszName); 214310152Satgutier@umich.edu nResult += cb; 214410152Satgutier@umich.edu // "Attrib=Value " 214510234Syasuko.eckert@amd.com if (pAttr->lpszValue) { 214610234Syasuko.eckert@amd.com cb = (int)ToXMLStringTool::lengthXMLString(pAttr->lpszValue); 214710234Syasuko.eckert@amd.com if (lpszMarker) { 214810234Syasuko.eckert@amd.com lpszMarker[nResult] = _CXML('='); 214910234Syasuko.eckert@amd.com lpszMarker[nResult+1] = _CXML('"'); 215010234Syasuko.eckert@amd.com if (cb) { 215110234Syasuko.eckert@amd.com ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult+2], 215210234Syasuko.eckert@amd.com pAttr->lpszValue); 215310234Syasuko.eckert@amd.com } 215410234Syasuko.eckert@amd.com lpszMarker[nResult+cb+2] = _CXML('"'); 215510152Satgutier@umich.edu } 215610234Syasuko.eckert@amd.com nResult += cb + 3; 215710152Satgutier@umich.edu } 215810152Satgutier@umich.edu if (lpszMarker) lpszMarker[nResult] = _CXML(' '); 215910152Satgutier@umich.edu nResult++; 216010152Satgutier@umich.edu } 216110152Satgutier@umich.edu pAttr++; 216210152Satgutier@umich.edu } 216310152Satgutier@umich.edu 216410234Syasuko.eckert@amd.com if (pEntry->isDeclaration) { 216510234Syasuko.eckert@amd.com if (lpszMarker) { 216610234Syasuko.eckert@amd.com lpszMarker[nResult-1] = _CXML('?'); 216710234Syasuko.eckert@amd.com lpszMarker[nResult] = _CXML('>'); 216810152Satgutier@umich.edu } 216910152Satgutier@umich.edu nResult++; 217010234Syasuko.eckert@amd.com if (nFormat != -1) { 217110234Syasuko.eckert@amd.com if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); 217210152Satgutier@umich.edu nResult++; 217310152Satgutier@umich.edu } 217410152Satgutier@umich.edu } else 217510152Satgutier@umich.edu // If there are child nodes we need to terminate the start tag 217610234Syasuko.eckert@amd.com if (nElementI) { 217710234Syasuko.eckert@amd.com if (lpszMarker) lpszMarker[nResult-1] = _CXML('>'); 217810234Syasuko.eckert@amd.com if (nFormat >= 0) { 217910234Syasuko.eckert@amd.com if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); 218010152Satgutier@umich.edu nResult++; 218110152Satgutier@umich.edu } 218210152Satgutier@umich.edu } else nResult--; 218310152Satgutier@umich.edu } 218410152Satgutier@umich.edu 218510152Satgutier@umich.edu // Calculate the child format for when we recurse. This is used to 218610152Satgutier@umich.edu // determine the number of spaces used for prefixes. 218710234Syasuko.eckert@amd.com if (nFormat != -1) { 218810234Syasuko.eckert@amd.com if (cbElement && (!pEntry->isDeclaration)) nChildFormat = nFormat + 1; 218910234Syasuko.eckert@amd.com else nChildFormat = nFormat; 219010152Satgutier@umich.edu } 219110152Satgutier@umich.edu 219210152Satgutier@umich.edu // Enumerate through remaining children 219310234Syasuko.eckert@amd.com for (i = 0; i < nElementI; i++) { 219410234Syasuko.eckert@amd.com j = pEntry->pOrder[i]; 219510234Syasuko.eckert@amd.com switch ((XMLElementType)(j&3)) { 219610234Syasuko.eckert@amd.com // Text nodes 219710234Syasuko.eckert@amd.com case eNodeText: { 219810234Syasuko.eckert@amd.com // "Text" 219910234Syasuko.eckert@amd.com XMLCSTR pChild = pEntry->pText[j>>2]; 220010234Syasuko.eckert@amd.com cb = (int)ToXMLStringTool::lengthXMLString(pChild); 220110234Syasuko.eckert@amd.com if (cb) { 220210234Syasuko.eckert@amd.com if (nFormat >= 0) { 220310234Syasuko.eckert@amd.com if (lpszMarker) { 220410234Syasuko.eckert@amd.com charmemset(&lpszMarker[nResult], INDENTCHAR, 220510234Syasuko.eckert@amd.com nFormat + 1); 220610234Syasuko.eckert@amd.com ToXMLStringTool::toXMLUnSafe( 220710234Syasuko.eckert@amd.com &lpszMarker[nResult+nFormat+1], pChild); 220810234Syasuko.eckert@amd.com lpszMarker[nResult+nFormat+1+cb] = _CXML('\n'); 220910152Satgutier@umich.edu } 221010234Syasuko.eckert@amd.com nResult += cb + nFormat + 2; 221110234Syasuko.eckert@amd.com } else { 221210234Syasuko.eckert@amd.com if (lpszMarker) { 221310234Syasuko.eckert@amd.com ToXMLStringTool::toXMLUnSafe(&lpszMarker[nResult], 221410234Syasuko.eckert@amd.com pChild); 221510234Syasuko.eckert@amd.com } 221610234Syasuko.eckert@amd.com nResult += cb; 221710152Satgutier@umich.edu } 221810234Syasuko.eckert@amd.com } 221910234Syasuko.eckert@amd.com break; 222010234Syasuko.eckert@amd.com } 222110234Syasuko.eckert@amd.com 222210234Syasuko.eckert@amd.com // Clear type nodes 222310234Syasuko.eckert@amd.com case eNodeClear: { 222410234Syasuko.eckert@amd.com XMLClear *pChild = pEntry->pClear + (j >> 2); 222510234Syasuko.eckert@amd.com // "OpenTag" 222610234Syasuko.eckert@amd.com cb = (int)LENSTR(pChild->lpszOpenTag); 222710234Syasuko.eckert@amd.com if (cb) { 222810234Syasuko.eckert@amd.com if (nFormat != -1) { 222910234Syasuko.eckert@amd.com if (lpszMarker) { 223010234Syasuko.eckert@amd.com charmemset(&lpszMarker[nResult], INDENTCHAR, 223110234Syasuko.eckert@amd.com nFormat + 1); 223210234Syasuko.eckert@amd.com xstrcpy(&lpszMarker[nResult+nFormat+1], 223310234Syasuko.eckert@amd.com pChild->lpszOpenTag); 223410234Syasuko.eckert@amd.com } 223510234Syasuko.eckert@amd.com nResult += cb + nFormat + 1; 223610234Syasuko.eckert@amd.com } else { 223710234Syasuko.eckert@amd.com if (lpszMarker) { 223810234Syasuko.eckert@amd.com xstrcpy(&lpszMarker[nResult], pChild->lpszOpenTag); 223910234Syasuko.eckert@amd.com } 224010234Syasuko.eckert@amd.com nResult += cb; 224110234Syasuko.eckert@amd.com } 224210152Satgutier@umich.edu } 224310152Satgutier@umich.edu 224410234Syasuko.eckert@amd.com // "OpenTag Value" 224510234Syasuko.eckert@amd.com cb = (int)LENSTR(pChild->lpszValue); 224610234Syasuko.eckert@amd.com if (cb) { 224710234Syasuko.eckert@amd.com if (lpszMarker) { 224810234Syasuko.eckert@amd.com xstrcpy(&lpszMarker[nResult], pChild->lpszValue); 224910152Satgutier@umich.edu } 225010234Syasuko.eckert@amd.com nResult += cb; 225110152Satgutier@umich.edu } 225210152Satgutier@umich.edu 225310234Syasuko.eckert@amd.com // "OpenTag Value CloseTag" 225410234Syasuko.eckert@amd.com cb = (int)LENSTR(pChild->lpszCloseTag); 225510234Syasuko.eckert@amd.com if (cb) { 225610234Syasuko.eckert@amd.com if (lpszMarker) { 225710234Syasuko.eckert@amd.com xstrcpy(&lpszMarker[nResult], pChild->lpszCloseTag); 225810234Syasuko.eckert@amd.com } 225910234Syasuko.eckert@amd.com nResult += cb; 226010234Syasuko.eckert@amd.com } 226110234Syasuko.eckert@amd.com 226210234Syasuko.eckert@amd.com if (nFormat != -1) { 226310234Syasuko.eckert@amd.com if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); 226410234Syasuko.eckert@amd.com nResult++; 226510234Syasuko.eckert@amd.com } 226610234Syasuko.eckert@amd.com break; 226710234Syasuko.eckert@amd.com } 226810234Syasuko.eckert@amd.com 226910152Satgutier@umich.edu // Element nodes 227010234Syasuko.eckert@amd.com case eNodeChild: { 227110234Syasuko.eckert@amd.com // Recursively add child nodes 227210234Syasuko.eckert@amd.com nResult += CreateXMLStringR(pEntry->pChild[j>>2].d, 227310234Syasuko.eckert@amd.com lpszMarker ? lpszMarker + nResult : 0, 227410234Syasuko.eckert@amd.com nChildFormat); 227510234Syasuko.eckert@amd.com break; 227610234Syasuko.eckert@amd.com } 227710234Syasuko.eckert@amd.com default: 227810234Syasuko.eckert@amd.com break; 227910152Satgutier@umich.edu } 228010152Satgutier@umich.edu } 228110152Satgutier@umich.edu 228210234Syasuko.eckert@amd.com if ((cbElement) && (!pEntry->isDeclaration)) { 228310152Satgutier@umich.edu // If we have child entries we need to use long XML notation for 228410152Satgutier@umich.edu // closing the element - "<elementname>blah blah blah</elementname>" 228510234Syasuko.eckert@amd.com if (nElementI) { 228610152Satgutier@umich.edu // "</elementname>\0" 228710234Syasuko.eckert@amd.com if (lpszMarker) { 228810234Syasuko.eckert@amd.com if (nFormat >= 0) { 228910234Syasuko.eckert@amd.com charmemset(&lpszMarker[nResult], INDENTCHAR, nFormat); 229010234Syasuko.eckert@amd.com nResult += nFormat; 229110152Satgutier@umich.edu } 229210152Satgutier@umich.edu 229310234Syasuko.eckert@amd.com lpszMarker[nResult] = _CXML('<'); 229410234Syasuko.eckert@amd.com lpszMarker[nResult+1] = _CXML('/'); 229510152Satgutier@umich.edu nResult += 2; 229610152Satgutier@umich.edu xstrcpy(&lpszMarker[nResult], pEntry->lpszName); 229710152Satgutier@umich.edu nResult += cbElement; 229810152Satgutier@umich.edu 229910234Syasuko.eckert@amd.com lpszMarker[nResult] = _CXML('>'); 230010152Satgutier@umich.edu if (nFormat == -1) nResult++; 230110234Syasuko.eckert@amd.com else { 230210234Syasuko.eckert@amd.com lpszMarker[nResult+1] = _CXML('\n'); 230310234Syasuko.eckert@amd.com nResult += 2; 230410152Satgutier@umich.edu } 230510234Syasuko.eckert@amd.com } else { 230610234Syasuko.eckert@amd.com if (nFormat >= 0) nResult += cbElement + 4 + nFormat; 230710234Syasuko.eckert@amd.com else if (nFormat == -1) nResult += cbElement + 3; 230810234Syasuko.eckert@amd.com else nResult += cbElement + 4; 230910152Satgutier@umich.edu } 231010234Syasuko.eckert@amd.com } else { 231110152Satgutier@umich.edu // If there are no children we can use shorthand XML notation - 231210152Satgutier@umich.edu // "<elementname/>" 231310152Satgutier@umich.edu // "/>\0" 231410234Syasuko.eckert@amd.com if (lpszMarker) { 231510234Syasuko.eckert@amd.com lpszMarker[nResult] = _CXML('/'); 231610234Syasuko.eckert@amd.com lpszMarker[nResult+1] = _CXML('>'); 231710234Syasuko.eckert@amd.com if (nFormat != -1) lpszMarker[nResult+2] = _CXML('\n'); 231810152Satgutier@umich.edu } 231910152Satgutier@umich.edu nResult += nFormat == -1 ? 2 : 3; 232010152Satgutier@umich.edu } 232110152Satgutier@umich.edu } 232210152Satgutier@umich.edu 232310152Satgutier@umich.edu return nResult; 232410152Satgutier@umich.edu} 232510152Satgutier@umich.edu 232610152Satgutier@umich.edu#undef LENSTR 232710152Satgutier@umich.edu 232810152Satgutier@umich.edu// Create an XML string 232910152Satgutier@umich.edu// @param int nFormat - 0 if no formatting is required 233010152Satgutier@umich.edu// otherwise nonzero for formatted text 233110152Satgutier@umich.edu// with carriage returns and indentation. 233210152Satgutier@umich.edu// @param int *pnSize - [out] pointer to the size of the 233310152Satgutier@umich.edu// returned string not including the 233410152Satgutier@umich.edu// NULL terminator. 233510152Satgutier@umich.edu// @return XMLSTR - Allocated XML string, you must free 233610152Satgutier@umich.edu// this with free(). 233710234Syasuko.eckert@amd.comXMLSTR XMLNode::createXMLString(int nFormat, int *pnSize) const { 233810234Syasuko.eckert@amd.com if (!d) { 233910234Syasuko.eckert@amd.com if (pnSize) *pnSize = 0; 234010234Syasuko.eckert@amd.com return NULL; 234110234Syasuko.eckert@amd.com } 234210152Satgutier@umich.edu 234310152Satgutier@umich.edu XMLSTR lpszResult = NULL; 234410152Satgutier@umich.edu int cbStr; 234510152Satgutier@umich.edu 234610152Satgutier@umich.edu // Recursively Calculate the size of the XML string 234710234Syasuko.eckert@amd.com if (!dropWhiteSpace) nFormat = 0; 234810152Satgutier@umich.edu nFormat = nFormat ? 0 : -1; 234910152Satgutier@umich.edu cbStr = CreateXMLStringR(d, 0, nFormat); 235010152Satgutier@umich.edu // Alllocate memory for the XML string + the NULL terminator and 235110152Satgutier@umich.edu // create the recursively XML string. 235210234Syasuko.eckert@amd.com lpszResult = (XMLSTR)malloc((cbStr + 1) * sizeof(XMLCHAR)); 235310152Satgutier@umich.edu CreateXMLStringR(d, lpszResult, nFormat); 235410234Syasuko.eckert@amd.com lpszResult[cbStr] = _CXML('\0'); 235510152Satgutier@umich.edu if (pnSize) *pnSize = cbStr; 235610152Satgutier@umich.edu return lpszResult; 235710152Satgutier@umich.edu} 235810152Satgutier@umich.edu 235910234Syasuko.eckert@amd.comint XMLNode::detachFromParent(XMLNodeData *d) { 236010234Syasuko.eckert@amd.com XMLNode *pa = d->pParent->pChild; 236110234Syasuko.eckert@amd.com int i = 0; 236210234Syasuko.eckert@amd.com while (((void*)(pa[i].d)) != ((void*)d)) i++; 236310152Satgutier@umich.edu d->pParent->nChild--; 236410234Syasuko.eckert@amd.com if (d->pParent->nChild) { 236510234Syasuko.eckert@amd.com memmove(pa + i, pa + i + 1, (d->pParent->nChild - i)*sizeof(XMLNode)); 236610234Syasuko.eckert@amd.com } else { 236710234Syasuko.eckert@amd.com free(pa); 236810234Syasuko.eckert@amd.com d->pParent->pChild = NULL; 236910234Syasuko.eckert@amd.com } 237010234Syasuko.eckert@amd.com return removeOrderElement(d->pParent, eNodeChild, i); 237110152Satgutier@umich.edu} 237210152Satgutier@umich.edu 237310234Syasuko.eckert@amd.comXMLNode::~XMLNode() { 237410152Satgutier@umich.edu if (!d) return; 237510152Satgutier@umich.edu d->ref_count--; 237610152Satgutier@umich.edu emptyTheNode(0); 237710152Satgutier@umich.edu} 237810234Syasuko.eckert@amd.comvoid XMLNode::deleteNodeContent() { 237910152Satgutier@umich.edu if (!d) return; 238010234Syasuko.eckert@amd.com if (d->pParent) { 238110234Syasuko.eckert@amd.com detachFromParent(d); 238210234Syasuko.eckert@amd.com d->pParent = NULL; 238310234Syasuko.eckert@amd.com d->ref_count--; 238410234Syasuko.eckert@amd.com } 238510152Satgutier@umich.edu emptyTheNode(1); 238610152Satgutier@umich.edu} 238710234Syasuko.eckert@amd.comvoid XMLNode::emptyTheNode(char force) { 238810234Syasuko.eckert@amd.com XMLNodeData *dd = d; // warning: must stay this way! 238910234Syasuko.eckert@amd.com if ((dd->ref_count == 0) || force) { 239010152Satgutier@umich.edu if (d->pParent) detachFromParent(d); 239110152Satgutier@umich.edu int i; 239210152Satgutier@umich.edu XMLNode *pc; 239310234Syasuko.eckert@amd.com for (i = 0; i < dd->nChild; i++) { 239410234Syasuko.eckert@amd.com pc = dd->pChild + i; 239510234Syasuko.eckert@amd.com pc->d->pParent = NULL; 239610152Satgutier@umich.edu pc->d->ref_count--; 239710152Satgutier@umich.edu pc->emptyTheNode(force); 239810152Satgutier@umich.edu } 239910152Satgutier@umich.edu myFree(dd->pChild); 240010234Syasuko.eckert@amd.com for (i = 0; i < dd->nText; i++) free((void*)dd->pText[i]); 240110152Satgutier@umich.edu myFree(dd->pText); 240210234Syasuko.eckert@amd.com for (i = 0; i < dd->nClear; i++) free((void*)dd->pClear[i].lpszValue); 240310152Satgutier@umich.edu myFree(dd->pClear); 240410234Syasuko.eckert@amd.com for (i = 0; i < dd->nAttribute; i++) { 240510152Satgutier@umich.edu free((void*)dd->pAttribute[i].lpszName); 240610234Syasuko.eckert@amd.com if (dd->pAttribute[i].lpszValue) { 240710234Syasuko.eckert@amd.com free((void*)dd->pAttribute[i].lpszValue); 240810234Syasuko.eckert@amd.com } 240910152Satgutier@umich.edu } 241010152Satgutier@umich.edu myFree(dd->pAttribute); 241110152Satgutier@umich.edu myFree(dd->pOrder); 241210152Satgutier@umich.edu myFree((void*)dd->lpszName); 241310234Syasuko.eckert@amd.com dd->nChild = 0; 241410234Syasuko.eckert@amd.com dd->nText = 0; 241510234Syasuko.eckert@amd.com dd->nClear = 0; 241610234Syasuko.eckert@amd.com dd->nAttribute = 0; 241710234Syasuko.eckert@amd.com dd->pChild = NULL; 241810234Syasuko.eckert@amd.com dd->pText = NULL; 241910234Syasuko.eckert@amd.com dd->pClear = NULL; 242010234Syasuko.eckert@amd.com dd->pAttribute = NULL; 242110234Syasuko.eckert@amd.com dd->pOrder = NULL; 242210234Syasuko.eckert@amd.com dd->lpszName = NULL; 242310234Syasuko.eckert@amd.com dd->pParent = NULL; 242410152Satgutier@umich.edu } 242510234Syasuko.eckert@amd.com if (dd->ref_count == 0) { 242610152Satgutier@umich.edu free(dd); 242710234Syasuko.eckert@amd.com d = NULL; 242810152Satgutier@umich.edu } 242910152Satgutier@umich.edu} 243010152Satgutier@umich.edu 243110234Syasuko.eckert@amd.comXMLNode& XMLNode::operator=( const XMLNode & A ) { 243210152Satgutier@umich.edu // shallow copy 243310234Syasuko.eckert@amd.com if (this != &A) { 243410234Syasuko.eckert@amd.com if (d) { 243510234Syasuko.eckert@amd.com d->ref_count--; 243610234Syasuko.eckert@amd.com emptyTheNode(0); 243710234Syasuko.eckert@amd.com } 243810234Syasuko.eckert@amd.com d = A.d; 243910152Satgutier@umich.edu if (d) (d->ref_count) ++ ; 244010152Satgutier@umich.edu } 244110152Satgutier@umich.edu return *this; 244210152Satgutier@umich.edu} 244310152Satgutier@umich.edu 244410234Syasuko.eckert@amd.comXMLNode::XMLNode(const XMLNode &A) { 244510152Satgutier@umich.edu // shallow copy 244610234Syasuko.eckert@amd.com d = A.d; 244710152Satgutier@umich.edu if (d) (d->ref_count)++ ; 244810152Satgutier@umich.edu} 244910152Satgutier@umich.edu 245010234Syasuko.eckert@amd.comXMLNode XMLNode::deepCopy() const { 245110152Satgutier@umich.edu if (!d) return XMLNode::emptyXMLNode; 245210234Syasuko.eckert@amd.com XMLNode x(NULL, stringDup(d->lpszName), d->isDeclaration); 245310234Syasuko.eckert@amd.com XMLNodeData *p = x.d; 245410234Syasuko.eckert@amd.com int n = d->nAttribute; 245510234Syasuko.eckert@amd.com if (n) { 245610234Syasuko.eckert@amd.com p->nAttribute = n; 245710234Syasuko.eckert@amd.com p->pAttribute = (XMLAttribute*)malloc(n * sizeof(XMLAttribute)); 245810234Syasuko.eckert@amd.com while (n--) { 245910234Syasuko.eckert@amd.com p->pAttribute[n].lpszName = stringDup(d->pAttribute[n].lpszName); 246010234Syasuko.eckert@amd.com p->pAttribute[n].lpszValue = stringDup(d->pAttribute[n].lpszValue); 246110152Satgutier@umich.edu } 246210152Satgutier@umich.edu } 246310234Syasuko.eckert@amd.com if (d->pOrder) { 246410234Syasuko.eckert@amd.com n = (d->nChild + d->nText + d->nClear) * sizeof(int); 246510234Syasuko.eckert@amd.com p->pOrder = (int*)malloc(n); 246610234Syasuko.eckert@amd.com memcpy(p->pOrder, d->pOrder, n); 246710152Satgutier@umich.edu } 246810234Syasuko.eckert@amd.com n = d->nText; 246910234Syasuko.eckert@amd.com if (n) { 247010234Syasuko.eckert@amd.com p->nText = n; 247110234Syasuko.eckert@amd.com p->pText = (XMLCSTR*)malloc(n * sizeof(XMLCSTR)); 247210234Syasuko.eckert@amd.com while (n--) p->pText[n] = stringDup(d->pText[n]); 247310152Satgutier@umich.edu } 247410234Syasuko.eckert@amd.com n = d->nClear; 247510234Syasuko.eckert@amd.com if (n) { 247610234Syasuko.eckert@amd.com p->nClear = n; 247710234Syasuko.eckert@amd.com p->pClear = (XMLClear*)malloc(n * sizeof(XMLClear)); 247810234Syasuko.eckert@amd.com while (n--) { 247910234Syasuko.eckert@amd.com p->pClear[n].lpszCloseTag = d->pClear[n].lpszCloseTag; 248010234Syasuko.eckert@amd.com p->pClear[n].lpszOpenTag = d->pClear[n].lpszOpenTag; 248110234Syasuko.eckert@amd.com p->pClear[n].lpszValue = stringDup(d->pClear[n].lpszValue); 248210152Satgutier@umich.edu } 248310152Satgutier@umich.edu } 248410234Syasuko.eckert@amd.com n = d->nChild; 248510234Syasuko.eckert@amd.com if (n) { 248610234Syasuko.eckert@amd.com p->nChild = n; 248710234Syasuko.eckert@amd.com p->pChild = (XMLNode*)malloc(n * sizeof(XMLNode)); 248810234Syasuko.eckert@amd.com while (n--) { 248910234Syasuko.eckert@amd.com p->pChild[n].d = NULL; 249010234Syasuko.eckert@amd.com p->pChild[n] = d->pChild[n].deepCopy(); 249110234Syasuko.eckert@amd.com p->pChild[n].d->pParent = p; 249210152Satgutier@umich.edu } 249310152Satgutier@umich.edu } 249410152Satgutier@umich.edu return x; 249510152Satgutier@umich.edu} 249610152Satgutier@umich.edu 249710234Syasuko.eckert@amd.comXMLNode XMLNode::addChild(XMLNode childNode, int pos) { 249810234Syasuko.eckert@amd.com XMLNodeData *dc = childNode.d; 249910234Syasuko.eckert@amd.com if ((!dc) || (!d)) return childNode; 250010234Syasuko.eckert@amd.com if (!dc->lpszName) { 250110152Satgutier@umich.edu // this is a root node: todo: correct fix 250210234Syasuko.eckert@amd.com int j = pos; 250310234Syasuko.eckert@amd.com while (dc->nChild) { 250410234Syasuko.eckert@amd.com addChild(dc->pChild[0], j); 250510234Syasuko.eckert@amd.com if (pos >= 0) j++; 250610152Satgutier@umich.edu } 250710152Satgutier@umich.edu return childNode; 250810152Satgutier@umich.edu } 250910234Syasuko.eckert@amd.com if (dc->pParent) { 251010234Syasuko.eckert@amd.com if ((detachFromParent(dc) <= pos) && (dc->pParent == d)) pos--; 251110234Syasuko.eckert@amd.com } else dc->ref_count++; 251210234Syasuko.eckert@amd.com dc->pParent = d; 251310152Satgutier@umich.edu// int nc=d->nChild; 251410152Satgutier@umich.edu// d->pChild=(XMLNode*)myRealloc(d->pChild,(nc+1),memoryIncrease,sizeof(XMLNode)); 251510234Syasuko.eckert@amd.com d->pChild = (XMLNode*)addToOrder(0, &pos, d->nChild, d->pChild, 251610234Syasuko.eckert@amd.com sizeof(XMLNode), eNodeChild); 251710234Syasuko.eckert@amd.com d->pChild[pos].d = dc; 251810152Satgutier@umich.edu d->nChild++; 251910152Satgutier@umich.edu return childNode; 252010152Satgutier@umich.edu} 252110152Satgutier@umich.edu 252210234Syasuko.eckert@amd.comvoid XMLNode::deleteAttribute(int i) { 252310234Syasuko.eckert@amd.com if ((!d) || (i < 0) || (i >= d->nAttribute)) return; 252410152Satgutier@umich.edu d->nAttribute--; 252510234Syasuko.eckert@amd.com XMLAttribute *p = d->pAttribute + i; 252610152Satgutier@umich.edu free((void*)p->lpszName); 252710152Satgutier@umich.edu if (p->lpszValue) free((void*)p->lpszValue); 252810234Syasuko.eckert@amd.com if (d->nAttribute) { 252910234Syasuko.eckert@amd.com memmove(p, p + 1, (d->nAttribute - i)*sizeof(XMLAttribute)); 253010234Syasuko.eckert@amd.com } 253110234Syasuko.eckert@amd.com else { 253210234Syasuko.eckert@amd.com free(p); 253310234Syasuko.eckert@amd.com d->pAttribute = NULL; 253410234Syasuko.eckert@amd.com } 253510152Satgutier@umich.edu} 253610152Satgutier@umich.edu 253710234Syasuko.eckert@amd.comvoid XMLNode::deleteAttribute(XMLAttribute *a) { 253810234Syasuko.eckert@amd.com if (a) deleteAttribute(a->lpszName); 253910234Syasuko.eckert@amd.com} 254010234Syasuko.eckert@amd.comvoid XMLNode::deleteAttribute(XMLCSTR lpszName) { 254110234Syasuko.eckert@amd.com int j = 0; 254210234Syasuko.eckert@amd.com getAttribute(lpszName, &j); 254310234Syasuko.eckert@amd.com if (j) deleteAttribute(j - 1); 254410152Satgutier@umich.edu} 254510152Satgutier@umich.edu 254610234Syasuko.eckert@amd.comXMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, 254710234Syasuko.eckert@amd.com XMLSTR lpszNewName, int i) { 254810234Syasuko.eckert@amd.com if (!d) { 254910234Syasuko.eckert@amd.com if (lpszNewValue) free(lpszNewValue); 255010234Syasuko.eckert@amd.com if (lpszNewName) free(lpszNewName); 255110152Satgutier@umich.edu return NULL; 255210152Satgutier@umich.edu } 255310234Syasuko.eckert@amd.com if (i >= d->nAttribute) { 255410234Syasuko.eckert@amd.com if (lpszNewName) return addAttribute_WOSD(lpszNewName, lpszNewValue); 255510234Syasuko.eckert@amd.com return NULL; 255610234Syasuko.eckert@amd.com } 255710234Syasuko.eckert@amd.com XMLAttribute *p = d->pAttribute + i; 255810234Syasuko.eckert@amd.com if (p->lpszValue && p->lpszValue != lpszNewValue) { 255910234Syasuko.eckert@amd.com free((void*)p->lpszValue); 256010234Syasuko.eckert@amd.com } 256110234Syasuko.eckert@amd.com p->lpszValue = lpszNewValue; 256210234Syasuko.eckert@amd.com if (lpszNewName && p->lpszName != lpszNewName) { 256310234Syasuko.eckert@amd.com free((void*)p->lpszName); 256410234Syasuko.eckert@amd.com p->lpszName = lpszNewName; 256510234Syasuko.eckert@amd.com }; 256610152Satgutier@umich.edu return p; 256710152Satgutier@umich.edu} 256810152Satgutier@umich.edu 256910234Syasuko.eckert@amd.comXMLAttribute *XMLNode::updateAttribute_WOSD(XMLAttribute *newAttribute, 257010234Syasuko.eckert@amd.com XMLAttribute *oldAttribute) { 257110234Syasuko.eckert@amd.com if (oldAttribute) { 257210234Syasuko.eckert@amd.com return updateAttribute_WOSD((XMLSTR)newAttribute->lpszValue, 257310234Syasuko.eckert@amd.com (XMLSTR)newAttribute->lpszName, 257410234Syasuko.eckert@amd.com oldAttribute->lpszName); 257510234Syasuko.eckert@amd.com } 257610234Syasuko.eckert@amd.com return addAttribute_WOSD((XMLSTR)newAttribute->lpszName, 257710234Syasuko.eckert@amd.com (XMLSTR)newAttribute->lpszValue); 257810152Satgutier@umich.edu} 257910152Satgutier@umich.edu 258010234Syasuko.eckert@amd.comXMLAttribute *XMLNode::updateAttribute_WOSD(XMLSTR lpszNewValue, 258110234Syasuko.eckert@amd.com XMLSTR lpszNewName, 258210234Syasuko.eckert@amd.com XMLCSTR lpszOldName) { 258310234Syasuko.eckert@amd.com int j = 0; 258410234Syasuko.eckert@amd.com getAttribute(lpszOldName, &j); 258510234Syasuko.eckert@amd.com if (j) return updateAttribute_WOSD(lpszNewValue, lpszNewName, j - 1); 258610234Syasuko.eckert@amd.com else { 258710234Syasuko.eckert@amd.com if (lpszNewName) { 258810234Syasuko.eckert@amd.com return addAttribute_WOSD(lpszNewName, lpszNewValue); 258910234Syasuko.eckert@amd.com } else { 259010234Syasuko.eckert@amd.com return addAttribute_WOSD(stringDup(lpszOldName), lpszNewValue); 259110234Syasuko.eckert@amd.com } 259210152Satgutier@umich.edu } 259310152Satgutier@umich.edu} 259410152Satgutier@umich.edu 259510234Syasuko.eckert@amd.comint XMLNode::indexText(XMLCSTR lpszValue) const { 259610152Satgutier@umich.edu if (!d) return -1; 259710234Syasuko.eckert@amd.com int i, l = d->nText; 259810234Syasuko.eckert@amd.com if (!lpszValue) { 259910234Syasuko.eckert@amd.com if (l) return 0; 260010234Syasuko.eckert@amd.com return -1; 260110234Syasuko.eckert@amd.com } 260210234Syasuko.eckert@amd.com XMLCSTR *p = d->pText; 260310234Syasuko.eckert@amd.com for (i = 0; i < l; i++) if (lpszValue == p[i]) return i; 260410152Satgutier@umich.edu return -1; 260510152Satgutier@umich.edu} 260610152Satgutier@umich.edu 260710234Syasuko.eckert@amd.comvoid XMLNode::deleteText(int i) { 260810234Syasuko.eckert@amd.com if ((!d) || (i < 0) || (i >= d->nText)) return; 260910152Satgutier@umich.edu d->nText--; 261010234Syasuko.eckert@amd.com XMLCSTR *p = d->pText + i; 261110152Satgutier@umich.edu free((void*)*p); 261210234Syasuko.eckert@amd.com if (d->nText) memmove(p, p + 1, (d->nText - i)*sizeof(XMLCSTR)); 261310234Syasuko.eckert@amd.com else { 261410234Syasuko.eckert@amd.com free(p); 261510234Syasuko.eckert@amd.com d->pText = NULL; 261610234Syasuko.eckert@amd.com } 261710234Syasuko.eckert@amd.com removeOrderElement(d, eNodeText, i); 261810152Satgutier@umich.edu} 261910152Satgutier@umich.edu 262010234Syasuko.eckert@amd.comvoid XMLNode::deleteText(XMLCSTR lpszValue) { 262110234Syasuko.eckert@amd.com deleteText(indexText(lpszValue)); 262210234Syasuko.eckert@amd.com} 262310152Satgutier@umich.edu 262410234Syasuko.eckert@amd.comXMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, int i) { 262510234Syasuko.eckert@amd.com if (!d) { 262610234Syasuko.eckert@amd.com if (lpszNewValue) free(lpszNewValue); 262710234Syasuko.eckert@amd.com return NULL; 262810234Syasuko.eckert@amd.com } 262910234Syasuko.eckert@amd.com if (i >= d->nText) return addText_WOSD(lpszNewValue); 263010234Syasuko.eckert@amd.com XMLCSTR *p = d->pText + i; 263110234Syasuko.eckert@amd.com if (*p != lpszNewValue) { 263210234Syasuko.eckert@amd.com free((void*)*p); 263310234Syasuko.eckert@amd.com *p = lpszNewValue; 263410234Syasuko.eckert@amd.com } 263510152Satgutier@umich.edu return lpszNewValue; 263610152Satgutier@umich.edu} 263710152Satgutier@umich.edu 263810234Syasuko.eckert@amd.comXMLCSTR XMLNode::updateText_WOSD(XMLSTR lpszNewValue, XMLCSTR lpszOldValue) { 263910234Syasuko.eckert@amd.com if (!d) { 264010234Syasuko.eckert@amd.com if (lpszNewValue) free(lpszNewValue); 264110234Syasuko.eckert@amd.com return NULL; 264210234Syasuko.eckert@amd.com } 264310234Syasuko.eckert@amd.com int i = indexText(lpszOldValue); 264410234Syasuko.eckert@amd.com if (i >= 0) return updateText_WOSD(lpszNewValue, i); 264510152Satgutier@umich.edu return addText_WOSD(lpszNewValue); 264610152Satgutier@umich.edu} 264710152Satgutier@umich.edu 264810234Syasuko.eckert@amd.comvoid XMLNode::deleteClear(int i) { 264910234Syasuko.eckert@amd.com if ((!d) || (i < 0) || (i >= d->nClear)) return; 265010152Satgutier@umich.edu d->nClear--; 265110234Syasuko.eckert@amd.com XMLClear *p = d->pClear + i; 265210152Satgutier@umich.edu free((void*)p->lpszValue); 265310234Syasuko.eckert@amd.com if (d->nClear) memmove(p, p + 1, (d->nClear - i)*sizeof(XMLClear)); 265410234Syasuko.eckert@amd.com else { 265510234Syasuko.eckert@amd.com free(p); 265610234Syasuko.eckert@amd.com d->pClear = NULL; 265710234Syasuko.eckert@amd.com } 265810234Syasuko.eckert@amd.com removeOrderElement(d, eNodeClear, i); 265910152Satgutier@umich.edu} 266010152Satgutier@umich.edu 266110234Syasuko.eckert@amd.comint XMLNode::indexClear(XMLCSTR lpszValue) const { 266210152Satgutier@umich.edu if (!d) return -1; 266310234Syasuko.eckert@amd.com int i, l = d->nClear; 266410234Syasuko.eckert@amd.com if (!lpszValue) { 266510234Syasuko.eckert@amd.com if (l) return 0; 266610234Syasuko.eckert@amd.com return -1; 266710234Syasuko.eckert@amd.com } 266810234Syasuko.eckert@amd.com XMLClear *p = d->pClear; 266910234Syasuko.eckert@amd.com for (i = 0; i < l; i++) if (lpszValue == p[i].lpszValue) return i; 267010152Satgutier@umich.edu return -1; 267110152Satgutier@umich.edu} 267210152Satgutier@umich.edu 267310234Syasuko.eckert@amd.comvoid XMLNode::deleteClear(XMLCSTR lpszValue) { 267410234Syasuko.eckert@amd.com deleteClear(indexClear(lpszValue)); 267510234Syasuko.eckert@amd.com} 267610234Syasuko.eckert@amd.comvoid XMLNode::deleteClear(XMLClear *a) { 267710234Syasuko.eckert@amd.com if (a) deleteClear(a->lpszValue); 267810234Syasuko.eckert@amd.com} 267910152Satgutier@umich.edu 268010234Syasuko.eckert@amd.comXMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, int i) { 268110234Syasuko.eckert@amd.com if (!d) { 268210234Syasuko.eckert@amd.com if (lpszNewContent) free(lpszNewContent); 268310234Syasuko.eckert@amd.com return NULL; 268410234Syasuko.eckert@amd.com } 268510234Syasuko.eckert@amd.com if (i >= d->nClear) return addClear_WOSD(lpszNewContent); 268610234Syasuko.eckert@amd.com XMLClear *p = d->pClear + i; 268710234Syasuko.eckert@amd.com if (lpszNewContent != p->lpszValue) { 268810234Syasuko.eckert@amd.com free((void*)p->lpszValue); 268910234Syasuko.eckert@amd.com p->lpszValue = lpszNewContent; 269010234Syasuko.eckert@amd.com } 269110152Satgutier@umich.edu return p; 269210152Satgutier@umich.edu} 269310152Satgutier@umich.edu 269410234Syasuko.eckert@amd.comXMLClear *XMLNode::updateClear_WOSD(XMLSTR lpszNewContent, 269510234Syasuko.eckert@amd.com XMLCSTR lpszOldValue) { 269610234Syasuko.eckert@amd.com if (!d) { 269710234Syasuko.eckert@amd.com if (lpszNewContent) free(lpszNewContent); 269810234Syasuko.eckert@amd.com return NULL; 269910234Syasuko.eckert@amd.com } 270010234Syasuko.eckert@amd.com int i = indexClear(lpszOldValue); 270110234Syasuko.eckert@amd.com if (i >= 0) return updateClear_WOSD(lpszNewContent, i); 270210152Satgutier@umich.edu return addClear_WOSD(lpszNewContent); 270310152Satgutier@umich.edu} 270410152Satgutier@umich.edu 270510234Syasuko.eckert@amd.comXMLClear *XMLNode::updateClear_WOSD(XMLClear *newP, XMLClear *oldP) { 270610234Syasuko.eckert@amd.com if (oldP) { 270710234Syasuko.eckert@amd.com return updateClear_WOSD((XMLSTR)newP->lpszValue, 270810234Syasuko.eckert@amd.com (XMLSTR)oldP->lpszValue); 270910234Syasuko.eckert@amd.com } 271010152Satgutier@umich.edu return NULL; 271110152Satgutier@umich.edu} 271210152Satgutier@umich.edu 271310234Syasuko.eckert@amd.comint XMLNode::nChildNode(XMLCSTR name) const { 271410152Satgutier@umich.edu if (!d) return 0; 271510234Syasuko.eckert@amd.com int i, j = 0, n = d->nChild; 271610234Syasuko.eckert@amd.com XMLNode *pc = d->pChild; 271710234Syasuko.eckert@amd.com for (i = 0; i < n; i++) { 271810234Syasuko.eckert@amd.com if (xstricmp(pc->d->lpszName, name) == 0) j++; 271910152Satgutier@umich.edu pc++; 272010152Satgutier@umich.edu } 272110152Satgutier@umich.edu return j; 272210152Satgutier@umich.edu} 272310152Satgutier@umich.edu 272410234Syasuko.eckert@amd.comXMLNode XMLNode::getChildNode(XMLCSTR name, int *j) const { 272510152Satgutier@umich.edu if (!d) return emptyXMLNode; 272610234Syasuko.eckert@amd.com int i = 0, n = d->nChild; 272710234Syasuko.eckert@amd.com if (j) i = *j; 272810234Syasuko.eckert@amd.com XMLNode *pc = d->pChild + i; 272910234Syasuko.eckert@amd.com for (; i < n; i++) { 273010234Syasuko.eckert@amd.com if (!xstricmp(pc->d->lpszName, name)) { 273110234Syasuko.eckert@amd.com if (j) *j = i + 1; 273210152Satgutier@umich.edu return *pc; 273310152Satgutier@umich.edu } 273410152Satgutier@umich.edu pc++; 273510152Satgutier@umich.edu } 273610152Satgutier@umich.edu return emptyXMLNode; 273710152Satgutier@umich.edu} 273810152Satgutier@umich.edu 273910234Syasuko.eckert@amd.comXMLNode XMLNode::getChildNode(XMLCSTR name, int j) const { 274010152Satgutier@umich.edu if (!d) return emptyXMLNode; 274110234Syasuko.eckert@amd.com if (j >= 0) { 274210234Syasuko.eckert@amd.com int i = 0; 274310234Syasuko.eckert@amd.com while (j-- > 0) getChildNode(name, &i); 274410234Syasuko.eckert@amd.com return getChildNode(name, &i); 274510152Satgutier@umich.edu } 274610234Syasuko.eckert@amd.com int i = d->nChild; 274710234Syasuko.eckert@amd.com while (i--) if (!xstricmp(name, d->pChild[i].d->lpszName)) break; 274810234Syasuko.eckert@amd.com if (i < 0) return emptyXMLNode; 274910152Satgutier@umich.edu return getChildNode(i); 275010152Satgutier@umich.edu} 275110152Satgutier@umich.edu 275210234Syasuko.eckert@amd.comXMLNode* XMLNode::getChildNodePtr(XMLCSTR name, int *j) const { 275310234Syasuko.eckert@amd.com if (!d) return &emptyXMLNode; 275410234Syasuko.eckert@amd.com int i = 0, n = d->nChild; 275510234Syasuko.eckert@amd.com int foundIndex = 0; 275610234Syasuko.eckert@amd.com XMLNode *pc = d->pChild + i; 275710234Syasuko.eckert@amd.com for (; i < n; i++) { 275810234Syasuko.eckert@amd.com if (!xstricmp(pc->d->lpszName, name)) { 275910234Syasuko.eckert@amd.com if (*j == foundIndex) return pc; 276010234Syasuko.eckert@amd.com foundIndex++; 276110234Syasuko.eckert@amd.com } 276210234Syasuko.eckert@amd.com pc++; 276310234Syasuko.eckert@amd.com } 276410234Syasuko.eckert@amd.com return &emptyXMLNode; 276510234Syasuko.eckert@amd.com} 276610234Syasuko.eckert@amd.com 276710234Syasuko.eckert@amd.comXMLNode XMLNode::getChildNodeByPath(XMLCSTR _path, char createMissing, 276810234Syasuko.eckert@amd.com XMLCHAR sep) { 276910234Syasuko.eckert@amd.com XMLSTR path = stringDup(_path); 277010234Syasuko.eckert@amd.com XMLNode x = getChildNodeByPathNonConst(path, createMissing, sep); 277110152Satgutier@umich.edu if (path) free(path); 277210152Satgutier@umich.edu return x; 277310152Satgutier@umich.edu} 277410152Satgutier@umich.edu 277510234Syasuko.eckert@amd.comXMLNode XMLNode::getChildNodeByPathNonConst(XMLSTR path, 277610234Syasuko.eckert@amd.com char createIfMissing, XMLCHAR sep) { 277710234Syasuko.eckert@amd.com if ((!path) || (!(*path))) return *this; 277810234Syasuko.eckert@amd.com XMLNode xn, xbase = *this; 277910234Syasuko.eckert@amd.com XMLCHAR *tend1, sepString[2]; 278010234Syasuko.eckert@amd.com sepString[0] = sep; 278110234Syasuko.eckert@amd.com sepString[1] = 0; 278210234Syasuko.eckert@amd.com tend1 = xstrstr(path, sepString); 278310234Syasuko.eckert@amd.com while (tend1) { 278410234Syasuko.eckert@amd.com *tend1 = 0; 278510234Syasuko.eckert@amd.com xn = xbase.getChildNode(path); 278610234Syasuko.eckert@amd.com if (xn.isEmpty()) { 278710234Syasuko.eckert@amd.com if (createIfMissing) xn = xbase.addChild(path); 278810234Syasuko.eckert@amd.com else { 278910234Syasuko.eckert@amd.com *tend1 = sep; 279010234Syasuko.eckert@amd.com return XMLNode::emptyXMLNode; 279110234Syasuko.eckert@amd.com } 279210152Satgutier@umich.edu } 279310234Syasuko.eckert@amd.com *tend1 = sep; 279410234Syasuko.eckert@amd.com xbase = xn; 279510234Syasuko.eckert@amd.com path = tend1 + 1; 279610234Syasuko.eckert@amd.com tend1 = xstrstr(path, sepString); 279710152Satgutier@umich.edu } 279810234Syasuko.eckert@amd.com xn = xbase.getChildNode(path); 279910234Syasuko.eckert@amd.com if (xn.isEmpty() && createIfMissing) xn = xbase.addChild(path); 280010152Satgutier@umich.edu return xn; 280110152Satgutier@umich.edu} 280210152Satgutier@umich.edu 280310234Syasuko.eckert@amd.comXMLElementPosition XMLNode::positionOfText (int i) const { 280410234Syasuko.eckert@amd.com if (i >= d->nText ) i = d->nText - 1; 280510234Syasuko.eckert@amd.com return findPosition(d, i, eNodeText ); 280610234Syasuko.eckert@amd.com} 280710234Syasuko.eckert@amd.comXMLElementPosition XMLNode::positionOfClear (int i) const { 280810234Syasuko.eckert@amd.com if (i >= d->nClear) i = d->nClear - 1; 280910234Syasuko.eckert@amd.com return findPosition(d, i, eNodeClear); 281010234Syasuko.eckert@amd.com} 281110234Syasuko.eckert@amd.comXMLElementPosition XMLNode::positionOfChildNode(int i) const { 281210234Syasuko.eckert@amd.com if (i >= d->nChild) i = d->nChild - 1; 281310234Syasuko.eckert@amd.com return findPosition(d, i, eNodeChild); 281410234Syasuko.eckert@amd.com} 281510234Syasuko.eckert@amd.comXMLElementPosition XMLNode::positionOfText (XMLCSTR lpszValue) const { 281610234Syasuko.eckert@amd.com return positionOfText (indexText (lpszValue)); 281710234Syasuko.eckert@amd.com} 281810234Syasuko.eckert@amd.comXMLElementPosition XMLNode::positionOfClear(XMLCSTR lpszValue) const { 281910234Syasuko.eckert@amd.com return positionOfClear(indexClear(lpszValue)); 282010234Syasuko.eckert@amd.com} 282110234Syasuko.eckert@amd.comXMLElementPosition XMLNode::positionOfClear(XMLClear *a) const { 282210234Syasuko.eckert@amd.com if (a) return positionOfClear(a->lpszValue); 282310234Syasuko.eckert@amd.com return positionOfClear(); 282410234Syasuko.eckert@amd.com} 282510234Syasuko.eckert@amd.comXMLElementPosition XMLNode::positionOfChildNode(XMLNode x) const { 282610234Syasuko.eckert@amd.com if ((!d) || (!x.d)) return -1; 282710234Syasuko.eckert@amd.com XMLNodeData *dd = x.d; 282810234Syasuko.eckert@amd.com XMLNode *pc = d->pChild; 282910234Syasuko.eckert@amd.com int i = d->nChild; 283010234Syasuko.eckert@amd.com while (i--) if (pc[i].d == dd) return findPosition(d, i, eNodeChild); 283110152Satgutier@umich.edu return -1; 283210152Satgutier@umich.edu} 283310234Syasuko.eckert@amd.comXMLElementPosition XMLNode::positionOfChildNode(XMLCSTR name, int count) const { 283410152Satgutier@umich.edu if (!name) return positionOfChildNode(count); 283510234Syasuko.eckert@amd.com int j = 0; 283610234Syasuko.eckert@amd.com do { 283710234Syasuko.eckert@amd.com getChildNode(name, &j); 283810234Syasuko.eckert@amd.com if (j < 0) return -1; 283910234Syasuko.eckert@amd.com } while (count--); 284010234Syasuko.eckert@amd.com return findPosition(d, j - 1, eNodeChild); 284110152Satgutier@umich.edu} 284210152Satgutier@umich.edu 284310234Syasuko.eckert@amd.comXMLNode XMLNode::getChildNodeWithAttribute(XMLCSTR name, XMLCSTR attributeName, 284410234Syasuko.eckert@amd.com XMLCSTR attributeValue, 284510234Syasuko.eckert@amd.com int *k) const { 284610234Syasuko.eckert@amd.com int i = 0, j; 284710234Syasuko.eckert@amd.com if (k) i = *k; 284810234Syasuko.eckert@amd.com XMLNode x; 284910234Syasuko.eckert@amd.com XMLCSTR t; 285010234Syasuko.eckert@amd.com do { 285110234Syasuko.eckert@amd.com x = getChildNode(name, &i); 285210234Syasuko.eckert@amd.com if (!x.isEmpty()) { 285310234Syasuko.eckert@amd.com if (attributeValue) { 285410234Syasuko.eckert@amd.com j = 0; 285510234Syasuko.eckert@amd.com do { 285610234Syasuko.eckert@amd.com t = x.getAttribute(attributeName, &j); 285710234Syasuko.eckert@amd.com if (t && (xstricmp(attributeValue, t) == 0)) { 285810234Syasuko.eckert@amd.com if (k) *k = i; 285910234Syasuko.eckert@amd.com return x; 286010234Syasuko.eckert@amd.com } 286110234Syasuko.eckert@amd.com } while (t); 286210234Syasuko.eckert@amd.com } else { 286310234Syasuko.eckert@amd.com if (x.isAttributeSet(attributeName)) { 286410234Syasuko.eckert@amd.com if (k) *k = i; 286510234Syasuko.eckert@amd.com return x; 286610234Syasuko.eckert@amd.com } 286710234Syasuko.eckert@amd.com } 286810234Syasuko.eckert@amd.com } 286910234Syasuko.eckert@amd.com } while (!x.isEmpty()); 287010234Syasuko.eckert@amd.com return emptyXMLNode; 287110152Satgutier@umich.edu} 287210152Satgutier@umich.edu 287310152Satgutier@umich.edu// Find an attribute on an node. 287410234Syasuko.eckert@amd.comXMLCSTR XMLNode::getAttribute(XMLCSTR lpszAttrib, int *j) const { 287510152Satgutier@umich.edu if (!d) return NULL; 287610234Syasuko.eckert@amd.com int i = 0, n = d->nAttribute; 287710234Syasuko.eckert@amd.com if (j) i = *j; 287810234Syasuko.eckert@amd.com XMLAttribute *pAttr = d->pAttribute + i; 287910234Syasuko.eckert@amd.com for (; i < n; i++) { 288010234Syasuko.eckert@amd.com if (xstricmp(pAttr->lpszName, lpszAttrib) == 0) { 288110234Syasuko.eckert@amd.com if (j) *j = i + 1; 288210152Satgutier@umich.edu return pAttr->lpszValue; 288310152Satgutier@umich.edu } 288410152Satgutier@umich.edu pAttr++; 288510152Satgutier@umich.edu } 288610152Satgutier@umich.edu return NULL; 288710152Satgutier@umich.edu} 288810152Satgutier@umich.edu 288910234Syasuko.eckert@amd.comchar XMLNode::isAttributeSet(XMLCSTR lpszAttrib) const { 289010152Satgutier@umich.edu if (!d) return FALSE; 289110234Syasuko.eckert@amd.com int i, n = d->nAttribute; 289210234Syasuko.eckert@amd.com XMLAttribute *pAttr = d->pAttribute; 289310234Syasuko.eckert@amd.com for (i = 0; i < n; i++) { 289410234Syasuko.eckert@amd.com if (xstricmp(pAttr->lpszName, lpszAttrib) == 0) { 289510152Satgutier@umich.edu return TRUE; 289610152Satgutier@umich.edu } 289710152Satgutier@umich.edu pAttr++; 289810152Satgutier@umich.edu } 289910152Satgutier@umich.edu return FALSE; 290010152Satgutier@umich.edu} 290110152Satgutier@umich.edu 290210234Syasuko.eckert@amd.comXMLCSTR XMLNode::getAttribute(XMLCSTR name, int j) const { 290310152Satgutier@umich.edu if (!d) return NULL; 290410234Syasuko.eckert@amd.com int i = 0; 290510234Syasuko.eckert@amd.com while (j-- > 0) getAttribute(name, &i); 290610234Syasuko.eckert@amd.com return getAttribute(name, &i); 290710152Satgutier@umich.edu} 290810152Satgutier@umich.edu 290910234Syasuko.eckert@amd.comXMLNodeContents XMLNode::enumContents(int i) const { 291010152Satgutier@umich.edu XMLNodeContents c; 291110234Syasuko.eckert@amd.com if (!d) { 291210234Syasuko.eckert@amd.com c.etype = eNodeNULL; 291310152Satgutier@umich.edu return c; 291410152Satgutier@umich.edu } 291510234Syasuko.eckert@amd.com if (i < d->nAttribute) { 291610234Syasuko.eckert@amd.com c.etype = eNodeAttribute; 291710234Syasuko.eckert@amd.com c.attrib = d->pAttribute[i]; 291810234Syasuko.eckert@amd.com return c; 291910234Syasuko.eckert@amd.com } 292010234Syasuko.eckert@amd.com i -= d->nAttribute; 292110234Syasuko.eckert@amd.com c.etype = (XMLElementType)(d->pOrder[i] & 3); 292210234Syasuko.eckert@amd.com i = (d->pOrder[i]) >> 2; 292310234Syasuko.eckert@amd.com switch (c.etype) { 292410234Syasuko.eckert@amd.com case eNodeChild: 292510234Syasuko.eckert@amd.com c.child = d->pChild[i]; 292610234Syasuko.eckert@amd.com break; 292710234Syasuko.eckert@amd.com case eNodeText: 292810234Syasuko.eckert@amd.com c.text = d->pText[i]; 292910234Syasuko.eckert@amd.com break; 293010234Syasuko.eckert@amd.com case eNodeClear: 293110234Syasuko.eckert@amd.com c.clear = d->pClear[i]; 293210234Syasuko.eckert@amd.com break; 293310234Syasuko.eckert@amd.com default: 293410234Syasuko.eckert@amd.com break; 293510152Satgutier@umich.edu } 293610152Satgutier@umich.edu return c; 293710152Satgutier@umich.edu} 293810152Satgutier@umich.edu 293910234Syasuko.eckert@amd.comXMLCSTR XMLNode::getName() const { 294010234Syasuko.eckert@amd.com if (!d) return NULL; 294110234Syasuko.eckert@amd.com return d->lpszName; 294210234Syasuko.eckert@amd.com} 294310234Syasuko.eckert@amd.comint XMLNode::nText() const { 294410234Syasuko.eckert@amd.com if (!d) return 0; 294510234Syasuko.eckert@amd.com return d->nText; 294610234Syasuko.eckert@amd.com} 294710234Syasuko.eckert@amd.comint XMLNode::nChildNode() const { 294810234Syasuko.eckert@amd.com if (!d) return 0; 294910234Syasuko.eckert@amd.com return d->nChild; 295010234Syasuko.eckert@amd.com} 295110234Syasuko.eckert@amd.comint XMLNode::nAttribute() const { 295210234Syasuko.eckert@amd.com if (!d) return 0; 295310234Syasuko.eckert@amd.com return d->nAttribute; 295410234Syasuko.eckert@amd.com} 295510234Syasuko.eckert@amd.comint XMLNode::nClear() const { 295610234Syasuko.eckert@amd.com if (!d) return 0; 295710234Syasuko.eckert@amd.com return d->nClear; 295810234Syasuko.eckert@amd.com} 295910234Syasuko.eckert@amd.comint XMLNode::nElement() const { 296010234Syasuko.eckert@amd.com if (!d) return 0; 296110234Syasuko.eckert@amd.com return d->nAttribute + d->nChild + d->nText + d->nClear; 296210234Syasuko.eckert@amd.com} 296310234Syasuko.eckert@amd.comXMLClear XMLNode::getClear (int i) const { 296410234Syasuko.eckert@amd.com if ((!d) || (i >= d->nClear )) return emptyXMLClear; 296510234Syasuko.eckert@amd.com return d->pClear[i]; 296610234Syasuko.eckert@amd.com} 296710234Syasuko.eckert@amd.comXMLAttribute XMLNode::getAttribute (int i) const { 296810234Syasuko.eckert@amd.com if ((!d) || (i >= d->nAttribute)) return emptyXMLAttribute; 296910234Syasuko.eckert@amd.com return d->pAttribute[i]; 297010234Syasuko.eckert@amd.com} 297110234Syasuko.eckert@amd.comXMLCSTR XMLNode::getAttributeName (int i) const { 297210234Syasuko.eckert@amd.com if ((!d) || (i >= d->nAttribute)) return NULL; 297310234Syasuko.eckert@amd.com return d->pAttribute[i].lpszName; 297410234Syasuko.eckert@amd.com} 297510234Syasuko.eckert@amd.comXMLCSTR XMLNode::getAttributeValue(int i) const { 297610234Syasuko.eckert@amd.com if ((!d) || (i >= d->nAttribute)) return NULL; 297710234Syasuko.eckert@amd.com return d->pAttribute[i].lpszValue; 297810234Syasuko.eckert@amd.com} 297910234Syasuko.eckert@amd.comXMLCSTR XMLNode::getText (int i) const { 298010234Syasuko.eckert@amd.com if ((!d) || (i >= d->nText )) return NULL; 298110234Syasuko.eckert@amd.com return d->pText[i]; 298210234Syasuko.eckert@amd.com} 298310234Syasuko.eckert@amd.comXMLNode XMLNode::getChildNode (int i) const { 298410234Syasuko.eckert@amd.com if ((!d) || (i >= d->nChild )) return emptyXMLNode; 298510234Syasuko.eckert@amd.com return d->pChild[i]; 298610234Syasuko.eckert@amd.com} 298710234Syasuko.eckert@amd.comXMLNode XMLNode::getParentNode ( ) const { 298810234Syasuko.eckert@amd.com if ((!d) || (!d->pParent )) return emptyXMLNode; 298910234Syasuko.eckert@amd.com return XMLNode(d->pParent); 299010234Syasuko.eckert@amd.com} 299110234Syasuko.eckert@amd.comchar XMLNode::isDeclaration ( ) const { 299210234Syasuko.eckert@amd.com if (!d) return 0; 299310234Syasuko.eckert@amd.com return d->isDeclaration; 299410234Syasuko.eckert@amd.com} 299510234Syasuko.eckert@amd.comchar XMLNode::isEmpty ( ) const { 299610234Syasuko.eckert@amd.com return (d == NULL); 299710234Syasuko.eckert@amd.com} 299810234Syasuko.eckert@amd.comXMLNode XMLNode::emptyNode ( ) { 299910234Syasuko.eckert@amd.com return XMLNode::emptyXMLNode; 300010234Syasuko.eckert@amd.com} 300110152Satgutier@umich.edu 300210234Syasuko.eckert@amd.comXMLNode XMLNode::addChild(XMLCSTR lpszName, char isDeclaration, 300310234Syasuko.eckert@amd.com XMLElementPosition pos) { 300410234Syasuko.eckert@amd.com return addChild_priv(0, stringDup(lpszName), isDeclaration, pos); 300510234Syasuko.eckert@amd.com} 300610234Syasuko.eckert@amd.comXMLNode XMLNode::addChild_WOSD(XMLSTR lpszName, char isDeclaration, 300710234Syasuko.eckert@amd.com XMLElementPosition pos) { 300810234Syasuko.eckert@amd.com return addChild_priv(0, lpszName, isDeclaration, pos); 300910234Syasuko.eckert@amd.com} 301010234Syasuko.eckert@amd.comXMLAttribute *XMLNode::addAttribute(XMLCSTR lpszName, XMLCSTR lpszValue) { 301110234Syasuko.eckert@amd.com return addAttribute_priv(0, stringDup(lpszName), stringDup(lpszValue)); 301210234Syasuko.eckert@amd.com} 301310234Syasuko.eckert@amd.comXMLAttribute *XMLNode::addAttribute_WOSD(XMLSTR lpszName, XMLSTR lpszValuev) { 301410234Syasuko.eckert@amd.com return addAttribute_priv(0, lpszName, lpszValuev); 301510234Syasuko.eckert@amd.com} 301610234Syasuko.eckert@amd.comXMLCSTR XMLNode::addText(XMLCSTR lpszValue, XMLElementPosition pos) { 301710234Syasuko.eckert@amd.com return addText_priv(0, stringDup(lpszValue), pos); 301810234Syasuko.eckert@amd.com} 301910234Syasuko.eckert@amd.comXMLCSTR XMLNode::addText_WOSD(XMLSTR lpszValue, XMLElementPosition pos) { 302010234Syasuko.eckert@amd.com return addText_priv(0, lpszValue, pos); 302110234Syasuko.eckert@amd.com} 302210234Syasuko.eckert@amd.comXMLClear *XMLNode::addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen, 302310234Syasuko.eckert@amd.com XMLCSTR lpszClose, XMLElementPosition pos) { 302410234Syasuko.eckert@amd.com return addClear_priv(0, stringDup(lpszValue), lpszOpen, lpszClose, pos); 302510234Syasuko.eckert@amd.com} 302610234Syasuko.eckert@amd.comXMLClear *XMLNode::addClear_WOSD(XMLSTR lpszValue, XMLCSTR lpszOpen, 302710234Syasuko.eckert@amd.com XMLCSTR lpszClose, XMLElementPosition pos) { 302810234Syasuko.eckert@amd.com return addClear_priv(0, lpszValue, lpszOpen, lpszClose, pos); 302910234Syasuko.eckert@amd.com} 303010234Syasuko.eckert@amd.comXMLCSTR XMLNode::updateName(XMLCSTR lpszName) { 303110234Syasuko.eckert@amd.com return updateName_WOSD(stringDup(lpszName)); 303210234Syasuko.eckert@amd.com} 303310234Syasuko.eckert@amd.comXMLAttribute *XMLNode::updateAttribute(XMLAttribute *newAttribute, 303410234Syasuko.eckert@amd.com XMLAttribute *oldAttribute) { 303510234Syasuko.eckert@amd.com return updateAttribute_WOSD(stringDup(newAttribute->lpszValue), 303610234Syasuko.eckert@amd.com stringDup(newAttribute->lpszName), 303710234Syasuko.eckert@amd.com oldAttribute->lpszName); 303810234Syasuko.eckert@amd.com} 303910234Syasuko.eckert@amd.comXMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, 304010234Syasuko.eckert@amd.com XMLCSTR lpszNewName, int i) { 304110234Syasuko.eckert@amd.com return updateAttribute_WOSD(stringDup(lpszNewValue), 304210234Syasuko.eckert@amd.com stringDup(lpszNewName), i); 304310234Syasuko.eckert@amd.com} 304410234Syasuko.eckert@amd.comXMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, 304510234Syasuko.eckert@amd.com XMLCSTR lpszNewName, 304610234Syasuko.eckert@amd.com XMLCSTR lpszOldName) { 304710234Syasuko.eckert@amd.com return updateAttribute_WOSD(stringDup(lpszNewValue), 304810234Syasuko.eckert@amd.com stringDup(lpszNewName), lpszOldName); 304910234Syasuko.eckert@amd.com} 305010234Syasuko.eckert@amd.comXMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue, int i) { 305110234Syasuko.eckert@amd.com return updateText_WOSD(stringDup(lpszNewValue), i); 305210234Syasuko.eckert@amd.com} 305310234Syasuko.eckert@amd.comXMLCSTR XMLNode::updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue) { 305410234Syasuko.eckert@amd.com return updateText_WOSD(stringDup(lpszNewValue), lpszOldValue); 305510234Syasuko.eckert@amd.com} 305610234Syasuko.eckert@amd.comXMLClear *XMLNode::updateClear(XMLCSTR lpszNewContent, int i) { 305710234Syasuko.eckert@amd.com return updateClear_WOSD(stringDup(lpszNewContent), i); 305810234Syasuko.eckert@amd.com} 305910234Syasuko.eckert@amd.comXMLClear *XMLNode::updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue) { 306010234Syasuko.eckert@amd.com return updateClear_WOSD(stringDup(lpszNewValue), lpszOldValue); 306110234Syasuko.eckert@amd.com} 306210234Syasuko.eckert@amd.comXMLClear *XMLNode::updateClear(XMLClear *newP, XMLClear *oldP) { 306310234Syasuko.eckert@amd.com return updateClear_WOSD(stringDup(newP->lpszValue), oldP->lpszValue); 306410234Syasuko.eckert@amd.com} 306510152Satgutier@umich.edu 306610234Syasuko.eckert@amd.comchar XMLNode::setGlobalOptions(XMLCharEncoding _characterEncoding, 306710234Syasuko.eckert@amd.com char _guessWideCharChars, 306810234Syasuko.eckert@amd.com char _dropWhiteSpace, 306910234Syasuko.eckert@amd.com char _removeCommentsInMiddleOfText) { 307010234Syasuko.eckert@amd.com guessWideCharChars = _guessWideCharChars; 307110234Syasuko.eckert@amd.com dropWhiteSpace = _dropWhiteSpace; 307210234Syasuko.eckert@amd.com removeCommentsInMiddleOfText = _removeCommentsInMiddleOfText; 307310152Satgutier@umich.edu#ifdef _XMLWIDECHAR 307410234Syasuko.eckert@amd.com if (_characterEncoding) characterEncoding = _characterEncoding; 307510152Satgutier@umich.edu#else 307610234Syasuko.eckert@amd.com switch (_characterEncoding) { 307710234Syasuko.eckert@amd.com case char_encoding_UTF8: 307810234Syasuko.eckert@amd.com characterEncoding = _characterEncoding; 307910234Syasuko.eckert@amd.com XML_ByteTable = XML_utf8ByteTable; 308010234Syasuko.eckert@amd.com break; 308110234Syasuko.eckert@amd.com case char_encoding_legacy: 308210234Syasuko.eckert@amd.com characterEncoding = _characterEncoding; 308310234Syasuko.eckert@amd.com XML_ByteTable = XML_legacyByteTable; 308410234Syasuko.eckert@amd.com break; 308510234Syasuko.eckert@amd.com case char_encoding_ShiftJIS: 308610234Syasuko.eckert@amd.com characterEncoding = _characterEncoding; 308710234Syasuko.eckert@amd.com XML_ByteTable = XML_sjisByteTable; 308810234Syasuko.eckert@amd.com break; 308910234Syasuko.eckert@amd.com case char_encoding_GB2312: 309010234Syasuko.eckert@amd.com characterEncoding = _characterEncoding; 309110234Syasuko.eckert@amd.com XML_ByteTable = XML_gb2312ByteTable; 309210234Syasuko.eckert@amd.com break; 309310152Satgutier@umich.edu case char_encoding_Big5: 309410234Syasuko.eckert@amd.com case char_encoding_GBK: 309510234Syasuko.eckert@amd.com characterEncoding = _characterEncoding; 309610234Syasuko.eckert@amd.com XML_ByteTable = XML_gbk_big5_ByteTable; 309710234Syasuko.eckert@amd.com break; 309810234Syasuko.eckert@amd.com default: 309910234Syasuko.eckert@amd.com return 1; 310010152Satgutier@umich.edu } 310110152Satgutier@umich.edu#endif 310210152Satgutier@umich.edu return 0; 310310152Satgutier@umich.edu} 310410152Satgutier@umich.edu 310510234Syasuko.eckert@amd.comXMLNode::XMLCharEncoding XMLNode::guessCharEncoding(void *buf, int l, 310610234Syasuko.eckert@amd.com char useXMLEncodingAttribute) { 310710152Satgutier@umich.edu#ifdef _XMLWIDECHAR 310810152Satgutier@umich.edu return (XMLCharEncoding)0; 310910152Satgutier@umich.edu#else 311010234Syasuko.eckert@amd.com if (l < 25) return (XMLCharEncoding)0; 311110234Syasuko.eckert@amd.com if (guessWideCharChars && (myIsTextWideChar(buf, l))) { 311210234Syasuko.eckert@amd.com return (XMLCharEncoding)0; 311310234Syasuko.eckert@amd.com } 311410234Syasuko.eckert@amd.com unsigned char *b = (unsigned char*)buf; 311510234Syasuko.eckert@amd.com if ((b[0] == 0xef) && (b[1] == 0xbb) && (b[2] == 0xbf)) { 311610234Syasuko.eckert@amd.com return char_encoding_UTF8; 311710234Syasuko.eckert@amd.com } 311810152Satgutier@umich.edu 311910152Satgutier@umich.edu // Match utf-8 model ? 312010234Syasuko.eckert@amd.com XMLCharEncoding bestGuess = char_encoding_UTF8; 312110234Syasuko.eckert@amd.com int i = 0; 312210234Syasuko.eckert@amd.com while (i < l) 312310234Syasuko.eckert@amd.com switch (XML_utf8ByteTable[b[i]]) { 312410234Syasuko.eckert@amd.com case 4: 312510234Syasuko.eckert@amd.com i++; 312610234Syasuko.eckert@amd.com if ((i < l) && (b[i]& 0xC0) != 0x80) { 312710234Syasuko.eckert@amd.com bestGuess = char_encoding_legacy; // 10bbbbbb ? 312810234Syasuko.eckert@amd.com i = l; 312910234Syasuko.eckert@amd.com } 313010234Syasuko.eckert@amd.com case 3: 313110234Syasuko.eckert@amd.com i++; 313210234Syasuko.eckert@amd.com if ((i < l) && (b[i]& 0xC0) != 0x80) { 313310234Syasuko.eckert@amd.com bestGuess = char_encoding_legacy; // 10bbbbbb ? 313410234Syasuko.eckert@amd.com i = l; 313510234Syasuko.eckert@amd.com } 313610234Syasuko.eckert@amd.com case 2: 313710234Syasuko.eckert@amd.com i++; 313810234Syasuko.eckert@amd.com if ((i < l) && (b[i]& 0xC0) != 0x80) { 313910234Syasuko.eckert@amd.com bestGuess = char_encoding_legacy; // 10bbbbbb ? 314010234Syasuko.eckert@amd.com i = l; 314110234Syasuko.eckert@amd.com } 314210234Syasuko.eckert@amd.com case 1: 314310234Syasuko.eckert@amd.com i++; 314410234Syasuko.eckert@amd.com break; 314510234Syasuko.eckert@amd.com case 0: 314610234Syasuko.eckert@amd.com i = l; 314710152Satgutier@umich.edu } 314810152Satgutier@umich.edu if (!useXMLEncodingAttribute) return bestGuess; 314910152Satgutier@umich.edu // if encoding is specified and different from utf-8 than it's non-utf8 315010152Satgutier@umich.edu // otherwise it's utf-8 315110152Satgutier@umich.edu char bb[201]; 315210234Syasuko.eckert@amd.com l = mmin(l, 200); 315310234Syasuko.eckert@amd.com memcpy(bb, buf, l); // copy buf into bb to be able to do "bb[l]=0" 315410234Syasuko.eckert@amd.com bb[l] = 0; 315510234Syasuko.eckert@amd.com b = (unsigned char*)strstr(bb, "encoding"); 315610152Satgutier@umich.edu if (!b) return bestGuess; 315710234Syasuko.eckert@amd.com b += 8; 315810234Syasuko.eckert@amd.com while XML_isSPACECHAR(*b) b++; 315910234Syasuko.eckert@amd.com if (*b != '=') return bestGuess; 316010234Syasuko.eckert@amd.com b++; 316110234Syasuko.eckert@amd.com while XML_isSPACECHAR(*b) b++; 316210234Syasuko.eckert@amd.com if ((*b != '\'') && (*b != '"')) return bestGuess; 316310234Syasuko.eckert@amd.com b++; 316410234Syasuko.eckert@amd.com while XML_isSPACECHAR(*b) b++; 316510152Satgutier@umich.edu 316610234Syasuko.eckert@amd.com if ((xstrnicmp((char*)b, "utf-8", 5) == 0) || 316710234Syasuko.eckert@amd.com (xstrnicmp((char*)b, "utf8", 4) == 0)) { 316810234Syasuko.eckert@amd.com if (bestGuess == char_encoding_legacy) return char_encoding_error; 316910152Satgutier@umich.edu return char_encoding_UTF8; 317010152Satgutier@umich.edu } 317110152Satgutier@umich.edu 317210234Syasuko.eckert@amd.com if ((xstrnicmp((char*)b, "shiftjis", 8) == 0) || 317310234Syasuko.eckert@amd.com (xstrnicmp((char*)b, "shift-jis", 9) == 0) || 317410234Syasuko.eckert@amd.com (xstrnicmp((char*)b, "sjis", 4) == 0)) return char_encoding_ShiftJIS; 317510152Satgutier@umich.edu 317610234Syasuko.eckert@amd.com if (xstrnicmp((char*)b, "GB2312", 6) == 0) return char_encoding_GB2312; 317710234Syasuko.eckert@amd.com if (xstrnicmp((char*)b, "Big5", 4) == 0) return char_encoding_Big5; 317810234Syasuko.eckert@amd.com if (xstrnicmp((char*)b, "GBK", 3) == 0) return char_encoding_GBK; 317910152Satgutier@umich.edu 318010152Satgutier@umich.edu return char_encoding_legacy; 318110152Satgutier@umich.edu#endif 318210152Satgutier@umich.edu} 318310152Satgutier@umich.edu#undef XML_isSPACECHAR 318410152Satgutier@umich.edu 318510152Satgutier@umich.edu////////////////////////////////////////////////////////// 318610152Satgutier@umich.edu// Here starts the base64 conversion functions. // 318710152Satgutier@umich.edu////////////////////////////////////////////////////////// 318810152Satgutier@umich.edu 318910234Syasuko.eckert@amd.com// used to mark partial words at the end 319010234Syasuko.eckert@amd.comstatic const char base64Fillchar = _CXML('='); 319110152Satgutier@umich.edu 319210152Satgutier@umich.edu// this lookup table defines the base64 encoding 319310234Syasuko.eckert@amd.comXMLCSTR base64EncodeTable = _CXML("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); 319410152Satgutier@umich.edu 319510152Satgutier@umich.edu// Decode Table gives the index of any valid base64 character in the Base64 table] 319610152Satgutier@umich.edu// 96: '=' - 97: space char - 98: illegal char - 99: end of string 319710152Satgutier@umich.educonst unsigned char base64DecodeTable[] = { 319810234Syasuko.eckert@amd.com 99, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, 98, 98, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, //00 -29 319910234Syasuko.eckert@amd.com 98, 98, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 62, 98, 98, 98, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 98, 98, //30 -59 320010234Syasuko.eckert@amd.com 98, 96, 98, 98, 98, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, //60 -89 320110234Syasuko.eckert@amd.com 25, 98, 98, 98, 98, 98, 98, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, //90 -119 320210234Syasuko.eckert@amd.com 49, 50, 51, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, //120 -149 320310234Syasuko.eckert@amd.com 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, //150 -179 320410234Syasuko.eckert@amd.com 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, //180 -209 320510234Syasuko.eckert@amd.com 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, //210 -239 320610234Syasuko.eckert@amd.com 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98 //240 -255 320710152Satgutier@umich.edu}; 320810152Satgutier@umich.edu 320910234Syasuko.eckert@amd.comXMLParserBase64Tool::~XMLParserBase64Tool() { 321010234Syasuko.eckert@amd.com freeBuffer(); 321110234Syasuko.eckert@amd.com} 321210152Satgutier@umich.edu 321310234Syasuko.eckert@amd.comvoid XMLParserBase64Tool::freeBuffer() { 321410234Syasuko.eckert@amd.com if (buf) free(buf); 321510234Syasuko.eckert@amd.com buf = NULL; 321610234Syasuko.eckert@amd.com buflen = 0; 321710234Syasuko.eckert@amd.com} 321810152Satgutier@umich.edu 321910234Syasuko.eckert@amd.comint XMLParserBase64Tool::encodeLength(int inlen, char formatted) { 322010234Syasuko.eckert@amd.com unsigned int i = ((inlen - 1) / 3 * 4 + 4 + 1); 322110234Syasuko.eckert@amd.com if (formatted) i += inlen / 54; 322210152Satgutier@umich.edu return i; 322310152Satgutier@umich.edu} 322410152Satgutier@umich.edu 322510234Syasuko.eckert@amd.comXMLSTR XMLParserBase64Tool::encode(unsigned char *inbuf, unsigned int inlen, 322610234Syasuko.eckert@amd.com char formatted) { 322710234Syasuko.eckert@amd.com int i = encodeLength(inlen, formatted), k = 17, eLen = inlen / 3, j; 322810152Satgutier@umich.edu alloc(i*sizeof(XMLCHAR)); 322910234Syasuko.eckert@amd.com XMLSTR curr = (XMLSTR)buf; 323010234Syasuko.eckert@amd.com for (i = 0; i < eLen; i++) { 323110152Satgutier@umich.edu // Copy next three bytes into lower 24 bits of int, paying attention to sign. 323210234Syasuko.eckert@amd.com j = (inbuf[0] << 16) | (inbuf[1] << 8) | inbuf[2]; 323310234Syasuko.eckert@amd.com inbuf += 3; 323410152Satgutier@umich.edu // Encode the int into four chars 323510234Syasuko.eckert@amd.com *(curr++) = base64EncodeTable[ j>>18 ]; 323610234Syasuko.eckert@amd.com *(curr++) = base64EncodeTable[(j>>12)&0x3f]; 323710234Syasuko.eckert@amd.com *(curr++) = base64EncodeTable[(j>> 6)&0x3f]; 323810234Syasuko.eckert@amd.com *(curr++) = base64EncodeTable[(j )&0x3f]; 323910234Syasuko.eckert@amd.com if (formatted) { 324010234Syasuko.eckert@amd.com if (!k) { 324110234Syasuko.eckert@amd.com *(curr++) = _CXML('\n'); 324210234Syasuko.eckert@amd.com k = 18; 324310234Syasuko.eckert@amd.com } 324410234Syasuko.eckert@amd.com k--; 324510234Syasuko.eckert@amd.com } 324610152Satgutier@umich.edu } 324710234Syasuko.eckert@amd.com eLen = inlen - eLen * 3; // 0 - 2. 324810234Syasuko.eckert@amd.com if (eLen == 1) { 324910234Syasuko.eckert@amd.com *(curr++) = base64EncodeTable[ inbuf[0] >> 2 ]; 325010234Syasuko.eckert@amd.com *(curr++) = base64EncodeTable[(inbuf[0] << 4) & 0x3F]; 325110234Syasuko.eckert@amd.com *(curr++) = base64Fillchar; 325210234Syasuko.eckert@amd.com *(curr++) = base64Fillchar; 325310234Syasuko.eckert@amd.com } else if (eLen == 2) { 325410234Syasuko.eckert@amd.com j = (inbuf[0] << 8) | inbuf[1]; 325510234Syasuko.eckert@amd.com *(curr++) = base64EncodeTable[ j>>10 ]; 325610234Syasuko.eckert@amd.com *(curr++) = base64EncodeTable[(j>> 4)&0x3f]; 325710234Syasuko.eckert@amd.com *(curr++) = base64EncodeTable[(j<< 2)&0x3f]; 325810234Syasuko.eckert@amd.com *(curr++) = base64Fillchar; 325910152Satgutier@umich.edu } 326010234Syasuko.eckert@amd.com *(curr++) = 0; 326110152Satgutier@umich.edu return (XMLSTR)buf; 326210152Satgutier@umich.edu} 326310152Satgutier@umich.edu 326410234Syasuko.eckert@amd.comunsigned int XMLParserBase64Tool::decodeSize(XMLCSTR data, XMLError *xe) { 326510234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorNone; 326610234Syasuko.eckert@amd.com int size = 0; 326710152Satgutier@umich.edu unsigned char c; 326810152Satgutier@umich.edu //skip any extra characters (e.g. newlines or spaces) 326910234Syasuko.eckert@amd.com while (*data) { 327010152Satgutier@umich.edu#ifdef _XMLWIDECHAR 327110234Syasuko.eckert@amd.com if (*data > 255) { 327210234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorBase64DecodeIllegalCharacter; 327310234Syasuko.eckert@amd.com return 0; 327410234Syasuko.eckert@amd.com } 327510152Satgutier@umich.edu#endif 327610234Syasuko.eckert@amd.com c = base64DecodeTable[(unsigned char)(*data)]; 327710234Syasuko.eckert@amd.com if (c < 97) size++; 327810234Syasuko.eckert@amd.com else if (c == 98) { 327910234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorBase64DecodeIllegalCharacter; 328010234Syasuko.eckert@amd.com return 0; 328110234Syasuko.eckert@amd.com } 328210152Satgutier@umich.edu data++; 328310152Satgutier@umich.edu } 328410234Syasuko.eckert@amd.com if (xe && (size % 4 != 0)) *xe = eXMLErrorBase64DataSizeIsNotMultipleOf4; 328510234Syasuko.eckert@amd.com if (size == 0) return 0; 328610234Syasuko.eckert@amd.com do { 328710234Syasuko.eckert@amd.com data--; 328810234Syasuko.eckert@amd.com size--; 328910234Syasuko.eckert@amd.com } while (*data == base64Fillchar); 329010234Syasuko.eckert@amd.com size++; 329110234Syasuko.eckert@amd.com return (unsigned int)((size*3) / 4); 329210152Satgutier@umich.edu} 329310152Satgutier@umich.edu 329410234Syasuko.eckert@amd.comunsigned char XMLParserBase64Tool::decode(XMLCSTR data, unsigned char *buf, 329510234Syasuko.eckert@amd.com int len, XMLError *xe) { 329610234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorNone; 329710234Syasuko.eckert@amd.com int i = 0, p = 0; 329810234Syasuko.eckert@amd.com unsigned char d, c; 329910234Syasuko.eckert@amd.com for (;;) { 330010152Satgutier@umich.edu 330110152Satgutier@umich.edu#ifdef _XMLWIDECHAR 330210152Satgutier@umich.edu#define BASE64DECODE_READ_NEXT_CHAR(c) \ 330310152Satgutier@umich.edu do { \ 330410152Satgutier@umich.edu if (data[i]>255){ c=98; break; } \ 330510152Satgutier@umich.edu c=base64DecodeTable[(unsigned char)data[i++]]; \ 330610152Satgutier@umich.edu }while (c==97); \ 330710152Satgutier@umich.edu if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; } 330810152Satgutier@umich.edu#else 330910152Satgutier@umich.edu#define BASE64DECODE_READ_NEXT_CHAR(c) \ 331010152Satgutier@umich.edu do { c=base64DecodeTable[(unsigned char)data[i++]]; }while (c==97); \ 331110152Satgutier@umich.edu if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; } 331210152Satgutier@umich.edu#endif 331310152Satgutier@umich.edu 331410152Satgutier@umich.edu BASE64DECODE_READ_NEXT_CHAR(c) 331510234Syasuko.eckert@amd.com if (c == 99) { 331610234Syasuko.eckert@amd.com return 2; 331710234Syasuko.eckert@amd.com } 331810234Syasuko.eckert@amd.com if (c == 96) { 331910234Syasuko.eckert@amd.com if (p == (int)len) return 2; 332010234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; 332110152Satgutier@umich.edu return 1; 332210152Satgutier@umich.edu } 332310152Satgutier@umich.edu 332410152Satgutier@umich.edu BASE64DECODE_READ_NEXT_CHAR(d) 332510234Syasuko.eckert@amd.com if ((d == 99) || (d == 96)) { 332610234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; 332710234Syasuko.eckert@amd.com return 1; 332810234Syasuko.eckert@amd.com } 332910234Syasuko.eckert@amd.com if (p == (int)len) { 333010234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorBase64DecodeBufferTooSmall; 333110234Syasuko.eckert@amd.com return 0; 333210234Syasuko.eckert@amd.com } 333310234Syasuko.eckert@amd.com buf[p++] = (unsigned char)((c << 2) | ((d >> 4) & 0x3)); 333410152Satgutier@umich.edu 333510152Satgutier@umich.edu BASE64DECODE_READ_NEXT_CHAR(c) 333610234Syasuko.eckert@amd.com if (c == 99) { 333710234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; 333810234Syasuko.eckert@amd.com return 1; 333910234Syasuko.eckert@amd.com } 334010234Syasuko.eckert@amd.com if (p == (int)len) { 334110234Syasuko.eckert@amd.com if (c == 96) return 2; 334210234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorBase64DecodeBufferTooSmall; 334310152Satgutier@umich.edu return 0; 334410152Satgutier@umich.edu } 334510234Syasuko.eckert@amd.com if (c == 96) { 334610234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; 334710234Syasuko.eckert@amd.com return 1; 334810234Syasuko.eckert@amd.com } 334910234Syasuko.eckert@amd.com buf[p++] = (unsigned char)(((d << 4) & 0xf0) | ((c >> 2) & 0xf)); 335010152Satgutier@umich.edu 335110152Satgutier@umich.edu BASE64DECODE_READ_NEXT_CHAR(d) 335210234Syasuko.eckert@amd.com if (d == 99 ) { 335310234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; 335410234Syasuko.eckert@amd.com return 1; 335510234Syasuko.eckert@amd.com } 335610234Syasuko.eckert@amd.com if (p == (int)len) { 335710234Syasuko.eckert@amd.com if (d == 96) return 2; 335810234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorBase64DecodeBufferTooSmall; 335910152Satgutier@umich.edu return 0; 336010152Satgutier@umich.edu } 336110234Syasuko.eckert@amd.com if (d == 96) { 336210234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorBase64DecodeTruncatedData; 336310234Syasuko.eckert@amd.com return 1; 336410234Syasuko.eckert@amd.com } 336510234Syasuko.eckert@amd.com buf[p++] = (unsigned char)(((c << 6) & 0xc0) | d); 336610152Satgutier@umich.edu } 336710152Satgutier@umich.edu} 336810152Satgutier@umich.edu#undef BASE64DECODE_READ_NEXT_CHAR 336910152Satgutier@umich.edu 337010234Syasuko.eckert@amd.comvoid XMLParserBase64Tool::alloc(int newsize) { 337110234Syasuko.eckert@amd.com if ((!buf) && (newsize)) { 337210234Syasuko.eckert@amd.com buf = malloc(newsize); 337310234Syasuko.eckert@amd.com buflen = newsize; 337410234Syasuko.eckert@amd.com return; 337510234Syasuko.eckert@amd.com } 337610234Syasuko.eckert@amd.com if (newsize > buflen) { 337710234Syasuko.eckert@amd.com buf = realloc(buf, newsize); 337810234Syasuko.eckert@amd.com buflen = newsize; 337910234Syasuko.eckert@amd.com } 338010152Satgutier@umich.edu} 338110152Satgutier@umich.edu 338210234Syasuko.eckert@amd.comunsigned char *XMLParserBase64Tool::decode(XMLCSTR data, int *outlen, XMLError *xe) { 338310234Syasuko.eckert@amd.com if (xe) *xe = eXMLErrorNone; 338410234Syasuko.eckert@amd.com unsigned int len = decodeSize(data, xe); 338510234Syasuko.eckert@amd.com if (outlen) *outlen = len; 338610152Satgutier@umich.edu if (!len) return NULL; 338710234Syasuko.eckert@amd.com alloc(len + 1); 338810234Syasuko.eckert@amd.com if (!decode(data, (unsigned char*)buf, len, xe)) { 338910234Syasuko.eckert@amd.com return NULL; 339010234Syasuko.eckert@amd.com } 339110152Satgutier@umich.edu return (unsigned char*)buf; 339210152Satgutier@umich.edu} 339310152Satgutier@umich.edu 3394