XmlBinaryDictionaryWriterTest.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  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. // 0x26-0x3F
  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, 4, 0x72, 0x6F, 0x6F, 0x74, 0x04, 1,
  94. 0x61, 0xA8, 0x02, 0x00, 0x98, 5, 0x20, 0x20,
  95. 0x20, 0x20, 0x20, 0x40, 3, 0x41, 0x41, 0x41,
  96. 0x08, 0x07, 0x75, 0x72, 0x6E, 0x3A, 0x41, 0x41,
  97. 0x41, 1, 0x41, 5, 0x65, 0x50, 0x66, 0x69,// 40
  98. // x!AAA$!e Pfix!urn :AAABBB$ $!AAA$!C CC(uni)$
  99. 0x78, 3, 0x41, 0x41, 0x41, 0x09, 5, 0x65,
  100. 0x50, 0x66, 0x69, 0x78, 10, 0x75, 0x72, 0x6E,
  101. 0x3A, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 1,
  102. 0x40, 3, 0x41, 0x41, 0x41, 0x98, 12, 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, 7, 0x41, 0x41, 0x41,
  106. 0x26, 0x41, 0x41, 0x41, 0x98, 7, 0x44, 0x44,
  107. 0x44, 0x26, 0x44, 0x44, 0x44, 0x98, 3, 0xE4,
  108. 0xB8, 0x81, 0x02, 7, 0x43, 0x4F, 0x4D, 0x4D,
  109. 0x45, 0x4E, 0x54, 0x01, 0x40, 3, 0x41, 0x41,// 120
  110. // A$!BBB$! bbb$!pfi x!BBB$!b bbbb$!CC C$!ccccc
  111. 0x41, 4, 0x03, 0x42, 0x42, 0x42, 0x98, 3,
  112. 0x62, 0x62, 0x62, 0x05, 0x04, 0x70, 0x66, 0x69,
  113. 0x78, 0x03, 0x42, 0x42, 0x42, 0x98, 0x05, 0x62,
  114. 0x62, 0x62, 0x62, 0x62, 0x26, 0x03, 0x43, 0x43,
  115. 0x43, 0x98, 0x05, 0x63, 0x63, 0x63, 0x63, 0x63,// 160
  116. // $!DDD$!d dddd$!cc c$!cdcdc $!xml!la ng$!ja$!
  117. 0x27, 0x03, 0x44, 0x44, 0x44, 0x98, 0x05, 0x64,
  118. 0x64, 0x64, 0x64, 0x64, 0x27, 0x03, 0x43, 0x43,
  119. 0x43, 0x98, 0x05, 0x63, 0x64, 0x63, 0x64, 0x63,
  120. 0x05, 0x03, 0x78, 0x6D, 0x6C, 0x04, 0x6C, 0x61,
  121. 0x6E, 0x67, 0x98, 0x02, 0x6A, 0x61, 0x05, 0x03,// 200
  122. // xml!spac e$!prese rve$!xml !lang$!l local:hog
  123. 0x78, 0x6D, 0x6C, 0x05, 0x73, 0x70, 0x61, 0x63,
  124. 0x65, 0x98, 0x08, 0x70, 0x72, 0x65, 0x73, 0x65,
  125. 0x72, 0x76, 0x65, 0x05, 0x03, 0x78, 0x6D, 0x6C,
  126. 0x04, 0x62, 0x61, 0x73, 0x65, 0x98, 0x0E, 0x6C,
  127. 0x6F, 0x63, 0x61, 0x6C, 0x3A, 0x68, 0x6F, 0x67,// 240
  128. // ehoge$!p fix!urn: bbb$!a!u rn:ccc$! b!urn:dd
  129. 0x65, 0x68, 0x6F, 0x67, 0x65, 0x09, 0x04, 0x70,
  130. 0x66, 0x69, 0x78, 0x07, 0x75, 0x72, 0x6E, 0x3A,
  131. 0x62, 0x62, 0x62, 0x09, 0x01, 0x61, 0x07, 0x75,
  132. 0x72, 0x6E, 0x3A, 0x63, 0x63, 0x63, 0x09, 0x01,
  133. 0x62, 0x07, 0x75, 0x72, 0x6E, 0x3A, 0x64, 0x64,// 280
  134. // d$!CCC$! (bs64)$
  135. 0x64, 0x98, 0x03, 0x43, 0x43, 0x43, 0x9F, 0x06,
  136. 0x20, 0x20, 0x20, 0xFF, 0x80, 0x30, 0x01,
  137. };
  138. [Test]
  139. [ExpectedException (typeof (ArgumentException))]
  140. public void ProcessingInstructions ()
  141. {
  142. MemoryStream ms = new MemoryStream ();
  143. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, null, null);
  144. w.WriteStartDocument ();
  145. w.WriteProcessingInstruction ("myPI", "myValue");
  146. }
  147. [Test]
  148. public void UseCase2 ()
  149. {
  150. XmlDictionary dic = new XmlDictionary ();
  151. MemoryStream ms = new MemoryStream ();
  152. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, null);
  153. XmlDictionaryString empty = dic.Add (String.Empty);
  154. // empty ns
  155. w.WriteStartElement (dic.Add ("FOO"), empty);
  156. // non-dic string
  157. w.WriteStartElement ("BAR");
  158. // second time ns
  159. w.WriteStartElement (dic.Add ("FOO"), empty);
  160. // first time dic string but prior non-dic name existed
  161. w.WriteStartElement (dic.Add ("BAR"), empty);
  162. w.WriteEndElement ();
  163. w.WriteEndElement ();
  164. w.WriteEndElement ();
  165. // dicstr w/ ns with empty prefix
  166. w.WriteStartElement (dic.Add ("BAR"), dic.Add ("urn:bar"));
  167. // with prefix
  168. w.WriteStartElement ("ppp", dic.Add ("BAR"), dic.Add ("urn:bar"));
  169. w.WriteChars (new char [] {'x', 'y', 'z'}, 0, 3);
  170. // w.WriteString ("xyz"); // the same as WriteChars()
  171. w.WriteEndElement ();
  172. w.WriteString ("bbbb");
  173. w.WriteCData ("ccc");
  174. w.WriteValue (new Guid ("11112222333344445555666677778888"));
  175. w.WriteEndElement ();
  176. w.WriteStartElement ("FOO");
  177. w.WriteStartAttribute ("AAA");
  178. w.WriteValue (new Guid ("11112222333344445555666677778888"));
  179. w.WriteEndAttribute ();
  180. w.WriteStartAttribute ("BBB");
  181. w.WriteValue (TimeSpan.Zero);
  182. w.WriteEndAttribute ();
  183. w.WriteStartAttribute ("CC");
  184. w.WriteValue (new UniqueId ("uuid-00000000-0000-0000-0000-000000000000-1"));
  185. w.WriteEndAttribute ();
  186. w.WriteStartElement ("XX");
  187. w.WriteValue (true);
  188. w.WriteValue (false);
  189. w.WriteEndElement ();
  190. w.WriteStartElement ("xx", "aaa", "urn:zzz");
  191. w.WriteEndElement ();
  192. w.WriteEndElement ();
  193. w.Close ();
  194. Assert.AreEqual (usecase2_result, ms.ToArray ());
  195. }
  196. // $ : kind
  197. // / : especially. EndElement
  198. // ! : length
  199. // @ : dictionary index
  200. // ^ : missing ns decl?
  201. // FIXME: see fixmes in the test itself.
  202. static readonly byte [] usecase2_result = new byte [] {
  203. // $@$!BAR$ @$@///$@ ^@$!ppp! $!ppp@$! xyz$!bbb
  204. 0x42, 2, 0x40, 3, 0x42, 0x41, 0x52, 0x42,
  205. 2, 0x42, 4, 1, 1, 1, 0x42, 4,
  206. 10, 6, 0x43, 3, 0x70, 0x70, 0x70, 4,
  207. 11, 3, 0x70, 0x70, 0x70, 6, 0x99, 3,
  208. 0x78, 0x79, 0x7A, 0x98, 4, 0x62, 0x62, 0x62,
  209. // b$!ccc$G UIDGUIDG UIDGUID$ !FOO$!GU IDGUIDGU
  210. 0x62, 0x98, 3, 0x63, 0x63, 0x63, 0xB1, 0x22,
  211. 0x22, 0x11, 0x11, 0x33, 0x33, 0x44, 0x44, 0x55,
  212. 0x55, 0x66, 0x66, 0x77, 0x77, 0x88, 0x88, 0x40,
  213. 3, 0x46, 0x4F, 0x4F, 0x04, 3, 0x41, 0x41,
  214. 0x41, 0xB0, 0x22, 0x22, 0x11, 0x11, 0x33, 0x33,
  215. // IDGUIDGU ID$!BBB$T IMESPAN $!CC$!UN IQUEIDUN
  216. 0x44, 0x44, 0x55, 0x55, 0x66, 0x66, 0x77, 0x77,
  217. 0x88, 0x88, 0x04, 3, 0x42, 0x42, 0x42, 0xAE,
  218. 0, 0, 0, 0, 0, 0, 0, 0,
  219. 0x04, 2, 0x43, 0x43, 0x98, 0x2B, 0x75, 0x75,
  220. 0x69, 0x64, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30,
  221. // IQUEIDUN IQUEIDUN IQUEIDUN IQUEID.. .$!XX$$$!
  222. 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30,
  223. 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30,
  224. 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30,
  225. 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2D,
  226. 0x31, 0x40, 2, 0x58, 0x58, 0x86, 0x85, 0x41, 2,
  227. // xx!aaa$!x x!urn:xxx
  228. 0x78, 0x78, 3, 0x61, 0x61, 0x61, 0x09, 2, 0x78,
  229. 0x78, 0x07, 0x75, 0x72, 0x6E, 0x3A, 0x7A, 0x7A,
  230. 0x7A, 1, 1, 1
  231. };
  232. [Test]
  233. public void WriteDictionaryStringWithNullDictionary ()
  234. {
  235. MemoryStream ms = new MemoryStream ();
  236. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, null, null);
  237. XmlDictionary dic = new XmlDictionary ();
  238. w.WriteStartElement (dic.Add ("FOO"), XmlDictionaryString.Empty);
  239. }
  240. class MyWriterSession1 : XmlBinaryWriterSession
  241. {
  242. int count;
  243. public override bool TryAdd (XmlDictionaryString d, out int idx)
  244. {
  245. base.TryAdd (d, out idx);
  246. Assert.AreEqual (count, idx, "#x1-" + count);
  247. if (count++ == 0)
  248. Assert.AreEqual (String.Empty, d.Value, "#x2");
  249. else
  250. Assert.AreEqual ("FOO", d.Value, "#x3");
  251. return true;
  252. }
  253. }
  254. [Test]
  255. public void WriteDictionaryStringWithSameDictionary ()
  256. {
  257. MemoryStream ms = new MemoryStream ();
  258. XmlDictionary dic = new XmlDictionary ();
  259. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, null);
  260. w.WriteStartElement (dic.Add ("FOO"), XmlDictionaryString.Empty);
  261. w.Close ();
  262. Assert.AreEqual (new byte [] {0x42, 0, 1}, ms.ToArray ());
  263. }
  264. [Test]
  265. public void WriteDictionaryStringWithDifferentDictionary () // it actually works
  266. {
  267. MemoryStream ms = new MemoryStream ();
  268. XmlBinaryWriterSession session = new XmlBinaryWriterSession ();
  269. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, new XmlDictionary (), session);
  270. XmlDictionary dic = new XmlDictionary ();
  271. w.WriteStartElement (dic.Add ("FOO"), XmlDictionaryString.Empty);
  272. w.Close ();
  273. Assert.AreEqual (new byte [] {0x42, 1, 1}, ms.ToArray ());
  274. }
  275. [Test]
  276. public void IndicesFromDictionaryAndSession ()
  277. {
  278. // So, I found out the solution for the indices puzzle.
  279. MemoryStream ms = new MemoryStream ();
  280. XmlBinaryWriterSession session = new XmlBinaryWriterSession ();
  281. XmlDictionary dic = new XmlDictionary ();
  282. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, session);
  283. XmlDictionary dic2 = new XmlDictionary ();
  284. XmlDictionary dic3 = new XmlDictionary ();
  285. w.WriteStartElement (dic.Add ("FOO"), XmlDictionaryString.Empty);
  286. w.WriteStartElement (dic2.Add ("FOO"), XmlDictionaryString.Empty);
  287. w.WriteStartElement (dic3.Add ("FOO"), XmlDictionaryString.Empty);
  288. w.WriteStartElement (dic2.Add ("BAR"), XmlDictionaryString.Empty);
  289. w.WriteStartElement (dic.Add ("BAR"), XmlDictionaryString.Empty);
  290. w.Close ();
  291. // ... so, looks like even indices are for dictionary,
  292. // and odd indices are for session.
  293. byte [] bytes = new byte [] {
  294. 0x42, 0, 0x42, 1, 0x42, 1,0x42, 3,
  295. 0x42, 2, 1, 1, 1, 1, 1};
  296. Assert.AreEqual (bytes, ms.ToArray ());
  297. }
  298. [Test]
  299. public void UseStandardSession ()
  300. {
  301. MemoryStream ms = new MemoryStream ();
  302. XmlBinaryWriterSession session =
  303. new XmlBinaryWriterSession ();
  304. XmlDictionary dic = new XmlDictionary ();
  305. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, session);
  306. w.WriteStartElement (dic.Add ("FOO"), XmlDictionaryString.Empty);
  307. w.WriteStartElement (dic.Add ("blah"), XmlDictionaryString.Empty);
  308. w.WriteStartElement (dic.Add ("blabla"), XmlDictionaryString.Empty);
  309. w.Close ();
  310. Assert.AreEqual (new byte [] {0x42, 0, 0x42, 2, 0x42, 4, 1, 1, 1}, ms.ToArray ());
  311. }
  312. [Test]
  313. public void UseStandardSession2 ()
  314. {
  315. MemoryStream ms = new MemoryStream ();
  316. XmlBinaryWriterSession session =
  317. new XmlBinaryWriterSession ();
  318. XmlDictionary dic = new XmlDictionary ();
  319. XmlDictionaryString x = dic.Add ("urn:foo");
  320. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, session);
  321. w.WriteStartElement (dic.Add ("FOO"), x);
  322. w.WriteStartElement (dic.Add ("blah"), x);
  323. w.WriteStartElement (dic.Add ("blabla"), x);
  324. w.Close ();
  325. Assert.AreEqual (new byte [] {0x42, 2, 0x0A, 0, 0x42, 4, 0x42, 6, 1, 1, 1}, ms.ToArray (), "#1");
  326. XmlDictionaryString ds;
  327. Assert.IsTrue (dic.TryLookup (0, out ds), "#2-1");
  328. Assert.AreEqual ("urn:foo", ds.Value, "#2-2");
  329. Assert.AreEqual (0, ds.Key, "#2-3");
  330. Assert.IsTrue (dic.TryLookup (1, out ds), "#3-1");
  331. Assert.AreEqual ("FOO", ds.Value, "#3-2");
  332. Assert.AreEqual (1, ds.Key, "#3-3");
  333. Assert.IsTrue (dic.TryLookup (2, out ds), "#4-1");
  334. Assert.AreEqual ("blah", ds.Value, "#4-2");
  335. Assert.AreEqual (2, ds.Key, "#4-3");
  336. Assert.IsTrue (dic.TryLookup (3, out ds), "#5-1");
  337. Assert.AreEqual ("blabla", ds.Value, "#5-2");
  338. Assert.AreEqual (3, ds.Key, "#5-3");
  339. }
  340. class MyWriterSession2 : XmlBinaryWriterSession
  341. {
  342. int count;
  343. public override bool TryAdd (XmlDictionaryString d, out int idx)
  344. {
  345. // do nothing
  346. idx = d.Value.Length;
  347. return true;
  348. }
  349. }
  350. [Test]
  351. public void UseNOPSession ()
  352. {
  353. MemoryStream ms = new MemoryStream ();
  354. MyWriterSession2 session = new MyWriterSession2 ();
  355. XmlDictionary dic = new XmlDictionary ();
  356. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, session);
  357. w.WriteStartElement (dic.Add ("FOO"), XmlDictionaryString.Empty);
  358. w.WriteStartElement (dic.Add ("blah"), XmlDictionaryString.Empty);
  359. w.WriteStartElement (dic.Add ("blabla"), XmlDictionaryString.Empty);
  360. w.Close ();
  361. Assert.AreEqual (new byte [] {0x42, 0, 0x42, 2, 0x42, 4, 1, 1, 1}, ms.ToArray ());
  362. }
  363. [Test]
  364. public void WriteElementWithNS ()
  365. {
  366. byte [] bytes = new byte [] {
  367. 0x42, 0, 10, 2, 0x98, 3, 0x61, 0x61,
  368. 0x61, 0x42, 0, 0x42, 2, 1, 1, 1};
  369. XmlDictionaryString ds;
  370. MemoryStream ms = new MemoryStream ();
  371. XmlDictionary dic = new XmlDictionary ();
  372. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, null);
  373. w.WriteStartElement (dic.Add ("FOO"), dic.Add ("foo"));
  374. Assert.IsTrue (dic.TryLookup ("foo", out ds), "#1");
  375. Assert.AreEqual (1, ds.Key, "#2");
  376. w.WriteString ("aaa");
  377. w.WriteStartElement (dic.Add ("FOO"), dic.Add ("foo"));
  378. w.WriteStartElement (dic.Add ("foo"), dic.Add ("foo"));
  379. w.Close ();
  380. Assert.AreEqual (bytes, ms.ToArray (), "result");
  381. /*
  382. byte [] bytes2 = new byte [] {
  383. 0x42, 1, 10, 2, 0x98, 3, 0x61, 0x61,
  384. 0x61, 0x42, 0, 0x42, 2, 1, 1, 1};
  385. XmlDictionaryReader dr = XmlDictionaryReader.CreateBinaryReader (new MemoryStream (bytes2), dic, new XmlDictionaryReaderQuotas ());
  386. try {
  387. dr.Read ();
  388. Assert.Fail ("dictionary index 1 should be regarded as invalid.");
  389. } catch (XmlException) {
  390. }
  391. */
  392. }
  393. [Test]
  394. public void Beyond128DictionaryEntries ()
  395. {
  396. XmlDictionaryString ds;
  397. MemoryStream ms = new MemoryStream ();
  398. XmlDictionary dic = new XmlDictionary ();
  399. for (int i = 0; i < 260; i++)
  400. Assert.AreEqual (i, dic.Add ("n" + i).Key, "d");
  401. XmlDictionary dic2 = new XmlDictionary ();
  402. XmlBinaryWriterSession session = new XmlBinaryWriterSession ();
  403. int idx;
  404. for (int i = 0; i < 260; i++)
  405. session.TryAdd (dic2.Add ("n" + i), out idx);
  406. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, session);
  407. w.WriteStartElement (dic.Add ("n128"), dic.Add ("n129"));
  408. w.WriteStartElement (dic2.Add ("n130"), dic2.Add ("n131"));
  409. w.WriteStartElement (dic.Add ("n132"), dic2.Add ("n133"));
  410. w.WriteStartElement (dic.Add ("n256"), dic2.Add ("n256"));
  411. w.Close ();
  412. byte [] bytes = new byte [] {
  413. // so, when it went beyond 128, the index
  414. // becomes 2 bytes, where
  415. // - the first byte always becomes > 80, and
  416. // - the second byte becomes (n / 0x80) * 2.
  417. 0x42, 0x80, 2, 0x0A, 0x82, 2,
  418. 0x42, 0x85, 2, 0x0A, 0x87, 2,
  419. 0x42, 0x88, 2, 0x0A, 0x8B, 2,
  420. 0x42, 0x80, 4, 0x0A, 0x81, 4,
  421. 1, 1, 1, 1};
  422. Assert.AreEqual (bytes, ms.ToArray (), "result");
  423. }
  424. [Test]
  425. public void GlobalAttributes ()
  426. {
  427. XmlDictionaryString ds;
  428. MemoryStream ms = new MemoryStream ();
  429. XmlDictionary dic = new XmlDictionary ();
  430. int idx;
  431. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, null);
  432. dic.Add ("n1");
  433. dic.Add ("urn:foo");
  434. dic.Add ("n2");
  435. dic.Add ("n3");
  436. dic.Add ("n4");
  437. dic.Add ("urn:bar");
  438. dic.Add ("n7");
  439. w.WriteStartElement (dic.Add ("n1"), dic.Add ("urn:foo"));
  440. w.WriteAttributeString (dic.Add ("n2"), dic.Add ("urn:bar"), String.Empty);
  441. w.WriteAttributeString (dic.Add ("n3"), dic.Add ("urn:foo"), "v");
  442. w.WriteAttributeString ("aaa", dic.Add ("n4"), dic.Add ("urn:bar"), String.Empty);
  443. w.WriteAttributeString ("bbb", "n5", "urn:foo", String.Empty);
  444. w.WriteAttributeString ("n6", String.Empty);
  445. w.WriteAttributeString (dic.Add ("n7"), XmlDictionaryString.Empty, String.Empty); // local attribute
  446. w.WriteAttributeString ("bbb", "n8", "urn:foo", String.Empty); // xmlns:bbb mapping already exists (n5), and written just once
  447. w.Close ();
  448. // 0x0C nameidx (value) 0x0D nameidx (value)
  449. // 0x07 (prefix) nameidx (value)
  450. // 0x05 (prefix) (name) (value)
  451. // 0x04... 0x06... 0x05...
  452. // 0x0A nsidx
  453. // 0x0B (prefix) nsidx
  454. // 0x0B... 0x0B...
  455. // 0x09 (prefix) (ns)
  456. byte [] bytes = new byte [] {
  457. // $@$@$$@$ !v$!aaa@
  458. // $@!bbb!n 5$$@$!a@
  459. // $!aaa!$! bbb$urn:foo$
  460. 0x42, 0,
  461. 0x0C, 4, 0xA8,
  462. 0x0D, 6, 0x98, 1, 0x76,
  463. 0x07, 3, 0x61, 0x61, 0x61, 8, 0xA8, // 16
  464. 0x05, 3, 0x62, 0x62, 0x62, 2, 0x6E, 0x35, 0xA8,
  465. 0x04, 2, 0x6E, 0x36, 0xA8, // 30
  466. 0x06, 12, 0xA8,
  467. 0x05, 3, 0x62, 0x62, 0x62, 2, 0x6E, 0x38, 0xA8,
  468. 0x0A, 2,
  469. 0x0B, 1, 0x61, 10, // 48
  470. 0x0B, 1, 0x62, 2,
  471. 0x0B, 3, 0x61, 0x61, 0x61, 10,
  472. 0x09, 3, 0x62, 0x62, 0x62,
  473. 0x07, 0x75, 0x72, 0x6E, 0x3A, 0x66, 0x6F, 0x6F,
  474. 1};
  475. Assert.AreEqual (bytes, ms.ToArray (), "result");
  476. }
  477. [Test]
  478. public void WriteAttributeXmlns ()
  479. {
  480. // equivalent to WriteXmlnsAttribute()
  481. XmlDictionaryString ds;
  482. MemoryStream ms = new MemoryStream ();
  483. XmlDictionary dic = new XmlDictionary ();
  484. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, null);
  485. w.WriteStartElement ("root");
  486. w.WriteAttributeString ("xmlns", "foo", "http://www.w3.org/2000/xmlns/", "urn:foo");
  487. w.WriteAttributeString (dic.Add ("xmlns"), dic.Add ("http://www.w3.org/2000/xmlns/"), "urn:bar");
  488. w.WriteAttributeString ("a", String.Empty);
  489. w.Close ();
  490. byte [] bytes = new byte [] {
  491. // 40 (root) 04 (a) A8
  492. // 09 (foo) (urn:foo) 08 (urn:bar)
  493. 0x40, 4, 0x72, 0x6F, 0x6F, 0x74,
  494. 0x04, 1, 0x61, 0xA8,
  495. 0x09, 3, 0x66, 0x6F, 0x6F, 7, 0x75, 0x72, 0x6E, 0x3A, 0x66, 0x6F, 0x6F,
  496. 0x08, 7, 0x75, 0x72, 0x6E, 0x3A, 0x62, 0x61, 0x72, 1
  497. };
  498. Assert.AreEqual (bytes, ms.ToArray ());
  499. }
  500. [Test]
  501. public void WriteXmlnsAttributeWithNullPrefix ()
  502. {
  503. MemoryStream ms = new MemoryStream ();
  504. XmlDictionary dic = new XmlDictionary ();
  505. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, dic, null);
  506. w.WriteStartElement ("root", "aaaaa");
  507. w.WriteXmlnsAttribute (null, "bbbbb");
  508. w.WriteStartElement ("child", "ccccc");
  509. w.WriteXmlnsAttribute (null, "ddddd");
  510. w.WriteEndElement ();
  511. w.WriteEndElement ();
  512. w.Close ();
  513. byte [] bytes = new byte [] {
  514. // 0x40 (root) 0x8 (aaaaa)
  515. 0x40, 0x4, 0x72, 0x6F, 0x6F, 0x74, 0x8, 0x5, 0x61, 0x61, 0x61, 0x61, 0x61,
  516. // 0x9 (a) (bbbbb)
  517. 0x9, 0x1, 0x61, 0x5, 0x62, 0x62, 0x62, 0x62, 0x62,
  518. // 0x40 (child) 0x8 (ccccc)
  519. 0x40, 0x5, 0x63, 0x68, 0x69, 0x6C, 0x64, 0x8, 0x5, 0x63, 0x63, 0x63, 0x63, 0x63,
  520. // 0x9 (b) (ddddd) 0x1 0x1
  521. 0x9, 0x1, 0x62, 0x5, 0x64, 0x64, 0x64, 0x64, 0x64, 0x1, 0x1
  522. };
  523. Assert.AreEqual (bytes, ms.ToArray ());
  524. }
  525. [Test]
  526. [ExpectedException (typeof (InvalidOperationException))]
  527. public void WriteAttributeWithoutElement ()
  528. {
  529. XmlDictionaryString ds;
  530. MemoryStream ms = new MemoryStream ();
  531. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, null, null);
  532. w.WriteAttributeString ("foo", "value");
  533. }
  534. [Test]
  535. [ExpectedException (typeof (ArgumentException))]
  536. public void OverwriteXmlnsUri ()
  537. {
  538. XmlDictionaryString ds;
  539. MemoryStream ms = new MemoryStream ();
  540. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, null, null);
  541. w.WriteStartElement ("root");
  542. w.WriteAttributeString ("xmlns", "foo", "urn:thisCausesError", "urn:foo");
  543. }
  544. [Test]
  545. public void WriteTypedValues ()
  546. {
  547. MemoryStream ms = new MemoryStream ();
  548. XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter (ms, null, null);
  549. w.WriteStartElement ("root");
  550. w.WriteValue ((byte) 5);
  551. w.WriteValue ((short) 893);
  552. w.WriteValue ((int) 37564);
  553. w.WriteValue ((long) 141421356);
  554. w.WriteValue ((long) 5670000000);
  555. w.WriteValue ((float) 1.7320508);
  556. w.WriteValue ((double) 2.2360679);
  557. w.WriteValue ((decimal) 3.141592);
  558. w.WriteValue (new DateTime (2000, 1, 2, 3, 4, 5));
  559. w.WriteValue (new XmlDictionary ().Add ("xxx"));
  560. // w.WriteValue ((object) null); ANE
  561. w.WriteValue (1);
  562. w.Close ();
  563. Assert.AreEqual (typed_values, ms.ToArray ());
  564. }
  565. byte [] typed_values = new byte [] {
  566. 0x40, 4, 0x72, 0x6F, 0x6F, 0x74,
  567. 0x88, 5,
  568. 0x8A, 0x7D, 0x03,
  569. 0x8C, 0xBC, 0x92, 0, 0, // int
  570. 0x8C, 0x2C, 0xEB, 0x6D, 0x08, // 20
  571. 0x8E, 0x80, 0x55, 0xF5, 0x51, 0x01, 0, 0, 0,
  572. 0x90, 0xD7, 0xB3, 0xDD, 0x3F, // float
  573. 0x92, 0x4C, 0x15, 0x31, 0x91, 0x77, 0xE3, 0x01, 0x40, // 43
  574. 0x94, 0, 0, 6, 0, 0, 0, 0, 0, 0xD8, 0xEF, 0x2F, 0, 0, 0, 0, 0,
  575. 0x96, 0x80, 0x40, 0xA3, 0x29, 0xE5, 0x22, 0xC1, 8,
  576. 0x98, 3, 0x78, 0x78, 0x78, // dictionary string is just a string here
  577. 0x83,
  578. };
  579. }
  580. }