parent
85914b5262
commit
fb74a1a6a7
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Exceptron.Driver" version="0.1.0.30" />
|
<package id="Exceptron.Driver" version="0.1.0.34" />
|
||||||
<package id="Newtonsoft.Json" version="4.5.4" />
|
<package id="Newtonsoft.Json" version="4.5.4" />
|
||||||
<package id="NLog" version="2.0.0.2000" />
|
<package id="NLog" version="2.0.0.2000" />
|
||||||
</packages>
|
</packages>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Exceptron.Driver
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents information that will be used to construct an exception report.
|
||||||
|
/// </summary>
|
||||||
|
public class ExceptionData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Exception that is being reported
|
||||||
|
/// </summary>
|
||||||
|
public Exception Exception { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Component that caused this error.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// It is common to use the logger name that was used to log the exception as the component.
|
||||||
|
/// </remarks>
|
||||||
|
/// <example>
|
||||||
|
/// DataAccess, Configuration, Registration, etc.
|
||||||
|
/// </example>
|
||||||
|
public string Component { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ID that will uniquely identify the user
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This Id does not have to be tied to the user's identity.
|
||||||
|
/// You can use a system generated unique ID such as GUID.
|
||||||
|
/// This field is used to report how many unique users are experiencing an error.
|
||||||
|
/// </remarks>
|
||||||
|
/// <example>
|
||||||
|
/// "62E5C8EF-0CA2-43AB-B278-FC6994F776ED"
|
||||||
|
/// "Timmy@aol.com"
|
||||||
|
/// "26437"
|
||||||
|
/// </example>
|
||||||
|
public string UserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Any message that should be attached to this exceptions
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// Something went wrong while checking for application updates.
|
||||||
|
/// </example>
|
||||||
|
public string Message { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Severity of the exception being reported
|
||||||
|
/// </summary>
|
||||||
|
public ExceptionSeverity Severity { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
namespace Exceptron.Driver
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Severity of the exception being reported
|
||||||
|
/// </summary>
|
||||||
|
public enum ExceptionSeverity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Excepted Error. Can be ignored
|
||||||
|
/// </summary>
|
||||||
|
None = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Error that can be handled gracefully
|
||||||
|
/// </summary>
|
||||||
|
Warning = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blocking user from completing their intended action
|
||||||
|
/// </summary>
|
||||||
|
Error = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Will most likely cause the application to crash
|
||||||
|
/// </summary>
|
||||||
|
Fatal = 3
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
namespace Exceptron.Driver
|
||||||
|
{
|
||||||
|
internal interface IRestClient
|
||||||
|
{
|
||||||
|
TResponse Put<TResponse>(string url, object report) where TResponse : class, new();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Exceptron.Driver.Message
|
||||||
|
{
|
||||||
|
internal class ExceptionReport
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// API key
|
||||||
|
/// </summary>
|
||||||
|
public string ap { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Application Version
|
||||||
|
/// </summary>
|
||||||
|
public string aver { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Exception Severity
|
||||||
|
/// </summary>
|
||||||
|
public int sv { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// User or Instance ID
|
||||||
|
/// </summary>
|
||||||
|
public string uid { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Type of exception
|
||||||
|
/// </summary>
|
||||||
|
public string ext { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Exception message
|
||||||
|
/// </summary>
|
||||||
|
public string exm { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of frames that make up the StackTrace of the exception
|
||||||
|
/// </summary>
|
||||||
|
public List<Frame> stk { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Component that experienced this exception
|
||||||
|
/// </summary>
|
||||||
|
public string cmp { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Environment that this exception occurred in.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>Dev, Stage, Production</example>
|
||||||
|
public string env { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Message that was logged along with the exception.
|
||||||
|
/// </summary>
|
||||||
|
public string msg { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// User's culture in
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.name.aspx</remarks>
|
||||||
|
public string cul { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// OS Version
|
||||||
|
/// </summary>
|
||||||
|
public string os { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the driver that generated and is sending this message
|
||||||
|
/// </summary>
|
||||||
|
public string dn { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Version of the driver that generated and is sending this message
|
||||||
|
/// </summary>
|
||||||
|
public string dv { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Exceptron.Driver.Message
|
||||||
|
{
|
||||||
|
public class ExceptionResponse
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Exception report reference ID. This ID will be shared across
|
||||||
|
/// similar exceptions
|
||||||
|
/// </summary>
|
||||||
|
public string RefId { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Was the report successfully processed on the server
|
||||||
|
/// </summary>
|
||||||
|
public bool Successful
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return !string.IsNullOrEmpty(RefId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Exception that caused the message to fail.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This property will only be populated if <see cref="ClientConfiguration.ThrowsExceptions"/> is set to <see cref="bool.False"/>/>
|
||||||
|
/// Exception is thrown if <see cref="ClientConfiguration.ThrowsExceptions"/> is set to <see cref="bool.True"/>.
|
||||||
|
/// </remarks>
|
||||||
|
public Exception Exception { get; internal set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
namespace Exceptron.Driver.Message
|
||||||
|
{
|
||||||
|
internal class Frame
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Order of current frame
|
||||||
|
/// </summary>
|
||||||
|
public int i { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Line number of the current frame
|
||||||
|
/// </summary>
|
||||||
|
public int ln { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// File name of the current frame
|
||||||
|
/// </summary>
|
||||||
|
public string fn { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method name for current frame
|
||||||
|
/// </summary>
|
||||||
|
public string m { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Class name for current frame
|
||||||
|
/// </summary>
|
||||||
|
public string c { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
namespace Exceptron.Driver
|
||||||
|
{
|
||||||
|
public class ValidationError
|
||||||
|
{
|
||||||
|
public string ErrorCode { get; set; }
|
||||||
|
|
||||||
|
public string FieldName { get; set; }
|
||||||
|
|
||||||
|
public string Message { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,408 @@
|
|||||||
|
//http://fastjson.codeplex.com/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Exceptron.Driver.fastJSON
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class encodes and decodes JSON strings.
|
||||||
|
/// Spec. details, see http://www.json.org/
|
||||||
|
///
|
||||||
|
/// JSON uses Arrays and Objects. These correspond here to the datatypes ArrayList and Hashtable.
|
||||||
|
/// All numbers are parsed to doubles.
|
||||||
|
/// </summary>
|
||||||
|
internal class JsonParser
|
||||||
|
{
|
||||||
|
enum Token
|
||||||
|
{
|
||||||
|
None = -1, // Used to denote no Lookahead available
|
||||||
|
Curly_Open,
|
||||||
|
Curly_Close,
|
||||||
|
Squared_Open,
|
||||||
|
Squared_Close,
|
||||||
|
Colon,
|
||||||
|
Comma,
|
||||||
|
String,
|
||||||
|
Number,
|
||||||
|
True,
|
||||||
|
False,
|
||||||
|
Null
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly char[] json;
|
||||||
|
readonly StringBuilder s = new StringBuilder();
|
||||||
|
Token lookAheadToken = Token.None;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
internal JsonParser(string json)
|
||||||
|
{
|
||||||
|
this.json = json.ToCharArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Decode()
|
||||||
|
{
|
||||||
|
return ParseValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> ParseObject()
|
||||||
|
{
|
||||||
|
Dictionary<string, object> table = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
ConsumeToken(); // {
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
switch (LookAhead())
|
||||||
|
{
|
||||||
|
|
||||||
|
case Token.Comma:
|
||||||
|
ConsumeToken();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Token.Curly_Close:
|
||||||
|
ConsumeToken();
|
||||||
|
return table;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
|
||||||
|
// name
|
||||||
|
string name = ParseString();
|
||||||
|
|
||||||
|
// :
|
||||||
|
if (NextToken() != Token.Colon)
|
||||||
|
{
|
||||||
|
throw new Exception("Expected colon at index " + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// value
|
||||||
|
object value = ParseValue();
|
||||||
|
|
||||||
|
table[name] = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SILVERLIGHT
|
||||||
|
private List<object> ParseArray()
|
||||||
|
{
|
||||||
|
List<object> array = new List<object>();
|
||||||
|
#else
|
||||||
|
private ArrayList ParseArray()
|
||||||
|
{
|
||||||
|
ArrayList array = new ArrayList();
|
||||||
|
#endif
|
||||||
|
ConsumeToken(); // [
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
switch (LookAhead())
|
||||||
|
{
|
||||||
|
|
||||||
|
case Token.Comma:
|
||||||
|
ConsumeToken();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Token.Squared_Close:
|
||||||
|
ConsumeToken();
|
||||||
|
return array;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
array.Add(ParseValue());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object ParseValue()
|
||||||
|
{
|
||||||
|
switch (LookAhead())
|
||||||
|
{
|
||||||
|
case Token.Number:
|
||||||
|
return ParseNumber();
|
||||||
|
|
||||||
|
case Token.String:
|
||||||
|
return ParseString();
|
||||||
|
|
||||||
|
case Token.Curly_Open:
|
||||||
|
return ParseObject();
|
||||||
|
|
||||||
|
case Token.Squared_Open:
|
||||||
|
return ParseArray();
|
||||||
|
|
||||||
|
case Token.True:
|
||||||
|
ConsumeToken();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case Token.False:
|
||||||
|
ConsumeToken();
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case Token.Null:
|
||||||
|
ConsumeToken();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception("Unrecognized token at index" + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ParseString()
|
||||||
|
{
|
||||||
|
ConsumeToken(); // "
|
||||||
|
|
||||||
|
s.Length = 0;
|
||||||
|
|
||||||
|
int runIndex = -1;
|
||||||
|
|
||||||
|
while (index < json.Length)
|
||||||
|
{
|
||||||
|
var c = json[index++];
|
||||||
|
|
||||||
|
if (c == '"')
|
||||||
|
{
|
||||||
|
if (runIndex != -1)
|
||||||
|
{
|
||||||
|
if (s.Length == 0)
|
||||||
|
return new string(json, runIndex, index - runIndex - 1);
|
||||||
|
|
||||||
|
s.Append(json, runIndex, index - runIndex - 1);
|
||||||
|
}
|
||||||
|
return s.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c != '\\')
|
||||||
|
{
|
||||||
|
if (runIndex == -1)
|
||||||
|
runIndex = index - 1;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == json.Length) break;
|
||||||
|
|
||||||
|
if (runIndex != -1)
|
||||||
|
{
|
||||||
|
s.Append(json, runIndex, index - runIndex - 1);
|
||||||
|
runIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (json[index++])
|
||||||
|
{
|
||||||
|
case '"':
|
||||||
|
s.Append('"');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
s.Append('\\');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '/':
|
||||||
|
s.Append('/');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
s.Append('\b');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
s.Append('\f');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
s.Append('\n');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'r':
|
||||||
|
s.Append('\r');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
s.Append('\t');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
{
|
||||||
|
int remainingLength = json.Length - index;
|
||||||
|
if (remainingLength < 4) break;
|
||||||
|
|
||||||
|
// parse the 32 bit hex into an integer codepoint
|
||||||
|
uint codePoint = ParseUnicode(json[index], json[index + 1], json[index + 2], json[index + 3]);
|
||||||
|
s.Append((char)codePoint);
|
||||||
|
|
||||||
|
// skip 4 chars
|
||||||
|
index += 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception("Unexpectedly reached end of string");
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint ParseSingleChar(char c1, uint multipliyer)
|
||||||
|
{
|
||||||
|
uint p1 = 0;
|
||||||
|
if (c1 >= '0' && c1 <= '9')
|
||||||
|
p1 = (uint)(c1 - '0') * multipliyer;
|
||||||
|
else if (c1 >= 'A' && c1 <= 'F')
|
||||||
|
p1 = (uint)((c1 - 'A') + 10) * multipliyer;
|
||||||
|
else if (c1 >= 'a' && c1 <= 'f')
|
||||||
|
p1 = (uint)((c1 - 'a') + 10) * multipliyer;
|
||||||
|
return p1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint ParseUnicode(char c1, char c2, char c3, char c4)
|
||||||
|
{
|
||||||
|
uint p1 = ParseSingleChar(c1, 0x1000);
|
||||||
|
uint p2 = ParseSingleChar(c2, 0x100);
|
||||||
|
uint p3 = ParseSingleChar(c3, 0x10);
|
||||||
|
uint p4 = ParseSingleChar(c4, 1);
|
||||||
|
|
||||||
|
return p1 + p2 + p3 + p4;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ParseNumber()
|
||||||
|
{
|
||||||
|
ConsumeToken();
|
||||||
|
|
||||||
|
// Need to start back one place because the first digit is also a token and would have been consumed
|
||||||
|
var startIndex = index - 1;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
var c = json[index];
|
||||||
|
|
||||||
|
if ((c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+' || c == 'e' || c == 'E')
|
||||||
|
{
|
||||||
|
if (++index == json.Length) throw new Exception("Unexpected end of string whilst parsing number");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
return new string(json, startIndex, index - startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Token LookAhead()
|
||||||
|
{
|
||||||
|
if (lookAheadToken != Token.None) return lookAheadToken;
|
||||||
|
|
||||||
|
return lookAheadToken = NextTokenCore();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConsumeToken()
|
||||||
|
{
|
||||||
|
lookAheadToken = Token.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Token NextToken()
|
||||||
|
{
|
||||||
|
var result = lookAheadToken != Token.None ? lookAheadToken : NextTokenCore();
|
||||||
|
|
||||||
|
lookAheadToken = Token.None;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Token NextTokenCore()
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
|
||||||
|
// Skip past whitespace
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c = json[index];
|
||||||
|
|
||||||
|
if (c > ' ') break;
|
||||||
|
if (c != ' ' && c != '\t' && c != '\n' && c != '\r') break;
|
||||||
|
|
||||||
|
} while (++index < json.Length);
|
||||||
|
|
||||||
|
if (index == json.Length)
|
||||||
|
{
|
||||||
|
throw new Exception("Reached end of string unexpectedly");
|
||||||
|
}
|
||||||
|
|
||||||
|
c = json[index];
|
||||||
|
|
||||||
|
index++;
|
||||||
|
|
||||||
|
//if (c >= '0' && c <= '9')
|
||||||
|
// return Token.Number;
|
||||||
|
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '{':
|
||||||
|
return Token.Curly_Open;
|
||||||
|
|
||||||
|
case '}':
|
||||||
|
return Token.Curly_Close;
|
||||||
|
|
||||||
|
case '[':
|
||||||
|
return Token.Squared_Open;
|
||||||
|
|
||||||
|
case ']':
|
||||||
|
return Token.Squared_Close;
|
||||||
|
|
||||||
|
case ',':
|
||||||
|
return Token.Comma;
|
||||||
|
|
||||||
|
case '"':
|
||||||
|
return Token.String;
|
||||||
|
|
||||||
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
|
case '-': case '+': case '.':
|
||||||
|
return Token.Number;
|
||||||
|
|
||||||
|
case ':':
|
||||||
|
return Token.Colon;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
if (json.Length - index >= 4 &&
|
||||||
|
json[index + 0] == 'a' &&
|
||||||
|
json[index + 1] == 'l' &&
|
||||||
|
json[index + 2] == 's' &&
|
||||||
|
json[index + 3] == 'e')
|
||||||
|
{
|
||||||
|
index += 4;
|
||||||
|
return Token.False;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
if (json.Length - index >= 3 &&
|
||||||
|
json[index + 0] == 'r' &&
|
||||||
|
json[index + 1] == 'u' &&
|
||||||
|
json[index + 2] == 'e')
|
||||||
|
{
|
||||||
|
index += 3;
|
||||||
|
return Token.True;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
if (json.Length - index >= 3 &&
|
||||||
|
json[index + 0] == 'u' &&
|
||||||
|
json[index + 1] == 'l' &&
|
||||||
|
json[index + 2] == 'l')
|
||||||
|
{
|
||||||
|
index += 3;
|
||||||
|
return Token.Null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception("Could not find token at index " + --index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue