コード例 #1
0
ファイル: basic_test.go プロジェクト: dmitris/ardielle-go
func TestMarshalSimpleTypes(test *testing.T) {
	//null
	var null interface{}
	tdata, err := Marshal(null)
	checkError(test, "nil", tdata, err, -1, []byte{24, 0})

	//bool
	var b bool
	tdata, err = Marshal(b)
	checkError(test, "bool false", tdata, err, -1, []byte{24, 1, 0})
	b = true
	tdata, err = Marshal(b)
	checkError(test, "bool true", tdata, err, -1, []byte{24, 1, 1})

	//int8
	var i8 int8
	tdata, err = Marshal(i8)
	checkError(test, "i8", tdata, err, -1, []byte{24, 2, 0})
	i8 = 23
	tdata, err = Marshal(i8)
	checkError(test, "i8 23", tdata, err, -1, []byte{24, 2, 46})
	i8 = -23
	tdata, err = Marshal(i8)
	checkError(test, "i8 -23", tdata, err, -1, []byte{24, 2, 45})
	i8 = 127
	tdata, err = Marshal(i8)
	checkError(test, "i8 127", tdata, err, -1, []byte{24, 2, 254, 1})
	i8 = -128
	tdata, err = Marshal(i8)
	checkError(test, "i8 -128", tdata, err, -1, []byte{24, 2, 255, 1})
	var u8 uint8 = 0xff
	tdata, err = Marshal(int8(u8))
	checkError(test, "u8 255", tdata, err, -1, []byte{24, 2, 1}) //uint8(0xff) == int8(-1)

	//int16
	var i16 int16 = 23
	tdata, err = Marshal(i16)
	checkError(test, "i16 23", tdata, err, -1, []byte{24, 3, 46})
	i16 = -23
	tdata, err = Marshal(i16)
	checkError(test, "i16 -23", tdata, err, -1, []byte{24, 3, 45})
	i16 = 32767
	tdata, err = Marshal(i16)
	checkError(test, "i16 32767", tdata, err, -1, []byte{24, 3, 254, 255, 3})
	i16 = -32768
	tdata, err = Marshal(i16)
	checkError(test, "i16 -32768", tdata, err, -1, []byte{24, 3, 255, 255, 3})
	var u16 uint16 = 0xffff
	tdata, err = Marshal(int16(u16))
	checkError(test, "u16 65535", tdata, err, -1, []byte{24, 3, 1}) //uint16(0xffff) == int16(-1)

	//int32
	var i32 int32 = 23
	tdata, err = Marshal(i32)
	checkError(test, "i32 23", tdata, err, -1, []byte{24, 4, 46})
	i32 = -23
	tdata, err = Marshal(i32)
	checkError(test, "i32 -23", tdata, err, -1, []byte{24, 4, 45})
	i32 = 0x7fffffff
	tdata, err = Marshal(i32)
	checkError(test, fmt.Sprintf("i32 %d", i32), tdata, err, -1, []byte{24, 4, 254, 255, 255, 255, 15})
	i32 = -(0x7fffffff) - 1
	tdata, err = Marshal(i32)
	checkError(test, fmt.Sprintf("i32 %d", i32), tdata, err, -1, []byte{24, 4, 255, 255, 255, 255, 15})
	var i = 23
	tdata, err = Marshal(i)
	checkError(test, "i 23", tdata, err, -1, []byte{24, 4, 46})
	var u32 uint32 = 0xffffffff
	tdata, err = Marshal(int32(u32))
	checkError(test, "u32 4294967295", tdata, err, -1, []byte{24, 4, 1}) //uint32(0xffffffff) == int32(-1)

	i32 = 23
	pt := ptrtest{1, &i32, nil}
	tdata, err = Marshal(pt)
	checkError(test, "pt.Pi32 &23", tdata, err, -1, []byte{0x18, 0x40, 0x13, 0x03, 0x03, 0x49, 0x33, 0x32, 0x04, 0x04, 0x50, 0x69, 0x33, 0x32, 0x04, 0x04, 0x4f, 0x69, 0x33, 0x32, 0x10, 0x40, 0x02, 0x2e, 0x00})
	pt.Oi32 = &i32
	tdata, err = Marshal(pt)
	checkError(test, "pt.Pi32 &23 pt.Oi32 = &23", tdata, err, -1, []byte{0x18, 0x40, 0x13, 0x03, 0x03, 0x49, 0x33, 0x32, 0x04, 0x04, 0x50, 0x69, 0x33, 0x32, 0x04, 0x04, 0x4f, 0x69, 0x33, 0x32, 0x10, 0x40, 0x02, 0x2e, 0x04, 0x2e})

	//int64
	var i64 int64 = 23
	tdata, err = Marshal(i64)
	checkError(test, "i64 23", tdata, err, -1, []byte{24, 5, 46})
	i64 = -23
	tdata, err = Marshal(i64)
	checkError(test, "i64 -23", tdata, err, -1, []byte{24, 5, 45})
	i64 = 0x7fffffffffffffff
	tdata, err = Marshal(i64)
	checkError(test, fmt.Sprintf("i64 %d", i64), tdata, err, -1, []byte{24, 5, 254, 255, 255, 255, 255, 255, 255, 255, 255, 1})
	i64 = -i64 - 1
	tdata, err = Marshal(i64)
	checkError(test, fmt.Sprintf("i64 %d", i64), tdata, err, -1, []byte{24, 5, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1})
	var u64 uint64 = 0xffffffffffffffff
	tdata, err = Marshal(int64(u64))
	checkError(test, "u64 18446744073709551615", tdata, err, -1, []byte{24, 5, 1}) //uint64(0xffffffffffffffff) == int64(-1)

	//float32
	var f32 float32
	tdata, err = Marshal(f32)
	checkError(test, "f32", tdata, err, -1, []byte{24, 6, 0, 0, 0, 0})

	f32 = 23.57
	tdata, err = Marshal(f32)
	checkError(test, "f32 23.57", tdata, err, -1, []byte{24, 6, 65, 188, 143, 92})

	//float64
	var f64 float64
	tdata, err = Marshal(f64)
	checkError(test, "f64", tdata, err, -1, []byte{24, 7, 0, 0, 0, 0, 0, 0, 0, 0})

	f64 = 23.57
	tdata, err = Marshal(f64)
	checkError(test, "f64 23.57", tdata, err, -1, []byte{24, 7, 64, 55, 145, 235, 133, 30, 184, 82})

	//bytes
	var bs []byte
	tdata, err = Marshal(bs)
	checkError(test, "bytes nil slice", tdata, err, -1, []byte{24, 0})
	bs = make([]byte, 0) //empty byte slice
	tdata, err = Marshal(bs)
	checkError(test, "bytes empty slice", tdata, err, -1, []byte{24, 8, 0})
	bs = []byte{1, 2, 3, 4, 5} //initialize byte slice
	tdata, err = Marshal(bs)
	checkError(test, "bytes slice with 5 elements", tdata, err, -1, []byte{24, 8, 5, 1, 2, 3, 4, 5})
	var ba [2]byte
	tdata, err = Marshal(&ba) //
	checkError(test, "bytes pointer to array of length 2", tdata, err, -1, []byte{24, 8, 2, 0, 0})
	tdata, err = Marshal(ba) //this is slower, reflect has a hard time with array values instead of slices
	checkError(test, "bytes array of length 2", tdata, err, -1, []byte{24, 8, 2, 0, 0})

	//string
	var s string
	tdata, err = Marshal(s)
	checkError(test, "s empty string", tdata, err, -1, []byte{24, 32})
	s = "foo"
	tdata, err = Marshal(s)
	checkError(test, "s tiny", tdata, err, -1, []byte{24, 35, 102, 111, 111})
	tdata, err = Marshal(&s)
	checkError(test, "s pointer to tiny", tdata, err, -1, []byte{24, 35, 102, 111, 111})
	s = "*can* fit into the tiny format"
	tdata, err = Marshal(s)
	checkError(test, "s largest tiny", tdata, err, -1, []byte{24, 62, 42, 99, 97, 110, 42, 32, 102, 105, 116, 32, 105, 110, 116, 111, 32, 116, 104, 101, 32, 116, 105, 110, 121, 32, 102, 111, 114, 109, 97, 116})
	s = "*can't* fit into the tiny format"
	tdata, err = Marshal(s)
	checkError(test, "s not tiny", tdata, err, -1, []byte{24, 9, 32, 42, 99, 97, 110, 39, 116, 42, 32, 102, 105, 116, 32, 105, 110, 116, 111, 32, 116, 104, 101, 32, 116, 105, 110, 121, 32, 102, 111, 114, 109, 97, 116})

	s = "tiny 姚冀清"
	tdata, err = Marshal(s)
	checkError(test, "s tiny multibyte", tdata, err, -1, []byte{24, 46, 116, 105, 110, 121, 32, 229, 167, 154, 229, 134, 128, 230, 184, 133})

	s = "looks tiny but is bigger姚冀清"
	tdata, err = Marshal(s)
	checkError(test, "s not quite tiny multibyte", tdata, err, -1, []byte{24, 9, 33, 108, 111, 111, 107, 115, 32, 116, 105, 110, 121, 32, 98, 117, 116, 32, 105, 115, 32, 98, 105, 103, 103, 101, 114, 229, 167, 154, 229, 134, 128, 230, 184, 133})

	//timestamp
	ts, _ := rdl.TimestampParse("2015-05-16T19:50:21.002Z")
	tdata, err = Marshal(ts)
	checkError(test, "timestamp", tdata, err, -1, []byte{24, 10, 65, 213, 85, 231, 223, 64, 32, 197})

	//uuid
	u := rdl.ParseUUID("373ab4c4-fc05-11e4-a198-14109fe4729f")
	tdata, err = Marshal(u)
	checkError(test, "uuid", tdata, err, -1, []byte{24, 12, 55, 58, 180, 196, 252, 5, 17, 228, 161, 152, 20, 16, 159, 228, 114, 159})

	//symbol
	sym := rdl.Symbol("foo")
	tdata, err = Marshal(sym)
	checkError(test, "sym", tdata, err, -1, []byte{24, 11, 0, 3, 102, 111, 111})
	sym2 := rdl.Symbol("bar")
	enc := NewEncoder(nil)
	enc.Encode(sym)
	enc.Encode(sym2)
	enc.Encode(sym)
	enc.Encode(sym2)
	tdata = enc.Bytes()
	checkError(test, "sym reuse", tdata, err, -1, []byte{24, 11, 0, 3, 102, 111, 111, 11, 1, 3, 98, 97, 114, 11, 0, 11, 1})
}
コード例 #2
0
ファイル: decoder.go プロジェクト: dmitris/ardielle-go
func (d *Decoder) DecodeReflect(v reflect.Value) error {
again:
	var tag int
	if d.pendingTag >= 0 {
		tag = d.pendingTag
		d.pendingTag = -1
	} else {
		tag = int(d.ParseUnsigned())
	}
	if d.err != nil {
		return d.err
	}
	if tag >= FirstUserTag {
		idx := int(tag - FirstUserTag)
		if idx < len(d.types) {
			ttype := d.types[idx]
			return d.decodeTypeReflect(ttype, v)
		}
		ttype := d.parseType()
		if ttype == nil {
			d.err = fmt.Errorf("First use of a user tag must be followed by a typedef.")
			return d.err
		}
		d.types = append(d.types, ttype)
		goto again
	} else {
		if (tag & TinyStrTagMask) == TinyStrTag {
			n := tag & TinyStrDataMask
			tinybuf := make([]byte, n)
			d.err = d.readBytes(tinybuf)
			if d.err == nil {
				s := string(tinybuf)
				if v.Kind() == reflect.Interface {
					vv := reflect.New(reflect.TypeOf(s))
					v.Set(vv)
				} else {
					v.SetString(s)
				}
			}
			return d.err
		}
		switch tag {
		case NullTag:
			//already zeroed
			return nil
		case BoolTag:
			b := d.ParseBool()
			if v.Kind() == reflect.Interface {
				v.Set(reflect.New(reflect.TypeOf(b)))
			} else {
				v.SetBool(b)
			}
			return d.err
		case Int8Tag:
			n := int8(d.ParseInt())
			if d.err == nil {
				if v.Kind() == reflect.Interface {
					v.Set(reflect.New(reflect.TypeOf(n)))
				} else {
					v.SetInt(int64(n))
				}
			}
			return d.err
		case Int16Tag:
			n := int16(d.ParseInt())
			if d.err == nil {
				if v.Kind() == reflect.Interface {
					v.Set(reflect.New(reflect.TypeOf(n)))
				} else {
					v.SetInt(int64(n))
				}
			}
			return d.err
		case Int32Tag:
			n := d.ParseInt()
			if d.err == nil {
				if v.Kind() == reflect.Interface {
					v.Set(reflect.New(reflect.TypeOf(n)))
				} else {
					v.SetInt(int64(n))
				}
			}
			return d.err
		case Int64Tag:
			n := d.ParseInt64()
			if d.err == nil {
				if v.Kind() == reflect.Interface {
					v.Set(reflect.New(reflect.TypeOf(n)))
				} else {
					v.SetInt(n)
				}
			}
			return d.err
		case Float32Tag:
			n, err := d.ParseFloat32()
			if err == nil {
				if v.Kind() == reflect.Interface {
					v.Set(reflect.New(reflect.TypeOf(n)))
				} else {
					v.SetFloat(float64(n))
				}
			}
			return err
		case Float64Tag:
			n, err := d.ParseFloat64()
			if err == nil {
				if v.Kind() == reflect.Interface {
					v.Set(reflect.New(reflect.TypeOf(n)))
				} else {
					v.SetFloat(n)
				}
			}
			return err
		case BytesTag:
			b, err := d.ParseBytes()
			if err == nil {
				if v.Kind() == reflect.Interface {
					v.Set(reflect.New(reflect.TypeOf(b)))
				} else {
					v.SetBytes(b)
				}
			}
			return err
		case StringTag:
			s, err := d.ParseString()
			if err == nil {
				if v.Kind() == reflect.Interface {
					v.Set(reflect.New(reflect.TypeOf(s)))
				} else {
					v.SetString(s)
				}
			}
			return err
		case SymbolTag:
			s, err := d.ParseSymbol()
			if err == nil {
				v.Set(reflect.ValueOf(rdl.Symbol(s)))
			}
			return err
		case TimestampTag:
			ts, err := d.ParseTimestamp()
			if err == nil {
				v.Set(reflect.ValueOf(ts))
			}
			return err
		case UUIDTag:
			u, err := d.ParseUUID()
			if err == nil {
				v.Set(reflect.ValueOf(u))
			}
			return err
		case StructTag:
			return d.DecodeStructReflect(v)
		case ArrayTag:
			return d.DecodeArrayReflect(v)
		case MapTag:
			return d.DecodeMapReflect(v)
		}
	}
	return fmt.Errorf("Unexpected tag value: 0x%02x", tag)
}
コード例 #3
0
ファイル: basic_test.go プロジェクト: dmitris/ardielle-go
func TestMarshalMaps(test *testing.T) {
	var tdata []byte
	var err error
	var expected []byte //maps with more than one entry may fail due to randomized hash order. So just check length.

	mbad := make(map[int]interface{})
	tdata, err = Marshal(mbad)
	if err == nil {
		test.Errorf("Map with non-string key did not get rejected as expected")
	}

	//generic map
	var m map[string]interface{}
	tdata, err = Marshal(m)
	checkError(test, "nil generic map", tdata, err, -1, []byte{24, 0})

	m = make(map[string]interface{})
	tdata, err = Marshal(m)
	checkError(test, "nil generic map", tdata, err, -1, []byte{24, 14, 0})

	//m["foo"] = int32(23)
	m["foo"] = 23 //int and int32 get encoded the same
	tdata, err = Marshal(m)
	checkError(test, "generic map of one string-to-int32", tdata, err, -1, []byte{24, 14, 1, 35, 102, 111, 111, 4, 46})
	m["bar"] = "blah"
	tdata, err = Marshal(m)
	expected = []byte{24, 14, 2, 35, 102, 111, 111, 4, 46, 35, 98, 97, 114, 36, 98, 108, 97, 104}
	checkError(test, "generic map of two items", tdata, err, len(expected), nil)

	//other key types
	m2 := make(map[rdl.Symbol]interface{})
	tdata, err = Marshal(m2)
	checkError(test, "empty symbol-to-any map", tdata, err, -1, []byte{24, 14, 0})

	m2 = make(map[rdl.Symbol]interface{})
	//m2[rdl.Symbol("foo")] = "bar"
	m2["foo"] = "bar" //a symbol *is* a string, so you can just pass it in
	tdata, err = Marshal(m2)
	//checkError(test, "symbol-to-any map, 1 entry", tdata, err, -1, []byte{24, 14, 1, 11, 0, 3, 102, 111, 111, 35, 98, 97, 114})

	m2["bar"] = rdl.Symbol("foo")
	tdata, err = Marshal(m2)
	expected = []byte{24, 14, 2, 11, 0, 3, 102, 111, 111, 35, 98, 97, 114, 11, 1, 3, 98, 97, 114, 11, 0}
	//checkError(test, "symbol-to-any map, 2 entries", tdata, err, len(expected), nil)
	var mmm map[rdl.Symbol]interface{}
	err = Unmarshal(tdata, &mmm)
	if err != nil {
		test.Errorf("Cannot unmarshal map[Symbol]interface{}")
	}

	//typed map
	var mii map[int]int
	tdata, err = Marshal(mii)
	if err == nil {
		//the type gets rejected, even though its nil value could have been encoded, to avoid programming errors
		test.Errorf("Map with non-string key did not get rejected as expected")
	}

	msi := make(map[string]int)
	tdata, err = Marshal(msi)
	checkError(test, "map<string,int> empty", tdata, err, -1, []byte{24, 64, 18, 9, 4, 64, 0}) //defines a new type tag (64), uses it

	msi = make(map[string]int)
	msi["foo"] = 23
	tdata, err = Marshal(msi)
	checkError(test, "map<string,int> 1 entry", tdata, err, -1, []byte{24, 64, 18, 9, 4, 64, 1, 3, 102, 111, 111, 46})

	var mmmm interface{}
	err = Unmarshal(tdata, &mmmm)
	if err != nil {
		test.Errorf("Cannot generic unmarshal map[string]int")
	}

	msymi := make(map[rdl.Symbol]int)
	msymi["foo"] = 23
	tdata, err = Marshal(msymi)
	//checkError(test, "map<rdl.Symbol,int> 1 entry", tdata, err, -1, []byte{24, 64, 18, 11, 4, 64, 1, 3, 102, 111, 111, 46})

	msi["bar"] = 57
	tdata, err = Marshal(msi)
	expected = []byte{24, 64, 18, 9, 4, 64, 2, 3, 102, 111, 111, 46, 3, 98, 97, 114, 114}
	checkError(test, "map<string,int> 2 entries", tdata, err, len(expected), nil)
}