XmlBaseReader.cs 117 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. // PERF, [....], [....]: Make LookupNamespace do something smarter when lots of names
  5. // PERF, [....], [....]: Make Attribute lookup smarter when lots of attributes
  6. namespace System.Xml
  7. {
  8. using System;
  9. using System.Collections;
  10. using System.Globalization;
  11. using System.IO;
  12. using System.Runtime;
  13. using System.Runtime.Serialization;
  14. using System.Text;
  15. // Large numbers of attributes
  16. // Use delimiter on node for figuring out Element/EndElement?
  17. // Optimize StringHandle.CompareTo
  18. // Fix FixXmlAttribute - Temporary until we actually write an XmlAttribute node
  19. abstract class XmlBaseReader : XmlDictionaryReader
  20. {
  21. XmlBufferReader bufferReader;
  22. XmlNode node;
  23. NamespaceManager nsMgr;
  24. XmlElementNode[] elementNodes;
  25. XmlAttributeNode[] attributeNodes;
  26. XmlAtomicTextNode atomicTextNode;
  27. int depth;
  28. int attributeCount;
  29. int attributeStart; // Starting index for searching
  30. XmlDictionaryReaderQuotas quotas;
  31. XmlNameTable nameTable;
  32. XmlDeclarationNode declarationNode;
  33. XmlComplexTextNode complexTextNode;
  34. XmlWhitespaceTextNode whitespaceTextNode;
  35. XmlCDataNode cdataNode;
  36. XmlCommentNode commentNode;
  37. XmlElementNode rootElementNode;
  38. int attributeIndex; // Index for iteration
  39. char[] chars;
  40. string prefix;
  41. string localName;
  42. string ns;
  43. string value;
  44. int trailCharCount;
  45. int trailByteCount;
  46. char[] trailChars;
  47. byte[] trailBytes;
  48. bool rootElement;
  49. bool readingElement;
  50. XmlSigningNodeWriter signingWriter;
  51. bool signing;
  52. AttributeSorter attributeSorter;
  53. static XmlInitialNode initialNode = new XmlInitialNode(XmlBufferReader.Empty);
  54. static XmlEndOfFileNode endOfFileNode = new XmlEndOfFileNode(XmlBufferReader.Empty);
  55. static XmlClosedNode closedNode = new XmlClosedNode(XmlBufferReader.Empty);
  56. static BinHexEncoding binhexEncoding;
  57. static Base64Encoding base64Encoding;
  58. const string xmlns = "xmlns";
  59. const string xml = "xml";
  60. const string xmlnsNamespace = "http://www.w3.org/2000/xmlns/";
  61. const string xmlNamespace = "http://www.w3.org/XML/1998/namespace";
  62. protected XmlBaseReader()
  63. {
  64. this.bufferReader = new XmlBufferReader(this);
  65. this.nsMgr = new NamespaceManager(bufferReader);
  66. this.quotas = new XmlDictionaryReaderQuotas();
  67. this.rootElementNode = new XmlElementNode(bufferReader);
  68. this.atomicTextNode = new XmlAtomicTextNode(bufferReader);
  69. this.node = closedNode;
  70. }
  71. static BinHexEncoding BinHexEncoding
  72. {
  73. get
  74. {
  75. if (binhexEncoding == null)
  76. binhexEncoding = new BinHexEncoding();
  77. return binhexEncoding;
  78. }
  79. }
  80. static Base64Encoding Base64Encoding
  81. {
  82. get
  83. {
  84. if (base64Encoding == null)
  85. base64Encoding = new Base64Encoding();
  86. return base64Encoding;
  87. }
  88. }
  89. protected XmlBufferReader BufferReader
  90. {
  91. get
  92. {
  93. return bufferReader;
  94. }
  95. }
  96. public override XmlDictionaryReaderQuotas Quotas
  97. {
  98. get
  99. {
  100. return quotas;
  101. }
  102. }
  103. protected XmlNode Node
  104. {
  105. get
  106. {
  107. return node;
  108. }
  109. }
  110. protected void MoveToNode(XmlNode node)
  111. {
  112. this.node = node;
  113. this.ns = null;
  114. this.localName = null;
  115. this.prefix = null;
  116. this.value = null;
  117. }
  118. protected void MoveToInitial(XmlDictionaryReaderQuotas quotas)
  119. {
  120. if (quotas == null)
  121. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("quotas");
  122. quotas.InternalCopyTo(this.quotas);
  123. this.quotas.MakeReadOnly();
  124. this.nsMgr.Clear();
  125. this.depth = 0;
  126. this.attributeCount = 0;
  127. this.attributeStart = -1;
  128. this.attributeIndex = -1;
  129. this.rootElement = false;
  130. this.readingElement = false;
  131. this.signing = false;
  132. MoveToNode(initialNode);
  133. }
  134. protected XmlDeclarationNode MoveToDeclaration()
  135. {
  136. if (attributeCount < 1)
  137. XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlDeclMissingVersion)));
  138. if (attributeCount > 3)
  139. XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl)));
  140. // version
  141. if (!CheckDeclAttribute(0, "version", "1.0", false, SR.XmlInvalidVersion))
  142. XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlDeclMissingVersion)));
  143. // encoding/standalone
  144. // We only validate that they are the only attributes that exist. Encoding can have any value.
  145. if (attributeCount > 1)
  146. {
  147. if (CheckDeclAttribute(1, "encoding", null, true, SR.XmlInvalidEncoding))
  148. {
  149. if (attributeCount == 3 && !CheckStandalone(2))
  150. XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl)));
  151. }
  152. else if (!CheckStandalone(1) || attributeCount > 2)
  153. {
  154. XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl)));
  155. }
  156. }
  157. if (declarationNode == null)
  158. {
  159. declarationNode = new XmlDeclarationNode(bufferReader);
  160. }
  161. MoveToNode(declarationNode);
  162. return declarationNode;
  163. }
  164. bool CheckStandalone(int attr)
  165. {
  166. XmlAttributeNode node = attributeNodes[attr];
  167. if (!node.Prefix.IsEmpty)
  168. XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl)));
  169. if (node.LocalName != "standalone")
  170. return false;
  171. if (!node.Value.Equals2("yes", false) && !node.Value.Equals2("no", false))
  172. XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlInvalidStandalone)));
  173. return true;
  174. }
  175. bool CheckDeclAttribute(int index, string localName, string value, bool checkLower, string valueSR)
  176. {
  177. XmlAttributeNode node = attributeNodes[index];
  178. if (!node.Prefix.IsEmpty)
  179. XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlMalformedDecl)));
  180. if (node.LocalName != localName)
  181. return false;
  182. if (value != null && !node.Value.Equals2(value, checkLower))
  183. XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(valueSR)));
  184. return true;
  185. }
  186. protected XmlCommentNode MoveToComment()
  187. {
  188. if (commentNode == null)
  189. {
  190. commentNode = new XmlCommentNode(bufferReader);
  191. }
  192. MoveToNode(commentNode);
  193. return commentNode;
  194. }
  195. protected XmlCDataNode MoveToCData()
  196. {
  197. if (cdataNode == null)
  198. {
  199. this.cdataNode = new XmlCDataNode(bufferReader);
  200. }
  201. MoveToNode(cdataNode);
  202. return cdataNode;
  203. }
  204. protected XmlAtomicTextNode MoveToAtomicText()
  205. {
  206. XmlAtomicTextNode textNode = this.atomicTextNode;
  207. MoveToNode(textNode);
  208. return textNode;
  209. }
  210. protected XmlComplexTextNode MoveToComplexText()
  211. {
  212. if (complexTextNode == null)
  213. {
  214. complexTextNode = new XmlComplexTextNode(bufferReader);
  215. }
  216. MoveToNode(complexTextNode);
  217. return complexTextNode;
  218. }
  219. protected XmlTextNode MoveToWhitespaceText()
  220. {
  221. if (whitespaceTextNode == null)
  222. {
  223. whitespaceTextNode = new XmlWhitespaceTextNode(bufferReader);
  224. }
  225. if (nsMgr.XmlSpace == XmlSpace.Preserve)
  226. whitespaceTextNode.NodeType = XmlNodeType.SignificantWhitespace;
  227. else
  228. whitespaceTextNode.NodeType = XmlNodeType.Whitespace;
  229. MoveToNode(whitespaceTextNode);
  230. return whitespaceTextNode;
  231. }
  232. protected XmlElementNode ElementNode
  233. {
  234. get
  235. {
  236. if (depth == 0)
  237. return rootElementNode;
  238. else
  239. return elementNodes[depth];
  240. }
  241. }
  242. protected void MoveToEndElement()
  243. {
  244. if (depth == 0)
  245. XmlExceptionHelper.ThrowInvalidBinaryFormat(this);
  246. XmlElementNode elementNode = elementNodes[depth];
  247. XmlEndElementNode endElementNode = elementNode.EndElement;
  248. endElementNode.Namespace = elementNode.Namespace;
  249. MoveToNode(endElementNode);
  250. }
  251. protected void MoveToEndOfFile()
  252. {
  253. if (depth != 0)
  254. XmlExceptionHelper.ThrowUnexpectedEndOfFile(this);
  255. MoveToNode(endOfFileNode);
  256. }
  257. protected XmlElementNode EnterScope()
  258. {
  259. if (depth == 0)
  260. {
  261. if (rootElement)
  262. XmlExceptionHelper.ThrowMultipleRootElements(this);
  263. rootElement = true;
  264. }
  265. nsMgr.EnterScope();
  266. depth++;
  267. if (depth > quotas.MaxDepth)
  268. XmlExceptionHelper.ThrowMaxDepthExceeded(this, quotas.MaxDepth);
  269. if (elementNodes == null)
  270. {
  271. elementNodes = new XmlElementNode[4];
  272. }
  273. else if (elementNodes.Length == depth)
  274. {
  275. XmlElementNode[] newElementNodes = new XmlElementNode[depth * 2];
  276. Array.Copy(elementNodes, newElementNodes, depth);
  277. elementNodes = newElementNodes;
  278. }
  279. XmlElementNode elementNode = elementNodes[depth];
  280. if (elementNode == null)
  281. {
  282. elementNode = new XmlElementNode(bufferReader);
  283. elementNodes[depth] = elementNode;
  284. }
  285. this.attributeCount = 0;
  286. this.attributeStart = -1;
  287. this.attributeIndex = -1;
  288. MoveToNode(elementNode);
  289. return elementNode;
  290. }
  291. protected void ExitScope()
  292. {
  293. if (depth == 0)
  294. XmlExceptionHelper.ThrowUnexpectedEndElement(this);
  295. depth--;
  296. nsMgr.ExitScope();
  297. }
  298. XmlAttributeNode AddAttribute(QNameType qnameType, bool isAtomicValue)
  299. {
  300. int attributeIndex = this.attributeCount;
  301. if (attributeNodes == null)
  302. {
  303. attributeNodes = new XmlAttributeNode[4];
  304. }
  305. else if (attributeNodes.Length == attributeIndex)
  306. {
  307. XmlAttributeNode[] newAttributeNodes = new XmlAttributeNode[attributeIndex * 2];
  308. Array.Copy(attributeNodes, newAttributeNodes, attributeIndex);
  309. attributeNodes = newAttributeNodes;
  310. }
  311. XmlAttributeNode attributeNode = attributeNodes[attributeIndex];
  312. if (attributeNode == null)
  313. {
  314. attributeNode = new XmlAttributeNode(bufferReader);
  315. attributeNodes[attributeIndex] = attributeNode;
  316. }
  317. attributeNode.QNameType = qnameType;
  318. attributeNode.IsAtomicValue = isAtomicValue;
  319. attributeNode.AttributeText.QNameType = qnameType;
  320. attributeNode.AttributeText.IsAtomicValue = isAtomicValue;
  321. this.attributeCount++;
  322. return attributeNode;
  323. }
  324. protected Namespace AddNamespace()
  325. {
  326. return nsMgr.AddNamespace();
  327. }
  328. protected XmlAttributeNode AddAttribute()
  329. {
  330. return AddAttribute(QNameType.Normal, true);
  331. }
  332. protected XmlAttributeNode AddXmlAttribute()
  333. {
  334. return AddAttribute(QNameType.Normal, true);
  335. }
  336. protected XmlAttributeNode AddXmlnsAttribute(Namespace ns)
  337. {
  338. if (!ns.Prefix.IsEmpty && ns.Uri.IsEmpty)
  339. XmlExceptionHelper.ThrowEmptyNamespace(this);
  340. // Some prefixes can only be bound to a particular namespace
  341. if (ns.Prefix.IsXml && ns.Uri != xmlNamespace)
  342. {
  343. XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlSpecificBindingPrefix, "xml", xmlNamespace)));
  344. }
  345. else if (ns.Prefix.IsXmlns && ns.Uri != xmlnsNamespace)
  346. {
  347. XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.XmlSpecificBindingPrefix, "xmlns", xmlnsNamespace)));
  348. }
  349. nsMgr.Register(ns);
  350. XmlAttributeNode attributeNode = AddAttribute(QNameType.Xmlns, false);
  351. attributeNode.Namespace = ns;
  352. attributeNode.AttributeText.Namespace = ns;
  353. return attributeNode;
  354. }
  355. protected void FixXmlAttribute(XmlAttributeNode attributeNode)
  356. {
  357. if (attributeNode.Prefix == xml)
  358. {
  359. if (attributeNode.LocalName == "lang")
  360. {
  361. nsMgr.AddLangAttribute(attributeNode.Value.GetString());
  362. }
  363. else if (attributeNode.LocalName == "space")
  364. {
  365. string value = attributeNode.Value.GetString();
  366. if (value == "preserve")
  367. {
  368. nsMgr.AddSpaceAttribute(XmlSpace.Preserve);
  369. }
  370. else if (value == "default")
  371. {
  372. nsMgr.AddSpaceAttribute(XmlSpace.Default);
  373. }
  374. }
  375. }
  376. }
  377. protected bool OutsideRootElement
  378. {
  379. get
  380. {
  381. return depth == 0;
  382. }
  383. }
  384. public override bool CanReadBinaryContent
  385. {
  386. get { return true; }
  387. }
  388. public override bool CanReadValueChunk
  389. {
  390. get { return true; }
  391. }
  392. public override string BaseURI
  393. {
  394. get
  395. {
  396. return string.Empty;
  397. }
  398. }
  399. public override bool HasValue
  400. {
  401. get
  402. {
  403. return node.HasValue;
  404. }
  405. }
  406. public override bool IsDefault
  407. {
  408. get
  409. {
  410. return false;
  411. }
  412. }
  413. public override string this[int index]
  414. {
  415. get
  416. {
  417. return GetAttribute(index);
  418. }
  419. }
  420. public override string this[string name]
  421. {
  422. get
  423. {
  424. return GetAttribute(name);
  425. }
  426. }
  427. public override string this[string localName, string namespaceUri]
  428. {
  429. get
  430. {
  431. return GetAttribute(localName, namespaceUri);
  432. }
  433. }
  434. public override int AttributeCount
  435. {
  436. get
  437. {
  438. if (node.CanGetAttribute)
  439. return attributeCount;
  440. return 0;
  441. }
  442. }
  443. public override void Close()
  444. {
  445. MoveToNode(closedNode);
  446. nameTable = null;
  447. if (attributeNodes != null && attributeNodes.Length > 16)
  448. attributeNodes = null;
  449. if (elementNodes != null && elementNodes.Length > 16)
  450. elementNodes = null;
  451. nsMgr.Close();
  452. bufferReader.Close();
  453. if (signingWriter != null)
  454. signingWriter.Close();
  455. if (attributeSorter != null)
  456. attributeSorter.Close();
  457. }
  458. public sealed override int Depth
  459. {
  460. get
  461. {
  462. // Internally, depth is simply measured by Element/EndElement. What XmlReader exposes is a little different
  463. // so we need to account for this with some minor adjustments.
  464. // We increment depth immediately when we see an element, but XmlTextReader waits until its consumed
  465. // We decrement depth when its consumed, but XmlTextReader decrements depth immediately
  466. // If we're on Attribute Text (i.e. ReadAttributeValue), then its considered a level deeper
  467. return this.depth + node.DepthDelta;
  468. }
  469. }
  470. public override bool EOF
  471. {
  472. get
  473. {
  474. return node.ReadState == ReadState.EndOfFile;
  475. }
  476. }
  477. XmlAttributeNode GetAttributeNode(int index)
  478. {
  479. if (!node.CanGetAttribute)
  480. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index", SR.GetString(SR.XmlElementAttributes)));
  481. if (index < 0)
  482. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index", SR.GetString(SR.ValueMustBeNonNegative)));
  483. if (index >= attributeCount)
  484. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("index", SR.GetString(SR.OffsetExceedsBufferSize, attributeCount)));
  485. return attributeNodes[index];
  486. }
  487. XmlAttributeNode GetAttributeNode(string name)
  488. {
  489. if (name == null)
  490. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("name"));
  491. if (!node.CanGetAttribute)
  492. return null;
  493. int index = name.IndexOf(':');
  494. string prefix;
  495. string localName;
  496. if (index == -1)
  497. {
  498. if (name == xmlns)
  499. {
  500. prefix = xmlns;
  501. localName = string.Empty;
  502. }
  503. else
  504. {
  505. prefix = string.Empty;
  506. localName = name;
  507. }
  508. }
  509. else
  510. {
  511. // If this function becomes a performance issue because of the allocated strings then we can
  512. // make a version of Equals that takes an offset and count into the string.
  513. prefix = name.Substring(0, index);
  514. localName = name.Substring(index + 1);
  515. }
  516. XmlAttributeNode[] attributeNodes = this.attributeNodes;
  517. int attributeCount = this.attributeCount;
  518. int attributeIndex = this.attributeStart;
  519. for (int i = 0; i < attributeCount; i++)
  520. {
  521. if (++attributeIndex >= attributeCount)
  522. {
  523. attributeIndex = 0;
  524. }
  525. XmlAttributeNode attributeNode = attributeNodes[attributeIndex];
  526. if (attributeNode.IsPrefixAndLocalName(prefix, localName))
  527. {
  528. this.attributeStart = attributeIndex;
  529. return attributeNode;
  530. }
  531. }
  532. return null;
  533. }
  534. XmlAttributeNode GetAttributeNode(string localName, string namespaceUri)
  535. {
  536. if (localName == null)
  537. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("localName"));
  538. if (namespaceUri == null)
  539. namespaceUri = string.Empty;
  540. if (!node.CanGetAttribute)
  541. return null;
  542. XmlAttributeNode[] attributeNodes = this.attributeNodes;
  543. int attributeCount = this.attributeCount;
  544. int attributeIndex = this.attributeStart;
  545. for (int i = 0; i < attributeCount; i++)
  546. {
  547. if (++attributeIndex >= attributeCount)
  548. {
  549. attributeIndex = 0;
  550. }
  551. XmlAttributeNode attributeNode = attributeNodes[attributeIndex];
  552. if (attributeNode.IsLocalNameAndNamespaceUri(localName, namespaceUri))
  553. {
  554. this.attributeStart = attributeIndex;
  555. return attributeNode;
  556. }
  557. }
  558. return null;
  559. }
  560. XmlAttributeNode GetAttributeNode(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
  561. {
  562. if (localName == null)
  563. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("localName"));
  564. if (namespaceUri == null)
  565. namespaceUri = XmlDictionaryString.Empty;
  566. if (!node.CanGetAttribute)
  567. return null;
  568. XmlAttributeNode[] attributeNodes = this.attributeNodes;
  569. int attributeCount = this.attributeCount;
  570. int attributeIndex = this.attributeStart;
  571. for (int i = 0; i < attributeCount; i++)
  572. {
  573. if (++attributeIndex >= attributeCount)
  574. {
  575. attributeIndex = 0;
  576. }
  577. XmlAttributeNode attributeNode = attributeNodes[attributeIndex];
  578. if (attributeNode.IsLocalNameAndNamespaceUri(localName, namespaceUri))
  579. {
  580. this.attributeStart = attributeIndex;
  581. return attributeNode;
  582. }
  583. }
  584. return null;
  585. }
  586. public override string GetAttribute(int index)
  587. {
  588. return GetAttributeNode(index).ValueAsString;
  589. }
  590. public override string GetAttribute(string name)
  591. {
  592. XmlAttributeNode attributeNode = GetAttributeNode(name);
  593. if (attributeNode == null)
  594. return null;
  595. return attributeNode.ValueAsString;
  596. }
  597. public override string GetAttribute(string localName, string namespaceUri)
  598. {
  599. XmlAttributeNode attributeNode = GetAttributeNode(localName, namespaceUri);
  600. if (attributeNode == null)
  601. return null;
  602. return attributeNode.ValueAsString;
  603. }
  604. public override string GetAttribute(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
  605. {
  606. XmlAttributeNode attributeNode = GetAttributeNode(localName, namespaceUri);
  607. if (attributeNode == null)
  608. return null;
  609. return attributeNode.ValueAsString;
  610. }
  611. public sealed override bool IsEmptyElement
  612. {
  613. get
  614. {
  615. return node.IsEmptyElement;
  616. }
  617. }
  618. public override string LocalName
  619. {
  620. get
  621. {
  622. if (this.localName == null)
  623. {
  624. this.localName = GetLocalName(true);
  625. }
  626. return this.localName;
  627. }
  628. }
  629. public override string LookupNamespace(string prefix)
  630. {
  631. Namespace ns = nsMgr.LookupNamespace(prefix);
  632. if (ns != null)
  633. return ns.Uri.GetString(NameTable);
  634. if (prefix == xmlns)
  635. return xmlnsNamespace;
  636. return null;
  637. }
  638. protected Namespace LookupNamespace(PrefixHandleType prefix)
  639. {
  640. Namespace ns = nsMgr.LookupNamespace(prefix);
  641. if (ns == null)
  642. XmlExceptionHelper.ThrowUndefinedPrefix(this, PrefixHandle.GetString(prefix));
  643. return ns;
  644. }
  645. protected Namespace LookupNamespace(PrefixHandle prefix)
  646. {
  647. Namespace ns = nsMgr.LookupNamespace(prefix);
  648. if (ns == null)
  649. XmlExceptionHelper.ThrowUndefinedPrefix(this, prefix.GetString());
  650. return ns;
  651. }
  652. protected void ProcessAttributes()
  653. {
  654. if (attributeCount > 0)
  655. {
  656. ProcessAttributes(attributeNodes, attributeCount);
  657. }
  658. }
  659. void ProcessAttributes(XmlAttributeNode[] attributeNodes, int attributeCount)
  660. {
  661. for (int i = 0; i < attributeCount; i++)
  662. {
  663. XmlAttributeNode attributeNode = attributeNodes[i];
  664. if (attributeNode.QNameType == QNameType.Normal)
  665. {
  666. PrefixHandle prefix = attributeNode.Prefix;
  667. if (!prefix.IsEmpty)
  668. {
  669. attributeNode.Namespace = LookupNamespace(prefix);
  670. }
  671. else
  672. {
  673. attributeNode.Namespace = NamespaceManager.EmptyNamespace;
  674. }
  675. attributeNode.AttributeText.Namespace = attributeNode.Namespace;
  676. }
  677. }
  678. if (attributeCount > 1)
  679. {
  680. if (attributeCount < 12)
  681. {
  682. // For small numbers of attributes, a naive n * (n - 1) / 2 comparisons to check for uniqueness is faster
  683. for (int i = 0; i < attributeCount - 1; i++)
  684. {
  685. XmlAttributeNode attributeNode1 = attributeNodes[i];
  686. QNameType qnameType = attributeNode1.QNameType;
  687. if (qnameType == QNameType.Normal)
  688. {
  689. for (int j = i + 1; j < attributeCount; j++)
  690. {
  691. XmlAttributeNode attributeNode2 = attributeNodes[j];
  692. if (attributeNode2.QNameType == QNameType.Normal && attributeNode1.LocalName == attributeNode2.LocalName && attributeNode1.Namespace.Uri == attributeNode2.Namespace.Uri)
  693. {
  694. XmlExceptionHelper.ThrowDuplicateAttribute(this, attributeNode1.Prefix.GetString(), attributeNode2.Prefix.GetString(), attributeNode1.LocalName.GetString(), attributeNode1.Namespace.Uri.GetString());
  695. }
  696. }
  697. }
  698. else
  699. {
  700. Fx.Assert(qnameType == QNameType.Xmlns, "");
  701. for (int j = i + 1; j < attributeCount; j++)
  702. {
  703. XmlAttributeNode attributeNode2 = attributeNodes[j];
  704. if (attributeNode2.QNameType == QNameType.Xmlns && attributeNode1.Namespace.Prefix == attributeNode2.Namespace.Prefix)
  705. XmlExceptionHelper.ThrowDuplicateAttribute(this, xmlns, xmlns, attributeNode1.Namespace.Prefix.GetString(), xmlnsNamespace);
  706. }
  707. }
  708. }
  709. }
  710. else
  711. {
  712. CheckAttributes(attributeNodes, attributeCount);
  713. }
  714. }
  715. }
  716. void CheckAttributes(XmlAttributeNode[] attributeNodes, int attributeCount)
  717. {
  718. // For large numbers of attributes, sorting the attributes (n * lg(n)) is faster
  719. if (attributeSorter == null)
  720. attributeSorter = new AttributeSorter();
  721. if (!attributeSorter.Sort(attributeNodes, attributeCount))
  722. {
  723. int attribute1, attribute2;
  724. attributeSorter.GetIndeces(out attribute1, out attribute2);
  725. if (attributeNodes[attribute1].QNameType == QNameType.Xmlns)
  726. XmlExceptionHelper.ThrowDuplicateXmlnsAttribute(this, attributeNodes[attribute1].Namespace.Prefix.GetString(), xmlnsNamespace);
  727. else
  728. XmlExceptionHelper.ThrowDuplicateAttribute(this, attributeNodes[attribute1].Prefix.GetString(), attributeNodes[attribute2].Prefix.GetString(), attributeNodes[attribute1].LocalName.GetString(), attributeNodes[attribute1].Namespace.Uri.GetString());
  729. }
  730. }
  731. public override void MoveToAttribute(int index)
  732. {
  733. MoveToNode(GetAttributeNode(index));
  734. this.attributeIndex = index;
  735. }
  736. public override bool MoveToAttribute(string name)
  737. {
  738. XmlNode attributeNode = GetAttributeNode(name);
  739. if (attributeNode == null)
  740. return false;
  741. MoveToNode(attributeNode);
  742. this.attributeIndex = this.attributeStart;
  743. return true;
  744. }
  745. public override bool MoveToAttribute(string localName, string namespaceUri)
  746. {
  747. XmlNode attributeNode = GetAttributeNode(localName, namespaceUri);
  748. if (attributeNode == null)
  749. return false;
  750. MoveToNode(attributeNode);
  751. this.attributeIndex = this.attributeStart;
  752. return true;
  753. }
  754. public override bool MoveToElement()
  755. {
  756. if (!node.CanMoveToElement)
  757. return false;
  758. if (depth == 0)
  759. MoveToDeclaration();
  760. else
  761. MoveToNode(elementNodes[depth]);
  762. this.attributeIndex = -1;
  763. return true;
  764. }
  765. public override XmlNodeType MoveToContent()
  766. {
  767. do
  768. {
  769. if (node.HasContent)
  770. {
  771. if (node.NodeType != XmlNodeType.Text && node.NodeType != XmlNodeType.CDATA)
  772. break;
  773. if (trailByteCount > 0)
  774. {
  775. break;
  776. }
  777. if (this.value == null)
  778. {
  779. if (!node.Value.IsWhitespace())
  780. break;
  781. }
  782. else
  783. {
  784. if (!XmlConverter.IsWhitespace(this.value))
  785. break;
  786. }
  787. }
  788. else
  789. {
  790. if (node.NodeType == XmlNodeType.Attribute)
  791. {
  792. MoveToElement();
  793. break;
  794. }
  795. }
  796. }
  797. while (Read());
  798. return node.NodeType;
  799. }
  800. public override bool MoveToFirstAttribute()
  801. {
  802. if (!node.CanGetAttribute || attributeCount == 0)
  803. return false;
  804. MoveToNode(GetAttributeNode(0));
  805. this.attributeIndex = 0;
  806. return true;
  807. }
  808. public override bool MoveToNextAttribute()
  809. {
  810. if (!node.CanGetAttribute)
  811. return false;
  812. int attributeIndex = this.attributeIndex + 1;
  813. if (attributeIndex >= attributeCount)
  814. return false;
  815. MoveToNode(GetAttributeNode(attributeIndex));
  816. this.attributeIndex = attributeIndex;
  817. return true;
  818. }
  819. public override string NamespaceURI
  820. {
  821. get
  822. {
  823. if (this.ns == null)
  824. {
  825. this.ns = GetNamespaceUri(true);
  826. }
  827. return this.ns;
  828. }
  829. }
  830. public override XmlNameTable NameTable
  831. {
  832. get
  833. {
  834. if (nameTable == null)
  835. {
  836. nameTable = new QuotaNameTable(this, quotas.MaxNameTableCharCount);
  837. nameTable.Add(xml);
  838. nameTable.Add(xmlns);
  839. nameTable.Add(xmlnsNamespace);
  840. nameTable.Add(xmlNamespace);
  841. for (PrefixHandleType i = PrefixHandleType.A; i <= PrefixHandleType.Z; i++)
  842. {
  843. nameTable.Add(PrefixHandle.GetString(i));
  844. }
  845. }
  846. return nameTable;
  847. }
  848. }
  849. public sealed override XmlNodeType NodeType
  850. {
  851. get
  852. {
  853. return node.NodeType;
  854. }
  855. }
  856. public override string Prefix
  857. {
  858. get
  859. {
  860. if (prefix == null)
  861. {
  862. QNameType qnameType = node.QNameType;
  863. if (qnameType == QNameType.Normal)
  864. {
  865. prefix = node.Prefix.GetString(NameTable);
  866. }
  867. else if (qnameType == QNameType.Xmlns)
  868. {
  869. if (node.Namespace.Prefix.IsEmpty)
  870. prefix = string.Empty;
  871. else
  872. prefix = xmlns;
  873. }
  874. else
  875. {
  876. prefix = xml;
  877. }
  878. }
  879. return prefix;
  880. }
  881. }
  882. public override char QuoteChar
  883. {
  884. get
  885. {
  886. return node.QuoteChar;
  887. }
  888. }
  889. string GetLocalName(bool enforceAtomization)
  890. {
  891. if (this.localName != null)
  892. {
  893. return this.localName;
  894. }
  895. QNameType qnameType = node.QNameType;
  896. if (qnameType == QNameType.Normal)
  897. {
  898. if (enforceAtomization || nameTable != null)
  899. {
  900. return node.LocalName.GetString(NameTable);
  901. }
  902. else
  903. {
  904. return node.LocalName.GetString();
  905. }
  906. }
  907. else
  908. {
  909. Fx.Assert(qnameType == QNameType.Xmlns, "");
  910. if (node.Namespace.Prefix.IsEmpty)
  911. {
  912. return xmlns;
  913. }
  914. else
  915. {
  916. if (enforceAtomization || nameTable != null)
  917. {
  918. return node.Namespace.Prefix.GetString(NameTable);
  919. }
  920. else
  921. {
  922. return node.Namespace.Prefix.GetString();
  923. }
  924. }
  925. }
  926. }
  927. string GetNamespaceUri(bool enforceAtomization)
  928. {
  929. if (this.ns != null)
  930. {
  931. return this.ns;
  932. }
  933. QNameType qnameType = node.QNameType;
  934. if (qnameType == QNameType.Normal)
  935. {
  936. if (enforceAtomization || nameTable != null)
  937. {
  938. return node.Namespace.Uri.GetString(NameTable);
  939. }
  940. else
  941. {
  942. return node.Namespace.Uri.GetString();
  943. }
  944. }
  945. else
  946. {
  947. Fx.Assert(qnameType == QNameType.Xmlns, "");
  948. return xmlnsNamespace;
  949. }
  950. }
  951. // In a XmlReader names of elements and attributes should be returned atomized
  952. // (see XmlReader.NameTable on MSDN for more information)
  953. // to allow a comparison based on object instance comparison instead of string comparison
  954. // This method allows to receive the localName and namespaceUri without enforcing atomization
  955. // to avoid the cost of atomization if this is not necessary.
  956. public override void GetNonAtomizedNames(out string localName, out string namespaceUri)
  957. {
  958. localName = GetLocalName(false);
  959. namespaceUri = GetNamespaceUri(false);
  960. }
  961. public override bool IsLocalName(string localName)
  962. {
  963. if (localName == null)
  964. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("localName"));
  965. return node.IsLocalName(localName);
  966. }
  967. public override bool IsLocalName(XmlDictionaryString localName)
  968. {
  969. if (localName == null)
  970. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("localName"));
  971. return node.IsLocalName(localName);
  972. }
  973. public override bool IsNamespaceUri(string namespaceUri)
  974. {
  975. if (namespaceUri == null)
  976. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri");
  977. return node.IsNamespaceUri(namespaceUri);
  978. }
  979. public override bool IsNamespaceUri(XmlDictionaryString namespaceUri)
  980. {
  981. if (namespaceUri == null)
  982. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri");
  983. return node.IsNamespaceUri(namespaceUri);
  984. }
  985. public override sealed bool IsStartElement()
  986. {
  987. XmlNodeType nodeType = node.NodeType;
  988. if (nodeType == XmlNodeType.Element)
  989. return true;
  990. if (nodeType == XmlNodeType.EndElement)
  991. return false;
  992. if (nodeType == XmlNodeType.None)
  993. {
  994. Read();
  995. if (node.NodeType == XmlNodeType.Element)
  996. return true;
  997. }
  998. return (MoveToContent() == XmlNodeType.Element);
  999. }
  1000. public override bool IsStartElement(string name)
  1001. {
  1002. if (name == null)
  1003. return false;
  1004. int index = name.IndexOf(':');
  1005. string prefix;
  1006. string localName;
  1007. if (index == -1)
  1008. {
  1009. prefix = string.Empty;
  1010. localName = name;
  1011. }
  1012. else
  1013. {
  1014. prefix = name.Substring(0, index);
  1015. localName = name.Substring(index + 1);
  1016. }
  1017. return (node.NodeType == XmlNodeType.Element || IsStartElement()) && node.Prefix == prefix && node.LocalName == localName;
  1018. }
  1019. public override bool IsStartElement(string localName, string namespaceUri)
  1020. {
  1021. if (localName == null)
  1022. return false;
  1023. if (namespaceUri == null)
  1024. return false;
  1025. return (node.NodeType == XmlNodeType.Element || IsStartElement()) && node.LocalName == localName && node.IsNamespaceUri(namespaceUri);
  1026. }
  1027. public override bool IsStartElement(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
  1028. {
  1029. if (localName == null)
  1030. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localName");
  1031. if (namespaceUri == null)
  1032. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri");
  1033. return (node.NodeType == XmlNodeType.Element || IsStartElement()) && node.LocalName == localName && node.IsNamespaceUri(namespaceUri);
  1034. }
  1035. public override int IndexOfLocalName(string[] localNames, string namespaceUri)
  1036. {
  1037. if (localNames == null)
  1038. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localNames");
  1039. if (namespaceUri == null)
  1040. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri");
  1041. QNameType qnameType = node.QNameType;
  1042. if (node.IsNamespaceUri(namespaceUri))
  1043. {
  1044. if (qnameType == QNameType.Normal)
  1045. {
  1046. StringHandle localName = node.LocalName;
  1047. for (int i = 0; i < localNames.Length; i++)
  1048. {
  1049. string value = localNames[i];
  1050. if (value == null)
  1051. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(string.Format(CultureInfo.InvariantCulture, "localNames[{0}]", i));
  1052. if (localName == value)
  1053. {
  1054. return i;
  1055. }
  1056. }
  1057. }
  1058. else
  1059. {
  1060. Fx.Assert(qnameType == QNameType.Xmlns, "");
  1061. PrefixHandle prefix = node.Namespace.Prefix;
  1062. for (int i = 0; i < localNames.Length; i++)
  1063. {
  1064. string value = localNames[i];
  1065. if (value == null)
  1066. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(string.Format(CultureInfo.InvariantCulture, "localNames[{0}]", i));
  1067. if (prefix == value)
  1068. {
  1069. return i;
  1070. }
  1071. }
  1072. }
  1073. }
  1074. return -1;
  1075. }
  1076. public override int IndexOfLocalName(XmlDictionaryString[] localNames, XmlDictionaryString namespaceUri)
  1077. {
  1078. if (localNames == null)
  1079. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localNames");
  1080. if (namespaceUri == null)
  1081. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("namespaceUri");
  1082. QNameType qnameType = node.QNameType;
  1083. if (node.IsNamespaceUri(namespaceUri))
  1084. {
  1085. if (qnameType == QNameType.Normal)
  1086. {
  1087. StringHandle localName = node.LocalName;
  1088. for (int i = 0; i < localNames.Length; i++)
  1089. {
  1090. XmlDictionaryString value = localNames[i];
  1091. if (value == null)
  1092. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(string.Format(CultureInfo.InvariantCulture, "localNames[{0}]", i));
  1093. if (localName == value)
  1094. {
  1095. return i;
  1096. }
  1097. }
  1098. }
  1099. else
  1100. {
  1101. Fx.Assert(qnameType == QNameType.Xmlns, "");
  1102. PrefixHandle prefix = node.Namespace.Prefix;
  1103. for (int i = 0; i < localNames.Length; i++)
  1104. {
  1105. XmlDictionaryString value = localNames[i];
  1106. if (value == null)
  1107. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(string.Format(CultureInfo.InvariantCulture, "localNames[{0}]", i));
  1108. if (prefix == value)
  1109. {
  1110. return i;
  1111. }
  1112. }
  1113. }
  1114. }
  1115. return -1;
  1116. }
  1117. public override int ReadValueChunk(char[] chars, int offset, int count)
  1118. {
  1119. if (chars == null)
  1120. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars"));
  1121. if (offset < 0)
  1122. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative)));
  1123. if (offset > chars.Length)
  1124. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, chars.Length)));
  1125. if (count < 0)
  1126. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative)));
  1127. if (count > chars.Length - offset)
  1128. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, chars.Length - offset)));
  1129. int actual;
  1130. if (this.value == null)
  1131. {
  1132. if (node.QNameType == QNameType.Normal)
  1133. {
  1134. if (node.Value.TryReadChars(chars, offset, count, out actual))
  1135. return actual;
  1136. }
  1137. }
  1138. string value = this.Value;
  1139. actual = Math.Min(count, value.Length);
  1140. value.CopyTo(0, chars, offset, actual);
  1141. this.value = value.Substring(actual);
  1142. return actual;
  1143. }
  1144. public override int ReadValueAsBase64(byte[] buffer, int offset, int count)
  1145. {
  1146. if (buffer == null)
  1147. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer"));
  1148. if (offset < 0)
  1149. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative)));
  1150. if (offset > buffer.Length)
  1151. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, buffer.Length)));
  1152. if (count < 0)
  1153. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative)));
  1154. if (count > buffer.Length - offset)
  1155. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, buffer.Length - offset)));
  1156. if (count == 0)
  1157. return 0;
  1158. int actual;
  1159. if (this.value == null)
  1160. {
  1161. if (trailByteCount == 0 && trailCharCount == 0)
  1162. {
  1163. if (node.QNameType == QNameType.Normal)
  1164. {
  1165. if (node.Value.TryReadBase64(buffer, offset, count, out actual))
  1166. return actual;
  1167. }
  1168. }
  1169. }
  1170. return ReadBytes(Base64Encoding, 3, 4, buffer, offset, Math.Min(count, 512), false);
  1171. }
  1172. public override string ReadElementContentAsString()
  1173. {
  1174. if (node.NodeType != XmlNodeType.Element)
  1175. MoveToStartElement();
  1176. if (node.IsEmptyElement)
  1177. {
  1178. Read();
  1179. return string.Empty;
  1180. }
  1181. else
  1182. {
  1183. Read();
  1184. string s = ReadContentAsString();
  1185. ReadEndElement();
  1186. return s;
  1187. }
  1188. }
  1189. public override string ReadElementString()
  1190. {
  1191. MoveToStartElement();
  1192. if (IsEmptyElement)
  1193. {
  1194. Read();
  1195. return string.Empty;
  1196. }
  1197. else
  1198. {
  1199. Read();
  1200. string s = ReadString();
  1201. ReadEndElement();
  1202. return s;
  1203. }
  1204. }
  1205. public override string ReadElementString(string name)
  1206. {
  1207. MoveToStartElement(name);
  1208. return ReadElementString();
  1209. }
  1210. public override string ReadElementString(string localName, string namespaceUri)
  1211. {
  1212. MoveToStartElement(localName, namespaceUri);
  1213. return ReadElementString();
  1214. }
  1215. public override void ReadStartElement()
  1216. {
  1217. if (node.NodeType != XmlNodeType.Element)
  1218. MoveToStartElement();
  1219. Read();
  1220. }
  1221. public override void ReadStartElement(string name)
  1222. {
  1223. MoveToStartElement(name);
  1224. Read();
  1225. }
  1226. public override void ReadStartElement(string localName, string namespaceUri)
  1227. {
  1228. MoveToStartElement(localName, namespaceUri);
  1229. Read();
  1230. }
  1231. public override void ReadEndElement()
  1232. {
  1233. if (node.NodeType != XmlNodeType.EndElement && MoveToContent() != XmlNodeType.EndElement)
  1234. {
  1235. int nodeDepth = node.NodeType == XmlNodeType.Element ? this.depth - 1 : this.depth;
  1236. if (nodeDepth == 0)
  1237. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.XmlEndElementNoOpenNodes)));
  1238. // If depth is non-zero, then the document isn't what was expected
  1239. XmlElementNode elementNode = elementNodes[nodeDepth];
  1240. XmlExceptionHelper.ThrowEndElementExpected(this, elementNode.LocalName.GetString(), elementNode.Namespace.Uri.GetString());
  1241. }
  1242. Read();
  1243. }
  1244. public override bool ReadAttributeValue()
  1245. {
  1246. XmlAttributeTextNode attributeTextNode = node.AttributeText;
  1247. if (attributeTextNode == null)
  1248. return false;
  1249. MoveToNode(attributeTextNode);
  1250. return true;
  1251. }
  1252. public override ReadState ReadState
  1253. {
  1254. get
  1255. {
  1256. return node.ReadState;
  1257. }
  1258. }
  1259. void SkipValue(XmlNode node)
  1260. {
  1261. if (node.SkipValue)
  1262. Read();
  1263. }
  1264. public override bool TryGetBase64ContentLength(out int length)
  1265. {
  1266. if (trailByteCount == 0 && trailCharCount == 0 && this.value == null)
  1267. {
  1268. XmlNode node = this.Node;
  1269. if (node.IsAtomicValue)
  1270. return node.Value.TryGetByteArrayLength(out length);
  1271. }
  1272. return base.TryGetBase64ContentLength(out length);
  1273. }
  1274. public override byte[] ReadContentAsBase64()
  1275. {
  1276. if (trailByteCount == 0 && trailCharCount == 0 && this.value == null)
  1277. {
  1278. XmlNode node = this.Node;
  1279. if (node.IsAtomicValue)
  1280. {
  1281. byte[] value = node.Value.ToByteArray();
  1282. if (value.Length > quotas.MaxArrayLength)
  1283. XmlExceptionHelper.ThrowMaxArrayLengthExceeded(this, quotas.MaxArrayLength);
  1284. SkipValue(node);
  1285. return value;
  1286. }
  1287. }
  1288. if (!bufferReader.IsStreamed)
  1289. return ReadContentAsBase64(quotas.MaxArrayLength, bufferReader.Buffer.Length);
  1290. return ReadContentAsBase64(quotas.MaxArrayLength, XmlDictionaryReader.MaxInitialArrayLength); // Initial count will get ignored
  1291. }
  1292. public override int ReadElementContentAsBase64(byte[] buffer, int offset, int count)
  1293. {
  1294. if (!readingElement)
  1295. {
  1296. if (IsEmptyElement)
  1297. {
  1298. Read();
  1299. return 0;
  1300. }
  1301. ReadStartElement();
  1302. readingElement = true;
  1303. }
  1304. int i = ReadContentAsBase64(buffer, offset, count);
  1305. if (i == 0)
  1306. {
  1307. ReadEndElement();
  1308. readingElement = false;
  1309. }
  1310. return i;
  1311. }
  1312. public override int ReadContentAsBase64(byte[] buffer, int offset, int count)
  1313. {
  1314. if (buffer == null)
  1315. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer"));
  1316. if (offset < 0)
  1317. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative)));
  1318. if (offset > buffer.Length)
  1319. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, buffer.Length)));
  1320. if (count < 0)
  1321. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative)));
  1322. if (count > buffer.Length - offset)
  1323. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, buffer.Length - offset)));
  1324. if (count == 0)
  1325. return 0;
  1326. int actual;
  1327. if (trailByteCount == 0 && trailCharCount == 0 && this.value == null)
  1328. {
  1329. if (node.QNameType == QNameType.Normal)
  1330. {
  1331. while (node.NodeType != XmlNodeType.Comment && node.Value.TryReadBase64(buffer, offset, count, out actual))
  1332. {
  1333. if (actual != 0)
  1334. return actual;
  1335. Read();
  1336. }
  1337. }
  1338. }
  1339. XmlNodeType nodeType = node.NodeType;
  1340. if (nodeType == XmlNodeType.Element || nodeType == XmlNodeType.EndElement)
  1341. return 0;
  1342. return ReadBytes(Base64Encoding, 3, 4, buffer, offset, Math.Min(count, 512), true);
  1343. }
  1344. public override byte[] ReadContentAsBinHex()
  1345. {
  1346. return ReadContentAsBinHex(quotas.MaxArrayLength);
  1347. }
  1348. public override int ReadElementContentAsBinHex(byte[] buffer, int offset, int count)
  1349. {
  1350. if (!readingElement)
  1351. {
  1352. if (IsEmptyElement)
  1353. {
  1354. Read();
  1355. return 0;
  1356. }
  1357. ReadStartElement();
  1358. readingElement = true;
  1359. }
  1360. int i = ReadContentAsBinHex(buffer, offset, count);
  1361. if (i == 0)
  1362. {
  1363. ReadEndElement();
  1364. readingElement = false;
  1365. }
  1366. return i;
  1367. }
  1368. public override int ReadContentAsBinHex(byte[] buffer, int offset, int count)
  1369. {
  1370. if (buffer == null)
  1371. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer"));
  1372. if (offset < 0)
  1373. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative)));
  1374. if (offset > buffer.Length)
  1375. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, buffer.Length)));
  1376. if (count < 0)
  1377. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative)));
  1378. if (count > buffer.Length - offset)
  1379. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, buffer.Length - offset)));
  1380. if (count == 0)
  1381. return 0;
  1382. return ReadBytes(BinHexEncoding, 1, 2, buffer, offset, Math.Min(count, 512), true);
  1383. }
  1384. int ReadBytes(Encoding encoding, int byteBlock, int charBlock, byte[] buffer, int offset, int byteCount, bool readContent)
  1385. {
  1386. // If there are any trailing buffer return them.
  1387. if (trailByteCount > 0)
  1388. {
  1389. int actual = Math.Min(trailByteCount, byteCount);
  1390. Array.Copy(trailBytes, 0, buffer, offset, actual);
  1391. trailByteCount -= actual;
  1392. Array.Copy(trailBytes, actual, trailBytes, 0, trailByteCount);
  1393. return actual;
  1394. }
  1395. XmlNodeType nodeType = node.NodeType;
  1396. if (nodeType == XmlNodeType.Element || nodeType == XmlNodeType.EndElement)
  1397. return 0;
  1398. int maxCharCount;
  1399. if (byteCount < byteBlock)
  1400. {
  1401. // Convert at least charBlock chars
  1402. maxCharCount = charBlock;
  1403. }
  1404. else
  1405. {
  1406. // Round down to the nearest multiple of charBlock
  1407. maxCharCount = byteCount / byteBlock * charBlock;
  1408. }
  1409. char[] chars = GetCharBuffer(maxCharCount);
  1410. int charCount = 0;
  1411. while (true)
  1412. {
  1413. // If we didn't align on the boundary, then we might have some remaining characters
  1414. if (trailCharCount > 0)
  1415. {
  1416. Array.Copy(trailChars, 0, chars, charCount, trailCharCount);
  1417. charCount += trailCharCount;
  1418. trailCharCount = 0;
  1419. }
  1420. // Read until we at least get a charBlock
  1421. while (charCount < charBlock)
  1422. {
  1423. int actualCharCount;
  1424. if (readContent)
  1425. {
  1426. actualCharCount = ReadContentAsChars(chars, charCount, maxCharCount - charCount);
  1427. // When deserializing base64 content which contains new line chars (CR, LF) chars from ReadObject, the reader reads in chunks of base64 content, LF char, base64 content, LF char and so on
  1428. // Relying on encoding.GetBytes' exception to handle LF char would result in performance degradation so skipping LF char here
  1429. if (actualCharCount == 1 && chars[charCount] == '\n')
  1430. continue;
  1431. }
  1432. else
  1433. actualCharCount = ReadValueChunk(chars, charCount, maxCharCount - charCount);
  1434. if (actualCharCount == 0)
  1435. break;
  1436. charCount += actualCharCount;
  1437. }
  1438. // Trim so its a multiple of charBlock
  1439. if (charCount >= charBlock)
  1440. {
  1441. trailCharCount = (charCount % charBlock);
  1442. if (trailCharCount > 0)
  1443. {
  1444. if (trailChars == null)
  1445. trailChars = new char[4];
  1446. charCount = charCount - trailCharCount;
  1447. Array.Copy(chars, charCount, trailChars, 0, trailCharCount);
  1448. }
  1449. }
  1450. try
  1451. {
  1452. if (byteCount < byteBlock)
  1453. {
  1454. if (trailBytes == null)
  1455. trailBytes = new byte[3];
  1456. trailByteCount = encoding.GetBytes(chars, 0, charCount, trailBytes, 0);
  1457. int actual = Math.Min(trailByteCount, byteCount);
  1458. Array.Copy(trailBytes, 0, buffer, offset, actual);
  1459. trailByteCount -= actual;
  1460. Array.Copy(trailBytes, actual, trailBytes, 0, trailByteCount);
  1461. return actual;
  1462. }
  1463. else
  1464. {
  1465. // charCount is a multiple of charBlock and we have enough room to convert everything
  1466. return encoding.GetBytes(chars, 0, charCount, buffer, offset);
  1467. }
  1468. }
  1469. catch (FormatException exception)
  1470. {
  1471. // Something was wrong with the format, see if we can strip the spaces
  1472. int i = 0;
  1473. int j = 0;
  1474. while (true)
  1475. {
  1476. while (j < charCount && XmlConverter.IsWhitespace(chars[j]))
  1477. j++;
  1478. if (j == charCount)
  1479. break;
  1480. chars[i++] = chars[j++];
  1481. }
  1482. // No spaces, so don't try again
  1483. if (i == charCount)
  1484. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(exception.Message, exception.InnerException));
  1485. charCount = i;
  1486. }
  1487. }
  1488. }
  1489. public override string ReadContentAsString()
  1490. {
  1491. string value;
  1492. XmlNode node = this.Node;
  1493. if (node.IsAtomicValue)
  1494. {
  1495. if (this.value != null)
  1496. {
  1497. value = this.value;
  1498. if (node.AttributeText == null)
  1499. this.value = string.Empty;
  1500. }
  1501. else
  1502. {
  1503. value = node.Value.GetString();
  1504. SkipValue(node);
  1505. if (value.Length > quotas.MaxStringContentLength)
  1506. XmlExceptionHelper.ThrowMaxStringContentLengthExceeded(this, quotas.MaxStringContentLength);
  1507. }
  1508. return value;
  1509. }
  1510. return base.ReadContentAsString(quotas.MaxStringContentLength);
  1511. }
  1512. public override Boolean ReadContentAsBoolean()
  1513. {
  1514. XmlNode node = this.Node;
  1515. if (this.value == null && node.IsAtomicValue)
  1516. {
  1517. bool value = node.Value.ToBoolean();
  1518. SkipValue(node);
  1519. return value;
  1520. }
  1521. return XmlConverter.ToBoolean(ReadContentAsString());
  1522. }
  1523. public override Int64 ReadContentAsLong()
  1524. {
  1525. XmlNode node = this.Node;
  1526. if (this.value == null && node.IsAtomicValue)
  1527. {
  1528. Int64 value = node.Value.ToLong();
  1529. SkipValue(node);
  1530. return value;
  1531. }
  1532. return XmlConverter.ToInt64(ReadContentAsString());
  1533. }
  1534. public override Int32 ReadContentAsInt()
  1535. {
  1536. XmlNode node = this.Node;
  1537. if (this.value == null && node.IsAtomicValue)
  1538. {
  1539. Int32 value = node.Value.ToInt();
  1540. SkipValue(node);
  1541. return value;
  1542. }
  1543. return XmlConverter.ToInt32(ReadContentAsString());
  1544. }
  1545. public override DateTime ReadContentAsDateTime()
  1546. {
  1547. XmlNode node = this.Node;
  1548. if (this.value == null && node.IsAtomicValue)
  1549. {
  1550. DateTime value = node.Value.ToDateTime();
  1551. SkipValue(node);
  1552. return value;
  1553. }
  1554. return XmlConverter.ToDateTime(ReadContentAsString());
  1555. }
  1556. public override Double ReadContentAsDouble()
  1557. {
  1558. XmlNode node = this.Node;
  1559. if (this.value == null && node.IsAtomicValue)
  1560. {
  1561. double value = node.Value.ToDouble();
  1562. SkipValue(node);
  1563. return value;
  1564. }
  1565. return XmlConverter.ToDouble(ReadContentAsString());
  1566. }
  1567. public override Single ReadContentAsFloat()
  1568. {
  1569. XmlNode node = this.Node;
  1570. if (this.value == null && node.IsAtomicValue)
  1571. {
  1572. float value = node.Value.ToSingle();
  1573. SkipValue(node);
  1574. return value;
  1575. }
  1576. return XmlConverter.ToSingle(ReadContentAsString());
  1577. }
  1578. public override Decimal ReadContentAsDecimal()
  1579. {
  1580. XmlNode node = this.Node;
  1581. if (this.value == null && node.IsAtomicValue)
  1582. {
  1583. decimal value = node.Value.ToDecimal();
  1584. SkipValue(node);
  1585. return value;
  1586. }
  1587. return XmlConverter.ToDecimal(ReadContentAsString());
  1588. }
  1589. public override UniqueId ReadContentAsUniqueId()
  1590. {
  1591. XmlNode node = this.Node;
  1592. if (this.value == null && node.IsAtomicValue)
  1593. {
  1594. UniqueId value = node.Value.ToUniqueId();
  1595. SkipValue(node);
  1596. return value;
  1597. }
  1598. return XmlConverter.ToUniqueId(ReadContentAsString());
  1599. }
  1600. public override TimeSpan ReadContentAsTimeSpan()
  1601. {
  1602. XmlNode node = this.Node;
  1603. if (this.value == null && node.IsAtomicValue)
  1604. {
  1605. TimeSpan value = node.Value.ToTimeSpan();
  1606. SkipValue(node);
  1607. return value;
  1608. }
  1609. return XmlConverter.ToTimeSpan(ReadContentAsString());
  1610. }
  1611. public override Guid ReadContentAsGuid()
  1612. {
  1613. XmlNode node = this.Node;
  1614. if (this.value == null && node.IsAtomicValue)
  1615. {
  1616. Guid value = node.Value.ToGuid();
  1617. SkipValue(node);
  1618. return value;
  1619. }
  1620. return XmlConverter.ToGuid(ReadContentAsString());
  1621. }
  1622. public override object ReadContentAsObject()
  1623. {
  1624. XmlNode node = this.Node;
  1625. if (this.value == null && node.IsAtomicValue)
  1626. {
  1627. object obj = node.Value.ToObject();
  1628. SkipValue(node);
  1629. return obj;
  1630. }
  1631. return ReadContentAsString();
  1632. }
  1633. public override object ReadContentAs(Type type, IXmlNamespaceResolver namespaceResolver)
  1634. {
  1635. if (type == typeof(ulong))
  1636. {
  1637. if (this.value == null && node.IsAtomicValue)
  1638. {
  1639. ulong value = node.Value.ToULong();
  1640. SkipValue(node);
  1641. return value;
  1642. }
  1643. else
  1644. {
  1645. return XmlConverter.ToUInt64(ReadContentAsString());
  1646. }
  1647. }
  1648. else if (type == typeof(bool))
  1649. return ReadContentAsBoolean();
  1650. else if (type == typeof(int))
  1651. return ReadContentAsInt();
  1652. else if (type == typeof(long))
  1653. return ReadContentAsLong();
  1654. else if (type == typeof(float))
  1655. return ReadContentAsFloat();
  1656. else if (type == typeof(double))
  1657. return ReadContentAsDouble();
  1658. else if (type == typeof(decimal))
  1659. return ReadContentAsDecimal();
  1660. else if (type == typeof(DateTime))
  1661. return ReadContentAsDateTime();
  1662. else if (type == typeof(UniqueId))
  1663. return ReadContentAsUniqueId();
  1664. else if (type == typeof(Guid))
  1665. return ReadContentAsGuid();
  1666. else if (type == typeof(TimeSpan))
  1667. return ReadContentAsTimeSpan();
  1668. else if (type == typeof(object))
  1669. return ReadContentAsObject();
  1670. else
  1671. return base.ReadContentAs(type, namespaceResolver);
  1672. }
  1673. public override void ResolveEntity()
  1674. {
  1675. throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.XmlInvalidOperation)));
  1676. }
  1677. public override void Skip()
  1678. {
  1679. if (node.ReadState != ReadState.Interactive)
  1680. return;
  1681. if ((node.NodeType == XmlNodeType.Element || MoveToElement()) && !IsEmptyElement)
  1682. {
  1683. int depth = Depth;
  1684. while (Read() && depth < Depth)
  1685. {
  1686. // Nothing, just read on
  1687. }
  1688. // consume end tag
  1689. if (node.NodeType == XmlNodeType.EndElement)
  1690. Read();
  1691. }
  1692. else
  1693. {
  1694. Read();
  1695. }
  1696. }
  1697. public override string Value
  1698. {
  1699. get
  1700. {
  1701. if (value == null)
  1702. {
  1703. value = node.ValueAsString;
  1704. }
  1705. return value;
  1706. }
  1707. }
  1708. public override Type ValueType
  1709. {
  1710. get
  1711. {
  1712. if (this.value == null && node.QNameType == QNameType.Normal)
  1713. {
  1714. Type type = node.Value.ToType();
  1715. if (node.IsAtomicValue)
  1716. return type;
  1717. if (type == typeof(byte[]))
  1718. return type;
  1719. }
  1720. return typeof(string);
  1721. }
  1722. }
  1723. public override string XmlLang
  1724. {
  1725. get
  1726. {
  1727. return nsMgr.XmlLang;
  1728. }
  1729. }
  1730. public override XmlSpace XmlSpace
  1731. {
  1732. get
  1733. {
  1734. return nsMgr.XmlSpace;
  1735. }
  1736. }
  1737. public override bool TryGetLocalNameAsDictionaryString(out XmlDictionaryString localName)
  1738. {
  1739. return node.TryGetLocalNameAsDictionaryString(out localName);
  1740. }
  1741. public override bool TryGetNamespaceUriAsDictionaryString(out XmlDictionaryString localName)
  1742. {
  1743. return node.TryGetNamespaceUriAsDictionaryString(out localName);
  1744. }
  1745. public override bool TryGetValueAsDictionaryString(out XmlDictionaryString value)
  1746. {
  1747. return node.TryGetValueAsDictionaryString(out value);
  1748. }
  1749. public override Int16[] ReadInt16Array(string localName, string namespaceUri)
  1750. {
  1751. return Int16ArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1752. }
  1753. public override Int16[] ReadInt16Array(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
  1754. {
  1755. return Int16ArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1756. }
  1757. public override Int32[] ReadInt32Array(string localName, string namespaceUri)
  1758. {
  1759. return Int32ArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1760. }
  1761. public override Int32[] ReadInt32Array(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
  1762. {
  1763. return Int32ArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1764. }
  1765. public override Int64[] ReadInt64Array(string localName, string namespaceUri)
  1766. {
  1767. return Int64ArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1768. }
  1769. public override Int64[] ReadInt64Array(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
  1770. {
  1771. return Int64ArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1772. }
  1773. public override float[] ReadSingleArray(string localName, string namespaceUri)
  1774. {
  1775. return SingleArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1776. }
  1777. public override float[] ReadSingleArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
  1778. {
  1779. return SingleArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1780. }
  1781. public override double[] ReadDoubleArray(string localName, string namespaceUri)
  1782. {
  1783. return DoubleArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1784. }
  1785. public override double[] ReadDoubleArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
  1786. {
  1787. return DoubleArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1788. }
  1789. public override decimal[] ReadDecimalArray(string localName, string namespaceUri)
  1790. {
  1791. return DecimalArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1792. }
  1793. public override decimal[] ReadDecimalArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
  1794. {
  1795. return DecimalArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1796. }
  1797. public override DateTime[] ReadDateTimeArray(string localName, string namespaceUri)
  1798. {
  1799. return DateTimeArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1800. }
  1801. public override DateTime[] ReadDateTimeArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
  1802. {
  1803. return DateTimeArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1804. }
  1805. public override Guid[] ReadGuidArray(string localName, string namespaceUri)
  1806. {
  1807. return GuidArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1808. }
  1809. public override Guid[] ReadGuidArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
  1810. {
  1811. return GuidArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1812. }
  1813. public override TimeSpan[] ReadTimeSpanArray(string localName, string namespaceUri)
  1814. {
  1815. return TimeSpanArrayHelperWithString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1816. }
  1817. public override TimeSpan[] ReadTimeSpanArray(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
  1818. {
  1819. return TimeSpanArrayHelperWithDictionaryString.Instance.ReadArray(this, localName, namespaceUri, quotas.MaxArrayLength);
  1820. }
  1821. public string GetOpenElements()
  1822. {
  1823. string s = string.Empty;
  1824. for (int i = depth; i > 0; i--)
  1825. {
  1826. string localName = elementNodes[i].LocalName.GetString();
  1827. if (i != depth)
  1828. s += ", ";
  1829. s += localName;
  1830. }
  1831. return s;
  1832. }
  1833. char[] GetCharBuffer(int count)
  1834. {
  1835. if (count > 1024)
  1836. return new char[count];
  1837. if (chars == null || chars.Length < count)
  1838. chars = new char[count];
  1839. return chars;
  1840. }
  1841. void SignStartElement(XmlSigningNodeWriter writer)
  1842. {
  1843. int prefixOffset, prefixLength;
  1844. byte[] prefixBuffer = node.Prefix.GetString(out prefixOffset, out prefixLength);
  1845. int localNameOffset, localNameLength;
  1846. byte[] localNameBuffer = node.LocalName.GetString(out localNameOffset, out localNameLength);
  1847. writer.WriteStartElement(prefixBuffer, prefixOffset, prefixLength, localNameBuffer, localNameOffset, localNameLength);
  1848. }
  1849. void SignAttribute(XmlSigningNodeWriter writer, XmlAttributeNode attributeNode)
  1850. {
  1851. QNameType qnameType = attributeNode.QNameType;
  1852. if (qnameType == QNameType.Normal)
  1853. {
  1854. int prefixOffset, prefixLength;
  1855. byte[] prefixBuffer = attributeNode.Prefix.GetString(out prefixOffset, out prefixLength);
  1856. int localNameOffset, localNameLength;
  1857. byte[] localNameBuffer = attributeNode.LocalName.GetString(out localNameOffset, out localNameLength);
  1858. writer.WriteStartAttribute(prefixBuffer, prefixOffset, prefixLength, localNameBuffer, localNameOffset, localNameLength);
  1859. attributeNode.Value.Sign(writer);
  1860. writer.WriteEndAttribute();
  1861. }
  1862. else
  1863. {
  1864. Fx.Assert(qnameType == QNameType.Xmlns, "");
  1865. int prefixOffset, prefixLength;
  1866. byte[] prefixBuffer = attributeNode.Namespace.Prefix.GetString(out prefixOffset, out prefixLength);
  1867. int nsOffset, nsLength;
  1868. byte[] nsBuffer = attributeNode.Namespace.Uri.GetString(out nsOffset, out nsLength);
  1869. writer.WriteXmlnsAttribute(prefixBuffer, prefixOffset, prefixLength, nsBuffer, nsOffset, nsLength);
  1870. }
  1871. }
  1872. void SignEndElement(XmlSigningNodeWriter writer)
  1873. {
  1874. int prefixOffset, prefixLength;
  1875. byte[] prefixBuffer = node.Prefix.GetString(out prefixOffset, out prefixLength);
  1876. int localNameOffset, localNameLength;
  1877. byte[] localNameBuffer = node.LocalName.GetString(out localNameOffset, out localNameLength);
  1878. writer.WriteEndElement(prefixBuffer, prefixOffset, prefixLength, localNameBuffer, localNameOffset, localNameLength);
  1879. }
  1880. void SignNode(XmlSigningNodeWriter writer)
  1881. {
  1882. switch (node.NodeType)
  1883. {
  1884. case XmlNodeType.None:
  1885. break;
  1886. case XmlNodeType.Element:
  1887. SignStartElement(writer);
  1888. for (int i = 0; i < attributeCount; i++)
  1889. SignAttribute(writer, attributeNodes[i]);
  1890. writer.WriteEndStartElement(node.IsEmptyElement);
  1891. break;
  1892. case XmlNodeType.Text:
  1893. case XmlNodeType.Whitespace:
  1894. case XmlNodeType.SignificantWhitespace:
  1895. case XmlNodeType.CDATA:
  1896. node.Value.Sign(writer);
  1897. break;
  1898. case XmlNodeType.XmlDeclaration:
  1899. writer.WriteDeclaration();
  1900. break;
  1901. case XmlNodeType.Comment:
  1902. writer.WriteComment(node.Value.GetString());
  1903. break;
  1904. case XmlNodeType.EndElement:
  1905. SignEndElement(writer);
  1906. break;
  1907. default:
  1908. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException());
  1909. }
  1910. }
  1911. public override bool CanCanonicalize
  1912. {
  1913. get
  1914. {
  1915. return true;
  1916. }
  1917. }
  1918. protected bool Signing
  1919. {
  1920. get
  1921. {
  1922. return signing;
  1923. }
  1924. }
  1925. protected void SignNode()
  1926. {
  1927. if (signing)
  1928. {
  1929. SignNode(signingWriter);
  1930. }
  1931. }
  1932. public override void StartCanonicalization(Stream stream, bool includeComments, string[] inclusivePrefixes)
  1933. {
  1934. if (signing)
  1935. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.XmlCanonicalizationStarted)));
  1936. if (signingWriter == null)
  1937. signingWriter = CreateSigningNodeWriter();
  1938. signingWriter.SetOutput(XmlNodeWriter.Null, stream, includeComments, inclusivePrefixes);
  1939. nsMgr.Sign(signingWriter);
  1940. signing = true;
  1941. }
  1942. public override void EndCanonicalization()
  1943. {
  1944. if (!signing)
  1945. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.XmlCanonicalizationNotStarted)));
  1946. signingWriter.Flush();
  1947. signingWriter.Close();
  1948. signing = false;
  1949. }
  1950. protected abstract XmlSigningNodeWriter CreateSigningNodeWriter();
  1951. protected enum QNameType
  1952. {
  1953. Normal,
  1954. Xmlns,
  1955. }
  1956. protected class XmlNode
  1957. {
  1958. XmlNodeType nodeType;
  1959. PrefixHandle prefix;
  1960. StringHandle localName;
  1961. ValueHandle value;
  1962. Namespace ns;
  1963. bool hasValue;
  1964. bool canGetAttribute;
  1965. bool canMoveToElement;
  1966. ReadState readState;
  1967. XmlAttributeTextNode attributeTextNode;
  1968. bool exitScope;
  1969. int depthDelta;
  1970. bool isAtomicValue;
  1971. bool skipValue;
  1972. QNameType qnameType;
  1973. bool hasContent;
  1974. bool isEmptyElement;
  1975. char quoteChar;
  1976. protected enum XmlNodeFlags
  1977. {
  1978. None = 0x00,
  1979. CanGetAttribute = 0x01,
  1980. CanMoveToElement = 0x02,
  1981. HasValue = 0x04,
  1982. AtomicValue = 0x08,
  1983. SkipValue = 0x10,
  1984. HasContent = 0x20
  1985. }
  1986. protected XmlNode(XmlNodeType nodeType,
  1987. PrefixHandle prefix,
  1988. StringHandle localName,
  1989. ValueHandle value,
  1990. XmlNodeFlags nodeFlags,
  1991. ReadState readState,
  1992. XmlAttributeTextNode attributeTextNode,
  1993. int depthDelta)
  1994. {
  1995. this.nodeType = nodeType;
  1996. this.prefix = prefix;
  1997. this.localName = localName;
  1998. this.value = value;
  1999. this.ns = NamespaceManager.EmptyNamespace;
  2000. this.hasValue = ((nodeFlags & XmlNodeFlags.HasValue) != 0);
  2001. this.canGetAttribute = ((nodeFlags & XmlNodeFlags.CanGetAttribute) != 0);
  2002. this.canMoveToElement = ((nodeFlags & XmlNodeFlags.CanMoveToElement) != 0);
  2003. this.isAtomicValue = ((nodeFlags & XmlNodeFlags.AtomicValue) != 0);
  2004. this.skipValue = ((nodeFlags & XmlNodeFlags.SkipValue) != 0);
  2005. this.hasContent = ((nodeFlags & XmlNodeFlags.HasContent) != 0);
  2006. this.readState = readState;
  2007. this.attributeTextNode = attributeTextNode;
  2008. this.exitScope = (nodeType == XmlNodeType.EndElement);
  2009. this.depthDelta = depthDelta;
  2010. this.isEmptyElement = false;
  2011. this.quoteChar = '"';
  2012. this.qnameType = QNameType.Normal;
  2013. }
  2014. // Most nodes are read-only and fixed for the particular node type, but a few need to be tweaked
  2015. // QNameType needs to get set for all nodes with a qname (Element/Attribute)
  2016. // NodeType gets set for WhiteSpace vs. SignificantWhitespace
  2017. // ExitScope/IsEmptyElement is only updated by text for empty elements
  2018. // QuoteChar is only updated by text for attributes
  2019. // IsAtomicValue is set to false for XmlnsAttributes so we don't have to check QNameType
  2020. public bool HasValue { get { return hasValue; } }
  2021. public ReadState ReadState { get { return readState; } }
  2022. public StringHandle LocalName { get { Fx.Assert(qnameType != QNameType.Xmlns, ""); return localName; } }
  2023. public PrefixHandle Prefix { get { Fx.Assert(qnameType != QNameType.Xmlns, ""); return prefix; } }
  2024. public bool CanGetAttribute { get { return canGetAttribute; } }
  2025. public bool CanMoveToElement { get { return canMoveToElement; } }
  2026. public XmlAttributeTextNode AttributeText { get { return attributeTextNode; } }
  2027. public bool SkipValue { get { return skipValue; } }
  2028. public ValueHandle Value { get { Fx.Assert(qnameType != QNameType.Xmlns, ""); return value; } }
  2029. public int DepthDelta { get { return depthDelta; } }
  2030. public bool HasContent { get { return hasContent; } }
  2031. public XmlNodeType NodeType
  2032. {
  2033. get
  2034. {
  2035. return nodeType;
  2036. }
  2037. set
  2038. {
  2039. nodeType = value;
  2040. }
  2041. }
  2042. public QNameType QNameType
  2043. {
  2044. get
  2045. {
  2046. return qnameType;
  2047. }
  2048. set
  2049. {
  2050. qnameType = value;
  2051. }
  2052. }
  2053. public Namespace Namespace
  2054. {
  2055. get
  2056. {
  2057. return ns;
  2058. }
  2059. set
  2060. {
  2061. ns = value;
  2062. }
  2063. }
  2064. public bool IsAtomicValue
  2065. {
  2066. get
  2067. {
  2068. return isAtomicValue;
  2069. }
  2070. set
  2071. {
  2072. isAtomicValue = value;
  2073. }
  2074. }
  2075. public bool ExitScope
  2076. {
  2077. get
  2078. {
  2079. return exitScope;
  2080. }
  2081. set
  2082. {
  2083. exitScope = value;
  2084. }
  2085. }
  2086. public bool IsEmptyElement
  2087. {
  2088. get
  2089. {
  2090. return isEmptyElement;
  2091. }
  2092. set
  2093. {
  2094. isEmptyElement = value;
  2095. }
  2096. }
  2097. public char QuoteChar
  2098. {
  2099. get
  2100. {
  2101. return quoteChar;
  2102. }
  2103. set
  2104. {
  2105. quoteChar = value;
  2106. }
  2107. }
  2108. public bool IsLocalName(string localName)
  2109. {
  2110. if (qnameType == QNameType.Normal)
  2111. {
  2112. return this.LocalName == localName;
  2113. }
  2114. else
  2115. {
  2116. Fx.Assert(qnameType == QNameType.Xmlns, "");
  2117. return this.Namespace.Prefix == localName;
  2118. }
  2119. }
  2120. public bool IsLocalName(XmlDictionaryString localName)
  2121. {
  2122. if (qnameType == QNameType.Normal)
  2123. {
  2124. return this.LocalName == localName;
  2125. }
  2126. else
  2127. {
  2128. Fx.Assert(qnameType == QNameType.Xmlns, "");
  2129. return this.Namespace.Prefix == localName;
  2130. }
  2131. }
  2132. public bool IsNamespaceUri(string ns)
  2133. {
  2134. if (qnameType == QNameType.Normal)
  2135. {
  2136. return this.Namespace.IsUri(ns);
  2137. }
  2138. else
  2139. {
  2140. Fx.Assert(qnameType == QNameType.Xmlns, "");
  2141. return ns == xmlnsNamespace;
  2142. }
  2143. }
  2144. public bool IsNamespaceUri(XmlDictionaryString ns)
  2145. {
  2146. if (qnameType == QNameType.Normal)
  2147. {
  2148. return this.Namespace.IsUri(ns);
  2149. }
  2150. else
  2151. {
  2152. Fx.Assert(qnameType == QNameType.Xmlns, "");
  2153. return ns.Value == xmlnsNamespace;
  2154. }
  2155. }
  2156. public bool IsLocalNameAndNamespaceUri(string localName, string ns)
  2157. {
  2158. if (qnameType == QNameType.Normal)
  2159. {
  2160. return this.LocalName == localName && this.Namespace.IsUri(ns);
  2161. }
  2162. else
  2163. {
  2164. Fx.Assert(qnameType == QNameType.Xmlns, "");
  2165. return this.Namespace.Prefix == localName && ns == xmlnsNamespace;
  2166. }
  2167. }
  2168. public bool IsLocalNameAndNamespaceUri(XmlDictionaryString localName, XmlDictionaryString ns)
  2169. {
  2170. if (qnameType == QNameType.Normal)
  2171. {
  2172. return this.LocalName == localName && this.Namespace.IsUri(ns);
  2173. }
  2174. else
  2175. {
  2176. Fx.Assert(qnameType == QNameType.Xmlns, "");
  2177. return this.Namespace.Prefix == localName && ns.Value == xmlnsNamespace;
  2178. }
  2179. }
  2180. public bool IsPrefixAndLocalName(string prefix, string localName)
  2181. {
  2182. if (qnameType == QNameType.Normal)
  2183. {
  2184. return this.Prefix == prefix && this.LocalName == localName;
  2185. }
  2186. else
  2187. {
  2188. Fx.Assert(qnameType == QNameType.Xmlns, "");
  2189. return prefix == xmlns && this.Namespace.Prefix == localName;
  2190. }
  2191. }
  2192. public bool TryGetLocalNameAsDictionaryString(out XmlDictionaryString localName)
  2193. {
  2194. if (qnameType == QNameType.Normal)
  2195. {
  2196. return this.LocalName.TryGetDictionaryString(out localName);
  2197. }
  2198. else
  2199. {
  2200. Fx.Assert(qnameType == QNameType.Xmlns, "");
  2201. localName = null;
  2202. return false;
  2203. }
  2204. }
  2205. public bool TryGetNamespaceUriAsDictionaryString(out XmlDictionaryString ns)
  2206. {
  2207. if (qnameType == QNameType.Normal)
  2208. {
  2209. return this.Namespace.Uri.TryGetDictionaryString(out ns);
  2210. }
  2211. else
  2212. {
  2213. Fx.Assert(qnameType == QNameType.Xmlns, "");
  2214. ns = null;
  2215. return false;
  2216. }
  2217. }
  2218. public bool TryGetValueAsDictionaryString(out XmlDictionaryString value)
  2219. {
  2220. if (qnameType == QNameType.Normal)
  2221. {
  2222. return this.Value.TryGetDictionaryString(out value);
  2223. }
  2224. else
  2225. {
  2226. Fx.Assert(qnameType == QNameType.Xmlns, "");
  2227. value = null;
  2228. return false;
  2229. }
  2230. }
  2231. public string ValueAsString
  2232. {
  2233. get
  2234. {
  2235. if (qnameType == QNameType.Normal)
  2236. {
  2237. return Value.GetString();
  2238. }
  2239. else
  2240. {
  2241. Fx.Assert(qnameType == QNameType.Xmlns, "");
  2242. return Namespace.Uri.GetString();
  2243. }
  2244. }
  2245. }
  2246. }
  2247. protected class XmlElementNode : XmlNode
  2248. {
  2249. XmlEndElementNode endElementNode;
  2250. int bufferOffset;
  2251. public XmlElementNode(XmlBufferReader bufferReader)
  2252. : this(new PrefixHandle(bufferReader),
  2253. new StringHandle(bufferReader),
  2254. new ValueHandle(bufferReader))
  2255. {
  2256. }
  2257. XmlElementNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
  2258. : base(XmlNodeType.Element,
  2259. prefix,
  2260. localName,
  2261. value,
  2262. XmlNodeFlags.CanGetAttribute | XmlNodeFlags.HasContent,
  2263. ReadState.Interactive,
  2264. null,
  2265. -1)
  2266. {
  2267. this.endElementNode = new XmlEndElementNode(prefix, localName, value);
  2268. }
  2269. public XmlEndElementNode EndElement
  2270. {
  2271. get
  2272. {
  2273. return endElementNode;
  2274. }
  2275. }
  2276. public int BufferOffset
  2277. {
  2278. get
  2279. {
  2280. return bufferOffset;
  2281. }
  2282. set
  2283. {
  2284. bufferOffset = value;
  2285. }
  2286. }
  2287. public int NameOffset;
  2288. public int NameLength;
  2289. }
  2290. protected class XmlAttributeNode : XmlNode
  2291. {
  2292. public XmlAttributeNode(XmlBufferReader bufferReader)
  2293. : this(new PrefixHandle(bufferReader), new StringHandle(bufferReader), new ValueHandle(bufferReader))
  2294. {
  2295. }
  2296. XmlAttributeNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
  2297. : base(XmlNodeType.Attribute,
  2298. prefix,
  2299. localName,
  2300. value,
  2301. XmlNodeFlags.CanGetAttribute | XmlNodeFlags.CanMoveToElement | XmlNodeFlags.HasValue | XmlNodeFlags.AtomicValue,
  2302. ReadState.Interactive,
  2303. new XmlAttributeTextNode(prefix, localName, value),
  2304. 0)
  2305. {
  2306. }
  2307. }
  2308. protected class XmlEndElementNode : XmlNode
  2309. {
  2310. public XmlEndElementNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
  2311. : base(XmlNodeType.EndElement,
  2312. prefix,
  2313. localName,
  2314. value,
  2315. XmlNodeFlags.HasContent,
  2316. ReadState.Interactive,
  2317. null,
  2318. -1)
  2319. {
  2320. }
  2321. }
  2322. protected class XmlTextNode : XmlNode
  2323. {
  2324. protected XmlTextNode(XmlNodeType nodeType,
  2325. PrefixHandle prefix,
  2326. StringHandle localName,
  2327. ValueHandle value,
  2328. XmlNodeFlags nodeFlags,
  2329. ReadState readState,
  2330. XmlAttributeTextNode attributeTextNode,
  2331. int depthDelta)
  2332. :
  2333. base(nodeType, prefix, localName, value, nodeFlags, readState, attributeTextNode, depthDelta)
  2334. {
  2335. }
  2336. }
  2337. protected class XmlAtomicTextNode : XmlTextNode
  2338. {
  2339. public XmlAtomicTextNode(XmlBufferReader bufferReader)
  2340. : base(XmlNodeType.Text,
  2341. new PrefixHandle(bufferReader),
  2342. new StringHandle(bufferReader),
  2343. new ValueHandle(bufferReader),
  2344. XmlNodeFlags.HasValue | XmlNodeFlags.AtomicValue | XmlNodeFlags.SkipValue | XmlNodeFlags.HasContent,
  2345. ReadState.Interactive,
  2346. null,
  2347. 0)
  2348. {
  2349. }
  2350. }
  2351. protected class XmlComplexTextNode : XmlTextNode
  2352. {
  2353. public XmlComplexTextNode(XmlBufferReader bufferReader)
  2354. : base(XmlNodeType.Text,
  2355. new PrefixHandle(bufferReader),
  2356. new StringHandle(bufferReader),
  2357. new ValueHandle(bufferReader),
  2358. XmlNodeFlags.HasValue | XmlNodeFlags.HasContent,
  2359. ReadState.Interactive,
  2360. null,
  2361. 0)
  2362. {
  2363. }
  2364. }
  2365. protected class XmlWhitespaceTextNode : XmlTextNode
  2366. {
  2367. public XmlWhitespaceTextNode(XmlBufferReader bufferReader)
  2368. : base(XmlNodeType.Whitespace,
  2369. new PrefixHandle(bufferReader),
  2370. new StringHandle(bufferReader),
  2371. new ValueHandle(bufferReader),
  2372. XmlNodeFlags.HasValue,
  2373. ReadState.Interactive,
  2374. null,
  2375. 0)
  2376. {
  2377. }
  2378. }
  2379. protected class XmlCDataNode : XmlTextNode
  2380. {
  2381. public XmlCDataNode(XmlBufferReader bufferReader)
  2382. : base(XmlNodeType.CDATA,
  2383. new PrefixHandle(bufferReader),
  2384. new StringHandle(bufferReader),
  2385. new ValueHandle(bufferReader),
  2386. XmlNodeFlags.HasValue | XmlNodeFlags.HasContent,
  2387. ReadState.Interactive,
  2388. null,
  2389. 0)
  2390. {
  2391. }
  2392. }
  2393. protected class XmlAttributeTextNode : XmlTextNode
  2394. {
  2395. public XmlAttributeTextNode(PrefixHandle prefix, StringHandle localName, ValueHandle value)
  2396. : base(XmlNodeType.Text,
  2397. prefix,
  2398. localName,
  2399. value,
  2400. XmlNodeFlags.HasValue | XmlNodeFlags.CanGetAttribute | XmlNodeFlags.CanMoveToElement | XmlNodeFlags.AtomicValue | XmlNodeFlags.HasContent,
  2401. ReadState.Interactive,
  2402. null,
  2403. 1)
  2404. {
  2405. }
  2406. }
  2407. protected class XmlInitialNode : XmlNode
  2408. {
  2409. public XmlInitialNode(XmlBufferReader bufferReader)
  2410. : base(XmlNodeType.None,
  2411. new PrefixHandle(bufferReader),
  2412. new StringHandle(bufferReader),
  2413. new ValueHandle(bufferReader),
  2414. XmlNodeFlags.None,
  2415. ReadState.Initial,
  2416. null,
  2417. 0)
  2418. {
  2419. }
  2420. }
  2421. protected class XmlDeclarationNode : XmlNode
  2422. {
  2423. public XmlDeclarationNode(XmlBufferReader bufferReader)
  2424. : base(XmlNodeType.XmlDeclaration,
  2425. new PrefixHandle(bufferReader),
  2426. new StringHandle(bufferReader),
  2427. new ValueHandle(bufferReader),
  2428. XmlNodeFlags.CanGetAttribute,
  2429. ReadState.Interactive,
  2430. null,
  2431. 0)
  2432. {
  2433. }
  2434. }
  2435. protected class XmlCommentNode : XmlNode
  2436. {
  2437. public XmlCommentNode(XmlBufferReader bufferReader)
  2438. : base(XmlNodeType.Comment,
  2439. new PrefixHandle(bufferReader),
  2440. new StringHandle(bufferReader),
  2441. new ValueHandle(bufferReader),
  2442. XmlNodeFlags.HasValue,
  2443. ReadState.Interactive,
  2444. null,
  2445. 0)
  2446. {
  2447. }
  2448. }
  2449. protected class XmlEndOfFileNode : XmlNode
  2450. {
  2451. public XmlEndOfFileNode(XmlBufferReader bufferReader)
  2452. : base(XmlNodeType.None,
  2453. new PrefixHandle(bufferReader),
  2454. new StringHandle(bufferReader),
  2455. new ValueHandle(bufferReader),
  2456. XmlNodeFlags.None,
  2457. ReadState.EndOfFile,
  2458. null,
  2459. 0)
  2460. {
  2461. }
  2462. }
  2463. protected class XmlClosedNode : XmlNode
  2464. {
  2465. public XmlClosedNode(XmlBufferReader bufferReader)
  2466. : base(XmlNodeType.None,
  2467. new PrefixHandle(bufferReader),
  2468. new StringHandle(bufferReader),
  2469. new ValueHandle(bufferReader),
  2470. XmlNodeFlags.None,
  2471. ReadState.Closed,
  2472. null,
  2473. 0)
  2474. {
  2475. }
  2476. }
  2477. class AttributeSorter : IComparer
  2478. {
  2479. object[] indeces;
  2480. XmlAttributeNode[] attributeNodes;
  2481. int attributeCount;
  2482. int attributeIndex1;
  2483. int attributeIndex2;
  2484. public bool Sort(XmlAttributeNode[] attributeNodes, int attributeCount)
  2485. {
  2486. this.attributeIndex1 = -1;
  2487. this.attributeIndex2 = -1;
  2488. this.attributeNodes = attributeNodes;
  2489. this.attributeCount = attributeCount;
  2490. bool sorted = Sort();
  2491. this.attributeNodes = null;
  2492. this.attributeCount = 0;
  2493. return sorted;
  2494. }
  2495. public void GetIndeces(out int attributeIndex1, out int attributeIndex2)
  2496. {
  2497. attributeIndex1 = this.attributeIndex1;
  2498. attributeIndex2 = this.attributeIndex2;
  2499. }
  2500. public void Close()
  2501. {
  2502. if (indeces != null && indeces.Length > 32)
  2503. {
  2504. indeces = null;
  2505. }
  2506. }
  2507. bool Sort()
  2508. {
  2509. // Optimistically use the last sort order and check to see if that works. This helps the case
  2510. // where elements with large numbers of attributes are repeated.
  2511. if (indeces != null && indeces.Length == attributeCount && IsSorted())
  2512. return true;
  2513. object[] newIndeces = new object[attributeCount];
  2514. for (int i = 0; i < newIndeces.Length; i++)
  2515. newIndeces[i] = i;
  2516. this.indeces = newIndeces;
  2517. Array.Sort(indeces, 0, attributeCount, this);
  2518. return IsSorted();
  2519. }
  2520. bool IsSorted()
  2521. {
  2522. for (int i = 0; i < indeces.Length - 1; i++)
  2523. {
  2524. if (Compare(indeces[i], indeces[i + 1]) >= 0)
  2525. {
  2526. attributeIndex1 = (int)indeces[i];
  2527. attributeIndex2 = (int)indeces[i + 1];
  2528. return false;
  2529. }
  2530. }
  2531. return true;
  2532. }
  2533. public int Compare(object obj1, object obj2)
  2534. {
  2535. int index1 = (int)obj1;
  2536. int index2 = (int)obj2;
  2537. XmlAttributeNode attribute1 = attributeNodes[index1];
  2538. XmlAttributeNode attribute2 = attributeNodes[index2];
  2539. int i = CompareQNameType(attribute1.QNameType, attribute2.QNameType);
  2540. if (i == 0)
  2541. {
  2542. QNameType qnameType = attribute1.QNameType;
  2543. if (qnameType == QNameType.Normal)
  2544. {
  2545. i = attribute1.LocalName.CompareTo(attribute2.LocalName);
  2546. if (i == 0)
  2547. {
  2548. i = attribute1.Namespace.Uri.CompareTo(attribute2.Namespace.Uri);
  2549. }
  2550. }
  2551. else
  2552. {
  2553. Fx.Assert(qnameType == QNameType.Xmlns, "");
  2554. i = attribute1.Namespace.Prefix.CompareTo(attribute2.Namespace.Prefix);
  2555. }
  2556. }
  2557. return i;
  2558. }
  2559. public int CompareQNameType(QNameType type1, QNameType type2)
  2560. {
  2561. return (int)type1 - (int)type2;
  2562. }
  2563. }
  2564. class NamespaceManager
  2565. {
  2566. XmlBufferReader bufferReader;
  2567. Namespace[] namespaces;
  2568. int nsCount;
  2569. int depth;
  2570. Namespace[] shortPrefixUri;
  2571. static Namespace emptyNamespace = new Namespace(XmlBufferReader.Empty);
  2572. static Namespace xmlNamespace;
  2573. XmlAttribute[] attributes;
  2574. int attributeCount;
  2575. XmlSpace space;
  2576. string lang;
  2577. public NamespaceManager(XmlBufferReader bufferReader)
  2578. {
  2579. this.bufferReader = bufferReader;
  2580. this.shortPrefixUri = new Namespace[(int)PrefixHandleType.Max];
  2581. this.shortPrefixUri[(int)PrefixHandleType.Empty] = emptyNamespace;
  2582. this.namespaces = null;
  2583. this.nsCount = 0;
  2584. this.attributes = null;
  2585. this.attributeCount = 0;
  2586. this.space = XmlSpace.None;
  2587. this.lang = string.Empty;
  2588. this.depth = 0;
  2589. }
  2590. public void Close()
  2591. {
  2592. if (namespaces != null && namespaces.Length > 32)
  2593. namespaces = null;
  2594. if (attributes != null && attributes.Length > 4)
  2595. attributes = null;
  2596. lang = string.Empty;
  2597. }
  2598. static public Namespace XmlNamespace
  2599. {
  2600. get
  2601. {
  2602. if (xmlNamespace == null)
  2603. {
  2604. byte[] xmlBuffer =
  2605. {
  2606. (byte)'x', (byte)'m', (byte)'l',
  2607. (byte)'h', (byte)'t', (byte)'t', (byte)'p', (byte)':', (byte)'/', (byte)'/', (byte)'w',
  2608. (byte)'w', (byte)'w', (byte)'.', (byte)'w', (byte)'3', (byte)'.', (byte)'o', (byte)'r',
  2609. (byte)'g', (byte)'/', (byte)'X', (byte)'M', (byte)'L', (byte)'/', (byte)'1', (byte)'9',
  2610. (byte)'9', (byte)'8', (byte)'/', (byte)'n', (byte)'a', (byte)'m', (byte)'e', (byte)'s',
  2611. (byte)'p', (byte)'a', (byte)'c', (byte)'e'
  2612. };
  2613. Namespace nameSpace = new Namespace(new XmlBufferReader(xmlBuffer));
  2614. nameSpace.Prefix.SetValue(0, 3);
  2615. nameSpace.Uri.SetValue(3, xmlBuffer.Length - 3);
  2616. xmlNamespace = nameSpace;
  2617. }
  2618. return xmlNamespace;
  2619. }
  2620. }
  2621. static public Namespace EmptyNamespace
  2622. {
  2623. get
  2624. {
  2625. return emptyNamespace;
  2626. }
  2627. }
  2628. public string XmlLang
  2629. {
  2630. get
  2631. {
  2632. return lang;
  2633. }
  2634. }
  2635. public XmlSpace XmlSpace
  2636. {
  2637. get
  2638. {
  2639. return space;
  2640. }
  2641. }
  2642. public void Clear()
  2643. {
  2644. if (nsCount != 0)
  2645. {
  2646. if (shortPrefixUri != null)
  2647. {
  2648. for (int i = 0; i < shortPrefixUri.Length; i++)
  2649. {
  2650. shortPrefixUri[i] = null;
  2651. }
  2652. }
  2653. shortPrefixUri[(int)PrefixHandleType.Empty] = emptyNamespace;
  2654. nsCount = 0;
  2655. }
  2656. this.attributeCount = 0;
  2657. this.space = XmlSpace.None;
  2658. this.lang = string.Empty;
  2659. this.depth = 0;
  2660. }
  2661. public void EnterScope()
  2662. {
  2663. depth++;
  2664. }
  2665. public void ExitScope()
  2666. {
  2667. while (nsCount > 0)
  2668. {
  2669. Namespace nameSpace = namespaces[nsCount - 1];
  2670. if (nameSpace.Depth != depth)
  2671. break;
  2672. PrefixHandleType shortPrefix;
  2673. if (nameSpace.Prefix.TryGetShortPrefix(out shortPrefix))
  2674. {
  2675. shortPrefixUri[(int)shortPrefix] = nameSpace.OuterUri;
  2676. }
  2677. nsCount--;
  2678. }
  2679. while (attributeCount > 0)
  2680. {
  2681. XmlAttribute attribute = attributes[attributeCount - 1];
  2682. if (attribute.Depth != depth)
  2683. break;
  2684. space = attribute.XmlSpace;
  2685. lang = attribute.XmlLang;
  2686. attributeCount--;
  2687. }
  2688. depth--;
  2689. }
  2690. public void Sign(XmlSigningNodeWriter writer)
  2691. {
  2692. for (int i = 0; i < nsCount; i++)
  2693. {
  2694. PrefixHandle prefix = namespaces[i].Prefix;
  2695. bool found = false;
  2696. for (int j = i + 1; j < nsCount; j++)
  2697. {
  2698. if (Equals(prefix, namespaces[j].Prefix))
  2699. {
  2700. found = true;
  2701. break;
  2702. }
  2703. }
  2704. if (!found)
  2705. {
  2706. int prefixOffset, prefixLength;
  2707. byte[] prefixBuffer = prefix.GetString(out prefixOffset, out prefixLength);
  2708. int nsOffset, nsLength;
  2709. byte[] nsBuffer = namespaces[i].Uri.GetString(out nsOffset, out nsLength);
  2710. writer.WriteXmlnsAttribute(prefixBuffer, prefixOffset, prefixLength, nsBuffer, nsOffset, nsLength);
  2711. }
  2712. }
  2713. }
  2714. public void AddLangAttribute(string lang)
  2715. {
  2716. AddAttribute();
  2717. this.lang = lang;
  2718. }
  2719. public void AddSpaceAttribute(XmlSpace space)
  2720. {
  2721. AddAttribute();
  2722. this.space = space;
  2723. }
  2724. void AddAttribute()
  2725. {
  2726. if (attributes == null)
  2727. {
  2728. attributes = new XmlAttribute[1];
  2729. }
  2730. else if (attributes.Length == attributeCount)
  2731. {
  2732. XmlAttribute[] newAttributes = new XmlAttribute[attributeCount * 2];
  2733. Array.Copy(attributes, newAttributes, attributeCount);
  2734. attributes = newAttributes;
  2735. }
  2736. XmlAttribute attribute = attributes[attributeCount];
  2737. if (attribute == null)
  2738. {
  2739. attribute = new XmlAttribute();
  2740. attributes[attributeCount] = attribute;
  2741. }
  2742. attribute.XmlLang = this.lang;
  2743. attribute.XmlSpace = this.space;
  2744. attribute.Depth = depth;
  2745. attributeCount++;
  2746. }
  2747. public void Register(Namespace nameSpace)
  2748. {
  2749. PrefixHandleType shortPrefix;
  2750. if (nameSpace.Prefix.TryGetShortPrefix(out shortPrefix))
  2751. {
  2752. nameSpace.OuterUri = shortPrefixUri[(int)shortPrefix];
  2753. shortPrefixUri[(int)shortPrefix] = nameSpace;
  2754. }
  2755. else
  2756. {
  2757. nameSpace.OuterUri = null;
  2758. }
  2759. }
  2760. public Namespace AddNamespace()
  2761. {
  2762. if (namespaces == null)
  2763. {
  2764. namespaces = new Namespace[4];
  2765. }
  2766. else if (namespaces.Length == nsCount)
  2767. {
  2768. Namespace[] newNamespaces = new Namespace[nsCount * 2];
  2769. Array.Copy(namespaces, newNamespaces, nsCount);
  2770. namespaces = newNamespaces;
  2771. }
  2772. Namespace nameSpace = namespaces[nsCount];
  2773. if (nameSpace == null)
  2774. {
  2775. nameSpace = new Namespace(bufferReader);
  2776. namespaces[nsCount] = nameSpace;
  2777. }
  2778. nameSpace.Clear();
  2779. nameSpace.Depth = depth;
  2780. nsCount++;
  2781. return nameSpace;
  2782. }
  2783. public Namespace LookupNamespace(PrefixHandleType prefix)
  2784. {
  2785. return shortPrefixUri[(int)prefix];
  2786. }
  2787. public Namespace LookupNamespace(PrefixHandle prefix)
  2788. {
  2789. PrefixHandleType shortPrefix;
  2790. if (prefix.TryGetShortPrefix(out shortPrefix))
  2791. return LookupNamespace(shortPrefix);
  2792. for (int i = nsCount - 1; i >= 0; i--)
  2793. {
  2794. Namespace nameSpace = namespaces[i];
  2795. if (nameSpace.Prefix == prefix)
  2796. return nameSpace;
  2797. }
  2798. if (prefix.IsXml)
  2799. return XmlNamespace;
  2800. return null;
  2801. }
  2802. public Namespace LookupNamespace(string prefix)
  2803. {
  2804. PrefixHandleType shortPrefix;
  2805. if (TryGetShortPrefix(prefix, out shortPrefix))
  2806. return LookupNamespace(shortPrefix);
  2807. for (int i = nsCount - 1; i >= 0; i--)
  2808. {
  2809. Namespace nameSpace = namespaces[i];
  2810. if (nameSpace.Prefix == prefix)
  2811. return nameSpace;
  2812. }
  2813. if (prefix == "xml")
  2814. return XmlNamespace;
  2815. return null;
  2816. }
  2817. bool TryGetShortPrefix(string s, out PrefixHandleType shortPrefix)
  2818. {
  2819. int length = s.Length;
  2820. if (length == 0)
  2821. {
  2822. shortPrefix = PrefixHandleType.Empty;
  2823. return true;
  2824. }
  2825. if (length == 1)
  2826. {
  2827. char ch = s[0];
  2828. if (ch >= 'a' && ch <= 'z')
  2829. {
  2830. shortPrefix = PrefixHandle.GetAlphaPrefix(ch - 'a');
  2831. return true;
  2832. }
  2833. }
  2834. shortPrefix = PrefixHandleType.Empty;
  2835. return false;
  2836. }
  2837. class XmlAttribute
  2838. {
  2839. XmlSpace space;
  2840. string lang;
  2841. int depth;
  2842. public XmlAttribute()
  2843. {
  2844. }
  2845. public int Depth
  2846. {
  2847. get
  2848. {
  2849. return depth;
  2850. }
  2851. set
  2852. {
  2853. depth = value;
  2854. }
  2855. }
  2856. public string XmlLang
  2857. {
  2858. get
  2859. {
  2860. return lang;
  2861. }
  2862. set
  2863. {
  2864. lang = value;
  2865. }
  2866. }
  2867. public XmlSpace XmlSpace
  2868. {
  2869. get
  2870. {
  2871. return space;
  2872. }
  2873. set
  2874. {
  2875. space = value;
  2876. }
  2877. }
  2878. }
  2879. }
  2880. protected class Namespace
  2881. {
  2882. PrefixHandle prefix;
  2883. StringHandle uri;
  2884. int depth;
  2885. Namespace outerUri;
  2886. string uriString;
  2887. public Namespace(XmlBufferReader bufferReader)
  2888. {
  2889. this.prefix = new PrefixHandle(bufferReader);
  2890. this.uri = new StringHandle(bufferReader);
  2891. this.outerUri = null;
  2892. this.uriString = null;
  2893. }
  2894. public void Clear()
  2895. {
  2896. this.uriString = null;
  2897. }
  2898. public int Depth
  2899. {
  2900. get
  2901. {
  2902. return depth;
  2903. }
  2904. set
  2905. {
  2906. depth = value;
  2907. }
  2908. }
  2909. public PrefixHandle Prefix
  2910. {
  2911. get
  2912. {
  2913. return prefix;
  2914. }
  2915. }
  2916. public bool IsUri(string s)
  2917. {
  2918. Fx.Assert(s != null, "");
  2919. if (object.ReferenceEquals(s, uriString))
  2920. return true;
  2921. if (uri == s)
  2922. {
  2923. uriString = s;
  2924. return true;
  2925. }
  2926. return false;
  2927. }
  2928. public bool IsUri(XmlDictionaryString s)
  2929. {
  2930. if (object.ReferenceEquals(s.Value, uriString))
  2931. return true;
  2932. if (uri == s)
  2933. {
  2934. uriString = s.Value;
  2935. return true;
  2936. }
  2937. return false;
  2938. }
  2939. public StringHandle Uri
  2940. {
  2941. get
  2942. {
  2943. return uri;
  2944. }
  2945. }
  2946. public Namespace OuterUri
  2947. {
  2948. get
  2949. {
  2950. return outerUri;
  2951. }
  2952. set
  2953. {
  2954. outerUri = value;
  2955. }
  2956. }
  2957. }
  2958. class QuotaNameTable : XmlNameTable
  2959. {
  2960. XmlDictionaryReader reader;
  2961. XmlNameTable nameTable;
  2962. int maxCharCount;
  2963. int charCount;
  2964. public QuotaNameTable(XmlDictionaryReader reader, int maxCharCount)
  2965. {
  2966. this.reader = reader;
  2967. this.nameTable = new NameTable();
  2968. this.maxCharCount = maxCharCount;
  2969. this.charCount = 0;
  2970. }
  2971. public override string Get(char[] chars, int offset, int count)
  2972. {
  2973. return nameTable.Get(chars, offset, count);
  2974. }
  2975. public override string Get(string value)
  2976. {
  2977. return nameTable.Get(value);
  2978. }
  2979. void Add(int charCount)
  2980. {
  2981. if (charCount > this.maxCharCount - this.charCount)
  2982. XmlExceptionHelper.ThrowMaxNameTableCharCountExceeded(reader, maxCharCount);
  2983. this.charCount += charCount;
  2984. }
  2985. public override string Add(char[] chars, int offset, int count)
  2986. {
  2987. string s = nameTable.Get(chars, offset, count);
  2988. if (s != null)
  2989. return s;
  2990. Add(count);
  2991. return nameTable.Add(chars, offset, count);
  2992. }
  2993. public override string Add(string value)
  2994. {
  2995. string s = nameTable.Get(value);
  2996. if (s != null)
  2997. return s;
  2998. Add(value.Length);
  2999. return nameTable.Add(value);
  3000. }
  3001. }
  3002. }
  3003. }