llxmlparser.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:9k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llxmlparser.cpp
  3.  * @brief LLXmlParser implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. // llxmlparser.cpp
  33. //              
  34. // copyright 2002, linden research inc
  35. #include "linden_common.h"
  36. #include "llxmlparser.h"
  37. #include "llerror.h"
  38. LLXmlParser::LLXmlParser()
  39. :
  40. mParser( NULL ),
  41. mDepth( 0 )
  42. {
  43. mAuxErrorString = "no error";
  44. // Override the document's declared encoding.
  45. mParser = XML_ParserCreate(NULL);
  46. XML_SetUserData(mParser, this);
  47. XML_SetElementHandler( mParser, startElementHandler, endElementHandler);
  48. XML_SetCharacterDataHandler( mParser, characterDataHandler);
  49. XML_SetProcessingInstructionHandler( mParser, processingInstructionHandler);
  50. XML_SetCommentHandler( mParser, commentHandler);
  51. XML_SetCdataSectionHandler( mParser, startCdataSectionHandler, endCdataSectionHandler);
  52. // This sets the default handler but does not inhibit expansion of internal entities.
  53. // The entity reference will not be passed to the default handler.
  54. XML_SetDefaultHandlerExpand( mParser, defaultDataHandler);
  55. XML_SetUnparsedEntityDeclHandler( mParser, unparsedEntityDeclHandler);
  56. }
  57. LLXmlParser::~LLXmlParser()
  58. {
  59. XML_ParserFree( mParser );
  60. }
  61. BOOL LLXmlParser::parseFile(const std::string &path)
  62. {
  63. llassert( !mDepth );
  64. BOOL success = TRUE;
  65. LLFILE* file = LLFile::fopen(path, "rb"); /* Flawfinder: ignore */
  66. if( !file )
  67. {
  68. mAuxErrorString = llformat( "Couldn't open file %s", path.c_str());
  69. success = FALSE;
  70. }
  71. else
  72. {
  73. S32 bytes_read = 0;
  74. fseek(file, 0L, SEEK_END);
  75. S32 buffer_size = ftell(file);
  76. fseek(file, 0L, SEEK_SET);
  77. void* buffer = XML_GetBuffer(mParser, buffer_size);
  78. if( !buffer ) 
  79. {
  80. mAuxErrorString = llformat( "Unable to allocate XML buffer while reading file %s", path.c_str() );
  81. success = FALSE;
  82. goto exit_label;
  83. }
  84. bytes_read = (S32)fread(buffer, 1, buffer_size, file);
  85. if( bytes_read <= 0 )
  86. {
  87. mAuxErrorString = llformat( "Error while reading file  %s", path.c_str() );
  88. success = FALSE;
  89. goto exit_label;
  90. }
  91. if( !XML_ParseBuffer(mParser, bytes_read, TRUE ) )
  92. {
  93. mAuxErrorString = llformat( "Error while parsing file  %s", path.c_str() );
  94. success = FALSE;
  95. }
  96. exit_label: 
  97. fclose( file );
  98. }
  99. if( success )
  100. {
  101. llassert( !mDepth );
  102. }
  103. mDepth = 0;
  104. if( !success )
  105. {
  106. llwarns << mAuxErrorString << llendl;
  107. }
  108. return success;
  109. }
  110. // Parses some input. Returns 0 if a fatal error is detected.
  111. // The last call must have isFinal true;
  112. // len may be zero for this call (or any other).
  113. S32 LLXmlParser::parse( const char* buf, int len, int isFinal )
  114. {
  115. return XML_Parse(mParser, buf, len, isFinal);
  116. }
  117. const char* LLXmlParser::getErrorString()
  118. {
  119. const char* error_string = XML_ErrorString(XML_GetErrorCode( mParser ));
  120. if( !error_string )
  121. {
  122. error_string = mAuxErrorString.c_str();
  123. }
  124. return error_string;
  125. }
  126. S32 LLXmlParser::getCurrentLineNumber()
  127. {
  128. return XML_GetCurrentLineNumber( mParser );
  129. }
  130. S32 LLXmlParser::getCurrentColumnNumber()
  131. {
  132. return XML_GetCurrentColumnNumber(mParser);
  133. }
  134. ///////////////////////////////////////////////////////////////////////////////
  135. // Pseudo-private methods.  These are only used by internal callbacks.
  136. // static 
  137. void LLXmlParser::startElementHandler(
  138.  void *userData,
  139.  const XML_Char *name,
  140.  const XML_Char **atts)
  141. {
  142. LLXmlParser* self = (LLXmlParser*) userData;
  143. self->startElement( name, atts );
  144. self->mDepth++;
  145. }
  146. // static 
  147. void LLXmlParser::endElementHandler(
  148. void *userData,
  149. const XML_Char *name)
  150. {
  151. LLXmlParser* self = (LLXmlParser*) userData;
  152. self->mDepth--;
  153. self->endElement( name );
  154. }
  155. // s is not 0 terminated.
  156. // static 
  157. void LLXmlParser::characterDataHandler(
  158. void *userData,
  159. const XML_Char *s,
  160. int len)
  161. {
  162. LLXmlParser* self = (LLXmlParser*) userData;
  163. self->characterData( s, len );
  164. }
  165. // target and data are 0 terminated
  166. // static 
  167. void LLXmlParser::processingInstructionHandler(
  168. void *userData,
  169. const XML_Char *target,
  170. const XML_Char *data)
  171. {
  172. LLXmlParser* self = (LLXmlParser*) userData;
  173. self->processingInstruction( target, data );
  174. }
  175. // data is 0 terminated 
  176. // static
  177. void LLXmlParser::commentHandler(void *userData, const XML_Char *data)
  178. {
  179. LLXmlParser* self = (LLXmlParser*) userData;
  180. self->comment( data );
  181. }
  182. // static
  183. void LLXmlParser::startCdataSectionHandler(void *userData)
  184. {
  185. LLXmlParser* self = (LLXmlParser*) userData;
  186. self->mDepth++;
  187. self->startCdataSection();
  188. }
  189. // static
  190. void LLXmlParser::endCdataSectionHandler(void *userData)
  191. {
  192. LLXmlParser* self = (LLXmlParser*) userData;
  193. self->endCdataSection();
  194. self->mDepth++;
  195. }
  196. // This is called for any characters in the XML document for
  197. // which there is no applicable handler.  This includes both
  198. // characters that are part of markup which is of a kind that is
  199. // not reported (comments, markup declarations), or characters
  200. // that are part of a construct which could be reported but
  201. // for which no handler has been supplied. The characters are passed
  202. // exactly as they were in the XML document except that
  203. // they will be encoded in UTF-8.  Line boundaries are not normalized.
  204. // Note that a byte order mark character is not passed to the default handler.
  205. // There are no guarantees about how characters are divided between calls
  206. // to the default handler: for example, a comment might be split between
  207. // multiple calls.
  208. // static 
  209. void LLXmlParser::defaultDataHandler(
  210. void *userData,
  211. const XML_Char *s,
  212. int len)
  213. {
  214. LLXmlParser* self = (LLXmlParser*) userData;
  215. self->defaultData( s, len );
  216. }
  217. // This is called for a declaration of an unparsed (NDATA)
  218. // entity.  The base argument is whatever was set by XML_SetBase.
  219. // The entityName, systemId and notationName arguments will never be null.
  220. // The other arguments may be.
  221. // static 
  222. void LLXmlParser::unparsedEntityDeclHandler(
  223. void *userData,
  224. const XML_Char *entityName,
  225. const XML_Char *base,
  226. const XML_Char *systemId,
  227. const XML_Char *publicId,
  228. const XML_Char *notationName)
  229. {
  230. LLXmlParser* self = (LLXmlParser*) userData;
  231. self->unparsedEntityDecl( entityName, base, systemId, publicId, notationName );
  232. }
  233. ////////////////////////////////////////////////////////////////////
  234. // Test code.
  235. /*
  236. class LLXmlDOMParser : public LLXmlParser
  237. {
  238. public:
  239. LLXmlDOMParser() {}
  240. virtual ~LLXmlDOMParser() {}
  241. void tabs()
  242. {
  243. for ( int i = 0; i < getDepth(); i++)
  244. {
  245. putchar(' ');
  246. }
  247. }
  248. virtual void startElement(const char *name, const char **atts) 
  249. {
  250. tabs();
  251. printf("startElement %sn", name);
  252. S32 i = 0;
  253. while( atts[i] && atts[i+1] )
  254. {
  255. tabs();
  256. printf( "t%s=%sn", atts[i], atts[i+1] );
  257. i += 2;
  258. }
  259. if( atts[i] )
  260. {
  261. tabs();
  262. printf( "ttrailing attribute: %sn", atts[i] );
  263. }
  264. }
  265. virtual void endElement(const char *name) 
  266. {
  267. tabs();
  268. printf("endElement %sn", name);
  269. }
  270. virtual void characterData(const char *s, int len) 
  271. {
  272. tabs();
  273. char* str = new char[len+1];
  274. strncpy( str, s, len );
  275. str[len] = '';
  276. printf("CharacterData %sn", str);
  277. delete str;
  278. }
  279. virtual void processingInstruction(const char *target, const char *data)
  280. {
  281. tabs();
  282. printf("processingInstruction %sn", data);
  283. }
  284. virtual void comment(const char *data)
  285. {
  286. tabs();
  287. printf("comment %sn", data);
  288. }
  289. virtual void startCdataSection()
  290. {
  291. tabs();
  292. printf("startCdataSectionn");
  293. }
  294. virtual void endCdataSection()
  295. {
  296. tabs();
  297. printf("endCdataSectionn");
  298. }
  299. virtual void defaultData(const char *s, int len)
  300. {
  301. tabs();
  302. char* str = new char[len+1];
  303. strncpy( str, s, len );
  304. str[len] = '';
  305. printf("defaultData %sn", str);
  306. delete str;
  307. }
  308. virtual void unparsedEntityDecl(
  309. const char *entityName,
  310. const char *base,
  311. const char *systemId,
  312. const char *publicId,
  313. const char *notationName)
  314. {
  315. tabs();
  316. printf(
  317. "unparsed entity:n"
  318. "tentityName %sn"
  319. "tbase %sn"
  320. "tsystemId %sn"
  321. "tpublicId %sn"
  322. "tnotationName %sn",
  323. entityName,
  324. base,
  325. systemId,
  326. publicId,
  327. notationName );
  328. }
  329. };
  330. int main()
  331. {
  332.   char buf[1024];
  333.   LLFILE* file = LLFile::fopen("test.xml", "rb");
  334.   if( !file )
  335.   {
  336.   return 1;
  337.   }
  338.   LLXmlDOMParser parser;
  339.   int done;
  340.   do {
  341.     size_t len = fread(buf, 1, sizeof(buf), file);
  342.     done = len < sizeof(buf);
  343.     if( 0 == parser.parse( buf, len, done) )
  344. {
  345.       fprintf(stderr,
  346.       "%s at line %dn",
  347.       parser.getErrorString(),
  348.       parser.getCurrentLineNumber() );
  349.       return 1;
  350.     }
  351.   } while (!done);
  352.   fclose( file );
  353.   return 0;
  354. }
  355. */