コード例 #1
0
        /// <summary>
        /// Writes the property name of a name/value pair on a Json object.
        /// </summary>
        /// <param name="name">The name of the property.</param>
        public override void WritePropertyName(string name)
        {
            base.WritePropertyName(name);

            int ref_index = 0;

            if (!this.PropertyReferences.TryGetValue(name, out ref_index))
            {
                bool   toShared = false;
                byte[] buf;
                if (SmileUtil.IsASCIIBytes(name, out buf))
                {
                    toShared = _writer.WriteAsciiPropertyName(buf);
                }
                else
                {
                    toShared = _writer.WriteUnicodePropertyName(buf);
                }

                if (toShared)
                {
                    ref_index = CurrentPropertyReferenceIndex;
                    this.PropertyReferences.Add(name, ref_index);
                    CurrentPropertyReferenceIndex++;
                }
            }
            else
            {
                _writer.WriteShortReferencePropertyName(ref_index);
            }
        }
コード例 #2
0
        private long ReadZigzag64()
        {
            int i = this._reader.ReadSByte();             // first 7 bits

            i = (i << 7) + this._reader.ReadSByte();      // 14 bits
            i = (i << 7) + this._reader.ReadSByte();      // 21
            i = (i << 7) + this._reader.ReadSByte();

            int ptr    = 4;
            int maxEnd = 11;

            // Ok: couple of bytes more
            long l = i;

            do
            {
                int value = this._reader.ReadSByte();
                ptr++;
                if (value < 0)
                {
                    l = (l << 6) + (value & 0x3F);
                    return(SmileUtil.zigzagDecode(l));
                }
                l = (l << 7) + value;
            } while (ptr < maxEnd);
            throw new FormatException("bad zigzag64");
        }
コード例 #3
0
        //private const int TOKEN_PREFIX_SMALL_INT = 0xC0;
        //private const int TOKEN_BYTE_INT_32 = 0x24;
        //private const int TOKEN_BYTE_INT_64 = 0x25;
        public void WriteInteger(int value)
        {
            int i = value;

            // First things first: let's zigzag encode number
            i = SmileUtil.zigzagEncode(i);
            // tiny (single byte) or small (type + 6-bit value) number?
            if (i <= 0x3F && i >= 0)
            {
                if (i <= 0x1F)                   // tiny
                {
                    this._writer.Write((byte)((byte)VALUE_CONSTANTS.SmallInteger_BEGIN + i));
                    return;
                }
                // nope, just small, 2 bytes (type, 1-byte zigzag value) for 6 bit value
                this._Write(VALUE_CONSTANTS.Integer, (byte)(0x80 + i));
                return;
            }
            // Ok: let's find minimal representation then
            byte b0 = (byte)(0x80 + (i & 0x3F));

            //i >>>= 6;
            i = (int)((uint)i >> 6);
            if (i <= 0x7F)               // 13 bits is enough (== 3 byte total encoding)
            {
                this._Write(VALUE_CONSTANTS.Integer, (byte)i, b0);
                return;
            }
            byte b1 = (byte)(i & 0x7F);

            i >>= 7;
            if (i <= 0x7F)
            {
                this._Write(VALUE_CONSTANTS.Integer, (byte)i, b1, b0);
                return;
            }
            byte b2 = (byte)(i & 0x7F);

            i >>= 7;
            if (i <= 0x7F)
            {
                this._Write(VALUE_CONSTANTS.Integer, (byte)i, b2, b1, b0);
                return;
            }
            // no, need all 5 bytes
            byte b3 = (byte)(i & 0x7F);

            this._Write(VALUE_CONSTANTS.Integer, (byte)(i >> 7), b3, b2, b1, b0);

//			throw new NotImplementedException();
        }
コード例 #4
0
        private int ReadZigzag32()
        {
            int value = this._reader.ReadSByte();
            int i;

            if (value < 0)                // 6 bits
            {
                value &= 0x3F;
            }
            else
            {
                i = this._reader.ReadSByte();
                if (i >= 0)                    // 13 bits
                {
                    value = (value << 7) + i;
                    i     = this._reader.ReadSByte();
                    if (i >= 0)
                    {
                        value = (value << 7) + i;
                        i     = this._reader.ReadSByte();
                        if (i >= 0)
                        {
                            value = (value << 7) + i;
                            // and then we must get negative
                            i = this._reader.ReadSByte();
                            if (i >= 0)
                            {
                                throw new Exception("Corrupt input; 32-bit VInt extends beyond 5 data bytes");
                            }
                        }
                    }
                }
                value = (value << 6) + (i & 0x3F);
            }
            value = SmileUtil.zigzagDecode(value);
            return(value);
        }
