XmlBinaryDictionaryWriterTest.cs 26 KB

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