XmlBinaryDictionaryWriterTest.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. //
  2. // XmlSimpleDictionaryWriterTest.cs
  3. //
  4. // Author:
  5. // Atsushi Enomoto <[email protected]>
  6. //
  7. // Copyright (C) 2005, 2007 Novell, Inc. http://www.novell.com
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. using System;
  29. using System.IO;
  30. using System.Text;
  31. using System.Xml;
  32. using NUnit.Framework;
  33. namespace MonoTests.System.Xml
  34. {
  35. [TestFixture]
  36. public class XmlBinaryDictionaryWriterTest
  37. {
  38. [Test]
  39. public void UseCase1 ()
  40. {
  41. Console.WriteLine ();
  42. MemoryStream ms = new MemoryStream ();
  43. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, null, null);
  44. w.WriteStartDocument (true);
  45. w.WriteStartElement ("root");
  46. w.WriteAttributeString ("a", "");
  47. w.WriteComment ("");
  48. w.WriteWhitespace (" ");
  49. w.WriteStartElement ("AAA", "urn:AAA");
  50. w.WriteEndElement ();
  51. w.WriteStartElement ("ePfix", "AAA", "urn:AAABBB");
  52. w.WriteEndElement ();
  53. w.WriteStartElement ("AAA");
  54. w.WriteCData ("CCC\u3005\u4E00CCC");
  55. w.WriteString ("AAA&AAA");
  56. w.WriteRaw ("DDD&DDD");
  57. w.WriteCharEntity ('\u4E01');
  58. w.WriteComment ("COMMENT");
  59. w.WriteEndElement ();
  60. w.WriteStartElement ("AAA");
  61. w.WriteAttributeString ("BBB", "bbb");
  62. // mhm, how namespace URIs are serialized then?
  63. w.WriteAttributeString ("pfix", "BBB", "urn:bbb", "bbbbb");
  64. // FIXME: They are not working
  65. // w.WriteAttributeString ("CCC", "urn:ccc", "ccccc");
  66. // w.WriteAttributeString ("DDD", "urn:ddd", "ddddd");
  67. // w.WriteAttributeString ("CCC", "urn:ddd", "cdcdc");
  68. // XmlLang
  69. w.WriteXmlAttribute ("lang", "ja");
  70. Assert.AreEqual ("ja", w.XmlLang, "XmlLang");
  71. // XmlSpace
  72. w.WriteStartAttribute ("xml", "space", "http://www.w3.org/XML/1998/namespace");
  73. w.WriteString ("pre");
  74. w.WriteString ("serve");
  75. w.WriteEndAttribute ();
  76. Assert.AreEqual (XmlSpace.Preserve, w.XmlSpace, "XmlSpace");
  77. w.WriteAttributeString ("xml", "base", "http://www.w3.org/XML/1998/namespace", "local:hogehoge");
  78. w.WriteString ("CCC");
  79. w.WriteBase64 (new byte [] {0x20, 0x20, 0x20, 0xFF, 0x80, 0x30}, 0, 6);
  80. w.WriteEndElement ();
  81. // this WriteEndElement() should result in one more
  82. // 0x3C, but .net does not output it.
  83. w.WriteEndElement ();
  84. w.WriteEndDocument ();
  85. w.Close ();
  86. Assert.AreEqual (usecase1_result, ms.ToArray ());
  87. }
  88. // $ : kind
  89. // ! : length
  90. // FIXME: see fixmes in the test itself.
  91. static readonly byte [] usecase1_result = new byte [] {
  92. // $!root$! a....!__ ___.!AAA $!urn:AA A$$!ePfi
  93. 0x40, 0x04, 0x72, 0x6F, 0x6F, 0x74, 0x04, 0x01,
  94. 0x61, 0xA8, 0x02, 0x00, 0x98, 0x05, 0x20, 0x20,
  95. 0x20, 0x20, 0x20, 0x40, 0x03, 0x41, 0x41, 0x41,
  96. 0x08, 0x07, 0x75, 0x72, 0x6E, 0x3A, 0x41, 0x41,
  97. 0x41, 0x01, 0x41, 0x05, 0x65, 0x50, 0x66, 0x69,// 40
  98. // x!AAA$!e Pfix!urn :AAABBB$ $!AAA$!C CC......
  99. 0x78, 0x03, 0x41, 0x41, 0x41, 0x09, 0x05, 0x65,
  100. 0x50, 0x66, 0x69, 0x78, 0x0A, 0x75, 0x72, 0x6E,
  101. 0x3A, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x01,
  102. 0x40, 0x03, 0x41, 0x41, 0x41, 0x98, 0x0C, 0x43,
  103. 0x43, 0x43, 0xE3, 0x80, 0x85, 0xE4, 0xB8, 0x80,// 80
  104. // AAA$!DDD $AAA$!DD D$DDD... ..$!COMM ENT$$!AA
  105. 0x43, 0x43, 0x43, 0x98, 0x07, 0x41, 0x41, 0x41,
  106. 0x26, 0x41, 0x41, 0x41, 0x98, 0x07, 0x44, 0x44,
  107. 0x44, 0x26, 0x44, 0x44, 0x44, 0x98, 0x03, 0xE4,
  108. 0xB8, 0x81, 0x02, 0x07, 0x43, 0x4F, 0x4D, 0x4D,
  109. 0x45, 0x4E, 0x54, 0x01, 0x40, 0x03, 0x41, 0x41,// 120
  110. // A$!BBB$! bbb$!pfi x!BBB$!b bbbb$!xm l!lang$!
  111. 0x41, 0x04, 0x03, 0x42, 0x42, 0x42, 0x98, 0x03,
  112. 0x62, 0x62, 0x62, 0x05, 0x04, 0x70, 0x66, 0x69,
  113. 0x78, 0x03, 0x42, 0x42, 0x42, 0x98, 0x05, 0x62,
  114. 0x62, 0x62, 0x62, 0x62, 0x05, 0x03, 0x78, 0x6D,
  115. 0x6C, 0x04, 0x6C, 0x61, 0x6E, 0x67, 0x98, 0x02,// 160
  116. // ja$!xml! space$!p reserve
  117. 0x6A, 0x61, 0x05, 0x03, 0x78, 0x6D, 0x6C, 0x05,
  118. 0x73, 0x70, 0x61, 0x63, 0x65, 0x98, 0x08, 0x70,
  119. 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x05,
  120. 0x03, 0x78, 0x6D, 0x6C, 0x04, 0x62, 0x61, 0x73,
  121. 0x65, 0x98, 0x0E, 0x6C, 0x6F, 0x63, 0x61, 0x6C,// 200
  122. // ..hogehog e$!pfix! urn:bbb$ $CCC$!BA SE64$
  123. 0x3A, 0x68, 0x6F, 0x67, 0x65, 0x68, 0x6F, 0x67,
  124. 0x65, 0x09, 0x04, 0x70, 0x66, 0x69, 0x78, 0x07,
  125. 0x75, 0x72, 0x6E, 0x3A, 0x62, 0x62, 0x62, 0x98,
  126. 0x03, 0x43, 0x43, 0x43, 0x9F, 0x06, 0x20, 0x20,
  127. 0x20, 0xFF, 0x80, 0x30, 0x01,
  128. };
  129. [Test]
  130. [ExpectedException (typeof (ArgumentException))]
  131. public void ProcessingInstructions ()
  132. {
  133. MemoryStream ms = new MemoryStream ();
  134. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, null, null);
  135. w.WriteStartDocument ();
  136. w.WriteProcessingInstruction ("myPI", "myValue");
  137. }
  138. [Test]
  139. public void UseCase2 ()
  140. {
  141. XmlDictionary dic = new XmlDictionary ();
  142. MemoryStream ms = new MemoryStream ();
  143. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, null);
  144. XmlDictionaryString empty = dic.Add (String.Empty);
  145. // empty ns
  146. w.WriteStartElement (dic.Add ("FOO"), empty);
  147. // non-dic string
  148. w.WriteStartElement ("BAR");
  149. // second time ns
  150. w.WriteStartElement (dic.Add ("FOO"), empty);
  151. // first time dic string but prior non-dic name existed
  152. w.WriteStartElement (dic.Add ("BAR"), empty);
  153. w.WriteEndElement ();
  154. w.WriteEndElement ();
  155. w.WriteEndElement ();
  156. // dicstr w/ ns with empty prefix
  157. w.WriteStartElement (dic.Add ("BAR"), dic.Add ("urn:bar"));
  158. // with prefix
  159. w.WriteStartElement ("ppp", dic.Add ("BAR"), dic.Add ("urn:bar"));
  160. w.WriteChars (new char [] {'x', 'y', 'z'}, 0, 3);
  161. // w.WriteString ("xyz"); // the same as WriteChars()
  162. w.WriteEndElement ();
  163. w.WriteString ("bbbb");
  164. w.WriteCData ("ccc");
  165. w.WriteValue (new Guid ("11112222333344445555666677778888"));
  166. w.WriteEndElement ();
  167. w.WriteStartElement ("FOO");
  168. w.WriteStartAttribute ("AAA");
  169. w.WriteValue (new Guid ("11112222333344445555666677778888"));
  170. w.WriteEndAttribute ();
  171. w.WriteStartAttribute ("BBB");
  172. w.WriteValue (TimeSpan.Zero);
  173. w.WriteEndAttribute ();
  174. w.WriteStartAttribute ("CC");
  175. w.WriteValue (new UniqueId ("uuid-00000000-0000-0000-0000-000000000000-1"));
  176. w.WriteEndAttribute ();
  177. w.WriteStartElement ("XX");
  178. w.WriteValue (true);
  179. w.WriteValue (false);
  180. w.WriteEndElement ();
  181. w.WriteStartElement ("xx", "aaa", "urn:zzz");
  182. w.WriteEndElement ();
  183. w.WriteEndElement ();
  184. w.Close ();
  185. Assert.AreEqual (usecase2_result, ms.ToArray ());
  186. }
  187. // $ : kind
  188. // / : especially. EndElement
  189. // ! : length
  190. // @ : dictionary index
  191. // ^ : missing ns decl?
  192. // FIXME: see fixmes in the test itself.
  193. static readonly byte [] usecase2_result = new byte [] {
  194. // $@$!BAR$ @$@///$@ ^@$!ppp! $!ppp@$! xyz$!bbb
  195. 0x42, 2, 0x40, 3, 0x42, 0x41, 0x52, 0x42,
  196. 2, 0x42, 4, 1, 1, 1, 0x42, 4,
  197. 10, 6, 0x43, 3, 0x70, 0x70, 0x70, 4,
  198. 11, 3, 0x70, 0x70, 0x70, 6, 0x99, 3,
  199. 0x78, 0x79, 0x7A, 0x98, 4, 0x62, 0x62, 0x62,
  200. // b$!ccc$G UIDGUIDG UIDGUID$ !FOO$!GU IDGUIDGU
  201. 0x62, 0x98, 3, 0x63, 0x63, 0x63, 0xB1, 0x22,
  202. 0x22, 0x11, 0x11, 0x33, 0x33, 0x44, 0x44, 0x55,
  203. 0x55, 0x66, 0x66, 0x77, 0x77, 0x88, 0x88, 0x40,
  204. 3, 0x46, 0x4F, 0x4F, 0x04, 3, 0x41, 0x41,
  205. 0x41, 0xB0, 0x22, 0x22, 0x11, 0x11, 0x33, 0x33,
  206. // IDGUIDGU ID$!BBB$T IMESPAN $!CC$!UN IQUEIDUN
  207. 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77,
  208. 0x88, 0x88, 0x04, 3, 0x42, 0x42, 0x42, 0xAE,
  209. 0, 0, 0, 0, 0, 0, 0, 0,
  210. 0x04, 2, 0x43, 0x43, 0x98, 0x2B, 0x75, 0x75,
  211. 0x69, 0x64, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30,
  212. // IQUEIDUN IQUEIDUN IQUEIDUN IQUEID.. .$!XX$$$!
  213. 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30,
  214. 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30,
  215. 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30,
  216. 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2D,
  217. 0x31, 0x40, 2, 0x58, 0x58, 0x86, 0x85, 0x41, 2,
  218. // xx!aaa$!x x!urn:xxx
  219. 0x78, 0x78, 3, 0x61, 0x61, 0x61, 0x09, 2, 0x78,
  220. 0x78, 0x07, 0x75, 0x72, 0x6E, 0x3A, 0x7A, 0x7A,
  221. 0x7A, 1, 1, 1
  222. };
  223. [Test]
  224. public void WriteDictionaryStringWithNullDictionary ()
  225. {
  226. MemoryStream ms = new MemoryStream ();
  227. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, null, null);
  228. XmlDictionary dic = new XmlDictionary ();
  229. w.WriteStartElement (dic.Add ("FOO"), XmlDictionaryString.Empty);
  230. }
  231. class MyWriterSession1 : XmlBinaryWriterSession
  232. {
  233. int count;
  234. public override bool TryAdd (XmlDictionaryString d, out int idx)
  235. {
  236. base.TryAdd (d, out idx);
  237. Assert.AreEqual (count, idx, "#x1-" + count);
  238. if (count++ == 0)
  239. Assert.AreEqual (String.Empty, d.Value, "#x2");
  240. else
  241. Assert.AreEqual ("FOO", d.Value, "#x3");
  242. return true;
  243. }
  244. }
  245. [Test]
  246. public void WriteDictionaryStringWithSameDictionary ()
  247. {
  248. MemoryStream ms = new MemoryStream ();
  249. XmlDictionary dic = new XmlDictionary ();
  250. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, null);
  251. w.WriteStartElement (dic.Add ("FOO"), XmlDictionaryString.Empty);
  252. w.Close ();
  253. Assert.AreEqual (new byte [] {0x42, 0, 1}, ms.ToArray ());
  254. }
  255. [Test]
  256. public void WriteDictionaryStringWithDifferentDictionary () // it actually works
  257. {
  258. MemoryStream ms = new MemoryStream ();
  259. XmlBinaryWriterSession session = new XmlBinaryWriterSession ();
  260. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, new XmlDictionary (), session);
  261. XmlDictionary dic = new XmlDictionary ();
  262. w.WriteStartElement (dic.Add ("FOO"), XmlDictionaryString.Empty);
  263. w.Close ();
  264. Assert.AreEqual (new byte [] {0x42, 1, 1}, ms.ToArray ());
  265. }
  266. [Test]
  267. public void IndicesFromDictionaryAndSession ()
  268. {
  269. // So, I found out the solution for the indices puzzle.
  270. MemoryStream ms = new MemoryStream ();
  271. XmlBinaryWriterSession session = new XmlBinaryWriterSession ();
  272. XmlDictionary dic = new XmlDictionary ();
  273. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, session);
  274. XmlDictionary dic2 = new XmlDictionary ();
  275. XmlDictionary dic3 = new XmlDictionary ();
  276. w.WriteStartElement (dic.Add ("FOO"), XmlDictionaryString.Empty);
  277. w.WriteStartElement (dic2.Add ("FOO"), XmlDictionaryString.Empty);
  278. w.WriteStartElement (dic3.Add ("FOO"), XmlDictionaryString.Empty);
  279. w.WriteStartElement (dic2.Add ("BAR"), XmlDictionaryString.Empty);
  280. w.WriteStartElement (dic.Add ("BAR"), XmlDictionaryString.Empty);
  281. w.Close ();
  282. // ... so, looks like even indices are for dictionary,
  283. // and odd indices are for session.
  284. byte [] bytes = new byte [] {
  285. 0x42, 0, 0x42, 1, 0x42, 1,0x42, 3,
  286. 0x42, 2, 1, 1, 1, 1, 1};
  287. Assert.AreEqual (bytes, ms.ToArray ());
  288. }
  289. [Test]
  290. public void UseStandardSession ()
  291. {
  292. MemoryStream ms = new MemoryStream ();
  293. XmlBinaryWriterSession session =
  294. new XmlBinaryWriterSession ();
  295. XmlDictionary dic = new XmlDictionary ();
  296. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, session);
  297. w.WriteStartElement (dic.Add ("FOO"), XmlDictionaryString.Empty);
  298. w.WriteStartElement (dic.Add ("blah"), XmlDictionaryString.Empty);
  299. w.WriteStartElement (dic.Add ("blabla"), XmlDictionaryString.Empty);
  300. w.Close ();
  301. Assert.AreEqual (new byte [] {0x42, 0, 0x42, 2, 0x42, 4, 1, 1, 1}, ms.ToArray ());
  302. }
  303. [Test]
  304. public void UseStandardSession2 ()
  305. {
  306. MemoryStream ms = new MemoryStream ();
  307. XmlBinaryWriterSession session =
  308. new XmlBinaryWriterSession ();
  309. XmlDictionary dic = new XmlDictionary ();
  310. XmlDictionaryString x = dic.Add ("urn:foo");
  311. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, session);
  312. w.WriteStartElement (dic.Add ("FOO"), x);
  313. w.WriteStartElement (dic.Add ("blah"), x);
  314. w.WriteStartElement (dic.Add ("blabla"), x);
  315. w.Close ();
  316. Assert.AreEqual (new byte [] {0x42, 2, 0x0A, 0, 0x42, 4, 0x42, 6, 1, 1, 1}, ms.ToArray (), "#1");
  317. XmlDictionaryString ds;
  318. Assert.IsTrue (dic.TryLookup (0, out ds), "#2-1");
  319. Assert.AreEqual ("urn:foo", ds.Value, "#2-2");
  320. Assert.AreEqual (0, ds.Key, "#2-3");
  321. Assert.IsTrue (dic.TryLookup (1, out ds), "#3-1");
  322. Assert.AreEqual ("FOO", ds.Value, "#3-2");
  323. Assert.AreEqual (1, ds.Key, "#3-3");
  324. Assert.IsTrue (dic.TryLookup (2, out ds), "#4-1");
  325. Assert.AreEqual ("blah", ds.Value, "#4-2");
  326. Assert.AreEqual (2, ds.Key, "#4-3");
  327. Assert.IsTrue (dic.TryLookup (3, out ds), "#5-1");
  328. Assert.AreEqual ("blabla", ds.Value, "#5-2");
  329. Assert.AreEqual (3, ds.Key, "#5-3");
  330. }
  331. class MyWriterSession2 : XmlBinaryWriterSession
  332. {
  333. int count;
  334. public override bool TryAdd (XmlDictionaryString d, out int idx)
  335. {
  336. // do nothing
  337. idx = d.Value.Length;
  338. return true;
  339. }
  340. }
  341. [Test]
  342. public void UseNOPSession ()
  343. {
  344. MemoryStream ms = new MemoryStream ();
  345. MyWriterSession2 session = new MyWriterSession2 ();
  346. XmlDictionary dic = new XmlDictionary ();
  347. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, session);
  348. w.WriteStartElement (dic.Add ("FOO"), XmlDictionaryString.Empty);
  349. w.WriteStartElement (dic.Add ("blah"), XmlDictionaryString.Empty);
  350. w.WriteStartElement (dic.Add ("blabla"), XmlDictionaryString.Empty);
  351. w.Close ();
  352. Assert.AreEqual (new byte [] {0x42, 0, 0x42, 2, 0x42, 4, 1, 1, 1}, ms.ToArray ());
  353. }
  354. [Test]
  355. public void WriteElementWithNS ()
  356. {
  357. byte [] bytes = new byte [] {
  358. 0x42, 0, 10, 2, 0x98, 3, 0x61, 0x61,
  359. 0x61, 0x42, 0, 0x42, 2, 1, 1, 1};
  360. XmlDictionaryString ds;
  361. MemoryStream ms = new MemoryStream ();
  362. XmlDictionary dic = new XmlDictionary ();
  363. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, null);
  364. w.WriteStartElement (dic.Add ("FOO"), dic.Add ("foo"));
  365. Assert.IsTrue (dic.TryLookup ("foo", out ds), "#1");
  366. Assert.AreEqual (1, ds.Key, "#2");
  367. w.WriteString ("aaa");
  368. w.WriteStartElement (dic.Add ("FOO"), dic.Add ("foo"));
  369. w.WriteStartElement (dic.Add ("foo"), dic.Add ("foo"));
  370. w.Close ();
  371. Assert.AreEqual (bytes, ms.ToArray (), "result");
  372. /*
  373. byte [] bytes2 = new byte [] {
  374. 0x42, 1, 10, 2, 0x98, 3, 0x61, 0x61,
  375. 0x61, 0x42, 0, 0x42, 2, 1, 1, 1};
  376. XmlDictionaryReader dr = XmlDictionaryReader.CreateBinaryReader (new MemoryStream (bytes2), dic, new XmlDictionaryReaderQuotas ());
  377. try {
  378. dr.Read ();
  379. Assert.Fail ("dictionary index 1 should be regarded as invalid.");
  380. } catch (XmlException) {
  381. }
  382. */
  383. }
  384. [Test]
  385. public void Beyond128DictionaryEntries ()
  386. {
  387. XmlDictionaryString ds;
  388. MemoryStream ms = new MemoryStream ();
  389. XmlDictionary dic = new XmlDictionary ();
  390. for (int i = 0; i < 260; i++)
  391. Assert.AreEqual (i, dic.Add ("n" + i).Key, "d");
  392. XmlDictionary dic2 = new XmlDictionary ();
  393. XmlBinaryWriterSession session = new XmlBinaryWriterSession ();
  394. int idx;
  395. for (int i = 0; i < 260; i++)
  396. session.TryAdd (dic2.Add ("n" + i), out idx);
  397. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, session);
  398. w.WriteStartElement (dic.Add ("n128"), dic.Add ("n129"));
  399. w.WriteStartElement (dic2.Add ("n130"), dic2.Add ("n131"));
  400. w.WriteStartElement (dic.Add ("n132"), dic2.Add ("n133"));
  401. w.WriteStartElement (dic.Add ("n256"), dic2.Add ("n256"));
  402. w.Close ();
  403. byte [] bytes = new byte [] {
  404. // so, when it went beyond 128, the index
  405. // becomes 2 bytes, where
  406. // - the first byte always becomes > 80, and
  407. // - the second byte becomes (n / 0x80) * 2.
  408. 0x42, 0x80, 2, 0x0A, 0x82, 2,
  409. 0x42, 0x85, 2, 0x0A, 0x87, 2,
  410. 0x42, 0x88, 2, 0x0A, 0x8B, 2,
  411. 0x42, 0x80, 4, 0x0A, 0x81, 4,
  412. 1, 1, 1, 1};
  413. Assert.AreEqual (bytes, ms.ToArray (), "result");
  414. }
  415. [Test]
  416. public void GlobalAttributes ()
  417. {
  418. XmlDictionaryString ds;
  419. MemoryStream ms = new MemoryStream ();
  420. XmlDictionary dic = new XmlDictionary ();
  421. int idx;
  422. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, null);
  423. dic.Add ("n1");
  424. dic.Add ("urn:foo");
  425. dic.Add ("n2");
  426. dic.Add ("n3");
  427. dic.Add ("n4");
  428. dic.Add ("urn:bar");
  429. dic.Add ("n7");
  430. w.WriteStartElement (dic.Add ("n1"), dic.Add ("urn:foo"));
  431. w.WriteAttributeString (dic.Add ("n2"), dic.Add ("urn:bar"), String.Empty);
  432. w.WriteAttributeString (dic.Add ("n3"), dic.Add ("urn:foo"), "v");
  433. w.WriteAttributeString ("aaa", dic.Add ("n4"), dic.Add ("urn:bar"), String.Empty);
  434. w.WriteAttributeString ("bbb", "n5", "urn:foo", String.Empty);
  435. w.WriteAttributeString ("n6", String.Empty);
  436. w.WriteAttributeString (dic.Add ("n7"), XmlDictionaryString.Empty, String.Empty); // local attribute
  437. w.WriteAttributeString ("bbb", "n8", "urn:foo", String.Empty); // xmlns:bbb mapping already exists (n5), and written just once
  438. w.Close ();
  439. // 0x0C nameidx (value) 0x0D nameidx (value)
  440. // 0x07 (prefix) nameidx (value)
  441. // 0x05 (prefix) (name) (value)
  442. // 0x04... 0x06... 0x05...
  443. // 0x0A nsidx
  444. // 0x0B (prefix) nsidx
  445. // 0x0B... 0x0B...
  446. // 0x09 (prefix) (ns)
  447. byte [] bytes = new byte [] {
  448. // $@$@$$@$ !v$!aaa@
  449. // $@!bbb!n 5$$@$!a@
  450. // $!aaa!$! bbb$urn:foo$
  451. 0x42, 0,
  452. 0x0C, 4, 0xA8,
  453. 0x0D, 6, 0x98, 1, 0x76,
  454. 0x07, 3, 0x61, 0x61, 0x61, 8, 0xA8, // 16
  455. 0x05, 3, 0x62, 0x62, 0x62, 2, 0x6E, 0x35, 0xA8,
  456. 0x04, 2, 0x6E, 0x36, 0xA8, // 30
  457. 0x06, 12, 0xA8,
  458. 0x05, 3, 0x62, 0x62, 0x62, 2, 0x6E, 0x38, 0xA8,
  459. 0x0A, 2,
  460. 0x0B, 1, 0x61, 10, // 48
  461. 0x0B, 1, 0x62, 2,
  462. 0x0B, 3, 0x61, 0x61, 0x61, 10,
  463. 0x09, 3, 0x62, 0x62, 0x62,
  464. 0x07, 0x75, 0x72, 0x6E, 0x3A, 0x66, 0x6F, 0x6F,
  465. 1};
  466. Assert.AreEqual (bytes, ms.ToArray (), "result");
  467. }
  468. [Test]
  469. public void WriteAttributeXmlns ()
  470. {
  471. // equivalent to WriteXmlnsAttribute()
  472. XmlDictionaryString ds;
  473. MemoryStream ms = new MemoryStream ();
  474. XmlDictionary dic = new XmlDictionary ();
  475. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, null);
  476. w.WriteStartElement ("root");
  477. w.WriteAttributeString ("xmlns", "foo", "http://www.w3.org/2000/xmlns/", "urn:foo");
  478. w.WriteAttributeString (dic.Add ("xmlns"), dic.Add ("http://www.w3.org/2000/xmlns/"), "urn:bar");
  479. w.WriteAttributeString ("a", String.Empty);
  480. w.Close ();
  481. byte [] bytes = new byte [] {
  482. // 40 (root) 04 (a) A8
  483. // 09 (foo) (urn:foo) 08 (urn:bar)
  484. 0x40, 4, 0x72, 0x6F, 0x6F, 0x74,
  485. 0x04, 1, 0x61, 0xA8,
  486. 0x09, 3, 0x66, 0x6F, 0x6F, 7, 0x75, 0x72, 0x6E, 0x3A, 0x66, 0x6F, 0x6F,
  487. 0x08, 7, 0x75, 0x72, 0x6E, 0x3A, 0x62, 0x61, 0x72, 1
  488. };
  489. Assert.AreEqual (bytes, ms.ToArray ());
  490. }
  491. [Test]
  492. public void WriteXmlnsAttributeWithNullPrefix ()
  493. {
  494. MemoryStream ms = new MemoryStream ();
  495. XmlDictionary dic = new XmlDictionary ();
  496. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, null);
  497. w.WriteStartElement ("root", "aaaaa");
  498. w.WriteXmlnsAttribute (null, "bbbbb");
  499. w.WriteStartElement ("child", "ccccc");
  500. w.WriteXmlnsAttribute (null, "ddddd");
  501. w.WriteEndElement ();
  502. w.WriteEndElement ();
  503. w.Close ();
  504. byte [] bytes = new byte [] {
  505. // 0x40 (root) 0x8 (aaaaa)
  506. 0x40, 0x4, 0x72, 0x6F, 0x6F, 0x74, 0x8, 0x5, 0x61, 0x61, 0x61, 0x61, 0x61,
  507. // 0x9 (a) (bbbbb)
  508. 0x9, 0x1, 0x61, 0x5, 0x62, 0x62, 0x62, 0x62, 0x62,
  509. // 0x40 (child) 0x8 (ccccc)
  510. 0x40, 0x5, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x8, 0x5, 0x63, 0x63, 0x63, 0x63, 0x63,
  511. // 0x9 (b) (ddddd) 0x1 0x1
  512. 0x9, 0x1, 0x62, 0x5, 0x64, 0x64, 0x64, 0x64, 0x64, 0x1, 0x1
  513. };
  514. Assert.AreEqual (bytes, ms.ToArray ());
  515. }
  516. [Test]
  517. [ExpectedException (typeof (InvalidOperationException))]
  518. public void WriteAttributeWithoutElement ()
  519. {
  520. XmlDictionaryString ds;
  521. MemoryStream ms = new MemoryStream ();
  522. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, null, null);
  523. w.WriteAttributeString ("foo", "value");
  524. }
  525. [Test]
  526. [ExpectedException (typeof (ArgumentException))]
  527. public void OverwriteXmlnsUri ()
  528. {
  529. XmlDictionaryString ds;
  530. MemoryStream ms = new MemoryStream ();
  531. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, null, null);
  532. w.WriteStartElement ("root");
  533. w.WriteAttributeString ("xmlns", "foo", "urn:thisCausesError", "urn:foo");
  534. }
  535. [Test]
  536. public void WriteTypedValues ()
  537. {
  538. MemoryStream ms = new MemoryStream ();
  539. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, null, null);
  540. w.WriteStartElement ("root");
  541. w.WriteValue ((byte) 5);
  542. w.WriteValue ((short) 893);
  543. w.WriteValue ((int) 37564);
  544. w.WriteValue ((long) 141421356);
  545. w.WriteValue ((long) 5670000000);
  546. w.WriteValue ((float) 1.7320508);
  547. w.WriteValue ((double) 2.2360679);
  548. w.WriteValue ((decimal) 3.141592);
  549. w.WriteValue (new DateTime (2000, 1, 2, 3, 4, 5));
  550. w.WriteValue (new XmlDictionary ().Add ("xxx"));
  551. // w.WriteValue ((object) null); ANE
  552. w.WriteValue (1);
  553. w.Close ();
  554. Assert.AreEqual (typed_values, ms.ToArray ());
  555. }
  556. byte [] typed_values = new byte [] {
  557. 0x40, 4, 0x72, 0x6F, 0x6F, 0x74,
  558. 0x88, 5,
  559. 0x8A, 0x7D, 0x03,
  560. 0x8C, 0xBC, 0x92, 0, 0, // int
  561. 0x8C, 0x2C, 0xEB, 0x6D, 0x08, // 20
  562. 0x8E, 0x80, 0x55, 0xF5, 0x51, 0x01, 0, 0, 0,
  563. 0x90, 0xD7, 0xB3, 0xDD, 0x3F, // float
  564. 0x92, 0x4C, 0x15, 0x31, 0x91, 0x77, 0xE3, 0x01, 0x40, // 43
  565. 0x94, 0, 0, 6, 0, 0, 0, 0, 0, 0xD8, 0xEF, 0x2F, 0, 0, 0, 0, 0,
  566. 0x96, 0x80, 0x40, 0xA3, 0x29, 0xE5, 0x22, 0xC1, 8,
  567. 0x98, 3, 0x78, 0x78, 0x78, // dictionary string is just a string here
  568. 0x83,
  569. };
  570. }
  571. }