Skip to content

Latest commit

 

History

History
1217 lines (847 loc) · 31.5 KB

README.md

File metadata and controls

1217 lines (847 loc) · 31.5 KB

generic

import "github.com/cloudwego/dynamicgo/thrift/generic"

Index

Variables

var (
    // UseNativeSkipForGet indicates to use native.Skip (instead of go.Skip) method to skip thrift value
    // This only works for single-value searching API like GetByInt()/GetByRaw()/GetByStr()/Field()/Index()/GetByPath() methods.
    // WARN: this will promote performance when thrift value to be skipped is large, but may decrease preformance when thrift value is small.
    UseNativeSkipForGet = false

    // DefaultNodeSliceCap is the default capacity of a Node or NodePath slice
    // Usually, a Node or NodePath slice is used to store intermediate or consequential elements of a generic API like Children()|Interface()|SetMany()
    DefaultNodeSliceCap = 16
)
var (
    // StoreChildrenByIdShreshold is the maximum id to store children node by id.
    StoreChildrenByIdShreshold = 256

    // StoreChildrenByIdShreshold is the minimum id to store children node by hash.
    StoreChildrenByIntHashShreshold = DefaultNodeSliceCap
)

func DescriptorToPathNode

func DescriptorToPathNode(desc *thrift.TypeDescriptor, root *PathNode, opts *Options) error

DescriptorToPathNode converts a thrift type descriptor to a DOM, assgining path to root NOTICE: it only recursively converts STRUCT type

func FreePathNode

func FreePathNode(p *PathNode)

FreePathNode put a PathNode back to memory pool

func GetDescByPath

func GetDescByPath(desc *thrift.TypeDescriptor, path ...Path) (ret *thrift.TypeDescriptor, err error)

GetDescByPath searches longitudinally and returns the sub descriptor of the desc specified by path

type Node

Node is a generic wrap of raw thrift data

type Node struct {
    // contains filtered or unexported fields
}

func NewNode

func NewNode(t thrift.Type, src []byte) Node

NewNodeBool create a new node with given type and data WARN: it WON'T check the correctness of the data

func NewNodeBinary

func NewNodeBinary(val []byte) Node

NewNodeBinary converts a []byte value to a STRING node

func NewNodeBool

func NewNodeBool(val bool) Node

NewNodeBool converts a bool value to a BOOL node

func NewNodeByte

func NewNodeByte(val byte) Node

NewNodeInt8 converts a byte value to a BYTE node

func NewNodeDouble

func NewNodeDouble(val float64) Node

NewNodeDouble converts a float64 value to a DOUBLE node

func NewNodeInt16

func NewNodeInt16(val int16) Node

NewNodeInt16 converts a int16 value to a I16 node

func NewNodeInt32

func NewNodeInt32(val int32) Node

NewNodeInt32 converts a int32 value to a I32 node

func NewNodeInt64

func NewNodeInt64(val int64) Node

NewNodeInt64 converts a int64 value to a I64 node

func NewNodeString

func NewNodeString(val string) Node

NewNodeString converts a string value to a STRING node

func NewTypedNode

func NewTypedNode(typ thrift.Type, et thrift.Type, kt thrift.Type) (ret Node)

NewTypedNode creates a new Node with the given typ, including element type (for LIST/SET/MAP) and key type (for MAP)

func (Node) Binary

func (self Node) Binary() ([]byte, error)

Binary returns the bytes value contained by a BINARY node

func (Node) Bool

func (self Node) Bool() (bool, error)

Bool returns the bool value contained by a BOOL node

func (Node) Byte

func (self Node) Byte() (byte, error)

Byte returns the byte value contained by a I8/BYTE node

func (*Node) Check

func (self *Node) Check() error

Check checks if it is a ERROR node and returns corresponding error

func (Node) Children

func (self Node) Children(out *[]PathNode, recurse bool, opts *Options) (err error)

Children loads all its children and children's children recursively (if recurse is true). out is used for store children, and it is always reset to zero length before use.

NOTICE: if opts.NotScanParentNode is true, the parent nodes (PathNode.Node) of complex (LIST/SET/MAP/STRUCT) type won't be assgined data

func (Node) ElemType

func (self Node) ElemType() thrift.Type

ElemType returns the thrift type of a LIST/SET/MAP node's element

func (Node) ErrCode

func (self Node) ErrCode() meta.ErrCode

ErrCode return the meta.ErrCode of a ERROR node

func (Node) Error

func (self Node) Error() string

Error return error message if it is a ERROR node

func (Node) Field

func (self Node) Field(id thrift.FieldID) (v Node)

