766 lines
24 KiB
C#
766 lines
24 KiB
C#
![]() |
using System;
|
|||
|
using System.Reflection;
|
|||
|
using System.Runtime.CompilerServices;
|
|||
|
using System.Text;
|
|||
|
|
|||
|
namespace CPF.Windows.Json.Deserialize
|
|||
|
{
|
|||
|
internal unsafe class JsonReader
|
|||
|
{
|
|||
|
#region pregenerated metas
|
|||
|
internal static FieldInfo _Json =
|
|||
|
typeof(JsonReader).GetField(nameof(Json), BindingFlags.NonPublic | BindingFlags.Instance);
|
|||
|
|
|||
|
internal static FieldInfo _Buffer =
|
|||
|
typeof(JsonReader).GetField(nameof(Buffer), BindingFlags.NonPublic | BindingFlags.Instance);
|
|||
|
|
|||
|
internal static FieldInfo _Length =
|
|||
|
typeof(JsonReader).GetField(nameof(Length), BindingFlags.NonPublic | BindingFlags.Instance);
|
|||
|
|
|||
|
internal static FieldInfo _Remaining =
|
|||
|
typeof(JsonReader).GetField(nameof(Remaining), BindingFlags.NonPublic | BindingFlags.Instance);
|
|||
|
|
|||
|
internal static MethodInfo _RollbackChar = GetMethodInfo(nameof(RollbackChar));
|
|||
|
|
|||
|
internal static MethodInfo _Rollback = GetMethodInfo(nameof(Rollback));
|
|||
|
|
|||
|
internal static MethodInfo _ReadObjLeft = GetMethodInfo(nameof(ReadObjLeft));
|
|||
|
|
|||
|
internal static MethodInfo _ReadNullOrObjLeft = GetMethodInfo(nameof(ReadNullOrObjLeft));
|
|||
|
|
|||
|
internal static MethodInfo _ReadObjRight = GetMethodInfo(nameof(ReadObjRight));
|
|||
|
|
|||
|
internal static MethodInfo _ReadBoolObjRight = GetMethodInfo(nameof(ReadBoolObjRight));
|
|||
|
|
|||
|
internal static MethodInfo _ReadBoolComma = GetMethodInfo(nameof(ReadBoolComma));
|
|||
|
|
|||
|
internal static MethodInfo _ReadComma = GetMethodInfo(nameof(ReadComma));
|
|||
|
|
|||
|
internal static MethodInfo _ReadColon = GetMethodInfo(nameof(ReadColon));
|
|||
|
|
|||
|
internal static MethodInfo _ReadQuotes = GetMethodInfo(nameof(ReadQuotes));
|
|||
|
|
|||
|
internal static MethodInfo _ReadArrayLeft = GetMethodInfo(nameof(ReadArrayLeft));
|
|||
|
|
|||
|
internal static MethodInfo _ReadNullOrArrayLeft = GetMethodInfo(nameof(ReadNullOrArrayLeft));
|
|||
|
|
|||
|
internal static MethodInfo _ReadArrayRight = GetMethodInfo(nameof(ReadArrayRight));
|
|||
|
|
|||
|
internal static MethodInfo _ReadBoolArrayRight = GetMethodInfo(nameof(ReadBoolArrayRight));
|
|||
|
|
|||
|
internal static MethodInfo _ReadEnd = GetMethodInfo(nameof(ReadEnd));
|
|||
|
|
|||
|
internal static MethodInfo _BeforAnnotation = GetMethodInfo(nameof(BeforAnnotation));
|
|||
|
|
|||
|
internal static MethodInfo _ReadAnnotation = GetMethodInfo(nameof(ReadAnnotation));
|
|||
|
|
|||
|
internal static MethodInfo _ReadString = GetMethodInfo(nameof(ReadString));
|
|||
|
|
|||
|
internal static MethodInfo _ReadBoolNull = GetMethodInfo(nameof(ReadBoolNull));
|
|||
|
|
|||
|
internal static MethodInfo _SkipObj = GetMethodInfo(nameof(SkipObj));
|
|||
|
|
|||
|
internal static MethodInfo _GetArrayLength = GetMethodInfo(nameof(GetArrayLength));
|
|||
|
|
|||
|
internal static MethodInfo _RemoveQuoteAndSubString = GetMethodInfo(nameof(RemoveQuoteAndSubString));
|
|||
|
|
|||
|
internal static MethodInfo _GetChar = GetMethodInfo(nameof(GetChar));
|
|||
|
#endregion
|
|||
|
|
|||
|
internal StringBuilder CharBufferSb;
|
|||
|
internal string Json;
|
|||
|
internal char[] Buffer;
|
|||
|
internal int Length;
|
|||
|
internal char* Pointer;
|
|||
|
internal int Remaining;
|
|||
|
|
|||
|
|
|||
|
internal JsonReader(string json, char* c)
|
|||
|
{
|
|||
|
Json = json;
|
|||
|
Length = json.Length;
|
|||
|
Pointer = c;
|
|||
|
Remaining = Length;
|
|||
|
CharBufferSb = null;
|
|||
|
Buffer = null;
|
|||
|
}
|
|||
|
|
|||
|
internal JsonReader(char[] buffer,int length, char* c)
|
|||
|
{
|
|||
|
Buffer = buffer;
|
|||
|
Length = length;
|
|||
|
Pointer = c;
|
|||
|
Remaining = Length;
|
|||
|
CharBufferSb = null;
|
|||
|
Json = null;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal string SubString(int start, int length)
|
|||
|
{
|
|||
|
if (Json != null)
|
|||
|
return Json.Substring(start, length);
|
|||
|
else//char[]
|
|||
|
return new string(Buffer, start, length);
|
|||
|
}
|
|||
|
|
|||
|
internal char this[int idx]
|
|||
|
{
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
get
|
|||
|
{
|
|||
|
if (Json != null)
|
|||
|
return Json[idx];
|
|||
|
else
|
|||
|
return Buffer[idx];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal char GetChar()
|
|||
|
{
|
|||
|
var c = *Pointer;
|
|||
|
Pointer++;
|
|||
|
Remaining--;
|
|||
|
return c;
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal int GetInt()
|
|||
|
{
|
|||
|
var i = *(int*)Pointer;
|
|||
|
Pointer += 2;
|
|||
|
Remaining -= 2;
|
|||
|
return i;
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal long GetLong()
|
|||
|
{
|
|||
|
var i = *(long*)Pointer;
|
|||
|
Pointer += 4;
|
|||
|
Remaining -= 4;
|
|||
|
return i;
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void RollbackChar()
|
|||
|
{
|
|||
|
Pointer--;
|
|||
|
Remaining++;
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void RollbackInt()
|
|||
|
{
|
|||
|
Pointer -= 2;
|
|||
|
Remaining += 2;
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void Rollback(int num)
|
|||
|
{
|
|||
|
Pointer -= num;
|
|||
|
Remaining += num;
|
|||
|
}
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void ReadObjLeft()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c != '{')
|
|||
|
throw new JsonWrongCharacterException(this, '{');
|
|||
|
}
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal bool ReadNullOrObjLeft()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c == 'n' && StrCompair("ull"))
|
|||
|
return true;
|
|||
|
if (c == '{')
|
|||
|
return false;
|
|||
|
throw new JsonWrongCharacterException(this, '{');
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void ReadObjRight()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c != '}')
|
|||
|
throw new JsonWrongCharacterException(this, '}');
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal bool ReadBoolObjRight()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c == '}') return true;
|
|||
|
|
|||
|
RollbackChar();
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal bool ReadBoolComma()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c == ',') return true;
|
|||
|
|
|||
|
RollbackChar();
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void ReadComma()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c != ',')
|
|||
|
throw new JsonWrongCharacterException(this, ',');
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void ReadColon()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c != ':')
|
|||
|
throw new JsonWrongCharacterException(this, ':');
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void ReadQuotes()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c != '"')
|
|||
|
throw new JsonWrongCharacterException(this, '"');
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void ReadArrayLeft()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c != '[')
|
|||
|
throw new JsonWrongCharacterException(this, '[');
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal bool ReadNullOrArrayLeft()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c == 'n' && StrCompair("ull"))
|
|||
|
return true;
|
|||
|
if (c == '[')
|
|||
|
return false;
|
|||
|
throw new JsonWrongCharacterException(this, '[');
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void ReadArrayRight()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c != ']')
|
|||
|
throw new JsonWrongCharacterException(this, ']');
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal bool ReadBoolArrayRight()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c == ']') return true;
|
|||
|
|
|||
|
RollbackChar();
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal bool ReadBoolNull()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c == 'n' && StrCompair("ull"))
|
|||
|
return true;
|
|||
|
else
|
|||
|
{
|
|||
|
RollbackChar();
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void ReadEnd()
|
|||
|
{
|
|||
|
if (Remaining > 0)
|
|||
|
ReadAnnotation();
|
|||
|
else if (Remaining < 0)
|
|||
|
throw new JsonWrongCharacterException();
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal char BeforAnnotation()
|
|||
|
{
|
|||
|
var c = GetChar();
|
|||
|
switch (c)
|
|||
|
{
|
|||
|
case '/':
|
|||
|
{
|
|||
|
if (Remaining == 0)
|
|||
|
throw new JsonWrongCharacterException();
|
|||
|
c = GetChar();
|
|||
|
if (c == '*')
|
|||
|
{
|
|||
|
var lastChar = ' ';
|
|||
|
while (Remaining > 0)
|
|||
|
{
|
|||
|
lastChar = c;
|
|||
|
c = GetChar();
|
|||
|
if (c == '/') // /* * */ , /* ***/////
|
|||
|
if (lastChar == '*')
|
|||
|
{
|
|||
|
if (Remaining > 0)
|
|||
|
{
|
|||
|
c = GetChar();
|
|||
|
if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
|
|||
|
return BeforAnnotation();
|
|||
|
return c;
|
|||
|
}
|
|||
|
|
|||
|
throw new JsonWrongCharacterException("Json is incomplete"); //json不完整
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else if (c == '/')
|
|||
|
{
|
|||
|
while (Remaining > 0)
|
|||
|
{
|
|||
|
c = GetChar();
|
|||
|
if (c == '\r' || c == '\n')
|
|||
|
{
|
|||
|
if (Remaining > 0)
|
|||
|
{
|
|||
|
c = GetChar();
|
|||
|
if (c == '\r' || c == '\n' || c == ' ' || c == '\t')
|
|||
|
return BeforAnnotation();
|
|||
|
return c;
|
|||
|
}
|
|||
|
|
|||
|
throw new JsonWrongCharacterException("Json is incomplete"); //json不完整
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
throw new JsonWrongCharacterException();
|
|||
|
}
|
|||
|
case '\r':
|
|||
|
case '\n':
|
|||
|
case '\t':
|
|||
|
case ' ':
|
|||
|
if (Remaining > 0)
|
|||
|
return BeforAnnotation();
|
|||
|
else
|
|||
|
throw new JsonWrongCharacterException("Json is incomplete"); //json不完整
|
|||
|
}
|
|||
|
|
|||
|
return c;
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void ReadAnnotation()
|
|||
|
{
|
|||
|
var c = GetChar();
|
|||
|
switch (c)
|
|||
|
{
|
|||
|
case '/':
|
|||
|
{
|
|||
|
if (Remaining == 0)
|
|||
|
throw new JsonWrongCharacterException();
|
|||
|
c = GetChar();
|
|||
|
if (c == '*')
|
|||
|
{
|
|||
|
var lastChar = ' ';
|
|||
|
while (Remaining > 0)
|
|||
|
{
|
|||
|
lastChar = c;
|
|||
|
c = GetChar();
|
|||
|
if (c == '/') // /* * */ , /* ***/////
|
|||
|
if (lastChar == '*')
|
|||
|
{
|
|||
|
if (Remaining > 0)
|
|||
|
ReadAnnotation();
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else if (c == '/')
|
|||
|
{
|
|||
|
while (Remaining > 0)
|
|||
|
{
|
|||
|
c = GetChar();
|
|||
|
if (c == '\r' || c == '\n')
|
|||
|
{
|
|||
|
if (Remaining > 0)
|
|||
|
ReadAnnotation();
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
case '\r':
|
|||
|
case '\n':
|
|||
|
case '\t':
|
|||
|
case ' ':
|
|||
|
if (Remaining > 0)
|
|||
|
ReadAnnotation();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
throw new JsonWrongCharacterException();
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal string ReadString()
|
|||
|
{
|
|||
|
//Currently, this method is only used for dynamic read keys and enums because it does not allow special characters
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c == '"')
|
|||
|
{
|
|||
|
var idx = Length - Remaining;
|
|||
|
var leng = 0;
|
|||
|
var isCorrectFormat = false;
|
|||
|
while (Remaining > 0)
|
|||
|
{
|
|||
|
c = GetChar();
|
|||
|
if (c == '"')
|
|||
|
{
|
|||
|
isCorrectFormat = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
leng++;
|
|||
|
}
|
|||
|
|
|||
|
if (isCorrectFormat)
|
|||
|
if (leng == 0)
|
|||
|
return string.Empty;
|
|||
|
else
|
|||
|
return this.SubString(idx, leng);
|
|||
|
}
|
|||
|
else if (c == 'n' && StrCompair("ull"))
|
|||
|
{
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
throw new JsonDeserializationTypeResolutionException(this, typeof(string));
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal int SkipObj(JsonDeserializeHandler handler)
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
var start = Remaining;
|
|||
|
switch (c)
|
|||
|
{
|
|||
|
case 'f':
|
|||
|
if (Remaining > 3)
|
|||
|
if (StrCompair("alse"))
|
|||
|
goto Return;
|
|||
|
break;
|
|||
|
case 't':
|
|||
|
if (Remaining > 2)
|
|||
|
if (StrCompair("rue"))
|
|||
|
goto Return;
|
|||
|
break;
|
|||
|
case 'n':
|
|||
|
if (Remaining > 2)
|
|||
|
if (StrCompair("ull"))
|
|||
|
goto Return;
|
|||
|
break;
|
|||
|
case '0':
|
|||
|
case '1':
|
|||
|
case '2':
|
|||
|
case '3':
|
|||
|
case '4':
|
|||
|
case '5':
|
|||
|
case '6':
|
|||
|
case '7':
|
|||
|
case '8':
|
|||
|
case '9':
|
|||
|
case '-':
|
|||
|
{
|
|||
|
SkipNumber();
|
|||
|
goto Return;
|
|||
|
}
|
|||
|
case '[':
|
|||
|
{
|
|||
|
if (ReadBoolArrayRight())
|
|||
|
goto Return;
|
|||
|
var moveNext = 1;
|
|||
|
while (moveNext-- > 0)
|
|||
|
{
|
|||
|
SkipObj(handler);
|
|||
|
if (ReadBoolComma())
|
|||
|
moveNext++;
|
|||
|
}
|
|||
|
|
|||
|
ReadArrayRight();
|
|||
|
goto Return;
|
|||
|
}
|
|||
|
case '{':
|
|||
|
{
|
|||
|
if (ReadBoolObjRight())
|
|||
|
goto Return;
|
|||
|
var moveNext = 1;
|
|||
|
while (moveNext-- > 0)
|
|||
|
{
|
|||
|
SkipString();
|
|||
|
ReadColon();
|
|||
|
SkipObj(handler);
|
|||
|
if (ReadBoolComma())
|
|||
|
moveNext++;
|
|||
|
}
|
|||
|
|
|||
|
ReadObjRight();
|
|||
|
goto Return;
|
|||
|
}
|
|||
|
case '"':
|
|||
|
{
|
|||
|
RollbackChar();
|
|||
|
SkipString();
|
|||
|
goto Return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
throw new JsonWrongCharacterException(this);
|
|||
|
Return:
|
|||
|
return start + 1 - Remaining;
|
|||
|
}
|
|||
|
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void SkipString()
|
|||
|
{
|
|||
|
var c = BeforAnnotation();
|
|||
|
if (c == '"')
|
|||
|
while (Remaining > 0)
|
|||
|
{
|
|||
|
c = GetChar();
|
|||
|
if (c == '"')
|
|||
|
return;
|
|||
|
if (c != '\\')
|
|||
|
continue;
|
|||
|
c = GetChar();
|
|||
|
switch (c)
|
|||
|
{
|
|||
|
case '"': continue;
|
|||
|
case '\\': continue;
|
|||
|
case '/': continue;
|
|||
|
case 'b': continue;
|
|||
|
case 'f': continue;
|
|||
|
case 'n': continue;
|
|||
|
case 'r': continue;
|
|||
|
case 't': continue;
|
|||
|
case 'u':
|
|||
|
{
|
|||
|
c = GetChar();
|
|||
|
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) throw new JsonDeserializationTypeResolutionException(this, typeof(string));
|
|||
|
c = GetChar();
|
|||
|
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) throw new JsonDeserializationTypeResolutionException(this, typeof(string));
|
|||
|
c = GetChar();
|
|||
|
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) throw new JsonDeserializationTypeResolutionException(this, typeof(string));
|
|||
|
c = GetChar();
|
|||
|
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) throw new JsonDeserializationTypeResolutionException(this, typeof(string));
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else if (c == 'n' && StrCompair("ull")) return;
|
|||
|
|
|||
|
throw new JsonDeserializationTypeResolutionException(this, typeof(string));
|
|||
|
}
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal void SkipNumber()
|
|||
|
{
|
|||
|
var seenDecimal = false;
|
|||
|
var seenExponent = false;
|
|||
|
char c;
|
|||
|
while (Remaining > 0)
|
|||
|
{
|
|||
|
c = GetChar();
|
|||
|
if (c >= '0' && c <= '9') continue;
|
|||
|
|
|||
|
if (c == '.' && !seenDecimal)
|
|||
|
{
|
|||
|
seenDecimal = true;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if ((c == 'e' || c == 'E') && !seenExponent)
|
|||
|
{
|
|||
|
c = GetChar();
|
|||
|
seenExponent = true;
|
|||
|
seenDecimal = true;
|
|||
|
|
|||
|
c = GetChar();
|
|||
|
if (c == '-' || c == '+' || c >= '0' && c <= '9') continue;
|
|||
|
throw new JsonWrongCharacterException(this, "Expected -, or a digit");
|
|||
|
}
|
|||
|
|
|||
|
RollbackChar();
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal int GetArrayLength(JsonDeserializeHandler handler)
|
|||
|
{
|
|||
|
//ReadObjLeft();
|
|||
|
if (ReadBoolArrayRight())
|
|||
|
{
|
|||
|
RollbackChar();
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
var start = Remaining;
|
|||
|
var elements = 0;
|
|||
|
var moveNext = 1;
|
|||
|
while (moveNext-- > 0)
|
|||
|
{
|
|||
|
++elements;
|
|||
|
SkipObj(handler);
|
|||
|
if (ReadBoolComma())
|
|||
|
moveNext++;
|
|||
|
}
|
|||
|
|
|||
|
ReadArrayRight();
|
|||
|
Rollback(start - Remaining);
|
|||
|
return elements;
|
|||
|
throw new JsonWrongCharacterException("Array character error");
|
|||
|
}
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal bool StrCompair(string str)
|
|||
|
{
|
|||
|
if (Remaining < str.Length)
|
|||
|
return false;
|
|||
|
//2,3,4,5,6,7,8,9
|
|||
|
fixed (char* p = str)
|
|||
|
{
|
|||
|
var o = p;
|
|||
|
switch (str.Length)
|
|||
|
{
|
|||
|
case 2:
|
|||
|
if (*(int*)Pointer != *(int*)o) return false;
|
|||
|
goto True;
|
|||
|
case 3:
|
|||
|
if (*(int*)Pointer != *(int*)o) return false;
|
|||
|
if (*(Pointer + 2) != *(o + 2)) return false;
|
|||
|
goto True;
|
|||
|
case 4:
|
|||
|
if (*(long*)Pointer != *(long*)o) return false;
|
|||
|
goto True;
|
|||
|
case 5:
|
|||
|
if (*(long*)Pointer != *(long*)o) return false;
|
|||
|
if (*(Pointer + 4) != *(o + 4)) return false;
|
|||
|
goto True;
|
|||
|
case 6:
|
|||
|
if (*(long*)Pointer != *(long*)o) return false;
|
|||
|
if (*(int*)(Pointer + 4) != *(int*)(o + 4)) return false;
|
|||
|
goto True;
|
|||
|
case 7:
|
|||
|
if (*(long*)Pointer != *(long*)o) return false;
|
|||
|
if (*(int*)(Pointer + 4) != *(int*)(o + 4)) return false;
|
|||
|
if (*(Pointer + 6) != *(o + 6)) return false;
|
|||
|
goto True;
|
|||
|
case 8:
|
|||
|
if (*(long*)Pointer != *(long*)o) return false;
|
|||
|
if (*(long*)(Pointer + 4) != *(long*)(o + 4)) return false;
|
|||
|
goto True;
|
|||
|
case 9:
|
|||
|
if (*(long*)Pointer != *(long*)o) return false;
|
|||
|
if (*(long*)(Pointer + 4) != *(long*)(o + 4)) return false;
|
|||
|
if (*(Pointer + 8) != *(o + 8)) return false;
|
|||
|
goto True;
|
|||
|
default:
|
|||
|
throw new Exception("Check the code,StrCompair no current length ");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
True:
|
|||
|
Remaining -= str.Length;
|
|||
|
Pointer += str.Length;
|
|||
|
return true;
|
|||
|
}
|
|||
|
#if !Net4
|
|||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|||
|
#endif
|
|||
|
internal string RemoveQuoteAndSubString(int idx, int length)
|
|||
|
{
|
|||
|
if (this[idx] == 'n')
|
|||
|
return null;
|
|||
|
return this.SubString(idx + 1, length - 2); //remove \" \"
|
|||
|
}
|
|||
|
|
|||
|
private static MethodInfo GetMethodInfo(string name)
|
|||
|
{
|
|||
|
return typeof(JsonReader).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|