コード例 #5
0
        public void WriteString(string value)
        {
            byte[] buf;
            bool   isASCII = SmileUtil.IsASCIIBytes(value, out buf);

            if (buf.Length == 0)
            {
                this._Write(VALUE_CONSTANTS.EmptyString);
            }

            else if (isASCII)
            {
                if (buf.Length >= 1 && buf.Length <= 64)
                {
                    this.WriteShortString((byte)((byte)VALUE_CONSTANTS.TinyAscii_BEGIN + buf.Length - 1), buf);
                }
                else
                {
                    this.WriteFCString((byte)VALUE_CONSTANTS.LongAsciiText, buf);
                }
            }
            else
            {
                if (buf.Length < 2)
                {
                    throw new FormatException("bad utf-8 string.");
                }
                else if (buf.Length >= 2 && buf.Length <= 64)
                {
                    this.WriteShortString((byte)((byte)VALUE_CONSTANTS.TinyUnicode_BEGIN + buf.Length - 2), buf);
                }
                else
                {
                    this.WriteFCString((byte)VALUE_CONSTANTS.LongUnicodeText, buf);
                }
            }
        }
コード例 #6
0
        private string ReadPropertyKey(byte b)
        {
            String propertyKey = null;

            if (b >= (byte)KEY_TYPES.ShortAsciiName_BEGIN && b <= (byte)KEY_TYPES.ShortAsciiName_END)
            {
                int    l   = b - (byte)KEY_TYPES.ShortAsciiName_BEGIN + 1;
                byte[] buf = this.ReadBytes(l);
                if (!SmileUtil.IsASCIIString(buf, out propertyKey))
                {
                    throw new FormatException("Wrong encoding.");
                }
                if (SharedKeyNames.Count >= 1024)
                {
                    SharedKeyNames.Clear();
                }
                SharedKeyNames.Add(propertyKey);
            }
            else if (b >= (byte)KEY_TYPES.ShortUnicodeName_BEGIN && b <= (byte)KEY_TYPES.ShortUnicodeName_END)
            {
                int    l    = b - (byte)KEY_TYPES.ShortUnicodeName_BEGIN + 1;
                byte[] buf  = this.ReadBytes(l);
                string name = Encoding.UTF8.GetString(buf, 0, buf.Length);
                if (SharedKeyNames.Count >= 1024)
                {
                    SharedKeyNames.Clear();
                }
                SharedKeyNames.Add(name);
                propertyKey = name;
            }
            else if (b >= (byte)KEY_TYPES.ShortSharedKeyNameReference_BEGIN && b <= (byte)KEY_TYPES.ShortSharedKeyNameReference_END)
            {
                int i = b - (byte)KEY_TYPES.ShortSharedKeyNameReference_BEGIN;
                if (this.SharedKeyNames.Count <= i)
                {
                    throw new IndexOutOfRangeException("invalid shared key index.");
                }
                propertyKey = this.SharedKeyNames [i];
            }
            else if (b == (byte)KEY_TYPES.EmptyString)
            {
                propertyKey = string.Empty;
            }
            else if (b >= (byte)KEY_TYPES.LongSharedKeyNameReference_BEGIN && b <= (byte)KEY_TYPES.LongSharedKeyNameReference_END)
            {
                byte nextByte = this.ReadByte();
                int  offset   = (((int)(b & 0x3)) << 8) | nextByte;
                if (this.SharedKeyNames.Count <= offset)
                {
                    throw new IndexOutOfRangeException("invalid shared key index.");
                }
                propertyKey = this.SharedKeyNames [offset];
            }
            else if (b == (byte)KEY_TYPES.LongUnicodeName)              //Long (not-yet-shared) Unicode name. Variable-length String
            {
                byte[] buf = ReadFCStringBuff();
                if (buf.Length < 64)
                {
                    throw new ArgumentOutOfRangeException("long unicode property name must be longer than 63bytes: " + buf.Length);
                }
                propertyKey = Encoding.UTF8.GetString(buf, 0, buf.Length);
                if (SharedKeyNames.Count >= 1024)
                {
                    SharedKeyNames.Clear();
                }
                if (SmileConstant.SHARE_LONG_UNICODE_KEY_NAME)
                {
                    SharedKeyNames.Add(propertyKey);
                }
            }
            else if (b == (byte)KEY_TYPES.BAD_0X3A)
            {
                throw new ArgumentOutOfRangeException("invalid property type: 0x3A");
            }
            else
            {
                throw new Exception(string.Format(CultureInfo.CurrentCulture, "bad property name type: {0:X}", b));
            }

            //System.Diagnostics.Debug.WriteLine("propertyKey: {0}", propertyKey);
            return(propertyKey);
        }