Field returns a sub node at the given field id from a STRUCT node.

func (Node) Fields

func (self Node) Fields(ids []PathNode, opts *Options) (err error)

Fields returns all sub nodes ids along with the given int path from a STRUCT node.

func (Node) Float64

func (self Node) Float64() (float64, error)

Float64 returns the float64 value contained by a DOUBLE node

func (Node) Foreach

func (self Node) Foreach(handler func(path Path, node Node) bool, opts *Options) error

Foreach scan each element of a complex type (LIST/SET/MAP/STRUCT), and call handler sequentially with corresponding path and node

func (Node) ForeachKV

func (self Node) ForeachKV(handler func(key Node, val Node) bool, opts *Options) error

ForeachKV scan each element of a MAP type, and call handler sequentially with corresponding key and value

func (Node) Fork

func (self Node) Fork() Node

Fork forks the node to a new node, copy underlying data as well

func (Node) GetByInt

func (self Node) GetByInt(key int) (v Node)

GetByInt returns a sub node at the given int key from a MAP<INT,xx> node.

func (Node) GetByPath

func (self Node) GetByPath(pathes ...Path) Node

GetByPath searches longitudinally and return a sub node at the given path from the node.

The path is a list of PathFieldId, PathIndex, PathStrKey, PathBinKey, PathIntKey, Each path MUST be a valid path type for current layer (e.g. PathFieldId is only valid for STRUCT). Empty path will return the current node.

func (Node) GetByRaw

func (self Node) GetByRaw(key []byte) (v Node)

GetByInt returns a sub node at the given bytes key from a MAP node. The key must be deep equal (bytes.Equal) to the key in the map.

func (Node) GetByStr

func (self Node) GetByStr(key string) (v Node)

GetByInt returns a sub node at the given int key from a MAP<STRING,xx> node.

func (Node) GetMany

func (self Node) GetMany(pathes []PathNode, opts *Options) error

GetMany searches transversely and returns all the sub nodes along with the given pathes.

func (Node) GetTree

func (self Node) GetTree(tree *PathNode, opts *Options) error

GetTree returns a tree of all sub nodes along with the given path on the tree. It supports longitudinally search (like GetByPath) and transversely search (like GetMany) both.

func (Node) Gets

func (self Node) Gets(keys []PathNode, opts *Options) (err error)

Gets returns all sub nodes along with the given key (PathStrKey|PathIntKey|PathBinKey) path from a MAP node.

func (Node) Index

func (self Node) Index(i int) (v Node)

Index returns a sub node at the given index from a LIST/SET node.

func (Node) Indexes

func (self Node) Indexes(ins []PathNode, opts *Options) (err error)

Indexes returns all sub nodes along with the given int path from a LIST/SET node.

func (Node) Int

func (self Node) Int() (int, error)

Int returns the int value contaned by a I8/I16/I32/I64 node

func (Node) IntMap

func (self Node) IntMap(opts *Options) (map[int]interface{}, error)

StrMap returns the integer keys and interface elements contained by a MAP<I8|I16|I32|I64,XX> node

func (Node) Interface

func (self Node) Interface(opts *Options) (interface{}, error)

Interface returns the go interface value contained by a node. If the node is a STRUCT, it will return a map[thrift.FieldID]interface{} If it is a map, it will return map[int|string|interface{}]interface{}, which depends on the key type

func (Node) InterfaceMap

func (self Node) InterfaceMap(opts *Options) (map[interface{}]interface{}, error)

InterfaceMap returns the interface keys and interface elements contained by a MAP node. If the key type is complex (LIST/SET/MAP/STRUCT), it will be stored using its pointer since its value are not supported by Go

func (Node) IsEmpty

func (self Node) IsEmpty() bool

IsEmpty tells if the node is thrift.STOP

func (Node) IsErrNotFound

func (self Node) IsErrNotFound() bool

IsErrorNotFound tells if the node is not-found-data error

func (Node) IsError

func (self Node) IsError() bool

IsEmtpy tells if the node is thrift.ERROR

func (Node) KeyType

func (self Node) KeyType() thrift.Type

KeyType returns the thrift type of a MAP node's key

func (Node) Len

func (self Node) Len() (int, error)

Len returns the element count of container-kind type (LIST/SET/MAP)

func (Node) List

func (self Node) List(opts *Options) ([]interface{}, error)

List returns interface elements contained by a LIST/SET node

func (Node) Raw

func (self Node) Raw() []byte

Return its underlying raw data

func (*Node) SetByPath

func (self *Node) SetByPath(sub Node, path ...Path) (exist bool, err error)

SetByPath sets the sub node at the given path.

