Beispiel #1
0
        private CBORObject ObjectFromUtf8Array(byte[] data, int lengthHint)
        {
            CBORObject cbor = data.Length == 0 ? CBORObject.FromObject(String.Empty) :
                              CBORObject.FromRawUtf8(data);

            if (this.stringRefs != null)
            {
                this.stringRefs.AddStringIfNeeded(cbor, lengthHint);
            }
            return(cbor);
        }
Beispiel #2
0
        private CBORObject ParseJSONObject(int depth)
        {
            // Assumes that the last character read was '{'
            if (depth > 1000)
            {
                this.RaiseError("Too deeply nested");
            }
            int        c;
            CBORObject key = null;
            CBORObject obj;
            var        nextchar  = new int[1];
            var        seenComma = false;
            var        myHashMap = new SortedDictionary <CBORObject, CBORObject>();

            while (true)
            {
                c = this.SkipWhitespaceJSON();
                switch (c)
                {
                case -1:
                    this.RaiseError("A JSON object must end with '}'");
                    break;

                case '}':
                    if (seenComma)
                    {
                        // Situation like '{"0"=>1,}'
                        this.RaiseError("Trailing comma");
                        return(null);
                    }
                    return(CBORObject.FromRaw(myHashMap));

                default: {
                    // Read the next string
                    if (c < 0)
                    {
                        this.RaiseError("Unexpected end of data");
                        return(null);
                    }
                    if (c != '"')
                    {
                        this.RaiseError("Expected a string as a key");
                        return(null);
                    }
                    // Parse a string that represents the object's key
                    // The tokenizer already checked the string for invalid
                    // surrogate pairs, so just call the CBORObject
                    // constructor directly
                    obj = CBORObject.FromRawUtf8(this.NextJSONString());
                    key = obj;
                    break;
                }
                }
                if (this.SkipWhitespaceJSON() != ':')
                {
                    this.RaiseError("Expected a ':' after a key");
                }
                int oldCount = myHashMap.Count;
                // NOTE: Will overwrite existing value
                myHashMap[key] = this.NextJSONValue(
                    this.SkipWhitespaceJSON(),
                    nextchar,
                    depth);
                int newCount = myHashMap.Count;
                if (!this.options.AllowDuplicateKeys &&
                    oldCount == newCount)
                {
                    this.RaiseError("Duplicate key already exists");
                    return(null);
                }
                switch (nextchar[0])
                {
                case ',':
                    seenComma = true;
                    break;

                case '}':
                    return(CBORObject.FromRaw(myHashMap));

                default: this.RaiseError("Expected a ',' or '}'");
                    break;
                }
            }
        }
Beispiel #3
0
        private CBORObject NextJSONValue(
            int firstChar,
            int[] nextChar,
            int depth)
        {
            int        c   = firstChar;
            CBORObject obj = null;

            if (c < 0)
            {
                this.RaiseError("Unexpected end of data");
            }
            switch (c)
            {
            case '"': {
                // Parse a string
                // The tokenizer already checked the string for invalid
                // surrogate pairs, so just call the CBORObject
                // constructor directly
                obj         = CBORObject.FromRawUtf8(this.NextJSONString());
                nextChar[0] = this.SkipWhitespaceJSON();
                return(obj);
            }

            case '{': {
                // Parse an object
                obj         = this.ParseJSONObject(depth + 1);
                nextChar[0] = this.SkipWhitespaceJSON();
                return(obj);
            }

            case '[': {
                // Parse an array
                obj         = this.ParseJSONArray(depth + 1);
                nextChar[0] = this.SkipWhitespaceJSON();
                return(obj);
            }

            case 't': {
                // Parse true
                if (this.endPos - this.index <= 2 ||
                    this.bytes[this.index] != (byte)0x72 ||
                    this.bytes[this.index + 1] != (byte)0x75 ||
                    this.bytes[this.index + 2] != (byte)0x65)
                {
                    this.RaiseError("Value can't be parsed.");
                }
                this.index += 3;
                nextChar[0] = this.SkipWhitespaceJSON();
                return(CBORObject.True);
            }

            case 'f': {
                // Parse false
                if (this.endPos - this.index <= 3 ||
                    this.bytes[this.index] != (byte)0x61 ||
                    this.bytes[this.index + 1] != (byte)0x6c ||
                    this.bytes[this.index + 2] != (byte)0x73 ||
                    this.bytes[this.index + 3] != (byte)0x65)
                {
                    this.RaiseError("Value can't be parsed.");
                }
                this.index += 4;
                nextChar[0] = this.SkipWhitespaceJSON();
                return(CBORObject.False);
            }

            case 'n': {
                // Parse null
                if (this.endPos - this.index <= 2 ||
                    this.bytes[this.index] != (byte)0x75 ||
                    this.bytes[this.index + 1] != (byte)0x6c ||
                    this.bytes[this.index + 2] != (byte)0x6c)
                {
                    this.RaiseError("Value can't be parsed.");
                }
                this.index += 3;
                nextChar[0] = this.SkipWhitespaceJSON();
                return(CBORObject.Null);
            }

            case '-': {
                // Parse a negative number
                return(this.NextJSONNegativeNumber(nextChar));
            }

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9': {
                // Parse a nonnegative number
                return(this.NextJSONNonnegativeNumber(c, nextChar));
            }

            default:
                this.RaiseError("Value can't be parsed.");
                break;
            }
            return(null);
        }