StringHandle.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.Xml
  5. {
  6. using System.Runtime;
  7. enum StringHandleConstStringType
  8. {
  9. Type = 0,
  10. Root = 1,
  11. Item = 2
  12. }
  13. class StringHandle
  14. {
  15. XmlBufferReader bufferReader;
  16. StringHandleType type;
  17. int key;
  18. int offset;
  19. int length;
  20. static string[] constStrings = {
  21. "type",
  22. "root",
  23. "item"
  24. };
  25. public StringHandle(XmlBufferReader bufferReader)
  26. {
  27. this.bufferReader = bufferReader;
  28. SetValue(0, 0);
  29. }
  30. public void SetValue(int offset, int length)
  31. {
  32. this.type = StringHandleType.UTF8;
  33. this.offset = offset;
  34. this.length = length;
  35. }
  36. public void SetConstantValue(StringHandleConstStringType constStringType)
  37. {
  38. type = StringHandleType.ConstString;
  39. key = (int)constStringType;
  40. }
  41. public void SetValue(int offset, int length, bool escaped)
  42. {
  43. this.type = (escaped ? StringHandleType.EscapedUTF8 : StringHandleType.UTF8);
  44. this.offset = offset;
  45. this.length = length;
  46. }
  47. public void SetValue(int key)
  48. {
  49. this.type = StringHandleType.Dictionary;
  50. this.key = key;
  51. }
  52. public void SetValue(StringHandle value)
  53. {
  54. this.type = value.type;
  55. this.key = value.key;
  56. this.offset = value.offset;
  57. this.length = value.length;
  58. }
  59. public bool IsEmpty
  60. {
  61. get
  62. {
  63. if (type == StringHandleType.UTF8)
  64. return length == 0;
  65. return Equals2(string.Empty);
  66. }
  67. }
  68. public bool IsXmlns
  69. {
  70. get
  71. {
  72. if (type == StringHandleType.UTF8)
  73. {
  74. if (this.length != 5)
  75. return false;
  76. byte[] buffer = bufferReader.Buffer;
  77. int offset = this.offset;
  78. return buffer[offset + 0] == 'x' &&
  79. buffer[offset + 1] == 'm' &&
  80. buffer[offset + 2] == 'l' &&
  81. buffer[offset + 3] == 'n' &&
  82. buffer[offset + 4] == 's';
  83. }
  84. return Equals2("xmlns");
  85. }
  86. }
  87. public void ToPrefixHandle(PrefixHandle prefix)
  88. {
  89. Fx.Assert(type == StringHandleType.UTF8, "");
  90. prefix.SetValue(offset, length);
  91. }
  92. public string GetString(XmlNameTable nameTable)
  93. {
  94. StringHandleType type = this.type;
  95. if (type == StringHandleType.UTF8)
  96. return bufferReader.GetString(offset, length, nameTable);
  97. if (type == StringHandleType.Dictionary)
  98. return nameTable.Add(bufferReader.GetDictionaryString(key).Value);
  99. if (type == StringHandleType.ConstString)
  100. return nameTable.Add(constStrings[key]);
  101. Fx.Assert(type == StringHandleType.EscapedUTF8, "");
  102. return bufferReader.GetEscapedString(offset, length, nameTable);
  103. }
  104. public string GetString()
  105. {
  106. StringHandleType type = this.type;
  107. if (type == StringHandleType.UTF8)
  108. return bufferReader.GetString(offset, length);
  109. if (type == StringHandleType.Dictionary)
  110. return bufferReader.GetDictionaryString(key).Value;
  111. if (type == StringHandleType.ConstString)
  112. return constStrings[key];
  113. Fx.Assert(type == StringHandleType.EscapedUTF8, "");
  114. return bufferReader.GetEscapedString(offset, length);
  115. }
  116. public byte[] GetString(out int offset, out int length)
  117. {
  118. StringHandleType type = this.type;
  119. if (type == StringHandleType.UTF8)
  120. {
  121. offset = this.offset;
  122. length = this.length;
  123. return bufferReader.Buffer;
  124. }
  125. if (type == StringHandleType.Dictionary)
  126. {
  127. byte[] buffer = bufferReader.GetDictionaryString(this.key).ToUTF8();
  128. offset = 0;
  129. length = buffer.Length;
  130. return buffer;
  131. }
  132. if (type == StringHandleType.ConstString)
  133. {
  134. byte[] buffer = XmlConverter.ToBytes(constStrings[key]);
  135. offset = 0;
  136. length = buffer.Length;
  137. return buffer;
  138. }
  139. else
  140. {
  141. Fx.Assert(type == StringHandleType.EscapedUTF8, "");
  142. byte[] buffer = XmlConverter.ToBytes(bufferReader.GetEscapedString(this.offset, this.length));
  143. offset = 0;
  144. length = buffer.Length;
  145. return buffer;
  146. }
  147. }
  148. public bool TryGetDictionaryString(out XmlDictionaryString value)
  149. {
  150. if (type == StringHandleType.Dictionary)
  151. {
  152. value = bufferReader.GetDictionaryString(key);
  153. return true;
  154. }
  155. else if (IsEmpty)
  156. {
  157. value = XmlDictionaryString.Empty;
  158. return true;
  159. }
  160. value = null;
  161. return false;
  162. }
  163. public override string ToString()
  164. {
  165. return GetString();
  166. }
  167. bool Equals2(int key2, XmlBufferReader bufferReader2)
  168. {
  169. StringHandleType type = this.type;
  170. if (type == StringHandleType.Dictionary)
  171. return bufferReader.Equals2(this.key, key2, bufferReader2);
  172. if (type == StringHandleType.UTF8)
  173. return bufferReader.Equals2(this.offset, this.length, bufferReader2.GetDictionaryString(key2).Value);
  174. Fx.Assert(type == StringHandleType.EscapedUTF8 || type == StringHandleType.ConstString, "");
  175. return GetString() == bufferReader.GetDictionaryString(key2).Value;
  176. }
  177. bool Equals2(XmlDictionaryString xmlString2)
  178. {
  179. StringHandleType type = this.type;
  180. if (type == StringHandleType.Dictionary)
  181. return bufferReader.Equals2(this.key, xmlString2);
  182. if (type == StringHandleType.UTF8)
  183. return bufferReader.Equals2(this.offset, this.length, xmlString2.ToUTF8());
  184. Fx.Assert(type == StringHandleType.EscapedUTF8 || type == StringHandleType.ConstString, "");
  185. return GetString() == xmlString2.Value;
  186. }
  187. bool Equals2(string s2)
  188. {
  189. StringHandleType type = this.type;
  190. if (type == StringHandleType.Dictionary)
  191. return bufferReader.GetDictionaryString(this.key).Value == s2;
  192. if (type == StringHandleType.UTF8)
  193. return bufferReader.Equals2(this.offset, this.length, s2);
  194. Fx.Assert(type == StringHandleType.EscapedUTF8 || type == StringHandleType.ConstString, "");
  195. return GetString() == s2;
  196. }
  197. bool Equals2(int offset2, int length2, XmlBufferReader bufferReader2)
  198. {
  199. StringHandleType type = this.type;
  200. if (type == StringHandleType.Dictionary)
  201. return bufferReader2.Equals2(offset2, length2, bufferReader.GetDictionaryString(this.key).Value);
  202. if (type == StringHandleType.UTF8)
  203. return bufferReader.Equals2(this.offset, this.length, bufferReader2, offset2, length2);
  204. Fx.Assert(type == StringHandleType.EscapedUTF8 || type == StringHandleType.ConstString, "");
  205. return GetString() == bufferReader.GetString(offset2, length2);
  206. }
  207. bool Equals2(StringHandle s2)
  208. {
  209. StringHandleType type = s2.type;
  210. if (type == StringHandleType.Dictionary)
  211. return Equals2(s2.key, s2.bufferReader);
  212. if (type == StringHandleType.UTF8)
  213. return Equals2(s2.offset, s2.length, s2.bufferReader);
  214. Fx.Assert(type == StringHandleType.EscapedUTF8 || type == StringHandleType.ConstString, "");
  215. return Equals2(s2.GetString());
  216. }
  217. static public bool operator ==(StringHandle s1, XmlDictionaryString xmlString2)
  218. {
  219. return s1.Equals2(xmlString2);
  220. }
  221. static public bool operator !=(StringHandle s1, XmlDictionaryString xmlString2)
  222. {
  223. return !s1.Equals2(xmlString2);
  224. }
  225. static public bool operator ==(StringHandle s1, string s2)
  226. {
  227. return s1.Equals2(s2);
  228. }
  229. static public bool operator !=(StringHandle s1, string s2)
  230. {
  231. return !s1.Equals2(s2);
  232. }
  233. static public bool operator ==(StringHandle s1, StringHandle s2)
  234. {
  235. return s1.Equals2(s2);
  236. }
  237. static public bool operator !=(StringHandle s1, StringHandle s2)
  238. {
  239. return !s1.Equals2(s2);
  240. }
  241. public int CompareTo(StringHandle that)
  242. {
  243. if (this.type == StringHandleType.UTF8 && that.type == StringHandleType.UTF8)
  244. return bufferReader.Compare(this.offset, this.length, that.offset, that.length);
  245. else
  246. return string.Compare(this.GetString(), that.GetString(), StringComparison.Ordinal);
  247. }
  248. public override bool Equals(object obj)
  249. {
  250. StringHandle that = obj as StringHandle;
  251. if (object.ReferenceEquals(that, null))
  252. return false;
  253. return this == that;
  254. }
  255. public override int GetHashCode()
  256. {
  257. return GetString().GetHashCode();
  258. }
  259. enum StringHandleType
  260. {
  261. Dictionary,
  262. UTF8,
  263. EscapedUTF8,
  264. ConstString
  265. }
  266. }
  267. }