func (*Node) SetMany

func (self *Node) SetMany(pathes []PathNode, opts *Options) (err error)

SetMany searches longitudinally and sets the sub nodes at the given pathes.

func (Node) StrMap

func (self Node) StrMap(opts *Options) (map[string]interface{}, error)

StrMap returns the string keys and interface elements contained by a MAP<STRING,XX> node

func (Node) String

func (self Node) String() (string, error)

String returns the string value contianed by a STRING node

func (Node) Type

func (self Node) Type() thrift.Type

Type returns the thrift type of the node

func (*Node) UnsetByPath

func (self *Node) UnsetByPath(path ...Path) error

type Options

Opions for generic.Node

type Options struct {
    // DisallowUnknow indicates to report error when read unknown fields.
    DisallowUnknow bool

    // WriteDefault indicates to write value if a DEFAULT requireness field is not set.
    WriteDefault bool

    // NoCheckRequireNess indicates not to check requiredness when writing.
    NotCheckRequireNess bool

    // UseNativeSkip indicates to use native.Skip (instead of go.Skip) method to skip thrift value
    // WARN: this will promote performance when thrift value to be skipped is large, but may decrease preformance when thrift value is small.
    UseNativeSkip bool

    // MapStructById indicates to use field id as map key instead of when call Node.Interface() on STRUCT type.
    MapStructById bool

    // CastStringAsBinary indicates to cast STRING type to []byte when call Node.Interface()/Map().
    CastStringAsBinary bool

    // NotScanParentNode indicates to only assign children node when PathNode.Load()/Node.Children.
    // Thies will promote performance but may be misued when handle PathNode.
    NotScanParentNode bool

    // ClearDirtyValues indicates one multi-query (includeing
    // Fields()/GetMany()/Gets()/Indexies()) to clear out all nodes
    // in passed []PathNode first
    ClearDirtyValues bool

    // StoreChildrenById indicates to store children node by id when call Node.Children() or PathNode.Load().
    // When field id exceeds StoreChildrenByIdShreshold, children node will be stored sequentially after the threshold.
    StoreChildrenById bool

    // StoreChildrenByHash indicates to store children node by str hash (mod parent's size) when call Node.Children() or PathNode.Load().
    StoreChildrenByHash bool
}

type Path

Path represents the relative position of a sub node in a complex parent node

type Path struct {
    // contains filtered or unexported fields
}

func NewPathBinKey

func NewPathBinKey(key []byte) Path

NewPathBinKey creates a PathBinKey path

func NewPathFieldId

func NewPathFieldId(id thrift.FieldID) Path

NewPathFieldId creates a PathFieldId path

func NewPathFieldName

func NewPathFieldName(name string) Path

NewPathFieldName creates a PathFieldName path

func NewPathIndex

func NewPathIndex(index int) Path

NewPathIndex creates a PathIndex path

func NewPathIntKey

func NewPathIntKey(key int) Path

NewPathIntKey creates a PathIntKey path

func NewPathStrKey

func NewPathStrKey(key string) Path

NewPathStrKey creates a PathStrKey path

func (Path) Bin

func (self Path) Bin() []byte

Bin returns the raw bytes value of a PathBinKey path

func (Path) Id

func (self Path) Id() thrift.FieldID

Id returns the field id of a PathFieldId path

func (Path) Int

func (self Path) Int() int

Int returns the int value of a PathIndex\PathIntKey path

func (Path) Str

func (self Path) Str() string

Str returns the string value of a PathFieldName\PathStrKey path

func (Path) String

func (self Path) String() string

String returns the string representation of a Path

func (Path) ToRaw

func (self Path) ToRaw(t thrift.Type) []byte

ToRaw converts underlying value to thrift-encoded bytes

func (Path) Type

func (self Path) Type() PathType

Type returns the type of a Path

func (Path) Value

func (self Path) Value() interface{}

Value returns the equivalent go interface of a Path

type PathNode

PathNode is a three node of DOM tree

type PathNode struct {
    Path
    Node
    Next []PathNode
}

func NewPathNode

func NewPathNode() *PathNode

NewPathNode get a new PathNode from memory pool

func (*PathNode) Assgin

func (self *PathNode) Assgin(recurse bool, opts *Options) error

Assgin assigns self's raw Value according to its Next Path, which must be set before calling this method.

func (*PathNode) Check

func (self *PathNode) Check() error

Check returns non-nil error if the PathNode has error

func (PathNode) CopyTo

func (self PathNode) CopyTo(to *PathNode)

CopyTo deeply copy self and its children to a PathNode

func (PathNode) Error

