示例#1
0
        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);
        }
示例#2
0
        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;
        }
示例#3
0
        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);
        }
示例#4
0
        public IValueWriter this[int key]
        {
            get
            {
                CurrentReference = new TargetPathInfo(key, ParentReference);

                return(this);
            }
        }
示例#5
0
        public IValueWriter this[int key]
        {
            [MethodImpl(VersionDifferences.AggressiveInlining)]
            get
            {
                if (options < JsonFormatterOptions.IgnoreNull)
                {
                    reference = new TargetPathInfo(key, reference.Parent);
                }

                return(this);
            }
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        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));
            }
        }
示例#9
0
        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);
            }
        }
示例#10
0
        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());
            }
        }
示例#11
0
        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();
        }
示例#12
0
 public PriorCheckReferenceWriter(ReferenceCache <TargetPathInfo> references, TargetPathInfo parentReference)
 {
     References      = references;
     ParentReference = parentReference;
 }
示例#13
0
 public ReferenceInfo(TargetPathInfo target, SourcePathInfo source)
 {
     this.target = target;
     this.source = source;
 }
示例#14
0
 /// <summary>
 /// 初始化实例
 /// </summary>
 internal JsonLoopReferencingException(TargetPathInfo ref1, TargetPathInfo ref2)
     : base(string.Format("Json serializating members '{0}' and '{1}' loop referencing.", ref1, ref2))
 {
 }
示例#15
0
        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();
        }
示例#16
0
        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());
        }
示例#17
0
        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;
            }
        }
示例#18
0
        public bool Filter(ValueFilterInfo <int> valueInfo)
        {
            reference = new TargetPathInfo(valueInfo.Key, reference.Parent);

            return(Filter(valueInfo.ValueCopyer));
        }