예제 #1
0
파일: manual.go 프로젝트: andyleap/chitin
// Name returns a view of the name. Caller must not keep references to
// it past the lifetime of the view.
//
// If the message is truncated, returns an empty string.
func (v *PersonV2View) Name() string {
	l, n := varuint.Uint64(v.data[slotsLenPersonV2View:])
	if n < 0 {
		return ""
	}
	if l == 0 {
		panic("TODO padding not handled yet")
	}
	l--
	const maxInt = int(^uint(0) >> 1)
	if l > uint64(maxInt) {
		// technically, it has to be truncated because it wouldn't fit
		// in memory ;)
		return ""
	}
	end := slotsLenPersonV2View + n + int(l)
	if end > len(v.data) {
		return ""
	}
	var s string
	p := (*reflect.StringHeader)(unsafe.Pointer(&s))
	p.Data = uintptr(unsafe.Pointer(&v.data[slotsLenPersonV2View+n]))
	p.Len = int(l)
	return s
}
예제 #2
0
// Next returns the contents of the next frame.
//
// Returns io.EOF if there are no more frames. Returns
// io.ErrUnexpectedEOF on truncated data.
func (v *FramedView) Next() ([]byte, error) {
loop:
	if len(v.data) == 0 {
		return nil, io.EOF
	}
	l, n := varuint.Uint64(v.data)
	if n < 0 {
		return nil, io.ErrUnexpectedEOF
	}
	if l == 0 {
		goto loop
	}
	l--
	const maxInt = int(^uint(0) >> 1)
	if l > uint64(maxInt) {
		// technically, it has to be truncated because it wouldn't fit
		// in memory ;)
		return nil, io.ErrUnexpectedEOF
	}
	end := n + int(l)
	if end > len(v.data) {
		return nil, io.ErrUnexpectedEOF
	}
	b := v.data[n:end]
	v.data = v.data[end:]
	return b, nil
}
예제 #3
0
func chitinParseLengthPrefixed(data []byte) (msg []byte, next []byte, err error) {
loop:
	l, n := varuint.Uint64(data)
	if n < 0 {
		return nil, nil, io.ErrUnexpectedEOF
	}
	if l == 0 {
		// padding
		data = data[n:]
		goto loop
	}
	l--

	const maxInt = int(^uint(0) >> 1)
	if l > uint64(maxInt) {
		// technically, it has to be truncated because it wouldn't fit
		// in memory ;)
		return nil, nil, io.ErrUnexpectedEOF
	}
	li := int(l)

	// TODO prevent overflow here
	end := n + li
	if end > len(data) {
		return nil, nil, io.ErrUnexpectedEOF
	}

	low := n
	high := low + li
	return data[low:high], data[high:], nil
}
예제 #4
0
func BenchmarkDchestUint64MaxLen(b *testing.B) {
	var res uint64
	b.SetBytes(8)
	for i := 0; i < b.N; i++ {
		res, _ = varuint.Uint64(tests[17].encoded)
	}
	_ = res
}
예제 #5
0
func BenchmarkDchestUint64All(b *testing.B) {
	var res uint64
	b.SetBytes(8)
	for i := 0; i < b.N; i++ {
		for _, test := range tests {
			res, _ = varuint.Uint64(test.encoded)
		}
	}
	_ = res
}
예제 #6
0
파일: manual.go 프로젝트: andyleap/chitin
func NewMyProtocolView(data []byte) (MyProtocolMessage, error) {
	if len(data) == 0 {
		return nil, chitin.ErrWrongSize
	}
	kind, n := varuint.Uint64(data)
	if n < 0 {
		return nil, chitin.ErrWrongSize
	}
	data = data[n:]
	switch kind {
	default:
		return nil, chitin.ErrUnknownMessageKind
	case 0:
		return nil, chitin.ErrIsPadding
	case 1:
		return NewPersonV2View(data)
	}
}
예제 #7
0
func TestVaruint(t *testing.T) {
	for i, test := range tests {
		b := make([]byte, len(test.encoded))
		n := varuint.PutUint64(b, test.decoded)
		if n != test.n {
			t.Errorf("encode %d: got %d want %d", i, n, test.n)
		}
		if !bytes.Equal(b, test.encoded) {
			t.Errorf("encode %d: got %v want %v", i, b[0:n], test.encoded)
		}
		v, n := varuint.Uint64(test.encoded)
		if n != test.n {
			t.Errorf("decode %d: got %d want %d", i, n, test.n)
		}
		if v != test.decoded {
			t.Errorf("decode %d: got %d want %d", i, v, test.decoded)
		}
	}
}