func (self PathNode) Error() string

Error returns non-empty string if the PathNode has error

func (*PathNode) Field

func (self *PathNode) Field(id thrift.FieldID, opts *Options) *PathNode

Field get the child node by field id. Only support STRUCT.

If opts.StoreChildrenById is true, it will try to use id (O(1)) as index to search the key. However, if the struct fields have changed, it may fallback to O(n) search.

func (PathNode) Fork

func (self PathNode) Fork() PathNode

Fork deeply copy self and its children to a new PathNode

func (*PathNode) GetByInt

func (self *PathNode) GetByInt(key int, opts *Options) *PathNode

GetByInt get the child node by integer. Only support MAP with integer-type key.

If opts.StoreChildrenByHash is true, it will try to use hash (O(1)) to search the key. However, if the map size has changed, it may fallback to O(n) search.

func (*PathNode) GetByStr

func (self *PathNode) GetByStr(key string, opts *Options) *PathNode

GetByInt get the child node by string. Only support MAP with string-type key.

If opts.StoreChildrenByHash is true, it will try to use hash (O(1)) to search the key. However, if the map size has changed, it may fallback to O(n) search.

func (*PathNode) Load

func (self *PathNode) Load(recurse bool, opts *Options) error

Load loads self's all children ( and children's children if recurse is true) into self.Next, no matter whether self.Next is empty or set before (will be reset). NOTICE: if opts.NotScanParentNode is true, the parent nodes (PathNode.Node) of complex (map/list/struct) type won't be assgined data

Example

{

	data := getExampleData()
	root := PathNode{
		Node: NewNode(thrift.STRUCT, data),
	}

	err := root.Load(false, opts)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v", root)

	err = root.Load(true, opts)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v", root)

	reuse := pathNodePool.Get().(*PathNode)
	root.Node = NewNode(thrift.STRUCT, data)
	err = root.Load(true, opts)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v", root)
	reuse.ResetValue()
	pathNodePool.Put(reuse)

}

func (PathNode) Marshal

func (self PathNode) Marshal(opt *Options) (out []byte, err error)

Marshal marshals self to thrift bytes

func (PathNode) MarshalIntoBuffer

func (self PathNode) MarshalIntoBuffer(out *[]byte, opt *Options) error

MarshalIntoBuffer marshals self to thrift bytes into a buffer

func (*PathNode) ResetAll

func (self *PathNode) ResetAll()

ResetAll resets self and its children, including path and node both

func (*PathNode) ResetValue

func (self *PathNode) ResetValue()

ResetValue resets self's node and its children's node

func (*PathNode) SetByInt

func (self *PathNode) SetByInt(key int, val Node, opts *Options) (bool, error)

SetByInt set the child node by integer. Only support MAP with integer-type key. If the key already exists, it will be overwritten and return true.

If opts.StoreChildrenByHash is true, it will try to use hash (O(1)) to search the key. However, if the map hash size has changed, it may fallback to O(n) search.

func (*PathNode) SetByStr

func (self *PathNode) SetByStr(key string, val Node, opts *Options) (bool, error)

SetByStr set the child node by string. Only support MAP with string-type key. If the key already exists, it will be overwritten and return true.

If opts.StoreChildrenByHash is true, it will try to use hash (O(1)) to search the key. However, if the map hash size has changed, it may fallback to O(n) search.

func (*PathNode) SetField

func (self *PathNode) SetField(id thrift.FieldID, val Node, opts *Options) (bool, error)

SetField set the child node by field id. Only support STRUCT. If the key already exists, it will be overwritten and return true.

If opts.StoreChildrenById is true, it will try to use id (O(1)) as index to search the key. However, if the struct fields have changed, it may fallback to O(n) search.

type PathType

PathType is the type of path

type PathType uint8
const (
    // PathFieldId represents a field id of STRUCT type
    PathFieldId PathType = 1 + iota

    // PathFieldName represents a field name of STRUCT type
    // NOTICE: it is only supported by Value
    PathFieldName

    // PathIndex represents a index of LIST\SET type
    PathIndex

    // Path represents a string key of MAP type
    PathStrKey

    // Path represents a int key of MAP type
    PathIntKey

    // Path represents a raw-bytes key of MAP type
    // It is usually used for neither-string-nor-integer type key
    PathBinKey
)

type Value

Value is a generic API wrapper for operations on thrift data. Node is the underlying raw bytes. Desc is the corresponding type descriptor.

type Value struct {
    Node
    Desc *thrift.TypeDescriptor
}
Example (3et Many)

