Commit ea5f7d61 authored by Kirill Smelkov's avatar Kirill Smelkov

go/neo/proto: Serialization support

Provide a way for every message to be encoded/decoded to/from NEO wire
encoding. For this introduce Msg interface with wire coding methods and
provide such methods for all message types.

For selected types the methods are implemented manually.
For most of the types the methods are generated automatically by protogen.go program.

protogen.go was mentioned in http://navytux.spb.ru/~kirr/neo.html#development-overview
in "On server-side NEO/go work started by first implementing messages
serialization in exactly the same wire format as NEO/py does ..." paragraph.

A bit of late protogen fixups history:

	lab.nexedi.com/kirr/neo/commit/c884bfd5
	lab.nexedi.com/kirr/neo/commit/385d813a
	lab.nexedi.com/kirr/neo/commit/0f7e0b00
	lab.nexedi.com/kirr/neo/commit/de3ef2c0

Also a message type can be reverse-looked up by message code via MsgType().
This will be later used in network receive code path.
parent fcd6f9f6
...@@ -26,11 +26,20 @@ import ( ...@@ -26,11 +26,20 @@ import (
"fmt" "fmt"
"math" "math"
"net" "net"
"reflect"
"strconv" "strconv"
"strings" "strings"
"time" "time"
) )
// MsgType looks up message type by message code.
//
// Nil is returned if message code is not valid.
func MsgType(msgCode uint16) reflect.Type {
return msgTypeRegistry[msgCode]
}
func (e *Error) Error() string { func (e *Error) Error() string {
// NOTE here, not in proto.go - because else stringer will be confused. // NOTE here, not in proto.go - because else stringer will be confused.
// XXX better translate to some other errors? // XXX better translate to some other errors?
......
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
// See COPYING file for full licensing terms. // See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options. // See https://www.nexedi.com/licensing for rationale and options.
// Package proto provides definition of NEO messages. // Package proto provides definition of NEO messages and their marshalling
// to/from wire format.
// //
// Two NEO nodes can exchange messages over underlying network link after // Two NEO nodes can exchange messages over underlying network link after
// performing NEO-specific handshake. A message is sent as a packet specifying // performing NEO-specific handshake. A message is sent as a packet specifying
...@@ -25,9 +26,12 @@ ...@@ -25,9 +26,12 @@
// //
// PktHeader describes packet header structure. // PktHeader describes packet header structure.
// //
// Messages are represented by corresponding types. // Messages are represented by corresponding types that all implement Msg interface.
// //
// The proto packages provides only message definitions. // A message type can be looked up by message code with MsgType.
//
// The proto packages provides only message definitions and low-level
// primitives for their marshalling.
package proto package proto
// This file defines everything that relates to messages on the wire. // This file defines everything that relates to messages on the wire.
...@@ -38,14 +42,19 @@ package proto ...@@ -38,14 +42,19 @@ package proto
// several messages and does not itself denote a separate message, its // several messages and does not itself denote a separate message, its
// definition is prefixed with `//neo:proto typeonly` comment. // definition is prefixed with `//neo:proto typeonly` comment.
// //
// The order of message definitions is significant - messages will be assigned // The order of message definitions is significant - messages are assigned
// message codes in the same order they are defined. // message codes in the same order they are defined.
// //
// For compatibility with neo/py a message will have its code assigned with "answer" // For compatibility with neo/py a message has its code assigned with "answer"
// bit set if either message name starts with "Answer" or message definition is // bit set if either message name starts with "Answer" or message definition is
// prefixed with `//neo:proto answer` comment. // prefixed with `//neo:proto answer` comment.
// //
// Packet structure and messages are the same as in neo/py (see protocol.py). // Packet structure and messages are bit-to-bit compatible with neo/py (see protocol.py).
//
// The code to marshal/unmarshal messages is generated by protogen.go .
//go:generate sh -c "go run protogen.go >zproto-marshal.go"
// TODO regroup messages definitions to stay more close to 1 communication topic // TODO regroup messages definitions to stay more close to 1 communication topic
// TODO document protocol itself better (who sends who what with which semantic) // TODO document protocol itself better (who sends who what with which semantic)
...@@ -60,6 +69,10 @@ import ( ...@@ -60,6 +69,10 @@ import (
"lab.nexedi.com/kirr/neo/go/zodb" "lab.nexedi.com/kirr/neo/go/zodb"
"lab.nexedi.com/kirr/neo/go/internal/packed" "lab.nexedi.com/kirr/neo/go/internal/packed"
"encoding/binary"
"errors"
"math"
) )
const ( const (
...@@ -95,6 +108,29 @@ type PktHeader struct { ...@@ -95,6 +108,29 @@ type PktHeader struct {
MsgLen packed.BE32 // payload message length (excluding packet header) MsgLen packed.BE32 // payload message length (excluding packet header)
} }
// Msg is the interface implemented by all NEO messages.
type Msg interface {
// marshal/unmarshal into/from wire format:
// NEOMsgCode returns message code needed to be used for particular message type
// on the wire.
NEOMsgCode() uint16
// NEOMsgEncodedLen returns how much space is needed to encode current message payload.
NEOMsgEncodedLen() int
// NEOMsgEncode encodes current message state into buf.
//
// len(buf) must be >= neoMsgEncodedLen().
NEOMsgEncode(buf []byte)
// NEOMsgDecode decodes data into message in-place.
NEOMsgDecode(data []byte) (nread int, err error)
}
// ErrDecodeOverflow is the error returned by neoMsgDecode when decoding hits buffer overflow
var ErrDecodeOverflow = errors.New("decode: buffer overflow")
// ---- messages ---- // ---- messages ----
type ErrorCode uint32 type ErrorCode uint32
...@@ -212,6 +248,42 @@ type Address struct { ...@@ -212,6 +248,42 @@ type Address struct {
Port uint16 Port uint16
} }
// NOTE if Host == "" -> Port not added to wire (see py.PAddress):
func (a *Address) neoEncodedLen() int {
l := string_neoEncodedLen(a.Host)
if a.Host != "" {
l += 2
}
return l
}
func (a *Address) neoEncode(b []byte) int {
n := string_neoEncode(a.Host, b[0:])
if a.Host != "" {
binary.BigEndian.PutUint16(b[n:], a.Port)
n += 2
}
return n
}
func (a *Address) neoDecode(b []byte) (uint64, bool) {
n, ok := string_neoDecode(&a.Host, b)
if !ok {
return 0, false
}
if a.Host != "" {
b = b[n:]
if len(b) < 2 {
return 0, false
}
a.Port = binary.BigEndian.Uint16(b)
n += 2
} else {
a.Port = 0
}
return n, true
}
// Checksum is a SHA1 hash. // Checksum is a SHA1 hash.
type Checksum [20]byte type Checksum [20]byte
...@@ -223,6 +295,33 @@ type PTid uint64 ...@@ -223,6 +295,33 @@ type PTid uint64
// IdTime represents time of identification. // IdTime represents time of identification.
type IdTime float64 type IdTime float64
func (t IdTime) neoEncodedLen() int {
return 8
}
func (t IdTime) neoEncode(b []byte) int {
// use -inf as value for no data (NaN != NaN -> hard to use NaN in tests)
// NOTE neo/py uses None for "no data"; we use 0 for "no data" to avoid pointer
tt := float64(t)
if tt == math.Inf(-1) {
tt = math.NaN()
}
float64_neoEncode(b, tt)
return 8
}
func (t *IdTime) neoDecode(data []byte) (uint64, bool) {
if len(data) < 8 {
return 0, false
}
tt := float64_neoDecode(data)
if math.IsNaN(tt) {
tt = math.Inf(-1)
}
*t = IdTime(tt)
return 8, true
}
// NodeInfo is information about a node. // NodeInfo is information about a node.
// //
//neo:proto typeonly //neo:proto typeonly
...@@ -974,3 +1073,74 @@ type Truncate struct { ...@@ -974,3 +1073,74 @@ type Truncate struct {
// answer = Error // answer = Error
} }
// ---- runtime support for protogen and custom codecs ----
// customCodec is the interface that is implemented by types with custom encodings.
//
// its semantic is very similar to Msg.
type customCodec interface {
neoEncodedLen() int
neoEncode(buf []byte) (nwrote int)
neoDecode(data []byte) (nread uint64, ok bool) // XXX uint64 or int here?
}
func byte2bool(b byte) bool {
return b != 0
}
func bool2byte(b bool) byte {
if b {
return 1
} else {
return 0
}
}
// NOTE py.None encodes as '\xff' * 8 (-> we use NaN for None)
// NOTE '\xff' * 8 represents FP NaN but many other NaN bits representations exist
func float64_neoEncode(b []byte, f float64) {
var fu uint64
if !math.IsNaN(f) {
fu = math.Float64bits(f)
} else {
// convert all NaNs to canonical \xff * 8
fu = 1<<64 - 1
}
binary.BigEndian.PutUint64(b, fu)
}
func float64_neoDecode(b []byte) float64 {
fu := binary.BigEndian.Uint64(b)
return math.Float64frombits(fu)
}
// XXX we need string_neo* only for Address
// XXX dup of genSlice1 in protogen.go
func string_neoEncodedLen(s string) int {
return 4 + len(s)
}
func string_neoEncode(s string, data []byte) int {
l := len(s)
binary.BigEndian.PutUint32(data, uint32(l))
copy(data[4:4+l], s) // NOTE [:l] to catch data overflow as copy copies minimal len
return 4 + l
}
func string_neoDecode(sp *string, data []byte) (nread uint64, ok bool) {
if len(data) < 4 {
return 0, false
}
l := binary.BigEndian.Uint32(data)
data = data[4:]
if uint64(len(data)) < uint64(l) {
return 0, false
}
*sp = string(data[:l])
return 4 + uint64(l), true
}
...@@ -18,11 +18,313 @@ ...@@ -18,11 +18,313 @@
// See https://www.nexedi.com/licensing for rationale and options. // See https://www.nexedi.com/licensing for rationale and options.
package proto package proto
// NEO. protocol encoding tests
import ( import (
"encoding/binary"
hexpkg "encoding/hex"
"fmt"
"reflect"
"runtime"
"strings"
"testing" "testing"
"unsafe"
"lab.nexedi.com/kirr/neo/go/zodb"
) )
// decode string as hex; panic on error
func hex(s string) string {
b, err := hexpkg.DecodeString(s)
if err != nil {
panic(err)
}
return string(b)
}
// uint16 -> string as encoded on the wire
func u16(v uint16) string {
var b [2]byte
binary.BigEndian.PutUint16(b[:], v)
return string(b[:])
}
// uint32 -> string as encoded on the wire
func u32(v uint32) string {
var b [4]byte
binary.BigEndian.PutUint32(b[:], v)
return string(b[:])
}
// uint64 -> string as encoded on the wire
func u64(v uint64) string {
var b [8]byte
binary.BigEndian.PutUint64(b[:], v)
return string(b[:])
}
func TestPktHeader(t *testing.T) {
// make sure PktHeader is really packed and its size matches PktHeaderLen
if unsafe.Sizeof(PktHeader{}) != 10 {
t.Fatalf("sizeof(PktHeader) = %v ; want 10", unsafe.Sizeof(PktHeader{}))
}
if unsafe.Sizeof(PktHeader{}) != PktHeaderLen {
t.Fatalf("sizeof(PktHeader) = %v ; want %v", unsafe.Sizeof(PktHeader{}), PktHeaderLen)
}
}
// test marshalling for one message type
func testMsgMarshal(t *testing.T, msg Msg, encoded string) {
typ := reflect.TypeOf(msg).Elem() // type of *msg
msg2 := reflect.New(typ).Interface().(Msg)
defer func() {
if e := recover(); e != nil {
t.Errorf("%v: panic ↓↓↓:", typ)
panic(e) // to show traceback
}
}()
// msg.encode() == expected
msgCode := msg.NEOMsgCode()
n := msg.NEOMsgEncodedLen()
msgType := MsgType(msgCode)
if msgType != typ {
t.Errorf("%v: msgCode = %v which corresponds to %v", typ, msgCode, msgType)
}
if n != len(encoded) {
t.Errorf("%v: encodedLen = %v ; want %v", typ, n, len(encoded))
}
buf := make([]byte, n)
msg.NEOMsgEncode(buf)
if string(buf) != encoded {
t.Errorf("%v: encode result unexpected:", typ)
t.Errorf("\thave: %s", hexpkg.EncodeToString(buf))
t.Errorf("\twant: %s", hexpkg.EncodeToString([]byte(encoded)))
}
// encode must panic if passed a smaller buffer
for l := len(buf) - 1; l >= 0; l-- {
func() {
defer func() {
subj := fmt.Sprintf("%v: encode(buf[:encodedLen-%v])", typ, len(encoded)-l)
e := recover()
if e == nil {
t.Errorf("%s did not panic", subj)
return
}
err, ok := e.(runtime.Error)
if !ok {
t.Errorf("%s panic(%#v) ; want runtime.Error", subj, e)
}
estr := err.Error()
if !(strings.Contains(estr, "slice bounds out of range") ||
strings.Contains(estr, "index out of range")) {
t.Errorf("%s unexpected runtime panic: %v", subj, estr)
}
}()
msg.NEOMsgEncode(buf[:l])
}()
}
// msg.decode() == expected
data := []byte(encoded + "noise")
n, err := msg2.NEOMsgDecode(data)
if err != nil {
t.Errorf("%v: decode error %v", typ, err)
}
if n != len(encoded) {
t.Errorf("%v: nread = %v ; want %v", typ, n, len(encoded))
}
if !reflect.DeepEqual(msg2, msg) {
t.Errorf("%v: decode result unexpected: %v ; want %v", typ, msg2, msg)
}
// decode must detect buffer overflow
for l := len(encoded) - 1; l >= 0; l-- {
n, err = msg2.NEOMsgDecode(data[:l])
if !(n == 0 && err == ErrDecodeOverflow) {
t.Errorf("%v: decode overflow not detected on [:%v]", typ, l)
}
}
}
// test encoding/decoding of messages
func TestMsgMarshal(t *testing.T) {
var testv = []struct {
msg Msg
encoded string // []byte
}{
// empty
{&Ping{}, ""},
// uint32, string
{&Error{Code: 0x01020304, Message: "hello"}, "\x01\x02\x03\x04\x00\x00\x00\x05hello"},
// Oid, Tid, bool, Checksum, []byte
{&StoreObject{
Oid: 0x0102030405060708,
Serial: 0x0a0b0c0d0e0f0102,
Compression: false,
Checksum: Checksum{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}, // XXX simpler?
Data: []byte("hello world"),
DataSerial: 0x0a0b0c0d0e0f0103,
Tid: 0x0a0b0c0d0e0f0104,
},
hex("01020304050607080a0b0c0d0e0f010200") +
hex("0102030405060708090a0b0c0d0e0f1011121314") +
hex("0000000b") + "hello world" +
hex("0a0b0c0d0e0f01030a0b0c0d0e0f0104")},
// PTid, [] (of [] of {UUID, CellState})
{&AnswerPartitionTable{
PTid: 0x0102030405060708,
RowList: []RowInfo{
{1, []CellInfo{{11, UP_TO_DATE}, {17, OUT_OF_DATE}}},
{2, []CellInfo{{11, FEEDING}}},
{7, []CellInfo{{11, CORRUPTED}, {15, DISCARDED}, {23, UP_TO_DATE}}},
},
},
hex("0102030405060708") +
hex("00000003") +
hex("00000001000000020000000b000000000000001100000001") +
hex("00000002000000010000000b00000002") +
hex("00000007000000030000000b000000040000000f000000030000001700000000"),
},
// map[Oid]struct {Tid,Tid,bool}
{&AnswerObjectUndoSerial{
ObjectTIDDict: map[zodb.Oid]struct {
CurrentSerial zodb.Tid
UndoSerial zodb.Tid
IsCurrent bool
}{
1: {1, 0, false},
2: {7, 1, true},
8: {7, 1, false},
5: {4, 3, true},
}},
u32(4) +
u64(1) + u64(1) + u64(0) + hex("00") +
u64(2) + u64(7) + u64(1) + hex("01") +
u64(5) + u64(4) + u64(3) + hex("01") +
u64(8) + u64(7) + u64(1) + hex("00"),
},
// map[uint32]UUID + trailing ...
{&CheckReplicas{
PartitionDict: map[uint32]NodeUUID{
1: 7,
2: 9,
7: 3,
4: 17,
},
MinTID: 23,
MaxTID: 128,
},
u32(4) +
u32(1) + u32(7) +
u32(2) + u32(9) +
u32(4) + u32(17) +
u32(7) + u32(3) +
u64(23) + u64(128),
},
// uint32, []uint32
{&PartitionCorrupted{7, []NodeUUID{1, 3, 9, 4}},
u32(7) + u32(4) + u32(1) + u32(3) + u32(9) + u32(4),
},
// uint32, Address, string, IdTime
{&RequestIdentification{CLIENT, 17, Address{"localhost", 7777}, "myname", 0.12345678},
u32(2) + u32(17) + u32(9) +
"localhost" + u16(7777) +
u32(6) + "myname" +
hex("3fbf9add1091c895"),
},
// IdTime, empty Address, int32
{&NotifyNodeInformation{1504466245.926185, []NodeInfo{
{CLIENT, Address{}, UUID(CLIENT, 1), RUNNING, 1504466245.925599}}},
hex("41d66b15517b469d") + u32(1) +
u32(2) + u32(0) /* <- ø Address */ + hex("e0000001") + u32(2) +
hex("41d66b15517b3d04"),
},
// empty IdTime
{&NotifyNodeInformation{IdTimeNone, []NodeInfo{}}, hex("ffffffffffffffff") + hex("00000000")},
// TODO we need tests for:
// []varsize + trailing
// map[]varsize + trailing
}
for _, tt := range testv {
testMsgMarshal(t, tt.msg, tt.encoded)
}
}
// For all message types: same as testMsgMarshal but zero-values only.
// this way we additionally lightly check encode / decode overflow behaviour for all types.
func TestMsgMarshalAllOverflowLightly(t *testing.T) {
for _, typ := range msgTypeRegistry {
// zero-value for a type
msg := reflect.New(typ).Interface().(Msg)
l := msg.NEOMsgEncodedLen()
zerol := make([]byte, l)
// decoding will turn nil slice & map into empty allocated ones.
// we need it so that reflect.DeepEqual works for msg encode/decode comparison
n, err := msg.NEOMsgDecode(zerol)
if !(n == l && err == nil) {
t.Errorf("%v: zero-decode unexpected: %v, %v ; want %v, nil", typ, n, err, l)
}
testMsgMarshal(t, msg, string(zerol))
}
}
// Verify overflow handling on decode len checks
func TestMsgDecodeLenOverflow(t *testing.T) {
var testv = []struct {
msg Msg // of type to decode into
data string // []byte - tricky data to exercise decoder u32 len checks overflow
}{
// [] with sizeof(item) = 8 -> len*sizeof(item) = 0 if u32
{&AnswerTIDs{}, u32(0x20000000)},
// {} with sizeof(key) = 8, sizeof(value) = 8 -> len*sizeof(key+value) = 0 if u32
{&AnswerLockedTransactions{}, u32(0x10000000)},
}
for _, tt := range testv {
data := []byte(tt.data)
func() {
defer func() {
if e := recover(); e != nil {
t.Errorf("%T: decode: panic on %x", tt.msg, data)
}
}()
n, err := tt.msg.NEOMsgDecode(data)
if !(n == 0 && err == ErrDecodeOverflow) {
t.Errorf("%T: decode %x\nhave: %d, %v\nwant: %d, %v", tt.msg, data,
n, err, 0, ErrDecodeOverflow)
}
}()
}
}
func TestUUID(t *testing.T) { func TestUUID(t *testing.T) {
var testv = []struct{typ NodeType; num int32; uuid uint32; str string}{ var testv = []struct{typ NodeType; num int32; uuid uint32; str string}{
{STORAGE, 1, 0x00000001, "S1"}, {STORAGE, 1, 0x00000001, "S1"},
......
// Copyright (C) 2016-2018 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Free Software licenses or any of the Open Source
// Initiative approved licenses and Convey the resulting work. Corresponding
// source of such a combination shall include the source code for all other
// software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options.
// +build ignore
/*
NEO. Protocol module. Code generator
This program generates marshalling code for message types defined in proto.go .
For every type 4 methods are generated in accordance with neo.Msg interface:
NEOMsgCode() uint16
NEOMsgEncodedLen() int
NEOMsgEncode(buf []byte)
NEOMsgDecode(data []byte) (nread int, err error)
List of message types is obtained via searching through proto.go AST - looking
for appropriate struct declarations there.
Code generation for a type is organized via recursively walking through type's
(sub-)elements and generating specialized code on leaf items (intX, slices,
maps, ...).
Top-level generation driver is in generateCodecCode(). It accepts type
specification and something that performs actual leaf-nodes code generation
(CodeGenerator interface). There are 3 particular codegenerators implemented -
- sizer, encoder & decoder - to generate each of the needed method functions.
The structure of whole process is very similar to what would be happening at
runtime if marshalling was reflect based, but statically with go/types we don't
spend runtime time on decisions and thus generated marshallers are faster.
For encoding format compatibility with Python NEO (neo/lib/protocol.py) is
preserved in order for two implementations to be able to communicate to each
other.
NOTE we do no try to emit very clever code - for cases where compiler
can do a good job the work is delegated to it.
--------
Also along the way types registry table is generated for
msgCode -> message type
lookup needed in packet receive codepath.
*/
package main
import (
"bytes"
"fmt"
"go/ast"
"go/format"
"go/importer"
"go/parser"
"go/token"
"go/types"
"log"
"os"
"sort"
"strings"
)
// parsed & typechecked input
var fset = token.NewFileSet()
var fileMap = map[string]*ast.File{} // fileName -> AST
var pkgMap = map[string]*types.Package{} // pkgPath -> Package
var typeInfo = &types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),
Defs: make(map[*ast.Ident]types.Object),
}
// complete position of something with .Pos()
func pos(x interface{ Pos() token.Pos }) token.Position {
return fset.Position(x.Pos())
}
// get type name in context of neo package
var zodbPkg *types.Package
var protoPkg *types.Package
func typeName(typ types.Type) string {
qf := func(pkg *types.Package) string {
switch pkg {
case protoPkg:
// same package - unqualified
return ""
case zodbPkg:
// zodb is imported - only name
return pkg.Name()
default:
// fully qualified otherwise
return pkg.Path()
}
}
return types.TypeString(typ, qf)
}
var neo_customCodec *types.Interface // type of neo.customCodec
var memBuf types.Type // type of mem.Buf
// bytes.Buffer + bell & whistles
type Buffer struct {
bytes.Buffer
}
func (b *Buffer) emit(format string, a ...interface{}) {
fmt.Fprintf(b, format+"\n", a...)
}
// importer that takes into account our already-loaded packages
type localImporter struct {
types.Importer
}
func (li *localImporter) Import(path string) (*types.Package, error) {
pkg := pkgMap[path]
if pkg != nil {
return pkg, nil
}
return li.Importer.Import(path)
}
// importer instance - only 1 so that for 2 top-level packages same dependent
// packages are not reimported several times.
var localImporterObj = &localImporter{importer.Default()}
func loadPkg(pkgPath string, sources ...string) *types.Package {
var filev []*ast.File
// parse
for _, src := range sources {
f, err := parser.ParseFile(fset, src, nil, parser.ParseComments)
if err != nil {
log.Fatalf("parse: %v", err)
}
fileMap[src] = f
filev = append(filev, f)
}
//ast.Print(fset, fv[0])
//return
// typecheck
conf := types.Config{Importer: localImporterObj}
pkg, err := conf.Check(pkgPath, fset, filev, typeInfo)
if err != nil {
log.Fatalf("typecheck: %v", err)
}
pkgMap[pkgPath] = pkg
return pkg
}
// `//neo:proto ...` annotations
type Annotation struct {
typeonly bool
answer bool
}
// parse checks doc for specific comment annotations and, if present, loads them.
func (a *Annotation) parse(doc *ast.CommentGroup) {
if doc == nil {
return // for many types .Doc = nil if there is no comments
}
for _, comment := range doc.List {
cpos := pos(comment)
if !(cpos.Column == 1 && strings.HasPrefix(comment.Text, "//neo:proto ")) {
continue
}
__ := strings.SplitN(comment.Text, " ", 2)
arg := __[1]
switch arg {
case "typeonly":
if a.typeonly {
log.Fatalf("%v: duplicate `typeonly`", cpos)
}
a.typeonly = true
case "answer":
if a.answer {
log.Fatalf("%v: duplicate `answer`", cpos)
}
a.answer = true
default:
log.Fatalf("%v: unknown neo:proto directive %q", cpos, arg)
}
}
}
// MsgCode represents message code in symbolic form: `serial (| answerBit)?`
type MsgCode struct {
msgSerial int
answer bool
}
func (c MsgCode) String() string {
s := fmt.Sprintf("%d", c.msgSerial)
if c.answer {
s += " | answerBit"
}
return s
}
// sort MsgCode by (serial, answer)
type BySerial []MsgCode
func (v BySerial) Less(i, j int) bool {
return (v[i].msgSerial < v[j].msgSerial) ||
(v[i].msgSerial == v[j].msgSerial && !v[i].answer && v[j].answer)
}
func (v BySerial) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
func (v BySerial) Len() int { return len(v) }
// ----------------------------------------
func main() {
var err error
log.SetFlags(0)
// go through proto.go and AST'ify & typecheck it
zodbPkg = loadPkg("lab.nexedi.com/kirr/neo/go/zodb", "../../zodb/zodb.go")
protoPkg = loadPkg("lab.nexedi.com/kirr/neo/go/neo/proto", "proto.go")
// extract neo.customCodec
cc := protoPkg.Scope().Lookup("customCodec")
if cc == nil {
log.Fatal("cannot find `customCodec`")
}
var ok bool
neo_customCodec, ok = cc.Type().Underlying().(*types.Interface)
if !ok {
log.Fatal("customCodec is not interface (got %v)", cc.Type())
}
// extract mem.Buf
memPath := "lab.nexedi.com/kirr/go123/mem"
var memPkg *types.Package
for _, pkg := range zodbPkg.Imports() {
if pkg.Path() == memPath {
memPkg = pkg
break
}
}
if memPkg == nil {
log.Fatalf("cannot find `%s` in zodb imports", memPath)
}
__ := memPkg.Scope().Lookup("Buf")
if __ == nil {
log.Fatal("cannot find `mem.Buf`")
}
memBuf = __.Type()
// prologue
f := fileMap["proto.go"]
buf := Buffer{}
buf.emit(`// Code generated by protogen.go; DO NOT EDIT.
package proto
// NEO. protocol messages to/from wire marshalling.
import (
"encoding/binary"
"reflect"
"sort"
"lab.nexedi.com/kirr/go123/mem"
"lab.nexedi.com/kirr/neo/go/zodb"
)`)
msgTypeRegistry := map[MsgCode]string{} // msgCode -> typename
// go over message types declaration and generate marshal code for them
buf.emit("// messages marshalling\n")
msgSerial := 0
for _, decl := range f.Decls {
// we look for types (which can be only under GenDecl)
gendecl, ok := decl.(*ast.GenDecl)
if !ok || gendecl.Tok != token.TYPE {
continue
}
//fmt.Println(gendecl)
//ast.Print(fset, gendecl)
//continue
// `//neo:proto ...` annotations for whole decl
// (e.g. <here> type ( t1 struct{...}; t2 struct{...} )
declAnnotation := Annotation{}
declAnnotation.parse(gendecl.Doc)
for _, spec := range gendecl.Specs {
typespec := spec.(*ast.TypeSpec) // must be because tok = TYPE
typename := typespec.Name.Name
// we are only interested in struct types
if _, ok := typespec.Type.(*ast.StructType); !ok {
continue
}
// `//neo:proto ...` annotation for this particular type
specAnnotation := declAnnotation // inheriting from decl
specAnnotation.parse(typespec.Doc)
// type only -> don't generate message interface for it
if specAnnotation.typeonly {
continue
}
// generate code for this type to implement neo.Msg
var msgCode MsgCode
msgCode.answer = specAnnotation.answer || strings.HasPrefix(typename, "Answer")
switch {
case !msgCode.answer || typename == "Error":
msgCode.msgSerial = msgSerial
// answer to something
default:
msgCode.msgSerial = msgSerial - 1
}
fmt.Fprintf(&buf, "// %s. %s\n\n", msgCode, typename)
buf.emit("func (*%s) NEOMsgCode() uint16 {", typename)
buf.emit("return %s", msgCode)
buf.emit("}\n")
buf.WriteString(generateCodecCode(typespec, &sizer{}))
buf.WriteString(generateCodecCode(typespec, &encoder{}))
buf.WriteString(generateCodecCode(typespec, &decoder{}))
msgTypeRegistry[msgCode] = typename
msgSerial++
}
}
// now generate message types registry
buf.emit("\n// registry of message types")
buf.emit("var msgTypeRegistry = map[uint16]reflect.Type {")
// ordered by msgCode
msgCodeV := []MsgCode{}
for msgCode := range msgTypeRegistry {
msgCodeV = append(msgCodeV, msgCode)
}
sort.Sort(BySerial(msgCodeV))
for _, msgCode := range msgCodeV {
buf.emit("%v: reflect.TypeOf(%v{}),", msgCode, msgTypeRegistry[msgCode])
}
buf.emit("}")
// format & output generated code
code, err := format.Source(buf.Bytes())
if err != nil {
panic(err) // should not happen
}
_, err = os.Stdout.Write(code)
if err != nil {
log.Fatal(err)
}
}
// info about encode/decode of a basic fixed-size type
type basicCodec struct {
wireSize int
encode string
decode string
}
var basicTypes = map[types.BasicKind]basicCodec{
// encode: %v %v will be `data[n:]`, value
// decode: %v will be `data[n:]` (and already made sure data has more enough bytes to read)
types.Bool: {1, "(%v)[0] = bool2byte(%v)", "byte2bool((%v)[0])"},
types.Int8: {1, "(%v)[0] = uint8(%v)", "int8((%v)[0])"},
types.Int16: {2, "binary.BigEndian.PutUint16(%v, uint16(%v))", "int16(binary.BigEndian.Uint16(%v))"},
types.Int32: {4, "binary.BigEndian.PutUint32(%v, uint32(%v))", "int32(binary.BigEndian.Uint32(%v))"},
types.Int64: {8, "binary.BigEndian.PutUint64(%v, uint64(%v))", "int64(binary.BigEndian.Uint64(%v))"},
types.Uint8: {1, "(%v)[0] = %v", "(%v)[0]"},
types.Uint16: {2, "binary.BigEndian.PutUint16(%v, %v)", "binary.BigEndian.Uint16(%v)"},
types.Uint32: {4, "binary.BigEndian.PutUint32(%v, %v)", "binary.BigEndian.Uint32(%v)"},
types.Uint64: {8, "binary.BigEndian.PutUint64(%v, %v)", "binary.BigEndian.Uint64(%v)"},
types.Float64: {8, "float64_neoEncode(%v, %v)", "float64_neoDecode(%v)"},
}
// does a type have fixed wire size and, if yes, what it is?
func typeSizeFixed(typ types.Type) (wireSize int, ok bool) {
switch u := typ.Underlying().(type) {
case *types.Basic:
basic, ok := basicTypes[u.Kind()]
if ok {
return basic.wireSize, ok
}
case *types.Struct:
for i := 0; i < u.NumFields(); i++ {
size, ok := typeSizeFixed(u.Field(i).Type())
if !ok {
goto notfixed
}
wireSize += size
}
return wireSize, true
case *types.Array:
elemSize, ok := typeSizeFixed(u.Elem())
if ok {
return int(u.Len()) * elemSize, ok
}
}
notfixed:
// everything else is of not fixed wire size
return 0, false
}
// does a type have fixed wire size == 1 ?
func typeSizeFixed1(typ types.Type) bool {
wireSize, _ := typeSizeFixed(typ)
return wireSize == 1
}
// interface of a codegenerator (for sizer/coder/decoder)
type CodeGenerator interface {
// tell codegen it should generate code for which type & receiver name
setFunc(recvName, typeName string, typ types.Type)
// generate code to process a basic fixed type (not string)
// userType is type actually used in source (for which typ is underlying), or nil
// path is associated data member - e.g. p.Address.Port (to read from or write to)
genBasic(path string, typ *types.Basic, userType types.Type)
// generate code to process slice or map
// (see genBasic for argument details)
genSlice(path string, typ *types.Slice, obj types.Object)
genMap(path string, typ *types.Map, obj types.Object)
// particular case of array or slice with 1-byte elem
//
// NOTE this particular case is kept separate because for 1-byte
// elements there are no byteordering issues so data can be directly
// either accessed or copied.
genArray1(path string, typ *types.Array)
genSlice1(path string, typ types.Type)
// mem.Buf
genBuf(path string)
// generate code for a custom type which implements its own
// encoding/decoding via implementing neo.customCodec interface.
genCustom(path string)
// get generated code.
generatedCode() string
}
// common part of codegenerators
type commonCodeGen struct {
buf Buffer // code is emitted here
recvName string // receiver/type for top-level func
typeName string // or empty
typ types.Type
varUsed map[string]bool // whether a variable was used
}
func (c *commonCodeGen) emit(format string, a ...interface{}) {
c.buf.emit(format, a...)
}
func (c *commonCodeGen) setFunc(recvName, typeName string, typ types.Type) {
c.recvName = recvName
c.typeName = typeName
c.typ = typ
}
// get variable for varname (and automatically mark this var as used)
func (c *commonCodeGen) var_(varname string) string {
if c.varUsed == nil {
c.varUsed = make(map[string]bool)
}
c.varUsed[varname] = true
return varname
}
// symbolic size
// consists of numeric & symbolic expression parts
// size is num + expr1 + expr2 + ...
type SymSize struct {
num int // numeric part of size
exprv []string // symbolic part of size
}
func (s *SymSize) Add(n int) {
s.num += n
}
func (s *SymSize) AddExpr(format string, a ...interface{}) {
expr := fmt.Sprintf(format, a...)
s.exprv = append(s.exprv, expr)
}
func (s *SymSize) String() string {
// num + expr1 + expr2 + ... (omitting what is possible)
sizev := []string{}
if s.num != 0 {
sizev = append(sizev, fmt.Sprintf("%v", s.num))
}
exprStr := s.ExprString()
if exprStr != "" {
sizev = append(sizev, exprStr)
}
sizeStr := strings.Join(sizev, " + ")
if sizeStr == "" {
sizeStr = "0"
}
return sizeStr
}
// expression part of size (without numeric part)
func (s *SymSize) ExprString() string {
return strings.Join(s.exprv, " + ")
}
func (s *SymSize) IsZero() bool {
return s.num == 0 && len(s.exprv) == 0
}
// is it numeric only?
func (s *SymSize) IsNumeric() bool {
return len(s.exprv) == 0
}
func (s *SymSize) Reset() {
*s = SymSize{}
}
// decoder overflow check state
type OverflowCheck struct {
// accumulator for size to check at overflow check point
checkSize SymSize
// whether overflow was already checked for current decodings
// (if yes, checkSize updates will be ignored)
checked bool
// stack operated by {Push,Pop}Checked
checkedStk []bool
}
// push/pop checked state
func (o *OverflowCheck) PushChecked(checked bool) {
o.checkedStk = append(o.checkedStk, o.checked)
o.checked = checked
}
func (o *OverflowCheck) PopChecked() bool {
popret := o.checked
l := len(o.checkedStk)
o.checked = o.checkedStk[l-1]
o.checkedStk = o.checkedStk[:l-1]
return popret
}
// Add and AddExpr update .checkSize accordingly, but only if overflow was not
// already marked as checked
func (o *OverflowCheck) Add(n int) {
if !o.checked {
o.checkSize.Add(n)
}
}
func (o *OverflowCheck) AddExpr(format string, a ...interface{}) {
if !o.checked {
o.checkSize.AddExpr(format, a...)
}
}
// sizer generates code to compute encoded size of a message
//
// when type is recursively walked, for every case symbolic size is added appropriately.
// in case when it was needed to generate loops, runtime accumulator variable is additionally used.
// result is: symbolic size + (optionally) runtime accumulator.
type sizer struct {
commonCodeGen
size SymSize // currently accumulated size
}
// encoder generates code to encode a message
//
// when type is recursively walked, for every case code to update `data[n:]` is generated.
// no overflow checks are generated as by neo.Msg interface provided data
// buffer should have at least payloadLen length returned by NEOMsgEncodedLen()
// (the size computed by sizer).
//
// the code emitted looks like:
//
// encode<typ1>(data[n1:], path1)
// encode<typ2>(data[n2:], path2)
// ...
//
// TODO encode have to care in NEOMsgEncode to emit preamble such that bound
// checking is performed only once (currently compiler emits many of them)
type encoder struct {
commonCodeGen
n int // current write position in data
}
// decoder generates code to decode a message
//
// when type is recursively walked, for every case code to decode next item from
// `data[n:]` is generated.
//
// overflow checks and nread updates are grouped and emitted so that they are
// performed in the beginning of greedy fixed-wire-size blocks - checking /
// updating as much as possible to do ahead in one go.
//
// the code emitted looks like:
//
// if len(data) < wireSize(typ1) + wireSize(typ2) + ... {
// goto overflow
// }
// <assignto1> = decode<typ1>(data[n1:])
// <assignto2> = decode<typ2>(data[n2:])
// ...
type decoder struct {
commonCodeGen
// done buffer for generated code
// current delayed overflow check will be inserted in between bufDone & buf
bufDone Buffer
n int // current read position in data.
nread int // numeric part of total nread return
nreadStk []int // stack to push/pop nread on loops
// overflow check state and size that will be checked for overflow at
// current overflow check point
overflow OverflowCheck
}
var _ CodeGenerator = (*sizer)(nil)
var _ CodeGenerator = (*encoder)(nil)
var _ CodeGenerator = (*decoder)(nil)
func (s *sizer) generatedCode() string {
code := Buffer{}
// prologue
code.emit("func (%s *%s) NEOMsgEncodedLen() int {", s.recvName, s.typeName)
if s.varUsed["size"] {
code.emit("var %s int", s.var_("size"))
}
code.Write(s.buf.Bytes())
// epilogue
size := s.size.String()
if s.varUsed["size"] {
size += " + " + s.var_("size")
}
code.emit("return %v", size)
code.emit("}\n")
return code.String()
}
func (e *encoder) generatedCode() string {
code := Buffer{}
// prologue
code.emit("func (%s *%s) NEOMsgEncode(data []byte) {", e.recvName, e.typeName)
code.Write(e.buf.Bytes())
// epilogue
code.emit("}\n")
return code.String()
}
// data = data[n:]
// n = 0
func (d *decoder) resetPos() {
if d.n != 0 {
d.emit("data = data[%v:]", d.n)
d.n = 0
}
}
// mark current place for insertion of overflow check code
//
// The check will be actually inserted later.
//
// later: because first we go forward in decode path scanning ahead as far as
// we can - until first seeing variable-size encoded something, and then -
// knowing fixed size would be to read - insert checking condition for
// accumulated size to here-marked overflow checkpoint.
//
// so overflowCheck does:
// 1. emit overflow checking code for previous overflow checkpoint
// 2. mark current place as next overflow checkpoint to eventually emit
//
// it has to be inserted
// - before reading a variable sized item
// - in the beginning of a loop inside (via overflowCheckLoopEntry)
// - right after loop exit (via overflowCheckLoopExit)
func (d *decoder) overflowCheck() {
// nop if we know overflow was already checked
if d.overflow.checked {
return
}
//d.bufDone.emit("// overflow check point")
if !d.overflow.checkSize.IsZero() {
lendata := "len(data)"
if !d.overflow.checkSize.IsNumeric() {
// symbolic checksize has uint64 type
lendata = "uint64(" + lendata + ")"
}
d.bufDone.emit("if %s < %v { goto overflow }", lendata, &d.overflow.checkSize)
// if size for overflow check was only numeric - just
// accumulate it at generation time
//
// otherwise accumulate into var(nread) at runtime.
// we do not break runtime accumulation into numeric & symbolic
// parts, because just above whole expression num + symbolic
// was given to compiler as a whole so compiler should have it
// just computed fully.
// XXX recheck ^^^ is actually good with the compiler
if d.overflow.checkSize.IsNumeric() {
d.nread += d.overflow.checkSize.num
} else {
d.bufDone.emit("%v += %v", d.var_("nread"), &d.overflow.checkSize)
}
}
d.overflow.checkSize.Reset()
d.bufDone.Write(d.buf.Bytes())
d.buf.Reset()
}
// overflowCheck variant that should be inserted at the beginning of a loop inside
func (d *decoder) overflowCheckLoopEntry() {
if d.overflow.checked {
return
}
d.overflowCheck()
// upon entering a loop organize new nread, because what will be statically
// read inside loop should be multiplied by loop len in parent context.
d.nreadStk = append(d.nreadStk, d.nread)
d.nread = 0
}
// overflowCheck variant that should be inserted right after loop exit
func (d *decoder) overflowCheckLoopExit(loopLenExpr string) {
if d.overflow.checked {
return
}
d.overflowCheck()
// merge-in numeric nread updates from loop
if d.nread != 0 {
d.emit("%v += %v * %v", d.var_("nread"), loopLenExpr, d.nread)
}
l := len(d.nreadStk)
d.nread = d.nreadStk[l-1]
d.nreadStk = d.nreadStk[:l-1]
}
func (d *decoder) generatedCode() string {
// flush for last overflow check point
d.overflowCheck()
code := Buffer{}
// prologue
code.emit("func (%s *%s) NEOMsgDecode(data []byte) (int, error) {", d.recvName, d.typeName)
if d.varUsed["nread"] {
code.emit("var %v uint64", d.var_("nread"))
}
code.Write(d.bufDone.Bytes())
// epilogue
retexpr := fmt.Sprintf("%v", d.nread)
if d.varUsed["nread"] {
// casting nread to int is ok even on 32 bit arches:
// if nread would overflow 32 bits it would be caught earlier,
// because on 32 bit arch len(data) is also 32 bit and in generated
// code len(data) is checked first to be less than encoded message.
retexpr += fmt.Sprintf(" + int(%v)", d.var_("nread"))
}
code.emit("return %v, nil", retexpr)
// `goto overflow` is not used only for empty structs
// NOTE for >0 check actual X in StdSizes{X} does not particularly matter
if (&types.StdSizes{8, 8}).Sizeof(d.typ) > 0 {
code.emit("\noverflow:")
code.emit("return 0, ErrDecodeOverflow")
}
code.emit("}\n")
return code.String()
}
// emit code to size/encode/decode basic fixed type
func (s *sizer) genBasic(path string, typ *types.Basic, userType types.Type) {
basic := basicTypes[typ.Kind()]
s.size.Add(basic.wireSize)
}
func (e *encoder) genBasic(path string, typ *types.Basic, userType types.Type) {
basic := basicTypes[typ.Kind()]
dataptr := fmt.Sprintf("data[%v:]", e.n)
if userType != typ && userType != nil {
// userType is a named type over some basic, like
// type ClusterState int32
// -> need to cast
path = fmt.Sprintf("%v(%v)", typeName(typ), path)
}
e.emit(basic.encode, dataptr, path)
e.n += basic.wireSize
}
func (d *decoder) genBasic(assignto string, typ *types.Basic, userType types.Type) {
basic := basicTypes[typ.Kind()]
// XXX specifying :hi is not needed - it is only a workaround to help BCE.
// see https://github.com/golang/go/issues/19126#issuecomment-358743715
dataptr := fmt.Sprintf("data[%v:%v+%d]", d.n, d.n, basic.wireSize)
decoded := fmt.Sprintf(basic.decode, dataptr)
if userType != typ && userType != nil {
// need to cast (like in encode case)
decoded = fmt.Sprintf("%v(%v)", typeName(userType), decoded)
}
// NOTE no space before "=" - to be able to merge with ":"
// prefix and become defining assignment
d.emit("%s= %s", assignto, decoded)
d.n += basic.wireSize
d.overflow.Add(basic.wireSize)
}
// emit code to size/encode/decode array with sizeof(elem)==1
// [len(A)]byte
func (s *sizer) genArray1(path string, typ *types.Array) {
s.size.Add(int(typ.Len()))
}
func (e *encoder) genArray1(path string, typ *types.Array) {
e.emit("copy(data[%v:], %v[:])", e.n, path)
e.n += int(typ.Len())
}
func (d *decoder) genArray1(assignto string, typ *types.Array) {
typLen := int(typ.Len())
d.emit("copy(%v[:], data[%v:%v])", assignto, d.n, d.n+typLen)
d.n += typLen
d.overflow.Add(typLen)
}
// emit code to size/encode/decode string or []byte
// len u32
// [len]byte
func (s *sizer) genSlice1(path string, typ types.Type) {
s.size.Add(4)
s.size.AddExpr("len(%s)", path)
}
func (e *encoder) genSlice1(path string, typ types.Type) {
e.emit("{")
e.emit("l := uint32(len(%s))", path)
e.genBasic("l", types.Typ[types.Uint32], nil)
e.emit("data = data[%v:]", e.n)
e.emit("copy(data, %v)", path)
e.emit("data = data[l:]")
e.emit("}")
e.n = 0
}
func (d *decoder) genSlice1(assignto string, typ types.Type) {
d.emit("{")
d.genBasic("l:", types.Typ[types.Uint32], nil)
d.resetPos()
d.overflowCheck()
d.overflow.AddExpr("uint64(l)")
switch t := typ.(type) {
case *types.Basic:
if t.Kind() != types.String {
log.Panicf("bad basic type in slice1: %v", t)
}
d.emit("%v= string(data[:l])", assignto)
case *types.Slice:
// TODO eventually do not copy, but reference data from original
d.emit("%v= make(%v, l)", assignto, typeName(typ))
d.emit("copy(%v, data[:l])", assignto)
default:
log.Panicf("bad type in slice1: %v", typ)
}
d.emit("data = data[l:]")
d.emit("}")
}
// emit code to size/encode/decode mem.Buf
// same as slice1 but buffer is allocated via mem.BufAlloc
func (s *sizer) genBuf(path string) {
s.genSlice1(path+".XData()", nil /* typ unused */)
}
func (e *encoder) genBuf(path string) {
e.genSlice1(path+".XData()", nil /* typ unused */)
}
func (d *decoder) genBuf(path string) {
d.emit("{")
d.genBasic("l:", types.Typ[types.Uint32], nil)
d.resetPos()
d.overflowCheck()
d.overflow.AddExpr("uint64(l)")
// TODO eventually do not copy but reference original
d.emit("%v= mem.BufAlloc(int(l))", path)
d.emit("copy(%v.Data, data[:l])", path)
d.emit("data = data[l:]")
d.emit("}")
}
// emit code to size/encode/decode slice
// len u32
// [len]item
func (s *sizer) genSlice(path string, typ *types.Slice, obj types.Object) {
s.size.Add(4)
// if size(item)==const - size update in one go
elemSize, ok := typeSizeFixed(typ.Elem())
if ok {
s.size.AddExpr("len(%v) * %v", path, elemSize)
return
}
curSize := s.size
s.size.Reset()
s.emit("for i := 0; i < len(%v); i++ {", path)
s.emit("a := &%s[i]", path)
codegenType("(*a)", typ.Elem(), obj, s)
// merge-in size updates
s.emit("%v += %v", s.var_("size"), s.size.ExprString())
s.emit("}")
if s.size.num != 0 {
curSize.AddExpr("len(%v) * %v", path, s.size.num)
}
s.size = curSize
}
func (e *encoder) genSlice(path string, typ *types.Slice, obj types.Object) {
e.emit("{")
e.emit("l := uint32(len(%s))", path)
e.genBasic("l", types.Typ[types.Uint32], nil)
e.emit("data = data[%v:]", e.n)
e.n = 0
e.emit("for i := 0; uint32(i) <l; i++ {")
e.emit("a := &%s[i]", path)
codegenType("(*a)", typ.Elem(), obj, e)
e.emit("data = data[%v:]", e.n)
e.emit("}")
e.emit("}")
e.n = 0
}
func (d *decoder) genSlice(assignto string, typ *types.Slice, obj types.Object) {
d.emit("{")
d.genBasic("l:", types.Typ[types.Uint32], nil)
d.resetPos()
// if size(item)==const - check overflow in one go
elemSize, elemFixed := typeSizeFixed(typ.Elem())
if elemFixed {
d.overflowCheck()
d.overflow.AddExpr("uint64(l) * %v", elemSize)
d.overflow.PushChecked(true)
defer d.overflow.PopChecked()
}
d.emit("%v= make(%v, l)", assignto, typeName(typ))
d.emit("for i := 0; uint32(i) < l; i++ {")
d.emit("a := &%s[i]", assignto)
d.overflowCheckLoopEntry()
codegenType("(*a)", typ.Elem(), obj, d)
d.resetPos()
d.emit("}")
d.overflowCheckLoopExit("uint64(l)")
d.emit("}")
}
// generate code to encode/decode map
// len u32
// [len](key, value)
func (s *sizer) genMap(path string, typ *types.Map, obj types.Object) {
keySize, keyFixed := typeSizeFixed(typ.Key())
elemSize, elemFixed := typeSizeFixed(typ.Elem())
if keyFixed && elemFixed {
s.size.Add(4)
s.size.AddExpr("len(%v) * %v", path, keySize+elemSize)
return
}
s.size.Add(4)
curSize := s.size
s.size.Reset()
// FIXME for map of map gives ...[key][key] => key -> different variables
s.emit("for key := range %s {", path)
codegenType("key", typ.Key(), obj, s)
codegenType(fmt.Sprintf("%s[key]", path), typ.Elem(), obj, s)
// merge-in size updates
s.emit("%v += %v", s.var_("size"), s.size.ExprString())
s.emit("}")
if s.size.num != 0 {
curSize.AddExpr("len(%v) * %v", path, s.size.num)
}
s.size = curSize
}
func (e *encoder) genMap(path string, typ *types.Map, obj types.Object) {
e.emit("{")
e.emit("l := uint32(len(%s))", path)
e.genBasic("l", types.Typ[types.Uint32], nil)
e.emit("data = data[%v:]", e.n)
e.n = 0
// output keys in sorted order on the wire
// (easier for debugging & deterministic for testing)
e.emit("keyv := make([]%s, 0, l)", typeName(typ.Key())) // FIXME do not throw old slice away -> do xslice.Realloc()
e.emit("for key := range %s {", path)
e.emit(" keyv = append(keyv, key)")
e.emit("}")
e.emit("sort.Slice(keyv, func (i, j int) bool { return keyv[i] < keyv[j] })")
e.emit("for _, key := range keyv {")
codegenType("key", typ.Key(), obj, e)
codegenType(fmt.Sprintf("%s[key]", path), typ.Elem(), obj, e)
e.emit("data = data[%v:]", e.n) // XXX wrt map of map?
e.emit("}")
e.emit("}")
e.n = 0
}
func (d *decoder) genMap(assignto string, typ *types.Map, obj types.Object) {
d.emit("{")
d.genBasic("l:", types.Typ[types.Uint32], nil)
d.resetPos()
// if size(key,item)==const - check overflow in one go
keySize, keyFixed := typeSizeFixed(typ.Key())
elemSize, elemFixed := typeSizeFixed(typ.Elem())
if keyFixed && elemFixed {
d.overflowCheck()
d.overflow.AddExpr("uint64(l) * %v", keySize+elemSize)
d.overflow.PushChecked(true)
defer d.overflow.PopChecked()
}
d.emit("%v= make(%v, l)", assignto, typeName(typ))
d.emit("m := %v", assignto)
d.emit("for i := 0; uint32(i) < l; i++ {")
d.overflowCheckLoopEntry()
codegenType("key:", typ.Key(), obj, d)
switch typ.Elem().Underlying().(type) {
// basic types can be directly assigned to map entry
case *types.Basic:
codegenType("m[key]", typ.Elem(), obj, d)
// otherwise assign via temporary
default:
d.emit("var v %v", typeName(typ.Elem()))
codegenType("v", typ.Elem(), obj, d)
d.emit("m[key] = v")
}
d.resetPos()
d.emit("}")
d.overflowCheckLoopExit("uint64(l)")
d.emit("}")
}
// emit code to size/encode/decode custom type
func (s *sizer) genCustom(path string) {
s.size.AddExpr("%s.neoEncodedLen()", path)
}
func (e *encoder) genCustom(path string) {
e.emit("{")
e.emit("n := %s.neoEncode(data[%v:])", path, e.n)
e.emit("data = data[%v + n:]", e.n)
e.emit("}")
e.n = 0
}
func (d *decoder) genCustom(path string) {
d.resetPos()
// make sure we check for overflow previous-code before proceeding to custom decoder.
d.overflowCheck()
d.emit("{")
d.emit("n, ok := %s.neoDecode(data)", path)
d.emit("if !ok { goto overflow }")
d.emit("data = data[n:]")
d.emit("%v += n", d.var_("nread"))
d.emit("}")
// insert overflow checkpoint after custom decoder so that overflow
// checks for following code are inserted after custom decoder call.
d.overflowCheck()
}
// top-level driver for emitting size/encode/decode code for a type
//
// obj is object that uses this type in source program (so in case of an error
// we can point to source location for where it happened)
func codegenType(path string, typ types.Type, obj types.Object, codegen CodeGenerator) {
// neo.customCodec
if types.Implements(typ, neo_customCodec) ||
types.Implements(types.NewPointer(typ), neo_customCodec) {
codegen.genCustom(path)
return
}
// mem.Buf
if tptr, ok := typ.Underlying().(*types.Pointer); ok && tptr.Elem() == memBuf {
codegen.genBuf(path)
return
}
switch u := typ.Underlying().(type) {
case *types.Basic:
// go puts string into basic, but it is really slice1
if u.Kind() == types.String {
codegen.genSlice1(path, u)
break
}
_, ok := basicTypes[u.Kind()]
if !ok {
log.Fatalf("%v: %v: basic type %v not supported", pos(obj), obj.Name(), u)
}
codegen.genBasic(path, u, typ)
case *types.Struct:
for i := 0; i < u.NumFields(); i++ {
v := u.Field(i)
codegenType(path+"."+v.Name(), v.Type(), v, codegen)
}
case *types.Array:
// [...]byte or [...]uint8 - just straight copy
if typeSizeFixed1(u.Elem()) {
codegen.genArray1(path, u)
} else {
var i int64
for i = 0; i < u.Len(); i++ {
codegenType(fmt.Sprintf("%v[%v]", path, i), u.Elem(), obj, codegen)
}
}
case *types.Slice:
if typeSizeFixed1(u.Elem()) {
codegen.genSlice1(path, u)
} else {
codegen.genSlice(path, u, obj)
}
case *types.Map:
codegen.genMap(path, u, obj)
case *types.Pointer:
default:
log.Fatalf("%v: %v has unsupported type %v (%v)", pos(obj),
obj.Name(), typ, u)
}
}
// generate size/encode/decode functions for a type declaration typespec
func generateCodecCode(typespec *ast.TypeSpec, codegen CodeGenerator) string {
// type & object which refers to this type
typ := typeInfo.Types[typespec.Type].Type
obj := typeInfo.Defs[typespec.Name]
codegen.setFunc("p", typespec.Name.Name, typ)
codegenType("p", typ, obj, codegen)
return codegen.generatedCode()
}
// Code generated by protogen.go; DO NOT EDIT.
package proto
// NEO. protocol messages to/from wire marshalling.
import (
"encoding/binary"
"reflect"
"sort"
"lab.nexedi.com/kirr/go123/mem"
"lab.nexedi.com/kirr/neo/go/zodb"
)
// messages marshalling
// 0 | answerBit. Error
func (*Error) NEOMsgCode() uint16 {
return 0 | answerBit
}
func (p *Error) NEOMsgEncodedLen() int {
return 8 + len(p.Message)
}
func (p *Error) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], uint32(p.Code))
{
l := uint32(len(p.Message))
binary.BigEndian.PutUint32(data[4:], l)
data = data[8:]
copy(data, p.Message)
data = data[l:]
}
}
func (p *Error) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 8 {
goto overflow
}
p.Code = ErrorCode(binary.BigEndian.Uint32(data[0 : 0+4]))
{
l := binary.BigEndian.Uint32(data[4 : 4+4])
data = data[8:]
if uint64(len(data)) < uint64(l) {
goto overflow
}
nread += uint64(l)
p.Message = string(data[:l])
data = data[l:]
}
return 8 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 1. RequestIdentification
func (*RequestIdentification) NEOMsgCode() uint16 {
return 1
}
func (p *RequestIdentification) NEOMsgEncodedLen() int {
return 12 + p.Address.neoEncodedLen() + len(p.ClusterName) + p.IdTime.neoEncodedLen()
}
func (p *RequestIdentification) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], uint32(int32(p.NodeType)))
binary.BigEndian.PutUint32(data[4:], uint32(int32(p.UUID)))
{
n := p.Address.neoEncode(data[8:])
data = data[8+n:]
}
{
l := uint32(len(p.ClusterName))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
copy(data, p.ClusterName)
data = data[l:]
}
{
n := p.IdTime.neoEncode(data[0:])
data = data[0+n:]
}
}
func (p *RequestIdentification) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 8 {
goto overflow
}
p.NodeType = NodeType(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
p.UUID = NodeUUID(int32(binary.BigEndian.Uint32(data[4 : 4+4])))
data = data[8:]
{
n, ok := p.Address.neoDecode(data)
if !ok {
goto overflow
}
data = data[n:]
nread += n
}
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < uint64(l) {
goto overflow
}
nread += uint64(l)
p.ClusterName = string(data[:l])
data = data[l:]
}
{
n, ok := p.IdTime.neoDecode(data)
if !ok {
goto overflow
}
data = data[n:]
nread += n
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 1 | answerBit. AcceptIdentification
func (*AcceptIdentification) NEOMsgCode() uint16 {
return 1 | answerBit
}
func (p *AcceptIdentification) NEOMsgEncodedLen() int {
return 20
}
func (p *AcceptIdentification) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], uint32(int32(p.NodeType)))
binary.BigEndian.PutUint32(data[4:], uint32(int32(p.MyUUID)))
binary.BigEndian.PutUint32(data[8:], p.NumPartitions)
binary.BigEndian.PutUint32(data[12:], p.NumReplicas)
binary.BigEndian.PutUint32(data[16:], uint32(int32(p.YourUUID)))
}
func (p *AcceptIdentification) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 20 {
goto overflow
}
p.NodeType = NodeType(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
p.MyUUID = NodeUUID(int32(binary.BigEndian.Uint32(data[4 : 4+4])))
p.NumPartitions = binary.BigEndian.Uint32(data[8 : 8+4])
p.NumReplicas = binary.BigEndian.Uint32(data[12 : 12+4])
p.YourUUID = NodeUUID(int32(binary.BigEndian.Uint32(data[16 : 16+4])))
return 20, nil
overflow:
return 0, ErrDecodeOverflow
}
// 3. Ping
func (*Ping) NEOMsgCode() uint16 {
return 3
}
func (p *Ping) NEOMsgEncodedLen() int {
return 0
}
func (p *Ping) NEOMsgEncode(data []byte) {
}
func (p *Ping) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 3 | answerBit. Pong
func (*Pong) NEOMsgCode() uint16 {
return 3 | answerBit
}
func (p *Pong) NEOMsgEncodedLen() int {
return 0
}
func (p *Pong) NEOMsgEncode(data []byte) {
}
func (p *Pong) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 5. CloseClient
func (*CloseClient) NEOMsgCode() uint16 {
return 5
}
func (p *CloseClient) NEOMsgEncodedLen() int {
return 0
}
func (p *CloseClient) NEOMsgEncode(data []byte) {
}
func (p *CloseClient) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 6. PrimaryMaster
func (*PrimaryMaster) NEOMsgCode() uint16 {
return 6
}
func (p *PrimaryMaster) NEOMsgEncodedLen() int {
return 0
}
func (p *PrimaryMaster) NEOMsgEncode(data []byte) {
}
func (p *PrimaryMaster) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 6 | answerBit. AnswerPrimary
func (*AnswerPrimary) NEOMsgCode() uint16 {
return 6 | answerBit
}
func (p *AnswerPrimary) NEOMsgEncodedLen() int {
return 4
}
func (p *AnswerPrimary) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], uint32(int32(p.PrimaryNodeUUID)))
}
func (p *AnswerPrimary) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 4 {
goto overflow
}
p.PrimaryNodeUUID = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
return 4, nil
overflow:
return 0, ErrDecodeOverflow
}
// 8. NotPrimaryMaster
func (*NotPrimaryMaster) NEOMsgCode() uint16 {
return 8
}
func (p *NotPrimaryMaster) NEOMsgEncodedLen() int {
var size int
for i := 0; i < len(p.KnownMasterList); i++ {
a := &p.KnownMasterList[i]
size += (*a).neoEncodedLen()
}
return 8 + size
}
func (p *NotPrimaryMaster) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], uint32(int32(p.Primary)))
{
l := uint32(len(p.KnownMasterList))
binary.BigEndian.PutUint32(data[4:], l)
data = data[8:]
for i := 0; uint32(i) < l; i++ {
a := &p.KnownMasterList[i]
{
n := (*a).neoEncode(data[0:])
data = data[0+n:]
}
data = data[0:]
}
}
}
func (p *NotPrimaryMaster) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 8 {
goto overflow
}
p.Primary = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
{
l := binary.BigEndian.Uint32(data[4 : 4+4])
data = data[8:]
p.KnownMasterList = make([]struct{ Address }, l)
for i := 0; uint32(i) < l; i++ {
a := &p.KnownMasterList[i]
{
n, ok := (*a).neoDecode(data)
if !ok {
goto overflow
}
data = data[n:]
nread += n
}
}
}
return 8 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 9. NotifyNodeInformation
func (*NotifyNodeInformation) NEOMsgCode() uint16 {
return 9
}
func (p *NotifyNodeInformation) NEOMsgEncodedLen() int {
var size int
for i := 0; i < len(p.NodeList); i++ {
a := &p.NodeList[i]
size += (*a).Addr.neoEncodedLen() + (*a).IdTime.neoEncodedLen()
}
return 4 + p.IdTime.neoEncodedLen() + len(p.NodeList)*12 + size
}
func (p *NotifyNodeInformation) NEOMsgEncode(data []byte) {
{
n := p.IdTime.neoEncode(data[0:])
data = data[0+n:]
}
{
l := uint32(len(p.NodeList))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
binary.BigEndian.PutUint32(data[0:], uint32(int32((*a).Type)))
{
n := (*a).Addr.neoEncode(data[4:])
data = data[4+n:]
}
binary.BigEndian.PutUint32(data[0:], uint32(int32((*a).UUID)))
binary.BigEndian.PutUint32(data[4:], uint32(int32((*a).State)))
{
n := (*a).IdTime.neoEncode(data[8:])
data = data[8+n:]
}
data = data[0:]
}
}
}
func (p *NotifyNodeInformation) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
{
n, ok := p.IdTime.neoDecode(data)
if !ok {
goto overflow
}
data = data[n:]
nread += n
}
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
p.NodeList = make([]NodeInfo, l)
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
if len(data) < 4 {
goto overflow
}
(*a).Type = NodeType(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
data = data[4:]
{
n, ok := (*a).Addr.neoDecode(data)
if !ok {
goto overflow
}
data = data[n:]
nread += n
}
if len(data) < 8 {
goto overflow
}
(*a).UUID = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
(*a).State = NodeState(int32(binary.BigEndian.Uint32(data[4 : 4+4])))
data = data[8:]
{
n, ok := (*a).IdTime.neoDecode(data)
if !ok {
goto overflow
}
data = data[n:]
nread += n
}
}
nread += uint64(l) * 12
}
return 4 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 10. Recovery
func (*Recovery) NEOMsgCode() uint16 {
return 10
}
func (p *Recovery) NEOMsgEncodedLen() int {
return 0
}
func (p *Recovery) NEOMsgEncode(data []byte) {
}
func (p *Recovery) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 10 | answerBit. AnswerRecovery
func (*AnswerRecovery) NEOMsgCode() uint16 {
return 10 | answerBit
}
func (p *AnswerRecovery) NEOMsgEncodedLen() int {
return 24
}
func (p *AnswerRecovery) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.PTid))
binary.BigEndian.PutUint64(data[8:], uint64(p.BackupTid))
binary.BigEndian.PutUint64(data[16:], uint64(p.TruncateTid))
}
func (p *AnswerRecovery) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 24 {
goto overflow
}
p.PTid = PTid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.BackupTid = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.TruncateTid = zodb.Tid(binary.BigEndian.Uint64(data[16 : 16+8]))
return 24, nil
overflow:
return 0, ErrDecodeOverflow
}
// 12. LastIDs
func (*LastIDs) NEOMsgCode() uint16 {
return 12
}
func (p *LastIDs) NEOMsgEncodedLen() int {
return 0
}
func (p *LastIDs) NEOMsgEncode(data []byte) {
}
func (p *LastIDs) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 12 | answerBit. AnswerLastIDs
func (*AnswerLastIDs) NEOMsgCode() uint16 {
return 12 | answerBit
}
func (p *AnswerLastIDs) NEOMsgEncodedLen() int {
return 16
}
func (p *AnswerLastIDs) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.LastOid))
binary.BigEndian.PutUint64(data[8:], uint64(p.LastTid))
}
func (p *AnswerLastIDs) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 16 {
goto overflow
}
p.LastOid = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.LastTid = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
return 16, nil
overflow:
return 0, ErrDecodeOverflow
}
// 14. AskPartitionTable
func (*AskPartitionTable) NEOMsgCode() uint16 {
return 14
}
func (p *AskPartitionTable) NEOMsgEncodedLen() int {
return 0
}
func (p *AskPartitionTable) NEOMsgEncode(data []byte) {
}
func (p *AskPartitionTable) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 14 | answerBit. AnswerPartitionTable
func (*AnswerPartitionTable) NEOMsgCode() uint16 {
return 14 | answerBit
}
func (p *AnswerPartitionTable) NEOMsgEncodedLen() int {
var size int
for i := 0; i < len(p.RowList); i++ {
a := &p.RowList[i]
size += len((*a).CellList) * 8
}
return 12 + len(p.RowList)*8 + size
}
func (p *AnswerPartitionTable) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.PTid))
{
l := uint32(len(p.RowList))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
for i := 0; uint32(i) < l; i++ {
a := &p.RowList[i]
binary.BigEndian.PutUint32(data[0:], (*a).Offset)
{
l := uint32(len((*a).CellList))
binary.BigEndian.PutUint32(data[4:], l)
data = data[8:]
for i := 0; uint32(i) < l; i++ {
a := &(*a).CellList[i]
binary.BigEndian.PutUint32(data[0:], uint32(int32((*a).UUID)))
binary.BigEndian.PutUint32(data[4:], uint32(int32((*a).State)))
data = data[8:]
}
}
data = data[0:]
}
}
}
func (p *AnswerPartitionTable) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.PTid = PTid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
p.RowList = make([]RowInfo, l)
for i := 0; uint32(i) < l; i++ {
a := &p.RowList[i]
if len(data) < 8 {
goto overflow
}
(*a).Offset = binary.BigEndian.Uint32(data[0 : 0+4])
{
l := binary.BigEndian.Uint32(data[4 : 4+4])
data = data[8:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
(*a).CellList = make([]CellInfo, l)
for i := 0; uint32(i) < l; i++ {
a := &(*a).CellList[i]
(*a).UUID = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
(*a).State = CellState(int32(binary.BigEndian.Uint32(data[4 : 4+4])))
data = data[8:]
}
}
}
nread += uint64(l) * 8
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 16. SendPartitionTable
func (*SendPartitionTable) NEOMsgCode() uint16 {
return 16
}
func (p *SendPartitionTable) NEOMsgEncodedLen() int {
var size int
for i := 0; i < len(p.RowList); i++ {
a := &p.RowList[i]
size += len((*a).CellList) * 8
}
return 12 + len(p.RowList)*8 + size
}
func (p *SendPartitionTable) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.PTid))
{
l := uint32(len(p.RowList))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
for i := 0; uint32(i) < l; i++ {
a := &p.RowList[i]
binary.BigEndian.PutUint32(data[0:], (*a).Offset)
{
l := uint32(len((*a).CellList))
binary.BigEndian.PutUint32(data[4:], l)
data = data[8:]
for i := 0; uint32(i) < l; i++ {
a := &(*a).CellList[i]
binary.BigEndian.PutUint32(data[0:], uint32(int32((*a).UUID)))
binary.BigEndian.PutUint32(data[4:], uint32(int32((*a).State)))
data = data[8:]
}
}
data = data[0:]
}
}
}
func (p *SendPartitionTable) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.PTid = PTid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
p.RowList = make([]RowInfo, l)
for i := 0; uint32(i) < l; i++ {
a := &p.RowList[i]
if len(data) < 8 {
goto overflow
}
(*a).Offset = binary.BigEndian.Uint32(data[0 : 0+4])
{
l := binary.BigEndian.Uint32(data[4 : 4+4])
data = data[8:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
(*a).CellList = make([]CellInfo, l)
for i := 0; uint32(i) < l; i++ {
a := &(*a).CellList[i]
(*a).UUID = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
(*a).State = CellState(int32(binary.BigEndian.Uint32(data[4 : 4+4])))
data = data[8:]
}
}
}
nread += uint64(l) * 8
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 17. NotifyPartitionChanges
func (*NotifyPartitionChanges) NEOMsgCode() uint16 {
return 17
}
func (p *NotifyPartitionChanges) NEOMsgEncodedLen() int {
return 12 + len(p.CellList)*12
}
func (p *NotifyPartitionChanges) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.PTid))
{
l := uint32(len(p.CellList))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
for i := 0; uint32(i) < l; i++ {
a := &p.CellList[i]
binary.BigEndian.PutUint32(data[0:], (*a).Offset)
binary.BigEndian.PutUint32(data[4:], uint32(int32((*a).CellInfo.UUID)))
binary.BigEndian.PutUint32(data[8:], uint32(int32((*a).CellInfo.State)))
data = data[12:]
}
}
}
func (p *NotifyPartitionChanges) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.PTid = PTid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
if uint64(len(data)) < uint64(l)*12 {
goto overflow
}
nread += uint64(l) * 12
p.CellList = make([]struct {
Offset uint32
CellInfo CellInfo
}, l)
for i := 0; uint32(i) < l; i++ {
a := &p.CellList[i]
(*a).Offset = binary.BigEndian.Uint32(data[0 : 0+4])
(*a).CellInfo.UUID = NodeUUID(int32(binary.BigEndian.Uint32(data[4 : 4+4])))
(*a).CellInfo.State = CellState(int32(binary.BigEndian.Uint32(data[8 : 8+4])))
data = data[12:]
}
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 18. StartOperation
func (*StartOperation) NEOMsgCode() uint16 {
return 18
}
func (p *StartOperation) NEOMsgEncodedLen() int {
return 1
}
func (p *StartOperation) NEOMsgEncode(data []byte) {
(data[0:])[0] = bool2byte(p.Backup)
}
func (p *StartOperation) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 1 {
goto overflow
}
p.Backup = byte2bool((data[0 : 0+1])[0])
return 1, nil
overflow:
return 0, ErrDecodeOverflow
}
// 19. StopOperation
func (*StopOperation) NEOMsgCode() uint16 {
return 19
}
func (p *StopOperation) NEOMsgEncodedLen() int {
return 0
}
func (p *StopOperation) NEOMsgEncode(data []byte) {
}
func (p *StopOperation) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 20. UnfinishedTransactions
func (*UnfinishedTransactions) NEOMsgCode() uint16 {
return 20
}
func (p *UnfinishedTransactions) NEOMsgEncodedLen() int {
return 4 + len(p.RowList)*4
}
func (p *UnfinishedTransactions) NEOMsgEncode(data []byte) {
{
l := uint32(len(p.RowList))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
for i := 0; uint32(i) < l; i++ {
a := &p.RowList[i]
binary.BigEndian.PutUint32(data[0:], (*a).Offset)
data = data[4:]
}
}
}
func (p *UnfinishedTransactions) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < uint64(l)*4 {
goto overflow
}
nread += uint64(l) * 4
p.RowList = make([]struct{ Offset uint32 }, l)
for i := 0; uint32(i) < l; i++ {
a := &p.RowList[i]
(*a).Offset = binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
}
}
return 4 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 20 | answerBit. AnswerUnfinishedTransactions
func (*AnswerUnfinishedTransactions) NEOMsgCode() uint16 {
return 20 | answerBit
}
func (p *AnswerUnfinishedTransactions) NEOMsgEncodedLen() int {
return 12 + len(p.TidList)*8
}
func (p *AnswerUnfinishedTransactions) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.MaxTID))
{
l := uint32(len(p.TidList))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
for i := 0; uint32(i) < l; i++ {
a := &p.TidList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a).UnfinishedTID))
data = data[8:]
}
}
}
func (p *AnswerUnfinishedTransactions) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.MaxTID = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
p.TidList = make([]struct{ UnfinishedTID zodb.Tid }, l)
for i := 0; uint32(i) < l; i++ {
a := &p.TidList[i]
(*a).UnfinishedTID = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 22. LockedTransactions
func (*LockedTransactions) NEOMsgCode() uint16 {
return 22
}
func (p *LockedTransactions) NEOMsgEncodedLen() int {
return 0
}
func (p *LockedTransactions) NEOMsgEncode(data []byte) {
}
func (p *LockedTransactions) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 22 | answerBit. AnswerLockedTransactions
func (*AnswerLockedTransactions) NEOMsgCode() uint16 {
return 22 | answerBit
}
func (p *AnswerLockedTransactions) NEOMsgEncodedLen() int {
return 4 + len(p.TidDict)*16
}
func (p *AnswerLockedTransactions) NEOMsgEncode(data []byte) {
{
l := uint32(len(p.TidDict))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
keyv := make([]zodb.Tid, 0, l)
for key := range p.TidDict {
keyv = append(keyv, key)
}
sort.Slice(keyv, func(i, j int) bool { return keyv[i] < keyv[j] })
for _, key := range keyv {
binary.BigEndian.PutUint64(data[0:], uint64(key))
binary.BigEndian.PutUint64(data[8:], uint64(p.TidDict[key]))
data = data[16:]
}
}
}
func (p *AnswerLockedTransactions) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < uint64(l)*16 {
goto overflow
}
nread += uint64(l) * 16
p.TidDict = make(map[zodb.Tid]zodb.Tid, l)
m := p.TidDict
for i := 0; uint32(i) < l; i++ {
key := zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
m[key] = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
data = data[16:]
}
}
return 4 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 24. FinalTID
func (*FinalTID) NEOMsgCode() uint16 {
return 24
}
func (p *FinalTID) NEOMsgEncodedLen() int {
return 8
}
func (p *FinalTID) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.TTID))
}
func (p *FinalTID) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.TTID = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// 24 | answerBit. AnswerFinalTID
func (*AnswerFinalTID) NEOMsgCode() uint16 {
return 24 | answerBit
}
func (p *AnswerFinalTID) NEOMsgEncodedLen() int {
return 8
}
func (p *AnswerFinalTID) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
}
func (p *AnswerFinalTID) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// 26. ValidateTransaction
func (*ValidateTransaction) NEOMsgCode() uint16 {
return 26
}
func (p *ValidateTransaction) NEOMsgEncodedLen() int {
return 16
}
func (p *ValidateTransaction) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.TTID))
binary.BigEndian.PutUint64(data[8:], uint64(p.Tid))
}
func (p *ValidateTransaction) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 16 {
goto overflow
}
p.TTID = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
return 16, nil
overflow:
return 0, ErrDecodeOverflow
}
// 27. BeginTransaction
func (*BeginTransaction) NEOMsgCode() uint16 {
return 27
}
func (p *BeginTransaction) NEOMsgEncodedLen() int {
return 8
}
func (p *BeginTransaction) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
}
func (p *BeginTransaction) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// 27 | answerBit. AnswerBeginTransaction
func (*AnswerBeginTransaction) NEOMsgCode() uint16 {
return 27 | answerBit
}
func (p *AnswerBeginTransaction) NEOMsgEncodedLen() int {
return 8
}
func (p *AnswerBeginTransaction) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
}
func (p *AnswerBeginTransaction) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// 29. FailedVote
func (*FailedVote) NEOMsgCode() uint16 {
return 29
}
func (p *FailedVote) NEOMsgEncodedLen() int {
return 12 + len(p.NodeList)*4
}
func (p *FailedVote) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
{
l := uint32(len(p.NodeList))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
binary.BigEndian.PutUint32(data[0:], uint32(int32((*a))))
data = data[4:]
}
}
}
func (p *FailedVote) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
if uint64(len(data)) < uint64(l)*4 {
goto overflow
}
nread += uint64(l) * 4
p.NodeList = make([]NodeUUID, l)
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
(*a) = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
data = data[4:]
}
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 30. FinishTransaction
func (*FinishTransaction) NEOMsgCode() uint16 {
return 30
}
func (p *FinishTransaction) NEOMsgEncodedLen() int {
return 16 + len(p.OIDList)*8 + len(p.CheckedList)*8
}
func (p *FinishTransaction) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
{
l := uint32(len(p.OIDList))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
for i := 0; uint32(i) < l; i++ {
a := &p.OIDList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
{
l := uint32(len(p.CheckedList))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
for i := 0; uint32(i) < l; i++ {
a := &p.CheckedList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
}
func (p *FinishTransaction) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
if uint64(len(data)) < 4+uint64(l)*8 {
goto overflow
}
nread += 4 + uint64(l)*8
p.OIDList = make([]zodb.Oid, l)
for i := 0; uint32(i) < l; i++ {
a := &p.OIDList[i]
(*a) = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
p.CheckedList = make([]zodb.Oid, l)
for i := 0; uint32(i) < l; i++ {
a := &p.CheckedList[i]
(*a) = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 30 | answerBit. AnswerTransactionFinished
func (*AnswerTransactionFinished) NEOMsgCode() uint16 {
return 30 | answerBit
}
func (p *AnswerTransactionFinished) NEOMsgEncodedLen() int {
return 16
}
func (p *AnswerTransactionFinished) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.TTid))
binary.BigEndian.PutUint64(data[8:], uint64(p.Tid))
}
func (p *AnswerTransactionFinished) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 16 {
goto overflow
}
p.TTid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
return 16, nil
overflow:
return 0, ErrDecodeOverflow
}
// 32. LockInformation
func (*LockInformation) NEOMsgCode() uint16 {
return 32
}
func (p *LockInformation) NEOMsgEncodedLen() int {
return 16
}
func (p *LockInformation) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Ttid))
binary.BigEndian.PutUint64(data[8:], uint64(p.Tid))
}
func (p *LockInformation) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 16 {
goto overflow
}
p.Ttid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
return 16, nil
overflow:
return 0, ErrDecodeOverflow
}
// 32 | answerBit. AnswerInformationLocked
func (*AnswerInformationLocked) NEOMsgCode() uint16 {
return 32 | answerBit
}
func (p *AnswerInformationLocked) NEOMsgEncodedLen() int {
return 8
}
func (p *AnswerInformationLocked) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Ttid))
}
func (p *AnswerInformationLocked) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.Ttid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// 34. InvalidateObjects
func (*InvalidateObjects) NEOMsgCode() uint16 {
return 34
}
func (p *InvalidateObjects) NEOMsgEncodedLen() int {
return 12 + len(p.OidList)*8
}
func (p *InvalidateObjects) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
{
l := uint32(len(p.OidList))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
}
func (p *InvalidateObjects) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
p.OidList = make([]zodb.Oid, l)
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
(*a) = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 35. NotifyUnlockInformation
func (*NotifyUnlockInformation) NEOMsgCode() uint16 {
return 35
}
func (p *NotifyUnlockInformation) NEOMsgEncodedLen() int {
return 8
}
func (p *NotifyUnlockInformation) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.TTID))
}
func (p *NotifyUnlockInformation) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.TTID = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// 36. AskNewOIDs
func (*AskNewOIDs) NEOMsgCode() uint16 {
return 36
}
func (p *AskNewOIDs) NEOMsgEncodedLen() int {
return 4
}
func (p *AskNewOIDs) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], p.NumOIDs)
}
func (p *AskNewOIDs) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 4 {
goto overflow
}
p.NumOIDs = binary.BigEndian.Uint32(data[0 : 0+4])
return 4, nil
overflow:
return 0, ErrDecodeOverflow
}
// 36 | answerBit. AnswerNewOIDs
func (*AnswerNewOIDs) NEOMsgCode() uint16 {
return 36 | answerBit
}
func (p *AnswerNewOIDs) NEOMsgEncodedLen() int {
return 4 + len(p.OidList)*8
}
func (p *AnswerNewOIDs) NEOMsgEncode(data []byte) {
{
l := uint32(len(p.OidList))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
}
func (p *AnswerNewOIDs) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
p.OidList = make([]zodb.Oid, l)
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
(*a) = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
return 4 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 38. NotifyDeadlock
func (*NotifyDeadlock) NEOMsgCode() uint16 {
return 38
}
func (p *NotifyDeadlock) NEOMsgEncodedLen() int {
return 16
}
func (p *NotifyDeadlock) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.TTid))
binary.BigEndian.PutUint64(data[8:], uint64(p.LockingTid))
}
func (p *NotifyDeadlock) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 16 {
goto overflow
}
p.TTid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.LockingTid = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
return 16, nil
overflow:
return 0, ErrDecodeOverflow
}
// 39. RebaseTransaction
func (*RebaseTransaction) NEOMsgCode() uint16 {
return 39
}
func (p *RebaseTransaction) NEOMsgEncodedLen() int {
return 16
}
func (p *RebaseTransaction) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.TTid))
binary.BigEndian.PutUint64(data[8:], uint64(p.LockingTid))
}
func (p *RebaseTransaction) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 16 {
goto overflow
}
p.TTid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.LockingTid = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
return 16, nil
overflow:
return 0, ErrDecodeOverflow
}
// 39 | answerBit. AnswerRebaseTransaction
func (*AnswerRebaseTransaction) NEOMsgCode() uint16 {
return 39 | answerBit
}
func (p *AnswerRebaseTransaction) NEOMsgEncodedLen() int {
return 4 + len(p.OidList)*8
}
func (p *AnswerRebaseTransaction) NEOMsgEncode(data []byte) {
{
l := uint32(len(p.OidList))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
}
func (p *AnswerRebaseTransaction) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
p.OidList = make([]zodb.Oid, l)
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
(*a) = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
return 4 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 41. RebaseObject
func (*RebaseObject) NEOMsgCode() uint16 {
return 41
}
func (p *RebaseObject) NEOMsgEncodedLen() int {
return 16
}
func (p *RebaseObject) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.TTid))
binary.BigEndian.PutUint64(data[8:], uint64(p.Oid))
}
func (p *RebaseObject) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 16 {
goto overflow
}
p.TTid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.Oid = zodb.Oid(binary.BigEndian.Uint64(data[8 : 8+8]))
return 16, nil
overflow:
return 0, ErrDecodeOverflow
}
// 41 | answerBit. AnswerRebaseObject
func (*AnswerRebaseObject) NEOMsgCode() uint16 {
return 41 | answerBit
}
func (p *AnswerRebaseObject) NEOMsgEncodedLen() int {
return 41 + len(p.Data.XData())
}
func (p *AnswerRebaseObject) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Serial))
binary.BigEndian.PutUint64(data[8:], uint64(p.ConflictSerial))
(data[16:])[0] = bool2byte(p.Compression)
copy(data[17:], p.Checksum[:])
{
l := uint32(len(p.Data.XData()))
binary.BigEndian.PutUint32(data[37:], l)
data = data[41:]
copy(data, p.Data.XData())
data = data[l:]
}
}
func (p *AnswerRebaseObject) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 41 {
goto overflow
}
p.Serial = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.ConflictSerial = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.Compression = byte2bool((data[16 : 16+1])[0])
copy(p.Checksum[:], data[17:37])
{
l := binary.BigEndian.Uint32(data[37 : 37+4])
data = data[41:]
if uint64(len(data)) < uint64(l) {
goto overflow
}
nread += uint64(l)
p.Data = mem.BufAlloc(int(l))
copy(p.Data.Data, data[:l])
data = data[l:]
}
return 41 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 43. StoreObject
func (*StoreObject) NEOMsgCode() uint16 {
return 43
}
func (p *StoreObject) NEOMsgEncodedLen() int {
return 57 + len(p.Data)
}
func (p *StoreObject) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Oid))
binary.BigEndian.PutUint64(data[8:], uint64(p.Serial))
(data[16:])[0] = bool2byte(p.Compression)
copy(data[17:], p.Checksum[:])
{
l := uint32(len(p.Data))
binary.BigEndian.PutUint32(data[37:], l)
data = data[41:]
copy(data, p.Data)
data = data[l:]
}
binary.BigEndian.PutUint64(data[0:], uint64(p.DataSerial))
binary.BigEndian.PutUint64(data[8:], uint64(p.Tid))
}
func (p *StoreObject) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 41 {
goto overflow
}
p.Oid = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.Serial = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.Compression = byte2bool((data[16 : 16+1])[0])
copy(p.Checksum[:], data[17:37])
{
l := binary.BigEndian.Uint32(data[37 : 37+4])
data = data[41:]
if uint64(len(data)) < 16+uint64(l) {
goto overflow
}
nread += 16 + uint64(l)
p.Data = make([]byte, l)
copy(p.Data, data[:l])
data = data[l:]
}
p.DataSerial = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
return 41 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 43 | answerBit. AnswerStoreObject
func (*AnswerStoreObject) NEOMsgCode() uint16 {
return 43 | answerBit
}
func (p *AnswerStoreObject) NEOMsgEncodedLen() int {
return 8
}
func (p *AnswerStoreObject) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Conflict))
}
func (p *AnswerStoreObject) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.Conflict = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// 45. AbortTransaction
func (*AbortTransaction) NEOMsgCode() uint16 {
return 45
}
func (p *AbortTransaction) NEOMsgEncodedLen() int {
return 12 + len(p.NodeList)*4
}
func (p *AbortTransaction) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
{
l := uint32(len(p.NodeList))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
binary.BigEndian.PutUint32(data[0:], uint32(int32((*a))))
data = data[4:]
}
}
}
func (p *AbortTransaction) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
if uint64(len(data)) < uint64(l)*4 {
goto overflow
}
nread += uint64(l) * 4
p.NodeList = make([]NodeUUID, l)
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
(*a) = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
data = data[4:]
}
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 46. StoreTransaction
func (*StoreTransaction) NEOMsgCode() uint16 {
return 46
}
func (p *StoreTransaction) NEOMsgEncodedLen() int {
return 24 + len(p.User) + len(p.Description) + len(p.Extension) + len(p.OidList)*8
}
func (p *StoreTransaction) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
{
l := uint32(len(p.User))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
copy(data, p.User)
data = data[l:]
}
{
l := uint32(len(p.Description))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
copy(data, p.Description)
data = data[l:]
}
{
l := uint32(len(p.Extension))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
copy(data, p.Extension)
data = data[l:]
}
{
l := uint32(len(p.OidList))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
}
func (p *StoreTransaction) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
if uint64(len(data)) < 4+uint64(l) {
goto overflow
}
nread += 4 + uint64(l)
p.User = string(data[:l])
data = data[l:]
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < 4+uint64(l) {
goto overflow
}
nread += 4 + uint64(l)
p.Description = string(data[:l])
data = data[l:]
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < 4+uint64(l) {
goto overflow
}
nread += 4 + uint64(l)
p.Extension = string(data[:l])
data = data[l:]
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
p.OidList = make([]zodb.Oid, l)
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
(*a) = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 46 | answerBit. AnswerStoreTransaction
func (*AnswerStoreTransaction) NEOMsgCode() uint16 {
return 46 | answerBit
}
func (p *AnswerStoreTransaction) NEOMsgEncodedLen() int {
return 0
}
func (p *AnswerStoreTransaction) NEOMsgEncode(data []byte) {
}
func (p *AnswerStoreTransaction) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 48. VoteTransaction
func (*VoteTransaction) NEOMsgCode() uint16 {
return 48
}
func (p *VoteTransaction) NEOMsgEncodedLen() int {
return 8
}
func (p *VoteTransaction) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
}
func (p *VoteTransaction) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// 48 | answerBit. AnswerVoteTransaction
func (*AnswerVoteTransaction) NEOMsgCode() uint16 {
return 48 | answerBit
}
func (p *AnswerVoteTransaction) NEOMsgEncodedLen() int {
return 0
}
func (p *AnswerVoteTransaction) NEOMsgEncode(data []byte) {
}
func (p *AnswerVoteTransaction) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 50. GetObject
func (*GetObject) NEOMsgCode() uint16 {
return 50
}
func (p *GetObject) NEOMsgEncodedLen() int {
return 24
}
func (p *GetObject) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Oid))
binary.BigEndian.PutUint64(data[8:], uint64(p.Serial))
binary.BigEndian.PutUint64(data[16:], uint64(p.Tid))
}
func (p *GetObject) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 24 {
goto overflow
}
p.Oid = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.Serial = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[16 : 16+8]))
return 24, nil
overflow:
return 0, ErrDecodeOverflow
}
// 50 | answerBit. AnswerObject
func (*AnswerObject) NEOMsgCode() uint16 {
return 50 | answerBit
}
func (p *AnswerObject) NEOMsgEncodedLen() int {
return 57 + len(p.Data.XData())
}
func (p *AnswerObject) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Oid))
binary.BigEndian.PutUint64(data[8:], uint64(p.Serial))
binary.BigEndian.PutUint64(data[16:], uint64(p.NextSerial))
(data[24:])[0] = bool2byte(p.Compression)
copy(data[25:], p.Checksum[:])
{
l := uint32(len(p.Data.XData()))
binary.BigEndian.PutUint32(data[45:], l)
data = data[49:]
copy(data, p.Data.XData())
data = data[l:]
}
binary.BigEndian.PutUint64(data[0:], uint64(p.DataSerial))
}
func (p *AnswerObject) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 49 {
goto overflow
}
p.Oid = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.Serial = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.NextSerial = zodb.Tid(binary.BigEndian.Uint64(data[16 : 16+8]))
p.Compression = byte2bool((data[24 : 24+1])[0])
copy(p.Checksum[:], data[25:45])
{
l := binary.BigEndian.Uint32(data[45 : 45+4])
data = data[49:]
if uint64(len(data)) < 8+uint64(l) {
goto overflow
}
nread += 8 + uint64(l)
p.Data = mem.BufAlloc(int(l))
copy(p.Data.Data, data[:l])
data = data[l:]
}
p.DataSerial = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 49 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 52. AskTIDs
func (*AskTIDs) NEOMsgCode() uint16 {
return 52
}
func (p *AskTIDs) NEOMsgEncodedLen() int {
return 20
}
func (p *AskTIDs) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], p.First)
binary.BigEndian.PutUint64(data[8:], p.Last)
binary.BigEndian.PutUint32(data[16:], p.Partition)
}
func (p *AskTIDs) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 20 {
goto overflow
}
p.First = binary.BigEndian.Uint64(data[0 : 0+8])
p.Last = binary.BigEndian.Uint64(data[8 : 8+8])
p.Partition = binary.BigEndian.Uint32(data[16 : 16+4])
return 20, nil
overflow:
return 0, ErrDecodeOverflow
}
// 52 | answerBit. AnswerTIDs
func (*AnswerTIDs) NEOMsgCode() uint16 {
return 52 | answerBit
}
func (p *AnswerTIDs) NEOMsgEncodedLen() int {
return 4 + len(p.TIDList)*8
}
func (p *AnswerTIDs) NEOMsgEncode(data []byte) {
{
l := uint32(len(p.TIDList))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
for i := 0; uint32(i) < l; i++ {
a := &p.TIDList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
}
func (p *AnswerTIDs) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
p.TIDList = make([]zodb.Tid, l)
for i := 0; uint32(i) < l; i++ {
a := &p.TIDList[i]
(*a) = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
return 4 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 54. TransactionInformation
func (*TransactionInformation) NEOMsgCode() uint16 {
return 54
}
func (p *TransactionInformation) NEOMsgEncodedLen() int {
return 8
}
func (p *TransactionInformation) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
}
func (p *TransactionInformation) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// 54 | answerBit. AnswerTransactionInformation
func (*AnswerTransactionInformation) NEOMsgCode() uint16 {
return 54 | answerBit
}
func (p *AnswerTransactionInformation) NEOMsgEncodedLen() int {
return 25 + len(p.User) + len(p.Description) + len(p.Extension) + len(p.OidList)*8
}
func (p *AnswerTransactionInformation) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
{
l := uint32(len(p.User))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
copy(data, p.User)
data = data[l:]
}
{
l := uint32(len(p.Description))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
copy(data, p.Description)
data = data[l:]
}
{
l := uint32(len(p.Extension))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
copy(data, p.Extension)
data = data[l:]
}
(data[0:])[0] = bool2byte(p.Packed)
{
l := uint32(len(p.OidList))
binary.BigEndian.PutUint32(data[1:], l)
data = data[5:]
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
}
func (p *AnswerTransactionInformation) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
if uint64(len(data)) < 4+uint64(l) {
goto overflow
}
nread += 4 + uint64(l)
p.User = string(data[:l])
data = data[l:]
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < 4+uint64(l) {
goto overflow
}
nread += 4 + uint64(l)
p.Description = string(data[:l])
data = data[l:]
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < 5+uint64(l) {
goto overflow
}
nread += 5 + uint64(l)
p.Extension = string(data[:l])
data = data[l:]
}
p.Packed = byte2bool((data[0 : 0+1])[0])
{
l := binary.BigEndian.Uint32(data[1 : 1+4])
data = data[5:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
p.OidList = make([]zodb.Oid, l)
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
(*a) = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 56. ObjectHistory
func (*ObjectHistory) NEOMsgCode() uint16 {
return 56
}
func (p *ObjectHistory) NEOMsgEncodedLen() int {
return 24
}
func (p *ObjectHistory) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Oid))
binary.BigEndian.PutUint64(data[8:], p.First)
binary.BigEndian.PutUint64(data[16:], p.Last)
}
func (p *ObjectHistory) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 24 {
goto overflow
}
p.Oid = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.First = binary.BigEndian.Uint64(data[8 : 8+8])
p.Last = binary.BigEndian.Uint64(data[16 : 16+8])
return 24, nil
overflow:
return 0, ErrDecodeOverflow
}
// 56 | answerBit. AnswerObjectHistory
func (*AnswerObjectHistory) NEOMsgCode() uint16 {
return 56 | answerBit
}
func (p *AnswerObjectHistory) NEOMsgEncodedLen() int {
return 12 + len(p.HistoryList)*12
}
func (p *AnswerObjectHistory) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Oid))
{
l := uint32(len(p.HistoryList))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
for i := 0; uint32(i) < l; i++ {
a := &p.HistoryList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a).Serial))
binary.BigEndian.PutUint32(data[8:], (*a).Size)
data = data[12:]
}
}
}
func (p *AnswerObjectHistory) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.Oid = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
if uint64(len(data)) < uint64(l)*12 {
goto overflow
}
nread += uint64(l) * 12
p.HistoryList = make([]struct {
Serial zodb.Tid
Size uint32
}, l)
for i := 0; uint32(i) < l; i++ {
a := &p.HistoryList[i]
(*a).Serial = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
(*a).Size = binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
}
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 58. PartitionList
func (*PartitionList) NEOMsgCode() uint16 {
return 58
}
func (p *PartitionList) NEOMsgEncodedLen() int {
return 12
}
func (p *PartitionList) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], p.MinOffset)
binary.BigEndian.PutUint32(data[4:], p.MaxOffset)
binary.BigEndian.PutUint32(data[8:], uint32(int32(p.NodeUUID)))
}
func (p *PartitionList) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 12 {
goto overflow
}
p.MinOffset = binary.BigEndian.Uint32(data[0 : 0+4])
p.MaxOffset = binary.BigEndian.Uint32(data[4 : 4+4])
p.NodeUUID = NodeUUID(int32(binary.BigEndian.Uint32(data[8 : 8+4])))
return 12, nil
overflow:
return 0, ErrDecodeOverflow
}
// 58 | answerBit. AnswerPartitionList
func (*AnswerPartitionList) NEOMsgCode() uint16 {
return 58 | answerBit
}
func (p *AnswerPartitionList) NEOMsgEncodedLen() int {
var size int
for i := 0; i < len(p.RowList); i++ {
a := &p.RowList[i]
size += len((*a).CellList) * 8
}
return 12 + len(p.RowList)*8 + size
}
func (p *AnswerPartitionList) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.PTid))
{
l := uint32(len(p.RowList))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
for i := 0; uint32(i) < l; i++ {
a := &p.RowList[i]
binary.BigEndian.PutUint32(data[0:], (*a).Offset)
{
l := uint32(len((*a).CellList))
binary.BigEndian.PutUint32(data[4:], l)
data = data[8:]
for i := 0; uint32(i) < l; i++ {
a := &(*a).CellList[i]
binary.BigEndian.PutUint32(data[0:], uint32(int32((*a).UUID)))
binary.BigEndian.PutUint32(data[4:], uint32(int32((*a).State)))
data = data[8:]
}
}
data = data[0:]
}
}
}
func (p *AnswerPartitionList) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.PTid = PTid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
p.RowList = make([]RowInfo, l)
for i := 0; uint32(i) < l; i++ {
a := &p.RowList[i]
if len(data) < 8 {
goto overflow
}
(*a).Offset = binary.BigEndian.Uint32(data[0 : 0+4])
{
l := binary.BigEndian.Uint32(data[4 : 4+4])
data = data[8:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
(*a).CellList = make([]CellInfo, l)
for i := 0; uint32(i) < l; i++ {
a := &(*a).CellList[i]
(*a).UUID = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
(*a).State = CellState(int32(binary.BigEndian.Uint32(data[4 : 4+4])))
data = data[8:]
}
}
}
nread += uint64(l) * 8
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 60. NodeList
func (*NodeList) NEOMsgCode() uint16 {
return 60
}
func (p *NodeList) NEOMsgEncodedLen() int {
return 4
}
func (p *NodeList) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], uint32(int32(p.NodeType)))
}
func (p *NodeList) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 4 {
goto overflow
}
p.NodeType = NodeType(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
return 4, nil
overflow:
return 0, ErrDecodeOverflow
}
// 60 | answerBit. AnswerNodeList
func (*AnswerNodeList) NEOMsgCode() uint16 {
return 60 | answerBit
}
func (p *AnswerNodeList) NEOMsgEncodedLen() int {
var size int
for i := 0; i < len(p.NodeList); i++ {
a := &p.NodeList[i]
size += (*a).Addr.neoEncodedLen() + (*a).IdTime.neoEncodedLen()
}
return 4 + len(p.NodeList)*12 + size
}
func (p *AnswerNodeList) NEOMsgEncode(data []byte) {
{
l := uint32(len(p.NodeList))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
binary.BigEndian.PutUint32(data[0:], uint32(int32((*a).Type)))
{
n := (*a).Addr.neoEncode(data[4:])
data = data[4+n:]
}
binary.BigEndian.PutUint32(data[0:], uint32(int32((*a).UUID)))
binary.BigEndian.PutUint32(data[4:], uint32(int32((*a).State)))
{
n := (*a).IdTime.neoEncode(data[8:])
data = data[8+n:]
}
data = data[0:]
}
}
}
func (p *AnswerNodeList) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
p.NodeList = make([]NodeInfo, l)
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
if len(data) < 4 {
goto overflow
}
(*a).Type = NodeType(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
data = data[4:]
{
n, ok := (*a).Addr.neoDecode(data)
if !ok {
goto overflow
}
data = data[n:]
nread += n
}
if len(data) < 8 {
goto overflow
}
(*a).UUID = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
(*a).State = NodeState(int32(binary.BigEndian.Uint32(data[4 : 4+4])))
data = data[8:]
{
n, ok := (*a).IdTime.neoDecode(data)
if !ok {
goto overflow
}
data = data[n:]
nread += n
}
}
nread += uint64(l) * 12
}
return 4 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 62. SetNodeState
func (*SetNodeState) NEOMsgCode() uint16 {
return 62
}
func (p *SetNodeState) NEOMsgEncodedLen() int {
return 8
}
func (p *SetNodeState) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], uint32(int32(p.NodeUUID)))
binary.BigEndian.PutUint32(data[4:], uint32(int32(p.NodeState)))
}
func (p *SetNodeState) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.NodeUUID = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
p.NodeState = NodeState(int32(binary.BigEndian.Uint32(data[4 : 4+4])))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// 63. AddPendingNodes
func (*AddPendingNodes) NEOMsgCode() uint16 {
return 63
}
func (p *AddPendingNodes) NEOMsgEncodedLen() int {
return 4 + len(p.NodeList)*4
}
func (p *AddPendingNodes) NEOMsgEncode(data []byte) {
{
l := uint32(len(p.NodeList))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
binary.BigEndian.PutUint32(data[0:], uint32(int32((*a))))
data = data[4:]
}
}
}
func (p *AddPendingNodes) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < uint64(l)*4 {
goto overflow
}
nread += uint64(l) * 4
p.NodeList = make([]NodeUUID, l)
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
(*a) = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
data = data[4:]
}
}
return 4 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 64. TweakPartitionTable
func (*TweakPartitionTable) NEOMsgCode() uint16 {
return 64
}
func (p *TweakPartitionTable) NEOMsgEncodedLen() int {
return 4 + len(p.NodeList)*4
}
func (p *TweakPartitionTable) NEOMsgEncode(data []byte) {
{
l := uint32(len(p.NodeList))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
binary.BigEndian.PutUint32(data[0:], uint32(int32((*a))))
data = data[4:]
}
}
}
func (p *TweakPartitionTable) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < uint64(l)*4 {
goto overflow
}
nread += uint64(l) * 4
p.NodeList = make([]NodeUUID, l)
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
(*a) = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
data = data[4:]
}
}
return 4 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 65. SetClusterState
func (*SetClusterState) NEOMsgCode() uint16 {
return 65
}
func (p *SetClusterState) NEOMsgEncodedLen() int {
return 4
}
func (p *SetClusterState) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], uint32(int32(p.State)))
}
func (p *SetClusterState) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 4 {
goto overflow
}
p.State = ClusterState(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
return 4, nil
overflow:
return 0, ErrDecodeOverflow
}
// 66. Repair
func (*Repair) NEOMsgCode() uint16 {
return 66
}
func (p *Repair) NEOMsgEncodedLen() int {
return 5 + len(p.NodeList)*4
}
func (p *Repair) NEOMsgEncode(data []byte) {
{
l := uint32(len(p.NodeList))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
binary.BigEndian.PutUint32(data[0:], uint32(int32((*a))))
data = data[4:]
}
}
(data[0:])[0] = bool2byte(p.repairFlags.DryRun)
}
func (p *Repair) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < 1+uint64(l)*4 {
goto overflow
}
nread += 1 + uint64(l)*4
p.NodeList = make([]NodeUUID, l)
for i := 0; uint32(i) < l; i++ {
a := &p.NodeList[i]
(*a) = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
data = data[4:]
}
}
p.repairFlags.DryRun = byte2bool((data[0 : 0+1])[0])
return 4 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 67. RepairOne
func (*RepairOne) NEOMsgCode() uint16 {
return 67
}
func (p *RepairOne) NEOMsgEncodedLen() int {
return 1
}
func (p *RepairOne) NEOMsgEncode(data []byte) {
(data[0:])[0] = bool2byte(p.repairFlags.DryRun)
}
func (p *RepairOne) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 1 {
goto overflow
}
p.repairFlags.DryRun = byte2bool((data[0 : 0+1])[0])
return 1, nil
overflow:
return 0, ErrDecodeOverflow
}
// 68. NotifyClusterState
func (*NotifyClusterState) NEOMsgCode() uint16 {
return 68
}
func (p *NotifyClusterState) NEOMsgEncodedLen() int {
return 4
}
func (p *NotifyClusterState) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], uint32(int32(p.State)))
}
func (p *NotifyClusterState) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 4 {
goto overflow
}
p.State = ClusterState(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
return 4, nil
overflow:
return 0, ErrDecodeOverflow
}
// 69. AskClusterState
func (*AskClusterState) NEOMsgCode() uint16 {
return 69
}
func (p *AskClusterState) NEOMsgEncodedLen() int {
return 0
}
func (p *AskClusterState) NEOMsgEncode(data []byte) {
}
func (p *AskClusterState) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 69 | answerBit. AnswerClusterState
func (*AnswerClusterState) NEOMsgCode() uint16 {
return 69 | answerBit
}
func (p *AnswerClusterState) NEOMsgEncodedLen() int {
return 4
}
func (p *AnswerClusterState) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], uint32(int32(p.State)))
}
func (p *AnswerClusterState) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 4 {
goto overflow
}
p.State = ClusterState(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
return 4, nil
overflow:
return 0, ErrDecodeOverflow
}
// 71. ObjectUndoSerial
func (*ObjectUndoSerial) NEOMsgCode() uint16 {
return 71
}
func (p *ObjectUndoSerial) NEOMsgEncodedLen() int {
return 28 + len(p.OidList)*8
}
func (p *ObjectUndoSerial) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
binary.BigEndian.PutUint64(data[8:], uint64(p.LTID))
binary.BigEndian.PutUint64(data[16:], uint64(p.UndoneTID))
{
l := uint32(len(p.OidList))
binary.BigEndian.PutUint32(data[24:], l)
data = data[28:]
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
}
func (p *ObjectUndoSerial) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 28 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.LTID = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.UndoneTID = zodb.Tid(binary.BigEndian.Uint64(data[16 : 16+8]))
{
l := binary.BigEndian.Uint32(data[24 : 24+4])
data = data[28:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
p.OidList = make([]zodb.Oid, l)
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
(*a) = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
return 28 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 71 | answerBit. AnswerObjectUndoSerial
func (*AnswerObjectUndoSerial) NEOMsgCode() uint16 {
return 71 | answerBit
}
func (p *AnswerObjectUndoSerial) NEOMsgEncodedLen() int {
return 4 + len(p.ObjectTIDDict)*25
}
func (p *AnswerObjectUndoSerial) NEOMsgEncode(data []byte) {
{
l := uint32(len(p.ObjectTIDDict))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
keyv := make([]zodb.Oid, 0, l)
for key := range p.ObjectTIDDict {
keyv = append(keyv, key)
}
sort.Slice(keyv, func(i, j int) bool { return keyv[i] < keyv[j] })
for _, key := range keyv {
binary.BigEndian.PutUint64(data[0:], uint64(key))
binary.BigEndian.PutUint64(data[8:], uint64(p.ObjectTIDDict[key].CurrentSerial))
binary.BigEndian.PutUint64(data[16:], uint64(p.ObjectTIDDict[key].UndoSerial))
(data[24:])[0] = bool2byte(p.ObjectTIDDict[key].IsCurrent)
data = data[25:]
}
}
}
func (p *AnswerObjectUndoSerial) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < uint64(l)*25 {
goto overflow
}
nread += uint64(l) * 25
p.ObjectTIDDict = make(map[zodb.Oid]struct {
CurrentSerial zodb.Tid
UndoSerial zodb.Tid
IsCurrent bool
}, l)
m := p.ObjectTIDDict
for i := 0; uint32(i) < l; i++ {
key := zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
var v struct {
CurrentSerial zodb.Tid
UndoSerial zodb.Tid
IsCurrent bool
}
v.CurrentSerial = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
v.UndoSerial = zodb.Tid(binary.BigEndian.Uint64(data[16 : 16+8]))
v.IsCurrent = byte2bool((data[24 : 24+1])[0])
m[key] = v
data = data[25:]
}
}
return 4 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 73. AskTIDsFrom
func (*AskTIDsFrom) NEOMsgCode() uint16 {
return 73
}
func (p *AskTIDsFrom) NEOMsgEncodedLen() int {
return 24
}
func (p *AskTIDsFrom) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.MinTID))
binary.BigEndian.PutUint64(data[8:], uint64(p.MaxTID))
binary.BigEndian.PutUint32(data[16:], p.Length)
binary.BigEndian.PutUint32(data[20:], p.Partition)
}
func (p *AskTIDsFrom) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 24 {
goto overflow
}
p.MinTID = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.MaxTID = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.Length = binary.BigEndian.Uint32(data[16 : 16+4])
p.Partition = binary.BigEndian.Uint32(data[20 : 20+4])
return 24, nil
overflow:
return 0, ErrDecodeOverflow
}
// 73 | answerBit. AnswerTIDsFrom
func (*AnswerTIDsFrom) NEOMsgCode() uint16 {
return 73 | answerBit
}
func (p *AnswerTIDsFrom) NEOMsgEncodedLen() int {
return 4 + len(p.TidList)*8
}
func (p *AnswerTIDsFrom) NEOMsgEncode(data []byte) {
{
l := uint32(len(p.TidList))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
for i := 0; uint32(i) < l; i++ {
a := &p.TidList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
}
func (p *AnswerTIDsFrom) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
p.TidList = make([]zodb.Tid, l)
for i := 0; uint32(i) < l; i++ {
a := &p.TidList[i]
(*a) = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
return 4 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 75. Pack
func (*Pack) NEOMsgCode() uint16 {
return 75
}
func (p *Pack) NEOMsgEncodedLen() int {
return 8
}
func (p *Pack) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
}
func (p *Pack) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// 75 | answerBit. AnswerPack
func (*AnswerPack) NEOMsgCode() uint16 {
return 75 | answerBit
}
func (p *AnswerPack) NEOMsgEncodedLen() int {
return 1
}
func (p *AnswerPack) NEOMsgEncode(data []byte) {
(data[0:])[0] = bool2byte(p.Status)
}
func (p *AnswerPack) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 1 {
goto overflow
}
p.Status = byte2bool((data[0 : 0+1])[0])
return 1, nil
overflow:
return 0, ErrDecodeOverflow
}
// 77. CheckReplicas
func (*CheckReplicas) NEOMsgCode() uint16 {
return 77
}
func (p *CheckReplicas) NEOMsgEncodedLen() int {
return 20 + len(p.PartitionDict)*8
}
func (p *CheckReplicas) NEOMsgEncode(data []byte) {
{
l := uint32(len(p.PartitionDict))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
keyv := make([]uint32, 0, l)
for key := range p.PartitionDict {
keyv = append(keyv, key)
}
sort.Slice(keyv, func(i, j int) bool { return keyv[i] < keyv[j] })
for _, key := range keyv {
binary.BigEndian.PutUint32(data[0:], key)
binary.BigEndian.PutUint32(data[4:], uint32(int32(p.PartitionDict[key])))
data = data[8:]
}
}
binary.BigEndian.PutUint64(data[0:], uint64(p.MinTID))
binary.BigEndian.PutUint64(data[8:], uint64(p.MaxTID))
}
func (p *CheckReplicas) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 4 {
goto overflow
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < 16+uint64(l)*8 {
goto overflow
}
nread += 16 + uint64(l)*8
p.PartitionDict = make(map[uint32]NodeUUID, l)
m := p.PartitionDict
for i := 0; uint32(i) < l; i++ {
key := binary.BigEndian.Uint32(data[0 : 0+4])
m[key] = NodeUUID(int32(binary.BigEndian.Uint32(data[4 : 4+4])))
data = data[8:]
}
}
p.MinTID = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.MaxTID = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
return 4 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 78. CheckPartition
func (*CheckPartition) NEOMsgCode() uint16 {
return 78
}
func (p *CheckPartition) NEOMsgEncodedLen() int {
return 24 + len(p.Source.UpstreamName) + p.Source.Address.neoEncodedLen()
}
func (p *CheckPartition) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], p.Partition)
{
l := uint32(len(p.Source.UpstreamName))
binary.BigEndian.PutUint32(data[4:], l)
data = data[8:]
copy(data, p.Source.UpstreamName)
data = data[l:]
}
{
n := p.Source.Address.neoEncode(data[0:])
data = data[0+n:]
}
binary.BigEndian.PutUint64(data[0:], uint64(p.MinTID))
binary.BigEndian.PutUint64(data[8:], uint64(p.MaxTID))
}
func (p *CheckPartition) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 8 {
goto overflow
}
p.Partition = binary.BigEndian.Uint32(data[0 : 0+4])
{
l := binary.BigEndian.Uint32(data[4 : 4+4])
data = data[8:]
if uint64(len(data)) < uint64(l) {
goto overflow
}
nread += uint64(l)
p.Source.UpstreamName = string(data[:l])
data = data[l:]
}
{
n, ok := p.Source.Address.neoDecode(data)
if !ok {
goto overflow
}
data = data[n:]
nread += n
}
if len(data) < 16 {
goto overflow
}
p.MinTID = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.MaxTID = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
return 24 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 79. CheckTIDRange
func (*CheckTIDRange) NEOMsgCode() uint16 {
return 79
}
func (p *CheckTIDRange) NEOMsgEncodedLen() int {
return 24
}
func (p *CheckTIDRange) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], p.Partition)
binary.BigEndian.PutUint32(data[4:], p.Length)
binary.BigEndian.PutUint64(data[8:], uint64(p.MinTID))
binary.BigEndian.PutUint64(data[16:], uint64(p.MaxTID))
}
func (p *CheckTIDRange) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 24 {
goto overflow
}
p.Partition = binary.BigEndian.Uint32(data[0 : 0+4])
p.Length = binary.BigEndian.Uint32(data[4 : 4+4])
p.MinTID = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.MaxTID = zodb.Tid(binary.BigEndian.Uint64(data[16 : 16+8]))
return 24, nil
overflow:
return 0, ErrDecodeOverflow
}
// 79 | answerBit. AnswerCheckTIDRange
func (*AnswerCheckTIDRange) NEOMsgCode() uint16 {
return 79 | answerBit
}
func (p *AnswerCheckTIDRange) NEOMsgEncodedLen() int {
return 32
}
func (p *AnswerCheckTIDRange) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], p.Count)
copy(data[4:], p.Checksum[:])
binary.BigEndian.PutUint64(data[24:], uint64(p.MaxTID))
}
func (p *AnswerCheckTIDRange) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 32 {
goto overflow
}
p.Count = binary.BigEndian.Uint32(data[0 : 0+4])
copy(p.Checksum[:], data[4:24])
p.MaxTID = zodb.Tid(binary.BigEndian.Uint64(data[24 : 24+8]))
return 32, nil
overflow:
return 0, ErrDecodeOverflow
}
// 81. CheckSerialRange
func (*CheckSerialRange) NEOMsgCode() uint16 {
return 81
}
func (p *CheckSerialRange) NEOMsgEncodedLen() int {
return 32
}
func (p *CheckSerialRange) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], p.Partition)
binary.BigEndian.PutUint32(data[4:], p.Length)
binary.BigEndian.PutUint64(data[8:], uint64(p.MinTID))
binary.BigEndian.PutUint64(data[16:], uint64(p.MaxTID))
binary.BigEndian.PutUint64(data[24:], uint64(p.MinOID))
}
func (p *CheckSerialRange) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 32 {
goto overflow
}
p.Partition = binary.BigEndian.Uint32(data[0 : 0+4])
p.Length = binary.BigEndian.Uint32(data[4 : 4+4])
p.MinTID = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.MaxTID = zodb.Tid(binary.BigEndian.Uint64(data[16 : 16+8]))
p.MinOID = zodb.Oid(binary.BigEndian.Uint64(data[24 : 24+8]))
return 32, nil
overflow:
return 0, ErrDecodeOverflow
}
// 81 | answerBit. AnswerCheckSerialRange
func (*AnswerCheckSerialRange) NEOMsgCode() uint16 {
return 81 | answerBit
}
func (p *AnswerCheckSerialRange) NEOMsgEncodedLen() int {
return 60
}
func (p *AnswerCheckSerialRange) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], p.Count)
copy(data[4:], p.TidChecksum[:])
binary.BigEndian.PutUint64(data[24:], uint64(p.MaxTID))
copy(data[32:], p.OidChecksum[:])
binary.BigEndian.PutUint64(data[52:], uint64(p.MaxOID))
}
func (p *AnswerCheckSerialRange) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 60 {
goto overflow
}
p.Count = binary.BigEndian.Uint32(data[0 : 0+4])
copy(p.TidChecksum[:], data[4:24])
p.MaxTID = zodb.Tid(binary.BigEndian.Uint64(data[24 : 24+8]))
copy(p.OidChecksum[:], data[32:52])
p.MaxOID = zodb.Oid(binary.BigEndian.Uint64(data[52 : 52+8]))
return 60, nil
overflow:
return 0, ErrDecodeOverflow
}
// 83. PartitionCorrupted
func (*PartitionCorrupted) NEOMsgCode() uint16 {
return 83
}
func (p *PartitionCorrupted) NEOMsgEncodedLen() int {
return 8 + len(p.CellList)*4
}
func (p *PartitionCorrupted) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], p.Partition)
{
l := uint32(len(p.CellList))
binary.BigEndian.PutUint32(data[4:], l)
data = data[8:]
for i := 0; uint32(i) < l; i++ {
a := &p.CellList[i]
binary.BigEndian.PutUint32(data[0:], uint32(int32((*a))))
data = data[4:]
}
}
}
func (p *PartitionCorrupted) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 8 {
goto overflow
}
p.Partition = binary.BigEndian.Uint32(data[0 : 0+4])
{
l := binary.BigEndian.Uint32(data[4 : 4+4])
data = data[8:]
if uint64(len(data)) < uint64(l)*4 {
goto overflow
}
nread += uint64(l) * 4
p.CellList = make([]NodeUUID, l)
for i := 0; uint32(i) < l; i++ {
a := &p.CellList[i]
(*a) = NodeUUID(int32(binary.BigEndian.Uint32(data[0 : 0+4])))
data = data[4:]
}
}
return 8 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 84. NotifyReady
func (*NotifyReady) NEOMsgCode() uint16 {
return 84
}
func (p *NotifyReady) NEOMsgEncodedLen() int {
return 0
}
func (p *NotifyReady) NEOMsgEncode(data []byte) {
}
func (p *NotifyReady) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 85. LastTransaction
func (*LastTransaction) NEOMsgCode() uint16 {
return 85
}
func (p *LastTransaction) NEOMsgEncodedLen() int {
return 0
}
func (p *LastTransaction) NEOMsgEncode(data []byte) {
}
func (p *LastTransaction) NEOMsgDecode(data []byte) (int, error) {
return 0, nil
}
// 85 | answerBit. AnswerLastTransaction
func (*AnswerLastTransaction) NEOMsgCode() uint16 {
return 85 | answerBit
}
func (p *AnswerLastTransaction) NEOMsgEncodedLen() int {
return 8
}
func (p *AnswerLastTransaction) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
}
func (p *AnswerLastTransaction) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// 87. CheckCurrentSerial
func (*CheckCurrentSerial) NEOMsgCode() uint16 {
return 87
}
func (p *CheckCurrentSerial) NEOMsgEncodedLen() int {
return 24
}
func (p *CheckCurrentSerial) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
binary.BigEndian.PutUint64(data[8:], uint64(p.Oid))
binary.BigEndian.PutUint64(data[16:], uint64(p.Serial))
}
func (p *CheckCurrentSerial) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 24 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.Oid = zodb.Oid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.Serial = zodb.Tid(binary.BigEndian.Uint64(data[16 : 16+8]))
return 24, nil
overflow:
return 0, ErrDecodeOverflow
}
// 87 | answerBit. AnswerCheckCurrentSerial
func (*AnswerCheckCurrentSerial) NEOMsgCode() uint16 {
return 87 | answerBit
}
func (p *AnswerCheckCurrentSerial) NEOMsgEncodedLen() int {
return 8
}
func (p *AnswerCheckCurrentSerial) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.AnswerStoreObject.Conflict))
}
func (p *AnswerCheckCurrentSerial) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.AnswerStoreObject.Conflict = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// 89. NotifyTransactionFinished
func (*NotifyTransactionFinished) NEOMsgCode() uint16 {
return 89
}
func (p *NotifyTransactionFinished) NEOMsgEncodedLen() int {
return 16
}
func (p *NotifyTransactionFinished) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.TTID))
binary.BigEndian.PutUint64(data[8:], uint64(p.MaxTID))
}
func (p *NotifyTransactionFinished) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 16 {
goto overflow
}
p.TTID = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.MaxTID = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
return 16, nil
overflow:
return 0, ErrDecodeOverflow
}
// 90. Replicate
func (*Replicate) NEOMsgCode() uint16 {
return 90
}
func (p *Replicate) NEOMsgEncodedLen() int {
var size int
for key := range p.SourceDict {
size += len(p.SourceDict[key])
}
return 16 + len(p.UpstreamName) + len(p.SourceDict)*8 + size
}
func (p *Replicate) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
{
l := uint32(len(p.UpstreamName))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
copy(data, p.UpstreamName)
data = data[l:]
}
{
l := uint32(len(p.SourceDict))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
keyv := make([]uint32, 0, l)
for key := range p.SourceDict {
keyv = append(keyv, key)
}
sort.Slice(keyv, func(i, j int) bool { return keyv[i] < keyv[j] })
for _, key := range keyv {
binary.BigEndian.PutUint32(data[0:], key)
{
l := uint32(len(p.SourceDict[key]))
binary.BigEndian.PutUint32(data[4:], l)
data = data[8:]
copy(data, p.SourceDict[key])
data = data[l:]
}
data = data[0:]
}
}
}
func (p *Replicate) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
if uint64(len(data)) < 4+uint64(l) {
goto overflow
}
nread += 4 + uint64(l)
p.UpstreamName = string(data[:l])
data = data[l:]
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
p.SourceDict = make(map[uint32]string, l)
m := p.SourceDict
for i := 0; uint32(i) < l; i++ {
if len(data) < 8 {
goto overflow
}
key := binary.BigEndian.Uint32(data[0 : 0+4])
{
l := binary.BigEndian.Uint32(data[4 : 4+4])
data = data[8:]
if uint64(len(data)) < uint64(l) {
goto overflow
}
nread += uint64(l)
m[key] = string(data[:l])
data = data[l:]
}
}
nread += uint64(l) * 8
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 91. ReplicationDone
func (*ReplicationDone) NEOMsgCode() uint16 {
return 91
}
func (p *ReplicationDone) NEOMsgEncodedLen() int {
return 12
}
func (p *ReplicationDone) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], p.Offset)
binary.BigEndian.PutUint64(data[4:], uint64(p.Tid))
}
func (p *ReplicationDone) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 12 {
goto overflow
}
p.Offset = binary.BigEndian.Uint32(data[0 : 0+4])
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[4 : 4+8]))
return 12, nil
overflow:
return 0, ErrDecodeOverflow
}
// 92. FetchTransactions
func (*FetchTransactions) NEOMsgCode() uint16 {
return 92
}
func (p *FetchTransactions) NEOMsgEncodedLen() int {
return 28 + len(p.TxnKnownList)*8
}
func (p *FetchTransactions) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], p.Partition)
binary.BigEndian.PutUint32(data[4:], p.Length)
binary.BigEndian.PutUint64(data[8:], uint64(p.MinTid))
binary.BigEndian.PutUint64(data[16:], uint64(p.MaxTid))
{
l := uint32(len(p.TxnKnownList))
binary.BigEndian.PutUint32(data[24:], l)
data = data[28:]
for i := 0; uint32(i) < l; i++ {
a := &p.TxnKnownList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
}
func (p *FetchTransactions) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 28 {
goto overflow
}
p.Partition = binary.BigEndian.Uint32(data[0 : 0+4])
p.Length = binary.BigEndian.Uint32(data[4 : 4+4])
p.MinTid = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.MaxTid = zodb.Tid(binary.BigEndian.Uint64(data[16 : 16+8]))
{
l := binary.BigEndian.Uint32(data[24 : 24+4])
data = data[28:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
p.TxnKnownList = make([]zodb.Tid, l)
for i := 0; uint32(i) < l; i++ {
a := &p.TxnKnownList[i]
(*a) = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
return 28 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 92 | answerBit. AnswerFetchTransactions
func (*AnswerFetchTransactions) NEOMsgCode() uint16 {
return 92 | answerBit
}
func (p *AnswerFetchTransactions) NEOMsgEncodedLen() int {
return 20 + len(p.TxnDeleteList)*8
}
func (p *AnswerFetchTransactions) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.PackTid))
binary.BigEndian.PutUint64(data[8:], uint64(p.NextTid))
{
l := uint32(len(p.TxnDeleteList))
binary.BigEndian.PutUint32(data[16:], l)
data = data[20:]
for i := 0; uint32(i) < l; i++ {
a := &p.TxnDeleteList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
}
func (p *AnswerFetchTransactions) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 20 {
goto overflow
}
p.PackTid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.NextTid = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
{
l := binary.BigEndian.Uint32(data[16 : 16+4])
data = data[20:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
p.TxnDeleteList = make([]zodb.Tid, l)
for i := 0; uint32(i) < l; i++ {
a := &p.TxnDeleteList[i]
(*a) = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
return 20 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 94. FetchObjects
func (*FetchObjects) NEOMsgCode() uint16 {
return 94
}
func (p *FetchObjects) NEOMsgEncodedLen() int {
var size int
for key := range p.ObjKnownDict {
size += len(p.ObjKnownDict[key]) * 8
}
return 36 + len(p.ObjKnownDict)*12 + size
}
func (p *FetchObjects) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint32(data[0:], p.Partition)
binary.BigEndian.PutUint32(data[4:], p.Length)
binary.BigEndian.PutUint64(data[8:], uint64(p.MinTid))
binary.BigEndian.PutUint64(data[16:], uint64(p.MaxTid))
binary.BigEndian.PutUint64(data[24:], uint64(p.MinOid))
{
l := uint32(len(p.ObjKnownDict))
binary.BigEndian.PutUint32(data[32:], l)
data = data[36:]
keyv := make([]zodb.Tid, 0, l)
for key := range p.ObjKnownDict {
keyv = append(keyv, key)
}
sort.Slice(keyv, func(i, j int) bool { return keyv[i] < keyv[j] })
for _, key := range keyv {
binary.BigEndian.PutUint64(data[0:], uint64(key))
{
l := uint32(len(p.ObjKnownDict[key]))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
for i := 0; uint32(i) < l; i++ {
a := &p.ObjKnownDict[key][i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
data = data[0:]
}
}
}
func (p *FetchObjects) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 36 {
goto overflow
}
p.Partition = binary.BigEndian.Uint32(data[0 : 0+4])
p.Length = binary.BigEndian.Uint32(data[4 : 4+4])
p.MinTid = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.MaxTid = zodb.Tid(binary.BigEndian.Uint64(data[16 : 16+8]))
p.MinOid = zodb.Oid(binary.BigEndian.Uint64(data[24 : 24+8]))
{
l := binary.BigEndian.Uint32(data[32 : 32+4])
data = data[36:]
p.ObjKnownDict = make(map[zodb.Tid][]zodb.Oid, l)
m := p.ObjKnownDict
for i := 0; uint32(i) < l; i++ {
if len(data) < 12 {
goto overflow
}
key := zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
var v []zodb.Oid
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
v = make([]zodb.Oid, l)
for i := 0; uint32(i) < l; i++ {
a := &v[i]
(*a) = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
m[key] = v
}
nread += uint64(l) * 12
}
return 36 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 94 | answerBit. AnswerFetchObjects
func (*AnswerFetchObjects) NEOMsgCode() uint16 {
return 94 | answerBit
}
func (p *AnswerFetchObjects) NEOMsgEncodedLen() int {
var size int
for key := range p.ObjDeleteDict {
size += len(p.ObjDeleteDict[key]) * 8
}
return 28 + len(p.ObjDeleteDict)*12 + size
}
func (p *AnswerFetchObjects) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.PackTid))
binary.BigEndian.PutUint64(data[8:], uint64(p.NextTid))
binary.BigEndian.PutUint64(data[16:], uint64(p.NextOid))
{
l := uint32(len(p.ObjDeleteDict))
binary.BigEndian.PutUint32(data[24:], l)
data = data[28:]
keyv := make([]zodb.Tid, 0, l)
for key := range p.ObjDeleteDict {
keyv = append(keyv, key)
}
sort.Slice(keyv, func(i, j int) bool { return keyv[i] < keyv[j] })
for _, key := range keyv {
binary.BigEndian.PutUint64(data[0:], uint64(key))
{
l := uint32(len(p.ObjDeleteDict[key]))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
for i := 0; uint32(i) < l; i++ {
a := &p.ObjDeleteDict[key][i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
data = data[0:]
}
}
}
func (p *AnswerFetchObjects) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 28 {
goto overflow
}
p.PackTid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.NextTid = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.NextOid = zodb.Oid(binary.BigEndian.Uint64(data[16 : 16+8]))
{
l := binary.BigEndian.Uint32(data[24 : 24+4])
data = data[28:]
p.ObjDeleteDict = make(map[zodb.Tid][]zodb.Oid, l)
m := p.ObjDeleteDict
for i := 0; uint32(i) < l; i++ {
if len(data) < 12 {
goto overflow
}
key := zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
var v []zodb.Oid
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
v = make([]zodb.Oid, l)
for i := 0; uint32(i) < l; i++ {
a := &v[i]
(*a) = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
m[key] = v
}
nread += uint64(l) * 12
}
return 28 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 96. AddTransaction
func (*AddTransaction) NEOMsgCode() uint16 {
return 96
}
func (p *AddTransaction) NEOMsgEncodedLen() int {
return 33 + len(p.User) + len(p.Description) + len(p.Extension) + len(p.OidList)*8
}
func (p *AddTransaction) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
{
l := uint32(len(p.User))
binary.BigEndian.PutUint32(data[8:], l)
data = data[12:]
copy(data, p.User)
data = data[l:]
}
{
l := uint32(len(p.Description))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
copy(data, p.Description)
data = data[l:]
}
{
l := uint32(len(p.Extension))
binary.BigEndian.PutUint32(data[0:], l)
data = data[4:]
copy(data, p.Extension)
data = data[l:]
}
(data[0:])[0] = bool2byte(p.Packed)
binary.BigEndian.PutUint64(data[1:], uint64(p.TTid))
{
l := uint32(len(p.OidList))
binary.BigEndian.PutUint32(data[9:], l)
data = data[13:]
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
binary.BigEndian.PutUint64(data[0:], uint64((*a)))
data = data[8:]
}
}
}
func (p *AddTransaction) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 12 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
{
l := binary.BigEndian.Uint32(data[8 : 8+4])
data = data[12:]
if uint64(len(data)) < 4+uint64(l) {
goto overflow
}
nread += 4 + uint64(l)
p.User = string(data[:l])
data = data[l:]
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < 4+uint64(l) {
goto overflow
}
nread += 4 + uint64(l)
p.Description = string(data[:l])
data = data[l:]
}
{
l := binary.BigEndian.Uint32(data[0 : 0+4])
data = data[4:]
if uint64(len(data)) < 13+uint64(l) {
goto overflow
}
nread += 13 + uint64(l)
p.Extension = string(data[:l])
data = data[l:]
}
p.Packed = byte2bool((data[0 : 0+1])[0])
p.TTid = zodb.Tid(binary.BigEndian.Uint64(data[1 : 1+8]))
{
l := binary.BigEndian.Uint32(data[9 : 9+4])
data = data[13:]
if uint64(len(data)) < uint64(l)*8 {
goto overflow
}
nread += uint64(l) * 8
p.OidList = make([]zodb.Oid, l)
for i := 0; uint32(i) < l; i++ {
a := &p.OidList[i]
(*a) = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
data = data[8:]
}
}
return 12 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 97. AddObject
func (*AddObject) NEOMsgCode() uint16 {
return 97
}
func (p *AddObject) NEOMsgEncodedLen() int {
return 49 + len(p.Data.XData())
}
func (p *AddObject) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Oid))
binary.BigEndian.PutUint64(data[8:], uint64(p.Serial))
(data[16:])[0] = bool2byte(p.Compression)
copy(data[17:], p.Checksum[:])
{
l := uint32(len(p.Data.XData()))
binary.BigEndian.PutUint32(data[37:], l)
data = data[41:]
copy(data, p.Data.XData())
data = data[l:]
}
binary.BigEndian.PutUint64(data[0:], uint64(p.DataSerial))
}
func (p *AddObject) NEOMsgDecode(data []byte) (int, error) {
var nread uint64
if len(data) < 41 {
goto overflow
}
p.Oid = zodb.Oid(binary.BigEndian.Uint64(data[0 : 0+8]))
p.Serial = zodb.Tid(binary.BigEndian.Uint64(data[8 : 8+8]))
p.Compression = byte2bool((data[16 : 16+1])[0])
copy(p.Checksum[:], data[17:37])
{
l := binary.BigEndian.Uint32(data[37 : 37+4])
data = data[41:]
if uint64(len(data)) < 8+uint64(l) {
goto overflow
}
nread += 8 + uint64(l)
p.Data = mem.BufAlloc(int(l))
copy(p.Data.Data, data[:l])
data = data[l:]
}
p.DataSerial = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 41 + int(nread), nil
overflow:
return 0, ErrDecodeOverflow
}
// 98. Truncate
func (*Truncate) NEOMsgCode() uint16 {
return 98
}
func (p *Truncate) NEOMsgEncodedLen() int {
return 8
}
func (p *Truncate) NEOMsgEncode(data []byte) {
binary.BigEndian.PutUint64(data[0:], uint64(p.Tid))
}
func (p *Truncate) NEOMsgDecode(data []byte) (int, error) {
if len(data) < 8 {
goto overflow
}
p.Tid = zodb.Tid(binary.BigEndian.Uint64(data[0 : 0+8]))
return 8, nil
overflow:
return 0, ErrDecodeOverflow
}
// registry of message types
var msgTypeRegistry = map[uint16]reflect.Type{
0 | answerBit: reflect.TypeOf(Error{}),
1: reflect.TypeOf(RequestIdentification{}),
1 | answerBit: reflect.TypeOf(AcceptIdentification{}),
3: reflect.TypeOf(Ping{}),
3 | answerBit: reflect.TypeOf(Pong{}),
5: reflect.TypeOf(CloseClient{}),
6: reflect.TypeOf(PrimaryMaster{}),
6 | answerBit: reflect.TypeOf(AnswerPrimary{}),
8: reflect.TypeOf(NotPrimaryMaster{}),
9: reflect.TypeOf(NotifyNodeInformation{}),
10: reflect.TypeOf(Recovery{}),
10 | answerBit: reflect.TypeOf(AnswerRecovery{}),
12: reflect.TypeOf(LastIDs{}),
12 | answerBit: reflect.TypeOf(AnswerLastIDs{}),
14: reflect.TypeOf(AskPartitionTable{}),
14 | answerBit: reflect.TypeOf(AnswerPartitionTable{}),
16: reflect.TypeOf(SendPartitionTable{}),
17: reflect.TypeOf(NotifyPartitionChanges{}),
18: reflect.TypeOf(StartOperation{}),
19: reflect.TypeOf(StopOperation{}),
20: reflect.TypeOf(UnfinishedTransactions{}),
20 | answerBit: reflect.TypeOf(AnswerUnfinishedTransactions{}),
22: reflect.TypeOf(LockedTransactions{}),
22 | answerBit: reflect.TypeOf(AnswerLockedTransactions{}),
24: reflect.TypeOf(FinalTID{}),
24 | answerBit: reflect.TypeOf(AnswerFinalTID{}),
26: reflect.TypeOf(ValidateTransaction{}),
27: reflect.TypeOf(BeginTransaction{}),
27 | answerBit: reflect.TypeOf(AnswerBeginTransaction{}),
29: reflect.TypeOf(FailedVote{}),
30: reflect.TypeOf(FinishTransaction{}),
30 | answerBit: reflect.TypeOf(AnswerTransactionFinished{}),
32: reflect.TypeOf(LockInformation{}),
32 | answerBit: reflect.TypeOf(AnswerInformationLocked{}),
34: reflect.TypeOf(InvalidateObjects{}),
35: reflect.TypeOf(NotifyUnlockInformation{}),
36: reflect.TypeOf(AskNewOIDs{}),
36 | answerBit: reflect.TypeOf(AnswerNewOIDs{}),
38: reflect.TypeOf(NotifyDeadlock{}),
39: reflect.TypeOf(RebaseTransaction{}),
39 | answerBit: reflect.TypeOf(AnswerRebaseTransaction{}),
41: reflect.TypeOf(RebaseObject{}),
41 | answerBit: reflect.TypeOf(AnswerRebaseObject{}),
43: reflect.TypeOf(StoreObject{}),
43 | answerBit: reflect.TypeOf(AnswerStoreObject{}),
45: reflect.TypeOf(AbortTransaction{}),
46: reflect.TypeOf(StoreTransaction{}),
46 | answerBit: reflect.TypeOf(AnswerStoreTransaction{}),
48: reflect.TypeOf(VoteTransaction{}),
48 | answerBit: reflect.TypeOf(AnswerVoteTransaction{}),
50: reflect.TypeOf(GetObject{}),
50 | answerBit: reflect.TypeOf(AnswerObject{}),
52: reflect.TypeOf(AskTIDs{}),
52 | answerBit: reflect.TypeOf(AnswerTIDs{}),
54: reflect.TypeOf(TransactionInformation{}),
54 | answerBit: reflect.TypeOf(AnswerTransactionInformation{}),
56: reflect.TypeOf(ObjectHistory{}),
56 | answerBit: reflect.TypeOf(AnswerObjectHistory{}),
58: reflect.TypeOf(PartitionList{}),
58 | answerBit: reflect.TypeOf(AnswerPartitionList{}),
60: reflect.TypeOf(NodeList{}),
60 | answerBit: reflect.TypeOf(AnswerNodeList{}),
62: reflect.TypeOf(SetNodeState{}),
63: reflect.TypeOf(AddPendingNodes{}),
64: reflect.TypeOf(TweakPartitionTable{}),
65: reflect.TypeOf(SetClusterState{}),
66: reflect.TypeOf(Repair{}),
67: reflect.TypeOf(RepairOne{}),
68: reflect.TypeOf(NotifyClusterState{}),
69: reflect.TypeOf(AskClusterState{}),
69 | answerBit: reflect.TypeOf(AnswerClusterState{}),
71: reflect.TypeOf(ObjectUndoSerial{}),
71 | answerBit: reflect.TypeOf(AnswerObjectUndoSerial{}),
73: reflect.TypeOf(AskTIDsFrom{}),
73 | answerBit: reflect.TypeOf(AnswerTIDsFrom{}),
75: reflect.TypeOf(Pack{}),
75 | answerBit: reflect.TypeOf(AnswerPack{}),
77: reflect.TypeOf(CheckReplicas{}),
78: reflect.TypeOf(CheckPartition{}),
79: reflect.TypeOf(CheckTIDRange{}),
79 | answerBit: reflect.TypeOf(AnswerCheckTIDRange{}),
81: reflect.TypeOf(CheckSerialRange{}),
81 | answerBit: reflect.TypeOf(AnswerCheckSerialRange{}),
83: reflect.TypeOf(PartitionCorrupted{}),
84: reflect.TypeOf(NotifyReady{}),
85: reflect.TypeOf(LastTransaction{}),
85 | answerBit: reflect.TypeOf(AnswerLastTransaction{}),
87: reflect.TypeOf(CheckCurrentSerial{}),
87 | answerBit: reflect.TypeOf(AnswerCheckCurrentSerial{}),
89: reflect.TypeOf(NotifyTransactionFinished{}),
90: reflect.TypeOf(Replicate{}),
91: reflect.TypeOf(ReplicationDone{}),
92: reflect.TypeOf(FetchTransactions{}),
92 | answerBit: reflect.TypeOf(AnswerFetchTransactions{}),
94: reflect.TypeOf(FetchObjects{}),
94 | answerBit: reflect.TypeOf(AnswerFetchObjects{}),
96: reflect.TypeOf(AddTransaction{}),
97: reflect.TypeOf(AddObject{}),
98: reflect.TypeOf(Truncate{}),
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment