| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.Runtime.Serialization.Json
- {
- using System.Globalization;
- using System.IO;
- using System.ServiceModel;
- using System.Text;
- using System.Runtime.Serialization;
- using System.Collections.Generic;
- using System.Xml;
- class XmlJsonReader : XmlBaseReader, IXmlJsonReaderInitializer
- {
- const int MaxTextChunk = 2048;
- static byte[] charType = new byte[256]
- {
- CharType.None, // 0 (.)
- CharType.None, // 1 (.)
- CharType.None, // 2 (.)
- CharType.None, // 3 (.)
- CharType.None, // 4 (.)
- CharType.None, // 5 (.)
- CharType.None, // 6 (.)
- CharType.None, // 7 (.)
- CharType.None, // 8 (.)
- CharType.None, // 9 (.)
- CharType.None, // A (.)
- CharType.None, // B (.)
- CharType.None, // C (.)
- CharType.None, // D (.)
- CharType.None, // E (.)
- CharType.None, // F (.)
- CharType.None, // 10 (.)
- CharType.None, // 11 (.)
- CharType.None, // 12 (.)
- CharType.None, // 13 (.)
- CharType.None, // 14 (.)
- CharType.None, // 15 (.)
- CharType.None, // 16 (.)
- CharType.None, // 17 (.)
- CharType.None, // 18 (.)
- CharType.None, // 19 (.)
- CharType.None, // 1A (.)
- CharType.None, // 1B (.)
- CharType.None, // 1C (.)
- CharType.None, // 1D (.)
- CharType.None, // 1E (.)
- CharType.None, // 1F (.)
- CharType.None, // 20 ( )
- CharType.None, // 21 (!)
- CharType.None, // 22 (")
- CharType.None, // 23 (#)
- CharType.None, // 24 ($)
- CharType.None, // 25 (%)
- CharType.None, // 26 (&)
- CharType.None, // 27 (')
- CharType.None, // 28 (()
- CharType.None, // 29 ())
- CharType.None, // 2A (*)
- CharType.None, // 2B (+)
- CharType.None, // 2C (,)
- CharType.None | CharType.Name, // 2D (-)
- CharType.None | CharType.Name, // 2E (.)
- CharType.None, // 2F (/)
- CharType.None | CharType.Name, // 30 (0)
- CharType.None | CharType.Name, // 31 (1)
- CharType.None | CharType.Name, // 32 (2)
- CharType.None | CharType.Name, // 33 (3)
- CharType.None | CharType.Name, // 34 (4)
- CharType.None | CharType.Name, // 35 (5)
- CharType.None | CharType.Name, // 36 (6)
- CharType.None | CharType.Name, // 37 (7)
- CharType.None | CharType.Name, // 38 (8)
- CharType.None | CharType.Name, // 39 (9)
- CharType.None, // 3A (:)
- CharType.None, // 3B (;)
- CharType.None, // 3C (<)
- CharType.None, // 3D (=)
- CharType.None, // 3E (>)
- CharType.None, // 3F (?)
- CharType.None, // 40 (@)
- CharType.None | CharType.FirstName | CharType.Name, // 41 (A)
- CharType.None | CharType.FirstName | CharType.Name, // 42 (B)
- CharType.None | CharType.FirstName | CharType.Name, // 43 (C)
- CharType.None | CharType.FirstName | CharType.Name, // 44 (D)
- CharType.None | CharType.FirstName | CharType.Name, // 45 (E)
- CharType.None | CharType.FirstName | CharType.Name, // 46 (F)
- CharType.None | CharType.FirstName | CharType.Name, // 47 (G)
- CharType.None | CharType.FirstName | CharType.Name, // 48 (H)
- CharType.None | CharType.FirstName | CharType.Name, // 49 (I)
- CharType.None | CharType.FirstName | CharType.Name, // 4A (J)
- CharType.None | CharType.FirstName | CharType.Name, // 4B (K)
- CharType.None | CharType.FirstName | CharType.Name, // 4C (L)
- CharType.None | CharType.FirstName | CharType.Name, // 4D (M)
- CharType.None | CharType.FirstName | CharType.Name, // 4E (N)
- CharType.None | CharType.FirstName | CharType.Name, // 4F (O)
- CharType.None | CharType.FirstName | CharType.Name, // 50 (P)
- CharType.None | CharType.FirstName | CharType.Name, // 51 (Q)
- CharType.None | CharType.FirstName | CharType.Name, // 52 (R)
- CharType.None | CharType.FirstName | CharType.Name, // 53 (S)
- CharType.None | CharType.FirstName | CharType.Name, // 54 (T)
- CharType.None | CharType.FirstName | CharType.Name, // 55 (U)
- CharType.None | CharType.FirstName | CharType.Name, // 56 (V)
- CharType.None | CharType.FirstName | CharType.Name, // 57 (W)
- CharType.None | CharType.FirstName | CharType.Name, // 58 (X)
- CharType.None | CharType.FirstName | CharType.Name, // 59 (Y)
- CharType.None | CharType.FirstName | CharType.Name, // 5A (Z)
- CharType.None, // 5B ([)
- CharType.None, // 5C (\)
- CharType.None, // 5D (])
- CharType.None, // 5E (^)
- CharType.None | CharType.FirstName | CharType.Name, // 5F (_)
- CharType.None, // 60 (`)
- CharType.None | CharType.FirstName | CharType.Name, // 61 (a)
- CharType.None | CharType.FirstName | CharType.Name, // 62 (b)
- CharType.None | CharType.FirstName | CharType.Name, // 63 (c)
- CharType.None | CharType.FirstName | CharType.Name, // 64 (d)
- CharType.None | CharType.FirstName | CharType.Name, // 65 (e)
- CharType.None | CharType.FirstName | CharType.Name, // 66 (f)
- CharType.None | CharType.FirstName | CharType.Name, // 67 (g)
- CharType.None | CharType.FirstName | CharType.Name, // 68 (h)
- CharType.None | CharType.FirstName | CharType.Name, // 69 (i)
- CharType.None | CharType.FirstName | CharType.Name, // 6A (j)
- CharType.None | CharType.FirstName | CharType.Name, // 6B (k)
- CharType.None | CharType.FirstName | CharType.Name, // 6C (l)
- CharType.None | CharType.FirstName | CharType.Name, // 6D (m)
- CharType.None | CharType.FirstName | CharType.Name, // 6E (n)
- CharType.None | CharType.FirstName | CharType.Name, // 6F (o)
- CharType.None | CharType.FirstName | CharType.Name, // 70 (p)
- CharType.None | CharType.FirstName | CharType.Name, // 71 (q)
- CharType.None | CharType.FirstName | CharType.Name, // 72 (r)
- CharType.None | CharType.FirstName | CharType.Name, // 73 (s)
- CharType.None | CharType.FirstName | CharType.Name, // 74 (t)
- CharType.None | CharType.FirstName | CharType.Name, // 75 (u)
- CharType.None | CharType.FirstName | CharType.Name, // 76 (v)
- CharType.None | CharType.FirstName | CharType.Name, // 77 (w)
- CharType.None | CharType.FirstName | CharType.Name, // 78 (x)
- CharType.None | CharType.FirstName | CharType.Name, // 79 (y)
- CharType.None | CharType.FirstName | CharType.Name, // 7A (z)
- CharType.None, // 7B ({)
- CharType.None, // 7C (|)
- CharType.None, // 7D (})
- CharType.None, // 7E (~)
- CharType.None, // 7F (.)
- CharType.None | CharType.FirstName | CharType.Name, // 80 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 81 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 82 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 83 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 84 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 85 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 86 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 87 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 88 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 89 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 8A (.)
- CharType.None | CharType.FirstName | CharType.Name, // 8B (.)
- CharType.None | CharType.FirstName | CharType.Name, // 8C (.)
- CharType.None | CharType.FirstName | CharType.Name, // 8D (.)
- CharType.None | CharType.FirstName | CharType.Name, // 8E (.)
- CharType.None | CharType.FirstName | CharType.Name, // 8F (.)
- CharType.None | CharType.FirstName | CharType.Name, // 90 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 91 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 92 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 93 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 94 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 95 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 96 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 97 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 98 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 99 (.)
- CharType.None | CharType.FirstName | CharType.Name, // 9A (.)
- CharType.None | CharType.FirstName | CharType.Name, // 9B (.)
- CharType.None | CharType.FirstName | CharType.Name, // 9C (.)
- CharType.None | CharType.FirstName | CharType.Name, // 9D (.)
- CharType.None | CharType.FirstName | CharType.Name, // 9E (.)
- CharType.None | CharType.FirstName | CharType.Name, // 9F (.)
- CharType.None | CharType.FirstName | CharType.Name, // A0 (�)
- CharType.None | CharType.FirstName | CharType.Name, // A1 (�)
- CharType.None | CharType.FirstName | CharType.Name, // A2 (�)
- CharType.None | CharType.FirstName | CharType.Name, // A3 (�)
- CharType.None | CharType.FirstName | CharType.Name, // A4 ()
- CharType.None | CharType.FirstName | CharType.Name, // A5 (�)
- CharType.None | CharType.FirstName | CharType.Name, // A6 (�)
- CharType.None | CharType.FirstName | CharType.Name, // A7 ()
- CharType.None | CharType.FirstName | CharType.Name, // A8 (")
- CharType.None | CharType.FirstName | CharType.Name, // A9 (c)
- CharType.None | CharType.FirstName | CharType.Name, // AA (�)
- CharType.None | CharType.FirstName | CharType.Name, // AB (�)
- CharType.None | CharType.FirstName | CharType.Name, // AC (�)
- CharType.None | CharType.FirstName | CharType.Name, // AD (-)
- CharType.None | CharType.FirstName | CharType.Name, // AE (r)
- CharType.None | CharType.FirstName | CharType.Name, // AF (_)
- CharType.None | CharType.FirstName | CharType.Name, // B0 (�)
- CharType.None | CharType.FirstName | CharType.Name, // B1 (�)
- CharType.None | CharType.FirstName | CharType.Name, // B2 (�)
- CharType.None | CharType.FirstName | CharType.Name, // B3 (3)
- CharType.None | CharType.FirstName | CharType.Name, // B4 (')
- CharType.None | CharType.FirstName | CharType.Name, // B5 (�)
- CharType.None | CharType.FirstName | CharType.Name, // B6 ()
- CharType.None | CharType.FirstName | CharType.Name, // B7 (�)
- CharType.None | CharType.FirstName | CharType.Name, // B8 (,)
- CharType.None | CharType.FirstName | CharType.Name, // B9 (1)
- CharType.None | CharType.FirstName | CharType.Name, // BA (�)
- CharType.None | CharType.FirstName | CharType.Name, // BB (�)
- CharType.None | CharType.FirstName | CharType.Name, // BC (�)
- CharType.None | CharType.FirstName | CharType.Name, // BD (�)
- CharType.None | CharType.FirstName | CharType.Name, // BE (_)
- CharType.None | CharType.FirstName | CharType.Name, // BF (�)
- CharType.None | CharType.FirstName | CharType.Name, // C0 (A)
- CharType.None | CharType.FirstName | CharType.Name, // C1 (A)
- CharType.None | CharType.FirstName | CharType.Name, // C2 (A)
- CharType.None | CharType.FirstName | CharType.Name, // C3 (A)
- CharType.None | CharType.FirstName | CharType.Name, // C4 (�)
- CharType.None | CharType.FirstName | CharType.Name, // C5 (�)
- CharType.None | CharType.FirstName | CharType.Name, // C6 (�)
- CharType.None | CharType.FirstName | CharType.Name, // C7 (�)
- CharType.None | CharType.FirstName | CharType.Name, // C8 (E)
- CharType.None | CharType.FirstName | CharType.Name, // C9 (�)
- CharType.None | CharType.FirstName | CharType.Name, // CA (E)
- CharType.None | CharType.FirstName | CharType.Name, // CB (E)
- CharType.None | CharType.FirstName | CharType.Name, // CC (I)
- CharType.None | CharType.FirstName | CharType.Name, // CD (I)
- CharType.None | CharType.FirstName | CharType.Name, // CE (I)
- CharType.None | CharType.FirstName | CharType.Name, // CF (I)
- CharType.None | CharType.FirstName | CharType.Name, // D0 (D)
- CharType.None | CharType.FirstName | CharType.Name, // D1 (�)
- CharType.None | CharType.FirstName | CharType.Name, // D2 (O)
- CharType.None | CharType.FirstName | CharType.Name, // D3 (O)
- CharType.None | CharType.FirstName | CharType.Name, // D4 (O)
- CharType.None | CharType.FirstName | CharType.Name, // D5 (O)
- CharType.None | CharType.FirstName | CharType.Name, // D6 (�)
- CharType.None | CharType.FirstName | CharType.Name, // D7 (x)
- CharType.None | CharType.FirstName | CharType.Name, // D8 (O)
- CharType.None | CharType.FirstName | CharType.Name, // D9 (U)
- CharType.None | CharType.FirstName | CharType.Name, // DA (U)
- CharType.None | CharType.FirstName | CharType.Name, // DB (U)
- CharType.None | CharType.FirstName | CharType.Name, // DC (�)
- CharType.None | CharType.FirstName | CharType.Name, // DD (Y)
- CharType.None | CharType.FirstName | CharType.Name, // DE (_)
- CharType.None | CharType.FirstName | CharType.Name, // DF (�)
- CharType.None | CharType.FirstName | CharType.Name, // E0 (�)
- CharType.None | CharType.FirstName | CharType.Name, // E1 (�)
- CharType.None | CharType.FirstName | CharType.Name, // E2 (�)
- CharType.None | CharType.FirstName | CharType.Name, // E3 (a)
- CharType.None | CharType.FirstName | CharType.Name, // E4 (�)
- CharType.None | CharType.FirstName | CharType.Name, // E5 (�)
- CharType.None | CharType.FirstName | CharType.Name, // E6 (�)
- CharType.None | CharType.FirstName | CharType.Name, // E7 (�)
- CharType.None | CharType.FirstName | CharType.Name, // E8 (�)
- CharType.None | CharType.FirstName | CharType.Name, // E9 (�)
- CharType.None | CharType.FirstName | CharType.Name, // EA (�)
- CharType.None | CharType.FirstName | CharType.Name, // EB (�)
- CharType.None | CharType.FirstName | CharType.Name, // EC (�)
- CharType.None | CharType.FirstName | CharType.Name, // ED (�)
- CharType.None | CharType.FirstName | CharType.Name, // EE (�)
- CharType.None | CharType.FirstName | CharType.Name, // EF (�)
- CharType.None | CharType.FirstName | CharType.Name, // F0 (d)
- CharType.None | CharType.FirstName | CharType.Name, // F1 (�)
- CharType.None | CharType.FirstName | CharType.Name, // F2 (�)
- CharType.None | CharType.FirstName | CharType.Name, // F3 (�)
- CharType.None | CharType.FirstName | CharType.Name, // F4 (�)
- CharType.None | CharType.FirstName | CharType.Name, // F5 (o)
- CharType.None | CharType.FirstName | CharType.Name, // F6 (�)
- CharType.None | CharType.FirstName | CharType.Name, // F7 (�)
- CharType.None | CharType.FirstName | CharType.Name, // F8 (o)
- CharType.None | CharType.FirstName | CharType.Name, // F9 (�)
- CharType.None | CharType.FirstName | CharType.Name, // FA (�)
- CharType.None | CharType.FirstName | CharType.Name, // FB (�)
- CharType.None | CharType.FirstName | CharType.Name, // FC (�)
- CharType.None | CharType.FirstName | CharType.Name, // FD (y)
- CharType.None | CharType.FirstName | CharType.Name, // FE (_)
- CharType.None | CharType.FirstName | CharType.Name, // FF (�)
- };
- bool buffered;
- byte[] charactersToSkipOnNextRead;
- JsonComplexTextMode complexTextMode = JsonComplexTextMode.None;
- bool expectingFirstElementInNonPrimitiveChild;
- int maxBytesPerRead;
- OnXmlDictionaryReaderClose onReaderClose;
- bool readServerTypeElement = false;
- int scopeDepth = 0;
- JsonNodeType[] scopes;
- enum JsonComplexTextMode
- {
- QuotedText,
- NumericalText,
- None
- };
- public override bool CanCanonicalize
- {
- get
- {
- return false;
- }
- }
- public override string Value
- {
- get
- {
- if (IsAttributeValue && !this.IsLocalName(JsonGlobals.typeString))
- {
- return UnescapeJsonString(base.Value);
- }
- return base.Value;
- }
- }
- bool IsAttributeValue
- {
- get
- {
- return (this.Node.NodeType == XmlNodeType.Attribute || this.Node is XmlAttributeTextNode);
- }
- }
- bool IsReadingCollection
- {
- get
- {
- return ((scopeDepth > 0) && (scopes[scopeDepth] == JsonNodeType.Collection));
- }
- }
- bool IsReadingComplexText
- {
- get
- {
- return ((!this.Node.IsAtomicValue) &&
- (this.Node.NodeType == XmlNodeType.Text));
- }
- }
- public override void Close()
- {
- base.Close();
- OnXmlDictionaryReaderClose onClose = this.onReaderClose;
- this.onReaderClose = null;
- ResetState();
- if (onClose != null)
- {
- try
- {
- onClose(this);
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e);
- }
- }
- }
- public override void EndCanonicalization()
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
- }
- public override string GetAttribute(int index)
- {
- return UnescapeJsonString(base.GetAttribute(index));
- }
- public override string GetAttribute(string localName, string namespaceUri)
- {
- if (localName != JsonGlobals.typeString)
- {
- return UnescapeJsonString(base.GetAttribute(localName, namespaceUri));
- }
- return base.GetAttribute(localName, namespaceUri);
- }
- public override string GetAttribute(string name)
- {
- if (name != JsonGlobals.typeString)
- {
- return UnescapeJsonString(base.GetAttribute(name));
- }
- return base.GetAttribute(name);
- }
- public override string GetAttribute(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
- {
- if (XmlDictionaryString.GetString(localName) != JsonGlobals.typeString)
- {
- return UnescapeJsonString(base.GetAttribute(localName, namespaceUri));
- }
- return base.GetAttribute(localName, namespaceUri);
- }
- public override bool Read()
- {
- if (this.Node.CanMoveToElement)
- {
- // If we're positioned on an attribute or attribute text on an empty element, we need to move back
- // to the element in order to get the correct setting of ExitScope
- MoveToElement();
- }
- if (this.Node.ReadState == ReadState.Closed)
- {
- return false;
- }
- if (this.Node.ExitScope)
- {
- ExitScope();
- }
- if (!buffered)
- {
- BufferReader.SetWindow(ElementNode.BufferOffset, this.maxBytesPerRead);
- }
- byte ch;
- // Skip whitespace before checking EOF
- // Complex text check necessary because whitespace could be part of really long
- // quoted text that's read using multiple Read() calls.
- // This also ensures that we deal with the whitespace-only input case properly by not
- // floating a root element at all.
- if (!IsReadingComplexText)
- {
- SkipWhitespaceInBufferReader();
- if (TryGetByte(out ch))
- {
- if (charactersToSkipOnNextRead[0] == ch || charactersToSkipOnNextRead[1] == ch)
- {
- BufferReader.SkipByte();
- charactersToSkipOnNextRead[0] = 0;
- charactersToSkipOnNextRead[1] = 0;
- }
- }
- SkipWhitespaceInBufferReader();
- if (TryGetByte(out ch))
- {
- if (ch == JsonGlobals.EndCollectionByte && IsReadingCollection)
- {
- BufferReader.SkipByte();
- SkipWhitespaceInBufferReader();
- ExitJsonScope();
- }
- }
- if (BufferReader.EndOfFile)
- {
- if (scopeDepth > 0)
- {
- MoveToEndElement();
- return true;
- }
- else
- {
- MoveToEndOfFile();
- return false;
- }
- }
- }
- ch = BufferReader.GetByte();
- if (scopeDepth == 0)
- {
- ReadNonExistentElementName(StringHandleConstStringType.Root);
- }
- else if (IsReadingComplexText)
- {
- switch (complexTextMode)
- {
- case JsonComplexTextMode.NumericalText:
- ReadNumericalText();
- break;
- case JsonComplexTextMode.QuotedText:
- if (ch == (byte)'\\')
- {
- ReadEscapedCharacter(true); // moveToText
- }
- else
- {
- ReadQuotedText(true); // moveToText
- }
- break;
- case JsonComplexTextMode.None:
- XmlExceptionHelper.ThrowXmlException(this,
- new XmlException(SR.GetString(SR.JsonEncounteredUnexpectedCharacter, (char)ch)));
- break;
- }
- }
- else if (IsReadingCollection)
- {
- ReadNonExistentElementName(StringHandleConstStringType.Item);
- }
- else if (ch == JsonGlobals.EndCollectionByte)
- {
- BufferReader.SkipByte();
- MoveToEndElement();
- ExitJsonScope();
- }
- else if (ch == JsonGlobals.ObjectByte)
- {
- BufferReader.SkipByte();
- SkipWhitespaceInBufferReader();
- ch = (byte)BufferReader.GetByte();
- if (ch == JsonGlobals.EndObjectByte)
- {
- BufferReader.SkipByte();
- SkipWhitespaceInBufferReader();
- if (TryGetByte(out ch))
- {
- if (ch == JsonGlobals.MemberSeparatorByte)
- {
- BufferReader.SkipByte();
- }
- }
- else
- {
- charactersToSkipOnNextRead[0] = JsonGlobals.MemberSeparatorByte;
- }
- MoveToEndElement();
- }
- else
- {
- EnterJsonScope(JsonNodeType.Object);
- ParseStartElement();
- }
- }
- else if (ch == JsonGlobals.EndObjectByte)
- {
- BufferReader.SkipByte();
- if (expectingFirstElementInNonPrimitiveChild)
- {
- SkipWhitespaceInBufferReader();
- ch = BufferReader.GetByte();
- if ((ch == JsonGlobals.MemberSeparatorByte) ||
- (ch == JsonGlobals.EndObjectByte))
- {
- BufferReader.SkipByte();
- }
- else
- {
- XmlExceptionHelper.ThrowXmlException(this,
- new XmlException(SR.GetString(SR.JsonEncounteredUnexpectedCharacter,
- (char)ch)));
- }
- expectingFirstElementInNonPrimitiveChild = false;
- }
- MoveToEndElement();
- }
- else if (ch == JsonGlobals.MemberSeparatorByte)
- {
- BufferReader.SkipByte();
- MoveToEndElement();
- }
- else if (ch == JsonGlobals.QuoteByte)
- {
- if (readServerTypeElement)
- {
- readServerTypeElement = false;
- EnterJsonScope(JsonNodeType.Object);
- ParseStartElement();
- }
- else if (this.Node.NodeType == XmlNodeType.Element)
- {
- if (expectingFirstElementInNonPrimitiveChild)
- {
- EnterJsonScope(JsonNodeType.Object);
- ParseStartElement();
- }
- else
- {
- BufferReader.SkipByte();
- ReadQuotedText(true); // moveToText
- }
- }
- else if (this.Node.NodeType == XmlNodeType.EndElement)
- {
- EnterJsonScope(JsonNodeType.Element);
- ParseStartElement();
- }
- else
- {
- XmlExceptionHelper.ThrowXmlException(this,
- new XmlException(SR.GetString(SR.JsonEncounteredUnexpectedCharacter,
- JsonGlobals.QuoteChar)));
- }
- }
- else if (ch == (byte)'f')
- {
- int offset;
- byte[] buffer = BufferReader.GetBuffer(5, out offset);
- if (buffer[offset + 1] != (byte)'a' ||
- buffer[offset + 2] != (byte)'l' ||
- buffer[offset + 3] != (byte)'s' ||
- buffer[offset + 4] != (byte)'e')
- {
- XmlExceptionHelper.ThrowTokenExpected(this, "false", Encoding.UTF8.GetString(buffer, offset, 5));
- }
- BufferReader.Advance(5);
- if (TryGetByte(out ch))
- {
- if (!IsWhitespace(ch) && ch != JsonGlobals.MemberSeparatorByte && ch != JsonGlobals.EndObjectChar && ch != JsonGlobals.EndCollectionByte)
- {
- XmlExceptionHelper.ThrowTokenExpected(this, "false", Encoding.UTF8.GetString(buffer, offset, 4) + (char)ch);
- }
- }
- MoveToAtomicText().Value.SetValue(ValueHandleType.UTF8, offset, 5);
- }
- else if (ch == (byte)'t')
- {
- int offset;
- byte[] buffer = BufferReader.GetBuffer(4, out offset);
- if (buffer[offset + 1] != (byte)'r' ||
- buffer[offset + 2] != (byte)'u' ||
- buffer[offset + 3] != (byte)'e')
- {
- XmlExceptionHelper.ThrowTokenExpected(this, "true", Encoding.UTF8.GetString(buffer, offset, 4));
- }
- BufferReader.Advance(4);
- if (TryGetByte(out ch))
- {
- if (!IsWhitespace(ch) && ch != JsonGlobals.MemberSeparatorByte && ch != JsonGlobals.EndObjectChar && ch != JsonGlobals.EndCollectionByte)
- {
- XmlExceptionHelper.ThrowTokenExpected(this, "true", Encoding.UTF8.GetString(buffer, offset, 4) + (char)ch);
- }
- }
- MoveToAtomicText().Value.SetValue(ValueHandleType.UTF8, offset, 4);
- }
- else if (ch == (byte)'n')
- {
- int offset;
- byte[] buffer = BufferReader.GetBuffer(4, out offset);
- if (buffer[offset + 1] != (byte)'u' ||
- buffer[offset + 2] != (byte)'l' ||
- buffer[offset + 3] != (byte)'l')
- {
- XmlExceptionHelper.ThrowTokenExpected(this, "null", Encoding.UTF8.GetString(buffer, offset, 4));
- }
- BufferReader.Advance(4);
- SkipWhitespaceInBufferReader();
- if (TryGetByte(out ch))
- {
- if (ch == JsonGlobals.MemberSeparatorByte || ch == JsonGlobals.EndObjectChar)
- {
- BufferReader.SkipByte();
- }
- else if (ch != JsonGlobals.EndCollectionByte)
- {
- XmlExceptionHelper.ThrowTokenExpected(this, "null", Encoding.UTF8.GetString(buffer, offset, 4) + (char)ch);
- }
- }
- else
- {
- charactersToSkipOnNextRead[0] = JsonGlobals.MemberSeparatorByte;
- charactersToSkipOnNextRead[1] = JsonGlobals.EndObjectByte;
- }
- MoveToEndElement();
- }
- else if ((ch == (byte)'-') ||
- (((byte)'0' <= ch) && (ch <= (byte)'9')) ||
- (ch == (byte)'I') ||
- (ch == (byte)'N'))
- {
- ReadNumericalText();
- }
- else
- {
- XmlExceptionHelper.ThrowXmlException(this,
- new XmlException(SR.GetString(SR.JsonEncounteredUnexpectedCharacter, (char)ch)));
- }
- return true;
- }
- public override decimal ReadContentAsDecimal()
- {
- string value = ReadContentAsString();
- try
- {
- return decimal.Parse(value, NumberStyles.Float, NumberFormatInfo.InvariantInfo);
- }
- catch (ArgumentException exception)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "decimal", exception));
- }
- catch (FormatException exception)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "decimal", exception));
- }
- catch (OverflowException exception)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "decimal", exception));
- }
- }
- public override int ReadContentAsInt()
- {
- return ParseInt(ReadContentAsString(), NumberStyles.Float);
- }
- public override long ReadContentAsLong()
- {
- string value = ReadContentAsString();
- try
- {
- return long.Parse(value, NumberStyles.Float, NumberFormatInfo.InvariantInfo);
- }
- catch (ArgumentException exception)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "Int64", exception));
- }
- catch (FormatException exception)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "Int64", exception));
- }
- catch (OverflowException exception)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "Int64", exception));
- }
- }
- public override int ReadValueAsBase64(byte[] buffer, int offset, int count)
- {
- if (IsAttributeValue)
- {
- if (buffer == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer"));
- }
- if (offset < 0)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ValueMustBeNonNegative)));
- }
- if (offset > buffer.Length)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.OffsetExceedsBufferSize, buffer.Length)));
- }
- if (count < 0)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ValueMustBeNonNegative)));
- }
- if (count > buffer.Length - offset)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.SizeExceedsRemainingBufferSpace, buffer.Length - offset)));
- }
- return 0;
- }
- return base.ReadValueAsBase64(buffer, offset, count);
- }
- public override int ReadValueChunk(char[] chars, int offset, int count)
- {
- if (IsAttributeValue)
- {
- if (chars == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars"));
- }
- if (offset < 0)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ValueMustBeNonNegative)));
- }
- if (offset > chars.Length)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.OffsetExceedsBufferSize, chars.Length)));
- }
- if (count < 0)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ValueMustBeNonNegative)));
- }
- if (count > chars.Length - offset)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.SizeExceedsRemainingBufferSpace, chars.Length - offset)));
- }
- int actual;
- string value = UnescapeJsonString(this.Node.ValueAsString);
- actual = Math.Min(count, value.Length);
- if (actual > 0)
- {
- value.CopyTo(0, chars, offset, actual);
- if (this.Node.QNameType == QNameType.Xmlns)
- {
- this.Node.Namespace.Uri.SetValue(0, 0);
- }
- else
- {
- this.Node.Value.SetValue(ValueHandleType.UTF8, 0, 0);
- }
- }
- return actual;
- }
- return base.ReadValueChunk(chars, offset, count);
- }
- public void SetInput(byte[] buffer, int offset, int count, Encoding encoding, XmlDictionaryReaderQuotas quotas,
- OnXmlDictionaryReaderClose onClose)
- {
- if (buffer == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("buffer");
- }
- if (offset < 0)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative)));
- }
- if (offset > buffer.Length)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new ArgumentOutOfRangeException("offset",
- SR.GetString(SR.JsonOffsetExceedsBufferSize, buffer.Length)));
- }
- if (count < 0)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative)));
- }
- if (count > buffer.Length - offset)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new ArgumentOutOfRangeException("count",
- SR.GetString(SR.JsonSizeExceedsRemainingBufferSpace,
- buffer.Length - offset)));
- }
- MoveToInitial(quotas, onClose);
- ArraySegment<byte> seg = JsonEncodingStreamWrapper.ProcessBuffer(buffer, offset, count, encoding);
- BufferReader.SetBuffer(seg.Array, seg.Offset, seg.Count, null, null);
- this.buffered = true;
- ResetState();
- }
- public void SetInput(Stream stream, Encoding encoding, XmlDictionaryReaderQuotas quotas,
- OnXmlDictionaryReaderClose onClose)
- {
- if (stream == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("stream");
- }
- MoveToInitial(quotas, onClose);
- stream = new JsonEncodingStreamWrapper(stream, encoding, true);
- BufferReader.SetBuffer(stream, null, null);
- this.buffered = false;
- ResetState();
- }
- public override void StartCanonicalization(Stream stream, bool includeComments, string[] inclusivePrefixes)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
- }
- internal static void CheckArray(Array array, int offset, int count)
- {
- if (array == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("array"));
- }
- if (offset < 0)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.ValueMustBeNonNegative)));
- }
- if (offset > array.Length)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR.GetString(SR.OffsetExceedsBufferSize, array.Length)));
- }
- if (count < 0)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.ValueMustBeNonNegative)));
- }
- if (count > array.Length - offset)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR.GetString(SR.SizeExceedsRemainingBufferSpace, array.Length - offset)));
- }
- }
- protected override XmlSigningNodeWriter CreateSigningNodeWriter()
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.JsonMethodNotSupported, "CreateSigningNodeWriter")));
- }
- static int BreakText(byte[] buffer, int offset, int length)
- {
- // See if we might be breaking a utf8 sequence
- if (length > 0 && (buffer[offset + length - 1] & 0x80) == 0x80)
- {
- // Find the lead char of the utf8 sequence (0x11xxxxxx)
- int originalLength = length;
- do
- {
- length--;
- } while (length > 0 && (buffer[offset + length] & 0xC0) != 0xC0);
- // Couldn't find the lead char
- if (length == 0)
- {
- return originalLength; // Invalid utf8 sequence - can't break
- }
- // Count how many bytes follow the lead char
- byte b = (byte)(buffer[offset + length] << 2);
- int byteCount = 2;
- while ((b & 0x80) == 0x80)
- {
- b = (byte)(b << 1);
- byteCount++;
- // There shouldn't be more than 3 bytes following the lead char
- if (byteCount > 4)
- {
- return originalLength; // Invalid utf8 sequence - can't break
- }
- }
- if (length + byteCount == originalLength)
- {
- return originalLength; // sequence fits exactly
- }
- if (length == 0)
- {
- return originalLength; // Quota too small to read a char
- }
- }
- return length;
- }
- static int ComputeNumericalTextLength(byte[] buffer, int offset, int offsetMax)
- {
- int beginOffset = offset;
- while (offset < offsetMax)
- {
- byte ch = buffer[offset];
- if (ch == JsonGlobals.MemberSeparatorByte || ch == JsonGlobals.EndObjectByte || ch == JsonGlobals.EndCollectionByte
- || IsWhitespace(ch))
- {
- break;
- }
- offset++;
- }
- return offset - beginOffset;
- }
- static int ComputeQuotedTextLengthUntilEndQuote(byte[] buffer, int offset, int offsetMax, out bool escaped)
- {
- // Assumes that for quoted text "someText", the first " has been consumed.
- // For original text "someText", buffer passed in is someText".
- // This method returns return 8 for someText" (s, o, m, e, T, e, x, t).
- int beginOffset = offset;
- escaped = false;
- while (offset < offsetMax)
- {
- byte ch = buffer[offset];
- if (ch < 0x20)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.GetString(SR.InvalidCharacterEncountered, (char)ch)));
- }
- else if (ch == (byte)'\\' || ch == 0xEF)
- {
- escaped = true;
- break;
- }
- else if (ch == JsonGlobals.QuoteByte)
- {
- break;
- }
- offset++;
- }
- return offset - beginOffset;
- }
- // From JSON spec:
- // ws = *(
- // %x20 / ; Space
- // %x09 / ; Horizontal tab
- // %x0A / ; Line feed or New line
- // %x0D ; Carriage return
- // )
- static bool IsWhitespace(byte ch)
- {
- return ((ch == 0x20) || (ch == 0x09) || (ch == 0x0A) || (ch == 0x0D));
- }
- static char ParseChar(string value, NumberStyles style)
- {
- int intValue = ParseInt(value, style);
- try
- {
- return Convert.ToChar(intValue);
- }
- catch (OverflowException exception)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "char", exception));
- }
- }
- static int ParseInt(string value, NumberStyles style)
- {
- try
- {
- return int.Parse(value, style, NumberFormatInfo.InvariantInfo);
- }
- catch (ArgumentException exception)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "Int32", exception));
- }
- catch (FormatException exception)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "Int32", exception));
- }
- catch (OverflowException exception)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "Int32", exception));
- }
- }
- void BufferElement()
- {
- int elementOffset = BufferReader.Offset;
- const int byteCount = 128;
- bool done = false;
- byte quoteChar = 0;
- while (!done)
- {
- int offset;
- int offsetMax;
- byte[] buffer = BufferReader.GetBuffer(byteCount, out offset, out offsetMax);
- if (offset + byteCount != offsetMax)
- {
- break;
- }
- for (int i = offset; i < offsetMax && !done; i++)
- {
- byte b = buffer[i];
- if (b == '\\')
- {
- i++;
- if (i >= offsetMax)
- {
- break;
- }
- }
- else if (quoteChar == 0)
- {
- if (b == (byte)'\'' || b == JsonGlobals.QuoteByte)
- {
- quoteChar = b;
- }
- if (b == JsonGlobals.NameValueSeparatorByte)
- {
- done = true;
- }
- }
- else
- {
- if (b == quoteChar)
- {
- quoteChar = 0;
- }
- }
- }
- BufferReader.Advance(byteCount);
- }
- BufferReader.Offset = elementOffset;
- }
- void EnterJsonScope(JsonNodeType currentNodeType)
- {
- scopeDepth++;
- if (scopes == null)
- {
- scopes = new JsonNodeType[4];
- }
- else if (scopes.Length == scopeDepth)
- {
- JsonNodeType[] newScopes = new JsonNodeType[scopeDepth * 2];
- Array.Copy(scopes, newScopes, scopeDepth);
- scopes = newScopes;
- }
- scopes[scopeDepth] = currentNodeType;
- }
- JsonNodeType ExitJsonScope()
- {
- JsonNodeType nodeTypeToReturn = scopes[scopeDepth];
- scopes[scopeDepth] = JsonNodeType.None;
- scopeDepth--;
- return nodeTypeToReturn;
- }
- new void MoveToEndElement()
- {
- ExitJsonScope();
- base.MoveToEndElement();
- }
- void MoveToInitial(XmlDictionaryReaderQuotas quotas, OnXmlDictionaryReaderClose onClose)
- {
- MoveToInitial(quotas);
- this.maxBytesPerRead = quotas.MaxBytesPerRead;
- this.onReaderClose = onClose;
- }
- void ParseAndSetLocalName()
- {
- XmlElementNode elementNode = EnterScope();
- elementNode.NameOffset = BufferReader.Offset;
- do
- {
- if (BufferReader.GetByte() == '\\')
- {
- ReadEscapedCharacter(false); // moveToText
- }
- else
- {
- ReadQuotedText(false); // moveToText
- }
- } while (complexTextMode == JsonComplexTextMode.QuotedText);
- int actualOffset = BufferReader.Offset - 1; // -1 to ignore " at end of local name
- elementNode.LocalName.SetValue(elementNode.NameOffset, actualOffset - elementNode.NameOffset);
- elementNode.NameLength = actualOffset - elementNode.NameOffset;
- elementNode.Namespace.Uri.SetValue(elementNode.NameOffset, 0);
- elementNode.Prefix.SetValue(PrefixHandleType.Empty);
- elementNode.IsEmptyElement = false;
- elementNode.ExitScope = false;
- elementNode.BufferOffset = actualOffset;
- int currentCharacter = (int)BufferReader.GetByte(elementNode.NameOffset);
- if ((charType[currentCharacter] & CharType.FirstName) == 0)
- {
- SetJsonNameWithMapping(elementNode);
- }
- else
- {
- for (int i = 0, offset = elementNode.NameOffset; i < elementNode.NameLength; i++, offset++)
- {
- currentCharacter = (int)BufferReader.GetByte(offset);
- if ((charType[currentCharacter] & CharType.Name) == 0 || currentCharacter >= 0x80)
- {
- SetJsonNameWithMapping(elementNode);
- break;
- }
- }
- }
- }
- void ParseStartElement()
- {
- if (!buffered)
- {
- BufferElement();
- }
- expectingFirstElementInNonPrimitiveChild = false;
- byte ch = BufferReader.GetByte();
- if (ch == JsonGlobals.QuoteByte)
- {
- BufferReader.SkipByte();
- ParseAndSetLocalName();
- SkipWhitespaceInBufferReader();
- SkipExpectedByteInBufferReader(JsonGlobals.NameValueSeparatorByte);
- SkipWhitespaceInBufferReader();
- if (BufferReader.GetByte() == JsonGlobals.ObjectByte)
- {
- BufferReader.SkipByte();
- expectingFirstElementInNonPrimitiveChild = true;
- }
- ReadAttributes();
- }
- else
- {
- // " and } are the only two valid characters that may follow a {
- XmlExceptionHelper.ThrowTokenExpected(this, "\"", (char)ch);
- }
- }
- void ReadAttributes()
- {
- XmlAttributeNode attribute = AddAttribute();
- attribute.LocalName.SetConstantValue(StringHandleConstStringType.Type);
- attribute.Namespace.Uri.SetValue(0, 0);
- attribute.Prefix.SetValue(PrefixHandleType.Empty);
- SkipWhitespaceInBufferReader();
- byte nextByte = BufferReader.GetByte();
- switch (nextByte)
- {
- case JsonGlobals.QuoteByte:
- if (!expectingFirstElementInNonPrimitiveChild)
- {
- attribute.Value.SetConstantValue(ValueHandleConstStringType.String);
- }
- else
- {
- attribute.Value.SetConstantValue(ValueHandleConstStringType.Object);
- ReadServerTypeAttribute(true);
- }
- break;
- case (byte)'n':
- attribute.Value.SetConstantValue(ValueHandleConstStringType.Null);
- break;
- case (byte)'t':
- case (byte)'f':
- attribute.Value.SetConstantValue(ValueHandleConstStringType.Boolean);
- break;
- case JsonGlobals.ObjectByte:
- attribute.Value.SetConstantValue(ValueHandleConstStringType.Object);
- ReadServerTypeAttribute(false);
- break;
- case JsonGlobals.EndObjectByte:
- if (expectingFirstElementInNonPrimitiveChild)
- {
- attribute.Value.SetConstantValue(ValueHandleConstStringType.Object);
- }
- else
- {
- XmlExceptionHelper.ThrowXmlException(this,
- new XmlException(SR.GetString(SR.JsonEncounteredUnexpectedCharacter, (char)nextByte)));
- }
- break;
- case JsonGlobals.CollectionByte:
- attribute.Value.SetConstantValue(ValueHandleConstStringType.Array);
- BufferReader.SkipByte();
- EnterJsonScope(JsonNodeType.Collection);
- break;
- default:
- if (nextByte == '-' ||
- (nextByte <= '9' && nextByte >= '0') ||
- nextByte == 'N' ||
- nextByte == 'I')
- {
- attribute.Value.SetConstantValue(ValueHandleConstStringType.Number);
- }
- else
- {
- XmlExceptionHelper.ThrowXmlException(this,
- new XmlException(SR.GetString(SR.JsonEncounteredUnexpectedCharacter, (char)nextByte)));
- }
- break;
- }
- }
- void ReadEscapedCharacter(bool moveToText)
- {
- BufferReader.SkipByte();
- char ch = (char)BufferReader.GetByte();
- if (ch == 'u')
- {
- BufferReader.SkipByte();
- int offset;
- byte[] buffer = BufferReader.GetBuffer(5, out offset);
- string bufferAsString = Encoding.UTF8.GetString(buffer, offset, 4);
- BufferReader.Advance(4);
- int charValue = ParseChar(bufferAsString, NumberStyles.HexNumber);
- if (Char.IsHighSurrogate((char)charValue))
- {
- byte nextByte = BufferReader.GetByte();
- if (nextByte == (byte)'\\')
- {
- BufferReader.SkipByte();
- SkipExpectedByteInBufferReader((byte)'u');
- buffer = BufferReader.GetBuffer(5, out offset);
- bufferAsString = Encoding.UTF8.GetString(buffer, offset, 4);
- BufferReader.Advance(4);
- char lowChar = ParseChar(bufferAsString, NumberStyles.HexNumber);
- if (!Char.IsLowSurrogate(lowChar))
- {
- XmlExceptionHelper.ThrowXmlException(this,
- new XmlException(System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.XmlInvalidLowSurrogate, bufferAsString)));
- }
- charValue = new SurrogateChar(lowChar, (char)charValue).Char;
- }
- }
- if (buffer[offset + 4] == JsonGlobals.QuoteByte)
- {
- BufferReader.SkipByte();
- if (moveToText)
- {
- MoveToAtomicText().Value.SetCharValue(charValue);
- }
- complexTextMode = JsonComplexTextMode.None;
- }
- else
- {
- if (moveToText)
- {
- MoveToComplexText().Value.SetCharValue(charValue);
- }
- complexTextMode = JsonComplexTextMode.QuotedText;
- }
- }
- else
- {
- switch (ch)
- {
- case 'b':
- ch = '\b';
- break;
- case 'f':
- ch = '\f';
- break;
- case 'n':
- ch = '\n';
- break;
- case 'r':
- ch = '\r';
- break;
- case 't':
- ch = '\t';
- break;
- case '\"':
- case '\\':
- case '/':
- // Do nothing. These are the actual unescaped values.
- break;
- default:
- XmlExceptionHelper.ThrowXmlException(this,
- new XmlException(SR.GetString(SR.JsonEncounteredUnexpectedCharacter, (char)ch)));
- break;
- }
- BufferReader.SkipByte();
- if (BufferReader.GetByte() == JsonGlobals.QuoteByte)
- {
- BufferReader.SkipByte();
- if (moveToText)
- {
- MoveToAtomicText().Value.SetCharValue(ch);
- }
- complexTextMode = JsonComplexTextMode.None;
- }
- else
- {
- if (moveToText)
- {
- MoveToComplexText().Value.SetCharValue(ch);
- }
- complexTextMode = JsonComplexTextMode.QuotedText;
- }
- }
- }
- void ReadNonExistentElementName(StringHandleConstStringType elementName)
- {
- EnterJsonScope(JsonNodeType.Object);
- XmlElementNode elementNode = EnterScope();
- elementNode.LocalName.SetConstantValue(elementName);
- elementNode.Namespace.Uri.SetValue(elementNode.NameOffset, 0);
- elementNode.Prefix.SetValue(PrefixHandleType.Empty);
- elementNode.BufferOffset = BufferReader.Offset;
- elementNode.IsEmptyElement = false;
- elementNode.ExitScope = false;
- ReadAttributes();
- }
- int ReadNonFFFE()
- {
- int off;
- byte[] buff = BufferReader.GetBuffer(3, out off);
- if (buff[off + 1] == 0xBF && (buff[off + 2] == 0xBE || buff[off + 2] == 0xBF))
- {
- XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.JsonInvalidFFFE)));
- }
- return 3;
- }
- void ReadNumericalText()
- {
- byte[] buffer;
- int offset;
- int offsetMax;
- int length;
- if (buffered)
- {
- buffer = BufferReader.GetBuffer(out offset, out offsetMax);
- length = ComputeNumericalTextLength(buffer, offset, offsetMax);
- }
- else
- {
- buffer = BufferReader.GetBuffer(MaxTextChunk, out offset, out offsetMax);
- length = ComputeNumericalTextLength(buffer, offset, offsetMax);
- length = BreakText(buffer, offset, length);
- }
- BufferReader.Advance(length);
- if (offset <= offsetMax - length)
- {
- MoveToAtomicText().Value.SetValue(ValueHandleType.UTF8, offset, length);
- complexTextMode = JsonComplexTextMode.None;
- }
- else
- {
- MoveToComplexText().Value.SetValue(ValueHandleType.UTF8, offset, length);
- complexTextMode = JsonComplexTextMode.NumericalText;
- }
- }
- void ReadQuotedText(bool moveToText)
- {
- byte[] buffer;
- int offset;
- int offsetMax;
- int length;
- bool escaped;
- bool endReached;
- if (buffered)
- {
- buffer = BufferReader.GetBuffer(out offset, out offsetMax);
- length = ComputeQuotedTextLengthUntilEndQuote(buffer, offset, offsetMax, out escaped);
- endReached = offset < offsetMax - length;
- }
- else
- {
- buffer = BufferReader.GetBuffer(MaxTextChunk, out offset, out offsetMax);
- length = ComputeQuotedTextLengthUntilEndQuote(buffer, offset, offsetMax, out escaped);
- endReached = offset < offsetMax - length;
- length = BreakText(buffer, offset, length);
- }
- if (escaped && BufferReader.GetByte() == 0xEF)
- {
- offset = BufferReader.Offset;
- length = ReadNonFFFE();
- }
- BufferReader.Advance(length);
- if (!escaped && endReached)
- {
- if (moveToText)
- {
- MoveToAtomicText().Value.SetValue(ValueHandleType.UTF8, offset, length);
- }
- SkipExpectedByteInBufferReader(JsonGlobals.QuoteByte);
- complexTextMode = JsonComplexTextMode.None;
- }
- else
- {
- if ((length == 0) && escaped)
- {
- ReadEscapedCharacter(moveToText);
- }
- else
- {
- if (moveToText)
- {
- MoveToComplexText().Value.SetValue(ValueHandleType.UTF8, offset, length);
- }
- complexTextMode = JsonComplexTextMode.QuotedText;
- }
- }
- }
- void ReadServerTypeAttribute(bool consumedObjectChar)
- {
- if (!consumedObjectChar)
- {
- SkipExpectedByteInBufferReader(JsonGlobals.ObjectByte);
- SkipWhitespaceInBufferReader();
- // we only allow " or } after {
- byte ch = BufferReader.GetByte();
- if (ch != JsonGlobals.QuoteByte && ch != JsonGlobals.EndObjectByte)
- {
- XmlExceptionHelper.ThrowTokenExpected(this, "\"", (char)ch);
- }
- }
- else
- {
- SkipWhitespaceInBufferReader();
- }
- int offset;
- int offsetMax;
- byte[] buffer = BufferReader.GetBuffer(8, out offset, out offsetMax);
- if (offset + 8 <= offsetMax)
- {
- if (buffer[offset + 0] == (byte)'\"' &&
- buffer[offset + 1] == (byte)'_' &&
- buffer[offset + 2] == (byte)'_' &&
- buffer[offset + 3] == (byte)'t' &&
- buffer[offset + 4] == (byte)'y' &&
- buffer[offset + 5] == (byte)'p' &&
- buffer[offset + 6] == (byte)'e' &&
- buffer[offset + 7] == (byte)'\"')
- {
- XmlAttributeNode attribute = AddAttribute();
- attribute.LocalName.SetValue(offset + 1, 6);
- attribute.Namespace.Uri.SetValue(0, 0);
- attribute.Prefix.SetValue(PrefixHandleType.Empty);
- BufferReader.Advance(8);
- if (!buffered)
- {
- BufferElement();
- }
- SkipWhitespaceInBufferReader();
- SkipExpectedByteInBufferReader(JsonGlobals.NameValueSeparatorByte);
- SkipWhitespaceInBufferReader();
- SkipExpectedByteInBufferReader(JsonGlobals.QuoteByte);
- buffer = BufferReader.GetBuffer(out offset, out offsetMax);
- do
- {
- if (BufferReader.GetByte() == '\\')
- {
- ReadEscapedCharacter(false); // moveToText
- }
- else
- {
- ReadQuotedText(false); // moveToText
- }
- } while (complexTextMode == JsonComplexTextMode.QuotedText);
- attribute.Value.SetValue(ValueHandleType.UTF8, offset, BufferReader.Offset - 1 - offset);
- SkipWhitespaceInBufferReader();
- if (BufferReader.GetByte() == JsonGlobals.MemberSeparatorByte)
- {
- BufferReader.SkipByte();
- readServerTypeElement = true;
- }
- }
- }
- if (BufferReader.GetByte() == JsonGlobals.EndObjectByte)
- {
- BufferReader.SkipByte();
- readServerTypeElement = false;
- expectingFirstElementInNonPrimitiveChild = false;
- }
- else
- {
- readServerTypeElement = true;
- }
- }
- void ResetState()
- {
- complexTextMode = JsonComplexTextMode.None;
- expectingFirstElementInNonPrimitiveChild = false;
- charactersToSkipOnNextRead = new byte[2];
- scopeDepth = 0;
- if ((scopes != null) && (scopes.Length > JsonGlobals.maxScopeSize))
- {
- scopes = null;
- }
- }
- void SetJsonNameWithMapping(XmlElementNode elementNode)
- {
- Namespace ns = AddNamespace();
- ns.Prefix.SetValue(PrefixHandleType.A);
- ns.Uri.SetConstantValue(StringHandleConstStringType.Item);
- AddXmlnsAttribute(ns);
- XmlAttributeNode attribute = AddAttribute();
- attribute.LocalName.SetConstantValue(StringHandleConstStringType.Item);
- attribute.Namespace.Uri.SetValue(0, 0);
- attribute.Prefix.SetValue(PrefixHandleType.Empty);
- attribute.Value.SetValue(ValueHandleType.UTF8, elementNode.NameOffset, elementNode.NameLength);
- elementNode.NameLength = 0;
- elementNode.Prefix.SetValue(PrefixHandleType.A);
- elementNode.LocalName.SetConstantValue(StringHandleConstStringType.Item);
- elementNode.Namespace = ns;
- }
- void SkipExpectedByteInBufferReader(byte characterToSkip)
- {
- if (BufferReader.GetByte() != characterToSkip)
- {
- XmlExceptionHelper.ThrowTokenExpected(this, ((char)characterToSkip).ToString(), (char)BufferReader.GetByte());
- }
- BufferReader.SkipByte();
- }
- void SkipWhitespaceInBufferReader()
- {
- byte ch;
- while (TryGetByte(out ch) && IsWhitespace(ch))
- {
- BufferReader.SkipByte();
- }
- }
- bool TryGetByte(out byte ch)
- {
- int offset, offsetMax;
- byte[] buffer = BufferReader.GetBuffer(1, out offset, out offsetMax);
- if (offset < offsetMax)
- {
- ch = buffer[offset];
- return true;
- }
- else
- {
- ch = (byte)'\0';
- return false;
- }
- }
- string UnescapeJsonString(string val)
- {
- if (val == null)
- {
- return null;
- }
- StringBuilder sb = null;
- int startIndex = 0, count = 0;
- for (int i = 0; i < val.Length; i++)
- {
- if (val[i] == '\\')
- {
- i++;
- if (sb == null)
- {
- sb = new StringBuilder();
- }
- sb.Append(val, startIndex, count);
- Fx.Assert(i < val.Length, "Found that an '\' was the last character in a string. ReadServerTypeAttriute validates that the escape sequence is valid when it calls ReadQuotedText and ReadEscapedCharacter");
- if (i >= val.Length)
- {
- XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR.GetString(SR.JsonEncounteredUnexpectedCharacter, val[i])));
- }
- switch (val[i])
- {
- case '"':
- case '\'':
- case '/':
- case '\\':
- sb.Append(val[i]);
- break;
- case 'b':
- sb.Append('\b');
- break;
- case 'f':
- sb.Append('\f');
- break;
- case 'n':
- sb.Append('\n');
- break;
- case 'r':
- sb.Append('\r');
- break;
- case 't':
- sb.Append('\t');
- break;
- case 'u':
- if ((i + 3) >= val.Length)
- {
- XmlExceptionHelper.ThrowXmlException(this,
- new XmlException(SR.GetString(SR.JsonEncounteredUnexpectedCharacter, val[i])));
- }
- sb.Append(ParseChar(val.Substring(i + 1, 4), NumberStyles.HexNumber));
- i += 4;
- break;
- }
- startIndex = i + 1;
- count = 0;
- }
- else
- {
- count++;
- }
- }
- if (sb == null)
- {
- return val;
- }
- if (count > 0)
- {
- sb.Append(val, startIndex, count);
- }
- return sb.ToString();
- }
- static class CharType
- {
- public const byte FirstName = 0x01;
- public const byte Name = 0x02;
- public const byte None = 0x00;
- }
- }
- }
|