public bool GetOrSaveReference(IDataReader dataReader, out TargetPathInfo reference) { var token = dataReader.ReferenceToken; if (token == null) { reference = null; return(false); } if (references.TryGetValue(token, out reference)) { if ((options & JsonFormatterOptions.PriorCheckReferences) != 0) { if (reference.Equals(this.reference)) { return(false); } } return(true); } references.Add(token, this.reference); reference = null; return(false); }
public void WriteObject(IDataReader <string> dataReader) { if (!CheckObject(dataReader)) { return; } WriteValueBefore(); Expand(2); Append('{'); WriteStructBefore(); var isInArray = this.isInArray; this.isInArray = false; int tOffset = offset; AddDepth(); if ((options & JsonFormatterOptions.PriorCheckReferences) != 0 && dataReader.Count != 0) { dataReader.OnReadAll(new PriorCheckReferenceWriter(references, reference)); } reference = new TargetPathInfo(null, reference); if (options >= JsonFormatterOptions.IgnoreNull) { dataReader.OnReadAll(this, this); } else { dataReader.OnReadAll(this); } reference = reference.Parent; SubtractDepth(); Expand(2); if (tOffset != offset) { --offset; } WriteStructAfter(); Append('}'); this.isInArray = isInArray; WriteValueAfter(); reference.IsFinish = true; }
private TargetPathInfo ReadRefReferenceTarget() { var refString = ReadString(); var refs = refString.Split('/'); var target = new TargetPathInfo("#", null); var index = 0; switch (refs[0]) { case "#": case "": ++index; break; } for (; index < refs.Length; ++index) { if (NumberHelper.Decimal.TryParse(refs[index], out long i) && i >= 0 && i <= int.MaxValue) { target = new TargetPathInfo((int)i, target); } else { target = new TargetPathInfo(refs[index], target); } } return(target); }
public IValueWriter this[int key] { get { CurrentReference = new TargetPathInfo(key, ParentReference); return(this); } }
public IValueWriter this[int key] { [MethodImpl(VersionDifferences.AggressiveInlining)] get { if (options < JsonFormatterOptions.IgnoreNull) { reference = new TargetPathInfo(key, reference.Parent); } return(this); } }
public JsonReferenceSerializer(JsonFormatterOptions options) { if ((options & JsonFormatterOptions.PriorCheckReferences) != 0 && (options & (JsonFormatterOptions.MultiReferencingNull | JsonFormatterOptions.MultiReferencingReference)) == 0) { options ^= JsonFormatterOptions.PriorCheckReferences; } this.options = options; references = new ReferenceCache <TargetPathInfo>(); reference = new TargetPathInfo("#", null); }
private bool TryReadRefReferenceTarget() { if (!IsObject) { return(false); } var temp = current; ++current; SkipWhiteSpace(); if (Length > 5 && (current[1] == '$' || current[0] == '$') && (EqualsByLower(RefKey) || EqualsByLower(RefName))) { if (*current == '$') { current += RefName.Length; } else { current += RefKey.Length; } SkipWhiteSpace(); if (current < end && *current == ':') { ++current; SkipWhiteSpace(); referenceTarget = ReadRefReferenceTarget(); SkipWhiteSpace(); if (current < end && *current == '}') { ++current; return(true); } } } current = temp; return(false); }
private static IDataReader InternalGetTarget(IDataReader dataReader, TargetPathInfo target) { if (target == null || target.IsRoot) { return(dataReader); } dataReader = InternalGetTarget(dataReader, target.Parent); if (target.Name != null) { return(RWHelper.CreateItemReader(dataReader.As <string>(), target.Name)); } else { return(RWHelper.CreateItemReader(dataReader.As <int>(), target.Index)); } }
public IValueWriter this[string key] { [MethodImpl(VersionDifferences.AggressiveInlining)] get { WriteKeyBefore(); InternalWriteString(key); WriteKeyAfter(); if (options < JsonFormatterOptions.IgnoreNull) { reference = new TargetPathInfo(key, reference.Parent); } return(this); } }
private static object InternalGetTarget(object obj, TargetPathInfo target) { if (target == null || target.IsRoot) { return(obj); } var dataReader = RWHelper.CreateReader(obj); dataReader = InternalGetTarget(dataReader, target.Parent); if (target.Name != null) { return(dataReader.As <string>()[target.Name].DirectRead()); } else { return(dataReader.As <int>()[target.Index].DirectRead()); } }
public void WriteReference(TargetPathInfo reference) { WriteValueBefore(); Expand(2); Append('{'); WriteMiddleChars(); Expand(8); Append('"'); Append('$'); Append('r'); Append('e'); Append('f'); Append('"'); WriteKeyAfter(); Expand(2); Append('"'); WriteReferenceItem(reference); Expand(3); Append('"'); WriteMiddleChars(); Append('}'); WriteValueAfter(); }
public PriorCheckReferenceWriter(ReferenceCache <TargetPathInfo> references, TargetPathInfo parentReference) { References = references; ParentReference = parentReference; }
public ReferenceInfo(TargetPathInfo target, SourcePathInfo source) { this.target = target; this.source = source; }
/// <summary> /// 初始化实例 /// </summary> internal JsonLoopReferencingException(TargetPathInfo ref1, TargetPathInfo ref2) : base(string.Format("Json serializating members '{0}' and '{1}' loop referencing.", ref1, ref2)) { }
private TargetPathInfo ReadRefReferenceTarget() { var nameBuilder = new StringBuilder(); var targetPathInfo = new TargetPathInfo("#", null); char textChar = chars[index]; ++index; while (index < length) { var c = chars[index]; if (c == textChar) { ++index; if (IsRootReference(nameBuilder) && targetPathInfo.IsRoot) { return(targetPathInfo); } return(new TargetPathInfo(nameBuilder.ToString(), targetPathInfo)); } else if (c == '/') { try { ++index; if (IsRootReference(nameBuilder) && targetPathInfo.IsRoot) { continue; } targetPathInfo = new TargetPathInfo(nameBuilder.ToString(), targetPathInfo); } finally { nameBuilder.Length = 0; } /* Index Reference. */ if (index < length && IsNumberChar(chars[index])) { var temp = index; int value = chars[index] - '0'; IndexLoop: ++index; if (index >= length) { break; } c = chars[index]; if (IsNumberChar(chars[index])) { value = (value * 10) + (c - '0'); goto IndexLoop; } targetPathInfo = new TargetPathInfo(value, targetPathInfo); if (c == textChar) { ++index; return(targetPathInfo); } if (c == '/') { ++index; continue; } index = temp; } } else if (c == '\\') { ++index; if (index >= length) { throw GetException(); } switch (chars[index]) { case 'b': nameBuilder.Append('\b'); break; case 'f': nameBuilder.Append('\f'); break; case 'n': nameBuilder.Append('\n'); break; case 't': nameBuilder.Append('\t'); break; case 'r': nameBuilder.Append('\r'); break; case 'u': if (index + 4 >= length) { throw GetException(); } nameBuilder.Append((char)((GetDigital(chars[index + 1]) << 12) | (GetDigital(chars[index + 2]) << 8) | (GetDigital(chars[index + 3]) << 4) | (GetDigital(chars[index + 4])))); index += 4; break; default: nameBuilder.Append(chars[index]); break; } } else if (c == '%') { if (index + 2 >= length) { throw GetException(); } ++index; if (NumberHelper.Hex.TryParse(chars + index, 2, out int utf8) != 2) { throw GetException(); } index += 2; if (utf8 >= 0B11100000) { if (index + 6 >= length) { throw GetException(); } if (chars[index] != '%' && chars[index + 3] != '%') { throw GetException(); } if (NumberHelper.Hex.TryParse(chars + index + 1, 2, out int t1) != 2 || NumberHelper.Hex.TryParse(chars + index + 4, 2, out int t2) != 2) { throw GetException(); } utf8 = ((utf8 & 0B1111) << 12) | ((t1 & 0B111111) << 6) | (t2 & 0B111111); index += 6; } else if (utf8 >= 0B11000000) { if (index + 3 >= length) { throw GetException(); } if (chars[index] != '%') { throw GetException(); } if (NumberHelper.Hex.TryParse(chars + index + 1, 2, out int t1) != 2) { throw GetException(); } utf8 = ((utf8 & 0B11111) << 6) | (t1 & 0B111111); index += 3; } nameBuilder.Append((char)utf8); } else { ++index; nameBuilder.Append(c); } } throw GetException(); }
private bool TryReadRefReferenceTarget() { if (chars[this.index] != '{') { return(false); } const string RefName = "$REF"; var index = this.index; ++index; while (index < length) { var c = chars[index]; switch (c) { case ' ': case '\n': case '\r': case '\t': ++index; continue; case '"': case '\'': ++index; if (StringHelper.StartWithByUpper(chars + index, length, RefName) && index + RefName.Length < length && chars[index + RefName.Length] == c) { ++index; index += RefName.Length; goto IsRef; } return(false); case '$': if (StringHelper.StartWithByUpper(chars + index, length, RefName) && index + RefName.Length < length) { switch (chars[index + RefName.Length]) { case ' ': case '\n': case '\r': case '\t': case ':': index += RefName.Length; goto IsRef; } } return(false); default: return(false); } } return(false); IsRef: index = StringHelper.IndexOf(chars, index, length, ':'); if (index == -1) { throw GetException(); } ++index; while (index < length) { switch (chars[index]) { case ' ': case '\n': case '\r': case '\t': ++index; continue; default: goto ReadReference; } } throw GetException(); ReadReference: this.index = index; referenceTarget = ReadRefReferenceTarget(); while (this.index < length) { switch (chars[this.index]) { case ' ': case '\n': case '\r': case '\t': ++this.index; continue; case '}': ++this.index; return(true); default: goto Error; } } throw GetException(); Error: throw new ArgumentException("Json reference object cannot contains other field.", GetException()); }
private void WriteReferenceItem(TargetPathInfo reference) { var temp = reference; var length = 0; GetLengthLoop: if (temp.Name != null) { var name = temp.Name; for (int i = name.Length - 1; i >= 0; --i) { switch (name[i]) { case '\\': case '/': case '"': length += 3; break; default: ++length; break; } } } else { length += GetLength(temp.Index); } if (temp.Parent != null) { temp = temp.Parent; ++length; goto GetLengthLoop; } Expand(length + 2); this.offset += length; var offset = this.offset; var chars = hGlobal.GetPointer(); AppendLoop: if (reference.Name != null) { var name = reference.Name; for (int i = name.Length - 1; i >= 0; --i) { var c = name[i]; switch (c) { case '\\': // %5C chars[--offset] = 'C'; chars[--offset] = '5'; chars[--offset] = '%'; break; case '/': // %2F chars[--offset] = 'F'; chars[--offset] = '2'; chars[--offset] = '%'; break; case '"': // %22 chars[--offset] = '2'; chars[--offset] = '2'; chars[--offset] = '%'; break; default: chars[--offset] = c; break; } } } else { var index = reference.Index; do { chars[--offset] = (char)(index - (index /= 10) * 10 + '0'); } while (index > 0); } if (reference.Parent != null) { reference = reference.Parent; chars[--offset] = '/'; goto AppendLoop; } }
public bool Filter(ValueFilterInfo <int> valueInfo) { reference = new TargetPathInfo(valueInfo.Key, reference.Parent); return(Filter(valueInfo.ValueCopyer)); }