{

	desc := getExampleDesc()
	data := getExampleData()
	d1 := desc.Struct().FieldByKey("Msg").Type()
	d2 := desc.Struct().FieldByKey("Subfix").Type()
	v := NewValue(desc, data)

	p := thrift.NewBinaryProtocol([]byte{})
	e1 := "test1"
	p.WriteString(e1)
	v1 := NewValue(d1, p.RawBuf())
	p = thrift.NewBinaryProtocol([]byte{})
	e2 := float64(-255.0001)
	p.WriteDouble(e2)
	v2 := NewValue(d2, p.RawBuf())
	v3 := v.GetByPath(NewPathFieldName("Base"))

	ps := []PathNode{
		{
			Path: NewPathFieldId(1),
			Node: v1.Node,
		},
		{
			Path: NewPathFieldId(32767),
			Node: v2.Node,
		},
		{
			Path: NewPathFieldId(255),
			Node: v3.Node,
		},
	}

	err := v.SetMany(ps, opts)
	if err != nil {
		panic(err)
	}
	any, err := v.Interface(opts)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v", any)

	ps2 := []PathNode{
		{
			Path: NewPathFieldId(1),
		},
		{
			Path: NewPathFieldId(32767),
		},
		{
			Path: NewPathFieldId(255),
		},
	}
	if err := v.GetMany(ps2, opts); err != nil {
		panic(err)
	}
	any0, err := ps2[2].Node.Interface(opts)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v", any0)
}

func NewValue

func NewValue(desc *thrift.TypeDescriptor, src []byte) Value

NewValue creates a new Value from a raw byte slice.

func (Value) Field

func (self Value) Field(id thrift.FieldID) (v Value)

Field returns a sub node at the given field id from a STRUCT value.

func (Value) FieldByName

func (self Value) FieldByName(name string) (v Value)

FieldByName returns a sub node at the given field name from a STRUCT value.

func (Value) Fork

func (self Value) Fork() Value

NewValueFromNode copy both Node and TypeDescriptor from another Value.

func (Value) GetByInt

func (self Value) GetByInt(key int) (v Value)

GetByInt returns a sub node at the given int key from a MAP value.

func (Value) GetByPath

func (self Value) GetByPath(pathes ...Path) Value

GetByPath searches longitudinally and return a sub value at the given path from the value.

The path is a list of PathFieldId, PathFieldName, PathIndex, PathStrKey, PathBinKey, PathIntKey, Each path MUST be a valid path type for current layer (e.g. PathFieldId is only valid for STRUCT). Empty path will return the current value.

func (Value) GetByStr

func (self Value) GetByStr(key string) (v Value)

GetByStr returns a sub node at the given string key from a MAP value.

func (Value) Index

func (self Value) Index(i int) (v Value)

Index returns a sub node at the given index from a LIST value.

func (Value) MarshalTo

func (self Value) MarshalTo(to *thrift.TypeDescriptor, opts *Options) ([]byte, error)

MarshalTo marshals self value into a sub value descripted by the to descriptor, alse called as "Cutting". Usually, the to descriptor is a subset of self descriptor.

Example

{

	desc := getExampleDesc()
	data := getExampleData()
	v := NewValue(desc, data)

	full, err := NewNode(thrift.STRUCT, data).Interface(opts)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v", full)

	pdesc := getExamplePartialDesc()

	out, err := v.MarshalTo(pdesc, opts)
	if err != nil {
		panic(err)
	}

	partial, err := NewNode(thrift.STRUCT, out).Interface(opts)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v", partial)
}

func (*Value) SetByPath

func (self *Value) SetByPath(sub Value, path ...Path) (exist bool, err error)

SetByPath searches longitudinally and sets a sub value at the given path from the value. exist tells whether the node is already exists.

Example

{

	desc := getExampleDesc()
	data := getExampleData()
	v := NewValue(desc, data)

	d := desc.Struct().FieldByKey("Base").Type().Struct().FieldByKey("Extra").Type().Elem()
	p := thrift.NewBinaryProtocol([]byte{})
	exp := "中文"
	p.WriteString(exp)
	buf := p.RawBuf()
	vv := NewValue(d, buf)

	ps := []Path{NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("b")}
	exist, err2 := v.SetByPath(vv, ps...)
	if err2 != nil {
		panic(err2)
	}
	println(exist)

	s2 := v.GetByPath(ps...)
	if s2.Error() != "" {
		panic(s2.Error())
	}
	f2, _ := s2.String()
	println(f2)
}

func (*Value) UnsetByPath

func (self *Value) UnsetByPath(path ...Path) error

UnsetByPath searches longitudinally and unsets a sub value at the given path from the value.

Generated by gomarkdoc