/// <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); } }
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"); }
//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(); }
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); }
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); } } }
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); }
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); } }
private int ReadZigzagNumber(int value) { return(SmileUtil.zigzagDecode(value)); }
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); }