parser2.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:4k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: parser2.c 271 2005-08-09 08:31:35Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "common.h"
  24. void ParserDataFeed(parser* p,const void* Ptr,size_t Len)
  25. {
  26. BufferWrite(&p->Buffer,Ptr,Len,4096);
  27. }
  28. void ParserStream(parser* p, stream* Stream)
  29. {
  30. p->Stream = Stream;
  31. if (Stream)
  32. {
  33. if (!p->Buffer.Data)
  34. {
  35. BufferAlloc(&p->Buffer,4096,1);
  36. BufferStream(&p->Buffer,p->Stream);
  37. }
  38. }
  39. else
  40. BufferClear(&p->Buffer);
  41. }
  42. const uint8_t* ParserPeek(parser* p, size_t Len)
  43. {
  44. if (p->Buffer.WritePos < p->Buffer.ReadPos+(int)Len) //buffer!
  45. {
  46. BufferStream(&p->Buffer,p->Stream);
  47. if (p->Buffer.WritePos < p->Buffer.ReadPos+(int)Len) //buffer!
  48. return NULL;
  49. }
  50. return p->Buffer.Data + p->Buffer.ReadPos;
  51. }
  52. static void SkipSpace(parser* p)
  53. {
  54. const uint8_t* i;
  55. while ((i = ParserPeek(p,1))!=NULL)
  56. {
  57. if (!IsSpace(*i) && *i!=10 && *i!=13)
  58. break;
  59. ++p->Buffer.ReadPos;
  60. }
  61. }
  62. static bool_t SkipAfter(parser* p, char ch)
  63. {
  64. const char* i;
  65. while ((i = (const char*)ParserPeek(p,1))!=NULL)
  66. {
  67. ++p->Buffer.ReadPos;
  68. if (*i == ch)
  69. return 1;
  70. }
  71. return 0;
  72. }
  73. bool_t ParserIsToken(parser* p, const tchar_t* Token)
  74. {
  75. size_t n = tcslen(Token);
  76. tchar_t* Tmp = alloca(sizeof(tchar_t)*(n+1));
  77. const char* i;
  78. SkipSpace(p);
  79. if ((i=(const char*)ParserPeek(p,n))!=NULL)
  80. {
  81. GetAsciiToken(Tmp,n+1,i,n);
  82. if (tcsicmp(Tmp,Token)==0)
  83. {
  84. p->Buffer.ReadPos += n;
  85. return 1;
  86. }
  87. }
  88. return 0;
  89. }
  90. static int Read(parser* p, tchar_t* Out, int OutLen, const char* Delimiter, bool_t Keep)
  91. {
  92. char* s = alloca(OutLen);
  93. int n=0;
  94. while (ParserPeek(p,1))
  95. {
  96. char ch = p->Buffer.Data[p->Buffer.ReadPos++];
  97. if (strchr(Delimiter,ch))
  98. {
  99. if (Keep)
  100. --p->Buffer.ReadPos;
  101. goto readok;
  102. }
  103. else
  104. if (ch!=13 && ++n<OutLen)
  105. s[n-1] = ch;
  106. }
  107. if (!n)
  108. return -1;
  109. readok:
  110. if (OutLen>0)
  111. {
  112. s[min(n,OutLen-1)]=0;
  113. StrToTcs(Out,OutLen,s);
  114. }
  115. return n;
  116. }
  117. bool_t ParserLine(parser* p, tchar_t* Out, size_t OutLen)
  118. {
  119. return Read(p,Out,OutLen,"n",0)>=0;
  120. }
  121. bool_t ParserIsElement(parser* p, tchar_t* Name, size_t NameLen)
  122. {
  123. if (!SkipAfter(p,'<'))
  124. return 0;
  125. if (ParserIsToken(p,T("/")) && NameLen>0)
  126. {
  127. *(Name++) = '/';
  128. --NameLen;
  129. }
  130. return Read(p,Name,NameLen," tn/>",1)>0;
  131. }
  132. void ParserElementSkip(parser *p)
  133. {
  134. while (ParserIsAttrib(p,NULL,0))
  135. ParserAttribSkip(p);
  136. }
  137. bool_t ParserElementContent(parser* p, tchar_t* Out, size_t OutLen)
  138. {
  139. ParserElementSkip(p);
  140. return Read(p,Out,OutLen,"<",1)>=0;
  141. }
  142. bool_t ParserIsAttrib(parser* p, tchar_t* Name, size_t NameLen)
  143. {
  144. SkipSpace(p);
  145. if (ParserIsToken(p,T(">")) || ParserIsToken(p,T("/>")))
  146. return 0;
  147. return Read(p,Name,NameLen,"= tn/>",1)>0;
  148. }
  149. int ParserAttribInt(parser* p)
  150. {
  151. tchar_t Token[MAXTOKEN];
  152. if (!ParserAttribString(p,Token,MAXTOKEN))
  153. return 0;
  154. if (Token[0]=='0' && Token[1]=='x')
  155. return StringToInt(Token+2,1);
  156. else
  157. return StringToInt(Token,0);
  158. }
  159. bool_t ParserAttribString(parser* p, tchar_t* Out, size_t OutLen)
  160. {
  161. if (!ParserIsToken(p,T("=")))
  162. return 0;
  163. SkipSpace(p);
  164. if (ParserIsToken(p,T(""")))
  165. return Read(p,Out,OutLen,""",0)>=0;
  166. else
  167. return Read(p,Out,OutLen," tn/>",1)>=0;
  168. }
  169. void ParserAttribSkip(parser* p)
  170. {
  171. ParserAttribString(p,NULL,0);
  172. }