コード例 #7
0
        private void ReadType(SmileType type)
        {
            switch (type.TypeClass)
            {
            case SmileTypeClass.TinyASCII:
            {
                int length = type.Value + 1;
                SetToken(JsonToken.String, ReadStringInLength(length));
                break;
            }

            case SmileTypeClass.ShortASCII:
            {
                int length = type.Value + 33;
                SetToken(JsonToken.String, ReadStringInLength(length));
                break;
            }

            case SmileTypeClass.TinyUnicode:
            {
                int length = type.Value + 2;
                SetToken(JsonToken.String, ReadStringInLength(length));
                break;
            }

            case SmileTypeClass.ShortUnicode:
            {
                int length = type.Value + 34;
                SetToken(JsonToken.String, ReadStringInLength(length));
                break;
            }

            case SmileTypeClass.SmallIntegers:
            {
                SetToken(JsonToken.Integer, ReadZigzagNumber(type.Value));
                break;
            }

            case SmileTypeClass.SimpleLiteralsNumbers:
            {
                switch (type.Value)
                {
                case 0x00:
                    SetToken(JsonToken.String, String.Empty);
                    break;

                case 0x01:
                    SetToken(JsonToken.Null);
                    break;

                case 0x02:
                    SetToken(JsonToken.Boolean, false);
                    break;

                case 0x03:
                    SetToken(JsonToken.Boolean, true);
                    break;

                case 0x04:
                    SetToken(JsonToken.Integer, ReadZigzag32());
                    break;

                case 0x05:
                    SetToken(JsonToken.Integer, ReadZigzag64());
                    break;

                case 0x06:
                    SetToken(JsonToken.Integer, ReadBigInteger());
                    break;

                case 0x08:
                    SetToken(JsonToken.Float, ReadFloat32());
                    break;

                case 0x09:
                    SetToken(JsonToken.Float, ReadFloat64());
                    break;

                case 0x0A:
                    SetToken(JsonToken.Float, ReadBigDecimal());
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                    break;
                }
                break;
            }

            case SmileTypeClass.START_OBJECT:
            {
                SetToken(JsonToken.StartObject);
                PushContext(SmileType.NewObject());
                break;
            }

            case SmileTypeClass.START_ARRAY:
            {
                SetToken(JsonToken.StartArray);
                PushContext(SmileType.NewArray());
                break;
            }

            case SmileTypeClass.Binary:
            {
                SmileBinaryType binaryType;
                byte[]          data = ReadBinary(out binaryType);

                object value = (binaryType != SmileBinaryType.Uuid)
                                                        ? data
                                                        : (object)new Guid(data);

                SetToken(JsonToken.Bytes, value);
                break;
            }

            case SmileTypeClass.Binary7bitEncoded:
            {
                byte[] data = Read7BitBinaryWithLength();
                SetToken(JsonToken.Bytes, data);
                break;
            }

            case SmileTypeClass.LongASCIIText:
            {
                byte[] data = ReadFCStringBuff();
                string text;
                if (!SmileUtil.IsASCIIString(data, out text))
                {
                    throw new FormatException("Wrong encoding.");
                }
                SetToken(JsonToken.String, text);
            }
            break;

            case SmileTypeClass.LongUnicodeText:
            {
                byte[] data = ReadFCStringBuff();
                string text = Encoding.UTF8.GetString(data, 0, data.Length);
                SetToken(JsonToken.String, text);
            }
            break;

            default:
                throw new ArgumentOutOfRangeException("type", "Unexpected SmileType value: " + type.TypeClass);
            }
        }
コード例 #8
0
 private int ReadZigzagNumber(int value)
 {
     return(SmileUtil.zigzagDecode(value));
 }
コード例 #9
0
        public void WriteLong(long value)
        {
            if (value >= int.MinValue && value <= int.MaxValue)
            {
                this.WriteInteger((int)value);
                return;
            }

            value = SmileUtil.zigzagEncode(value);
            // Ok, well, we do know that 5 lowest-significant bytes are needed
            int i = (int)value;
            // 4 can be extracted from lower int
            byte b0 = (byte)(0x80 + (i & 0x3F));              // sign bit set in the last byte
            byte b1 = (byte)((i >> 6) & 0x7F);
            byte b2 = (byte)((i >> 13) & 0x7F);
            byte b3 = (byte)((i >> 20) & 0x7F);

            // fifth one is split between ints:
            value = (long)((ulong)value >> 27);
            byte b4 = (byte)(((int)value) & 0x7F);

            i = (int)(value >> 7);
            if (i == 0)
            {
                this._Write(VALUE_CONSTANTS.Long, b4, b3, b2, b1, b0);
                return;
            }
            if (i <= 0x7F)
            {
                this._Write(VALUE_CONSTANTS.Long, (byte)i, b4, b3, b2, b1, b0);
                return;
            }
            byte b5 = (byte)(i & 0x7F);

            i >>= 7;
            if (i <= 0x7F)
            {
                this._Write(VALUE_CONSTANTS.Long, (byte)i, b5, b4, b3, b2, b1, b0);
                return;
            }
            byte b6 = (byte)(i & 0x7F);

            i >>= 7;
            if (i <= 0x7F)
            {
                this._Write(VALUE_CONSTANTS.Long, (byte)i, b6, b5, b4, b3, b2, b1, b0);
                return;
            }
            byte b7 = (byte)(i & 0x7F);

            i >>= 7;
            if (i <= 0x7F)
            {
                this._Write(VALUE_CONSTANTS.Long, (byte)i, b7, b6, b5, b4, b3, b2, b1, b0);
                return;
            }
            byte b8 = (byte)(i & 0x7F);

            i >>= 7;
            // must be done, with 10 bytes! (9 * 7 + 6 == 69 bits; only need 63)
            this._Write(VALUE_CONSTANTS.Long, (byte)i, b8, b7, b6, b5, b4, b3, b2, b1, b0);
        }