github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/ngaut/go-zookeeper/zk/structs.go (about)

     1  package zk
     2  
     3  import (
     4  	"encoding/binary"
     5  	"errors"
     6  	"reflect"
     7  	"runtime"
     8  	"time"
     9  )
    10  
    11  var (
    12  	ErrUnhandledFieldType = errors.New("zk: unhandled field type")
    13  	ErrPtrExpected        = errors.New("zk: encode/decode expect a non-nil pointer to struct")
    14  	ErrShortBuffer        = errors.New("zk: buffer too small")
    15  )
    16  
    17  type ACL struct {
    18  	Perms  int32
    19  	Scheme string
    20  	ID     string
    21  }
    22  
    23  type zkstat struct {
    24  	ZCzxid          int64 // The zxid of the change that caused this znode to be created.
    25  	ZMzxid          int64 // The zxid of the change that last modified this znode.
    26  	ZCtime          int64 // The time in milliseconds from epoch when this znode was created.
    27  	ZMtime          int64 // The time in milliseconds from epoch when this znode was last modified.
    28  	ZVersion        int32 // The number of changes to the data of this znode.
    29  	ZCversion       int32 // The number of changes to the children of this znode.
    30  	ZAversion       int32 // The number of changes to the ACL of this znode.
    31  	ZEphemeralOwner int64 // The session id of the owner of this znode if the znode is an ephemeral node. If it is not an ephemeral node, it will be zero.
    32  	ZDataLength     int32 // The length of the data field of this znode.
    33  	ZNumChildren    int32 // The number of children of this znode.
    34  	ZPzxid          int64 // last modified children
    35  }
    36  
    37  type Stat interface {
    38  	Czxid() int64
    39  	Mzxid() int64
    40  	CTime() time.Time
    41  	MTime() time.Time
    42  	Version() int
    43  	CVersion() int
    44  	AVersion() int
    45  	EphemeralOwner() int64
    46  	DataLength() int
    47  	NumChildren() int
    48  	Pzxid() int64
    49  }
    50  
    51  // Czxid returns the zxid of the change that caused the node to be created.
    52  func (s *zkstat) Czxid() int64 {
    53  	return s.ZCzxid
    54  }
    55  
    56  // Mzxid returns the zxid of the change that last modified the node.
    57  func (s *zkstat) Mzxid() int64 {
    58  	return s.ZMzxid
    59  }
    60  
    61  func millisec2time(ms int64) time.Time {
    62  	return time.Unix(ms/1e3, ms%1e3*1e6)
    63  }
    64  
    65  // CTime returns the time (at millisecond resolution)  when the node was
    66  // created.
    67  func (s *zkstat) CTime() time.Time {
    68  	return millisec2time(s.ZCtime)
    69  }
    70  
    71  // MTime returns the time (at millisecond resolution) when the node was
    72  // last modified.
    73  func (s *zkstat) MTime() time.Time {
    74  	return millisec2time(int64(s.ZMtime))
    75  }
    76  
    77  // Version returns the number of changes to the data of the node.
    78  func (s *zkstat) Version() int {
    79  	return int(s.ZVersion)
    80  }
    81  
    82  // CVersion returns the number of changes to the children of the node.
    83  // This only changes when children are created or removed.
    84  func (s *zkstat) CVersion() int {
    85  	return int(s.ZCversion)
    86  }
    87  
    88  // AVersion returns the number of changes to the ACL of the node.
    89  func (s *zkstat) AVersion() int {
    90  	return int(s.ZAversion)
    91  }
    92  
    93  // If the node is an ephemeral node, EphemeralOwner returns the session id
    94  // of the owner of the node; otherwise it will return zero.
    95  func (s *zkstat) EphemeralOwner() int64 {
    96  	return int64(s.ZEphemeralOwner)
    97  }
    98  
    99  // DataLength returns the length of the data in the node in bytes.
   100  func (s *zkstat) DataLength() int {
   101  	return int(s.ZDataLength)
   102  }
   103  
   104  // NumChildren returns the number of children of the node.
   105  func (s *zkstat) NumChildren() int {
   106  	return int(s.ZNumChildren)
   107  }
   108  
   109  // Pzxid returns the Pzxid of the node, whatever that is.
   110  func (s *zkstat) Pzxid() int64 {
   111  	return int64(s.ZPzxid)
   112  }
   113  
   114  type requestHeader struct {
   115  	Xid    int32
   116  	Opcode int32
   117  }
   118  
   119  type responseHeader struct {
   120  	Xid  int32
   121  	Zxid int64
   122  	Err  ErrCode
   123  }
   124  
   125  type multiHeader struct {
   126  	Type int32
   127  	Done bool
   128  	Err  ErrCode
   129  }
   130  
   131  type auth struct {
   132  	Type   int32
   133  	Scheme string
   134  	Auth   []byte
   135  }
   136  
   137  // Generic request structs
   138  
   139  type pathRequest struct {
   140  	Path string
   141  }
   142  
   143  type PathVersionRequest struct {
   144  	Path    string
   145  	Version int32
   146  }
   147  
   148  type pathWatchRequest struct {
   149  	Path  string
   150  	Watch bool
   151  }
   152  
   153  type pathResponse struct {
   154  	Path string
   155  }
   156  
   157  type statResponse struct {
   158  	Stat zkstat
   159  }
   160  
   161  //
   162  
   163  type CheckVersionRequest PathVersionRequest
   164  type closeRequest struct{}
   165  type closeResponse struct{}
   166  
   167  type connectRequest struct {
   168  	ProtocolVersion int32
   169  	LastZxidSeen    int64
   170  	TimeOut         int32
   171  	SessionID       int64
   172  	Passwd          []byte
   173  }
   174  
   175  type connectResponse struct {
   176  	ProtocolVersion int32
   177  	TimeOut         int32
   178  	SessionID       int64
   179  	Passwd          []byte
   180  }
   181  
   182  type CreateRequest struct {
   183  	Path  string
   184  	Data  []byte
   185  	Acl   []ACL
   186  	Flags int32
   187  }
   188  
   189  type createResponse pathResponse
   190  type DeleteRequest PathVersionRequest
   191  type deleteResponse struct{}
   192  
   193  type errorResponse struct {
   194  	Err int32
   195  }
   196  
   197  type existsRequest pathWatchRequest
   198  type existsResponse statResponse
   199  type getAclRequest pathRequest
   200  
   201  type getAclResponse struct {
   202  	Acl  []ACL
   203  	Stat zkstat
   204  }
   205  
   206  type getChildrenRequest pathRequest
   207  
   208  type getChildrenResponse struct {
   209  	Children []string
   210  }
   211  
   212  type getChildren2Request pathWatchRequest
   213  
   214  type getChildren2Response struct {
   215  	Children []string
   216  	Stat     zkstat
   217  }
   218  
   219  type getDataRequest pathWatchRequest
   220  
   221  type getDataResponse struct {
   222  	Data []byte
   223  	Stat zkstat
   224  }
   225  
   226  type getMaxChildrenRequest pathRequest
   227  
   228  type getMaxChildrenResponse struct {
   229  	Max int32
   230  }
   231  
   232  type getSaslRequest struct {
   233  	Token []byte
   234  }
   235  
   236  type pingRequest struct{}
   237  type pingResponse struct{}
   238  
   239  type setAclRequest struct {
   240  	Path    string
   241  	Acl     []ACL
   242  	Version int32
   243  }
   244  
   245  type setAclResponse statResponse
   246  
   247  type SetDataRequest struct {
   248  	Path    string
   249  	Data    []byte
   250  	Version int32
   251  }
   252  
   253  type setDataResponse statResponse
   254  
   255  type setMaxChildren struct {
   256  	Path string
   257  	Max  int32
   258  }
   259  
   260  type setSaslRequest struct {
   261  	Token string
   262  }
   263  
   264  type setSaslResponse struct {
   265  	Token string
   266  }
   267  
   268  type setWatchesRequest struct {
   269  	RelativeZxid int64
   270  	DataWatches  []string
   271  	ExistWatches []string
   272  	ChildWatches []string
   273  }
   274  
   275  type setWatchesResponse struct{}
   276  
   277  type syncRequest pathRequest
   278  type syncResponse pathResponse
   279  
   280  type setAuthRequest auth
   281  type setAuthResponse struct{}
   282  
   283  type multiRequestOp struct {
   284  	Header multiHeader
   285  	Op     interface{}
   286  }
   287  type multiRequest struct {
   288  	Ops        []multiRequestOp
   289  	DoneHeader multiHeader
   290  }
   291  type multiResponseOp struct {
   292  	Header multiHeader
   293  	String string
   294  	Stat   *zkstat
   295  }
   296  type multiResponse struct {
   297  	Ops        []multiResponseOp
   298  	DoneHeader multiHeader
   299  }
   300  
   301  func (r *multiRequest) Encode(buf []byte) (int, error) {
   302  	total := 0
   303  	for _, op := range r.Ops {
   304  		op.Header.Done = false
   305  		n, err := encodePacketValue(buf[total:], reflect.ValueOf(op))
   306  		if err != nil {
   307  			return total, err
   308  		}
   309  		total += n
   310  	}
   311  	r.DoneHeader.Done = true
   312  	n, err := encodePacketValue(buf[total:], reflect.ValueOf(r.DoneHeader))
   313  	if err != nil {
   314  		return total, err
   315  	}
   316  	total += n
   317  
   318  	return total, nil
   319  }
   320  
   321  func (r *multiRequest) Decode(buf []byte) (int, error) {
   322  	r.Ops = make([]multiRequestOp, 0)
   323  	r.DoneHeader = multiHeader{-1, true, -1}
   324  	total := 0
   325  	for {
   326  		header := &multiHeader{}
   327  		n, err := decodePacketValue(buf[total:], reflect.ValueOf(header))
   328  		if err != nil {
   329  			return total, err
   330  		}
   331  		total += n
   332  		if header.Done {
   333  			r.DoneHeader = *header
   334  			break
   335  		}
   336  
   337  		req := requestStructForOp(header.Type)
   338  		if req == nil {
   339  			return total, ErrAPIError
   340  		}
   341  		n, err = decodePacketValue(buf[total:], reflect.ValueOf(req))
   342  		if err != nil {
   343  			return total, err
   344  		}
   345  		total += n
   346  		r.Ops = append(r.Ops, multiRequestOp{*header, req})
   347  	}
   348  	return total, nil
   349  }
   350  
   351  func (r *multiResponse) Decode(buf []byte) (int, error) {
   352  	r.Ops = make([]multiResponseOp, 0)
   353  	r.DoneHeader = multiHeader{-1, true, -1}
   354  	total := 0
   355  	for {
   356  		header := &multiHeader{}
   357  		n, err := decodePacketValue(buf[total:], reflect.ValueOf(header))
   358  		if err != nil {
   359  			return total, err
   360  		}
   361  		total += n
   362  		if header.Done {
   363  			r.DoneHeader = *header
   364  			break
   365  		}
   366  
   367  		res := multiResponseOp{Header: *header}
   368  		var w reflect.Value
   369  		switch header.Type {
   370  		default:
   371  			return total, ErrAPIError
   372  		case opCreate:
   373  			w = reflect.ValueOf(&res.String)
   374  		case opSetData:
   375  			res.Stat = new(zkstat)
   376  			w = reflect.ValueOf(res.Stat)
   377  		case opCheck, opDelete:
   378  		}
   379  		if w.IsValid() {
   380  			n, err := decodePacketValue(buf[total:], w)
   381  			if err != nil {
   382  				return total, err
   383  			}
   384  			total += n
   385  		}
   386  		r.Ops = append(r.Ops, res)
   387  	}
   388  	return total, nil
   389  }
   390  
   391  type watcherEvent struct {
   392  	Type  EventType
   393  	State State
   394  	Path  string
   395  }
   396  
   397  type decoder interface {
   398  	Decode(buf []byte) (int, error)
   399  }
   400  
   401  type encoder interface {
   402  	Encode(buf []byte) (int, error)
   403  }
   404  
   405  func decodePacket(buf []byte, st interface{}) (n int, err error) {
   406  	defer func() {
   407  		if r := recover(); r != nil {
   408  			if e, ok := r.(runtime.Error); ok && e.Error() == "runtime error: slice bounds out of range" {
   409  				err = ErrShortBuffer
   410  			} else {
   411  				panic(r)
   412  			}
   413  		}
   414  	}()
   415  
   416  	v := reflect.ValueOf(st)
   417  	if v.Kind() != reflect.Ptr || v.IsNil() {
   418  		return 0, ErrPtrExpected
   419  	}
   420  	return decodePacketValue(buf, v)
   421  }
   422  
   423  func decodePacketValue(buf []byte, v reflect.Value) (int, error) {
   424  	rv := v
   425  	kind := v.Kind()
   426  	if kind == reflect.Ptr {
   427  		if v.IsNil() {
   428  			v.Set(reflect.New(v.Type().Elem()))
   429  		}
   430  		v = v.Elem()
   431  		kind = v.Kind()
   432  	}
   433  
   434  	n := 0
   435  	switch kind {
   436  	default:
   437  		return n, ErrUnhandledFieldType
   438  	case reflect.Struct:
   439  		if de, ok := rv.Interface().(decoder); ok {
   440  			return de.Decode(buf)
   441  		} else if de, ok := v.Interface().(decoder); ok {
   442  			return de.Decode(buf)
   443  		} else {
   444  			for i := 0; i < v.NumField(); i++ {
   445  				field := v.Field(i)
   446  				n2, err := decodePacketValue(buf[n:], field)
   447  				n += n2
   448  				if err != nil {
   449  					return n, err
   450  				}
   451  			}
   452  		}
   453  	case reflect.Bool:
   454  		v.SetBool(buf[n] != 0)
   455  		n++
   456  	case reflect.Int32:
   457  		v.SetInt(int64(binary.BigEndian.Uint32(buf[n : n+4])))
   458  		n += 4
   459  	case reflect.Int64:
   460  		v.SetInt(int64(binary.BigEndian.Uint64(buf[n : n+8])))
   461  		n += 8
   462  	case reflect.String:
   463  		ln := int(binary.BigEndian.Uint32(buf[n : n+4]))
   464  		v.SetString(string(buf[n+4 : n+4+ln]))
   465  		n += 4 + ln
   466  	case reflect.Slice:
   467  		switch v.Type().Elem().Kind() {
   468  		default:
   469  			count := int(binary.BigEndian.Uint32(buf[n : n+4]))
   470  			n += 4
   471  			values := reflect.MakeSlice(v.Type(), count, count)
   472  			v.Set(values)
   473  			for i := 0; i < count; i++ {
   474  				n2, err := decodePacketValue(buf[n:], values.Index(i))
   475  				n += n2
   476  				if err != nil {
   477  					return n, err
   478  				}
   479  			}
   480  		case reflect.Uint8:
   481  			ln := int(int32(binary.BigEndian.Uint32(buf[n : n+4])))
   482  			if ln < 0 {
   483  				n += 4
   484  				v.SetBytes(nil)
   485  			} else {
   486  				bytes := make([]byte, ln)
   487  				copy(bytes, buf[n+4:n+4+ln])
   488  				v.SetBytes(bytes)
   489  				n += 4 + ln
   490  			}
   491  		}
   492  	}
   493  	return n, nil
   494  }
   495  
   496  func encodePacket(buf []byte, st interface{}) (n int, err error) {
   497  	defer func() {
   498  		if r := recover(); r != nil {
   499  			if e, ok := r.(runtime.Error); ok && e.Error() == "runtime error: slice bounds out of range" {
   500  				err = ErrShortBuffer
   501  			} else {
   502  				panic(r)
   503  			}
   504  		}
   505  	}()
   506  
   507  	v := reflect.ValueOf(st)
   508  	if v.Kind() != reflect.Ptr || v.IsNil() {
   509  		return 0, ErrPtrExpected
   510  	}
   511  	return encodePacketValue(buf, v)
   512  }
   513  
   514  func encodePacketValue(buf []byte, v reflect.Value) (int, error) {
   515  	rv := v
   516  	for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
   517  		v = v.Elem()
   518  	}
   519  
   520  	n := 0
   521  	switch v.Kind() {
   522  	default:
   523  		return n, ErrUnhandledFieldType
   524  	case reflect.Struct:
   525  		if en, ok := rv.Interface().(encoder); ok {
   526  			return en.Encode(buf)
   527  		} else if en, ok := v.Interface().(encoder); ok {
   528  			return en.Encode(buf)
   529  		} else {
   530  			for i := 0; i < v.NumField(); i++ {
   531  				field := v.Field(i)
   532  				n2, err := encodePacketValue(buf[n:], field)
   533  				n += n2
   534  				if err != nil {
   535  					return n, err
   536  				}
   537  			}
   538  		}
   539  	case reflect.Bool:
   540  		if v.Bool() {
   541  			buf[n] = 1
   542  		} else {
   543  			buf[n] = 0
   544  		}
   545  		n++
   546  	case reflect.Int32:
   547  		binary.BigEndian.PutUint32(buf[n:n+4], uint32(v.Int()))
   548  		n += 4
   549  	case reflect.Int64:
   550  		binary.BigEndian.PutUint64(buf[n:n+8], uint64(v.Int()))
   551  		n += 8
   552  	case reflect.String:
   553  		str := v.String()
   554  		binary.BigEndian.PutUint32(buf[n:n+4], uint32(len(str)))
   555  		copy(buf[n+4:n+4+len(str)], []byte(str))
   556  		n += 4 + len(str)
   557  	case reflect.Slice:
   558  		switch v.Type().Elem().Kind() {
   559  		default:
   560  			count := v.Len()
   561  			startN := n
   562  			n += 4
   563  			for i := 0; i < count; i++ {
   564  				n2, err := encodePacketValue(buf[n:], v.Index(i))
   565  				n += n2
   566  				if err != nil {
   567  					return n, err
   568  				}
   569  			}
   570  			binary.BigEndian.PutUint32(buf[startN:startN+4], uint32(count))
   571  		case reflect.Uint8:
   572  			if v.IsNil() {
   573  				binary.BigEndian.PutUint32(buf[n:n+4], uint32(0xffffffff))
   574  				n += 4
   575  			} else {
   576  				bytes := v.Bytes()
   577  				binary.BigEndian.PutUint32(buf[n:n+4], uint32(len(bytes)))
   578  				copy(buf[n+4:n+4+len(bytes)], bytes)
   579  				n += 4 + len(bytes)
   580  			}
   581  		}
   582  	}
   583  	return n, nil
   584  }
   585  
   586  func requestStructForOp(op int32) interface{} {
   587  	switch op {
   588  	case opClose:
   589  		return &closeRequest{}
   590  	case opCreate:
   591  		return &CreateRequest{}
   592  	case opDelete:
   593  		return &DeleteRequest{}
   594  	case opExists:
   595  		return &existsRequest{}
   596  	case opGetAcl:
   597  		return &getAclRequest{}
   598  	case opGetChildren:
   599  		return &getChildrenRequest{}
   600  	case opGetChildren2:
   601  		return &getChildren2Request{}
   602  	case opGetData:
   603  		return &getDataRequest{}
   604  	case opPing:
   605  		return &pingRequest{}
   606  	case opSetAcl:
   607  		return &setAclRequest{}
   608  	case opSetData:
   609  		return &SetDataRequest{}
   610  	case opSetWatches:
   611  		return &setWatchesRequest{}
   612  	case opSync:
   613  		return &syncRequest{}
   614  	case opSetAuth:
   615  		return &setAuthRequest{}
   616  	case opCheck:
   617  		return &CheckVersionRequest{}
   618  	case opMulti:
   619  		return &multiRequest{}
   620  	}
   621  	return nil
   622  }
   623  
   624  func responseStructForOp(op int32) interface{} {
   625  	switch op {
   626  	case opClose:
   627  		return &closeResponse{}
   628  	case opCreate:
   629  		return &createResponse{}
   630  	case opDelete:
   631  		return &deleteResponse{}
   632  	case opExists:
   633  		return &existsResponse{}
   634  	case opGetAcl:
   635  		return &getAclResponse{}
   636  	case opGetChildren:
   637  		return &getChildrenResponse{}
   638  	case opGetChildren2:
   639  		return &getChildren2Response{}
   640  	case opGetData:
   641  		return &getDataResponse{}
   642  	case opPing:
   643  		return &pingResponse{}
   644  	case opSetAcl:
   645  		return &setAclResponse{}
   646  	case opSetData:
   647  		return &setDataResponse{}
   648  	case opSetWatches:
   649  		return &setWatchesResponse{}
   650  	case opSync:
   651  		return &syncResponse{}
   652  	case opWatcherEvent:
   653  		return &watcherEvent{}
   654  	case opSetAuth:
   655  		return &setAuthResponse{}
   656  	// case opCheck:
   657  	// 	return &checkVersionResponse{}
   658  	case opMulti:
   659  		return &multiResponse{}
   660  	}
   661  	return nil
   662  }