github.com/urso/go-structform@v0.0.2/cborl/visitor.go (about)

     1  package cborl
     2  
     3  import (
     4  	"encoding/binary"
     5  	"io"
     6  	"math"
     7  
     8  	structform "github.com/urso/go-structform"
     9  )
    10  
    11  type Visitor struct {
    12  	w       writer
    13  	scratch [16]byte
    14  
    15  	length lengthStack
    16  }
    17  
    18  type writer struct {
    19  	out io.Writer
    20  }
    21  
    22  func (w writer) write(b []byte) error {
    23  	_, err := w.out.Write(b)
    24  	return err
    25  }
    26  
    27  func NewVisitor(out io.Writer) *Visitor {
    28  	v := &Visitor{w: writer{out}}
    29  	v.length.stack = v.length.stack0[:0]
    30  	return v
    31  }
    32  
    33  func (vs *Visitor) writeByte(b byte) error {
    34  	vs.scratch[0] = b
    35  	return vs.w.write(vs.scratch[:1])
    36  }
    37  
    38  func (vs *Visitor) OnObjectStart(len int, baseType structform.BaseType) error {
    39  	if err := vs.optLen(majorMap, len); err != nil {
    40  		return err
    41  	}
    42  
    43  	vs.length.push(int64(len))
    44  	return nil
    45  }
    46  
    47  func (vs *Visitor) OnObjectFinished() error {
    48  	if vs.length.pop() < 0 {
    49  		return vs.writeByte(codeBreak)
    50  	}
    51  	return nil
    52  }
    53  
    54  func (vs *Visitor) OnKey(s string) error {
    55  	return vs.string(str2Bytes(s))
    56  }
    57  
    58  func (vs *Visitor) OnKeyRef(s []byte) error {
    59  	return vs.string(s)
    60  }
    61  
    62  func (vs *Visitor) OnArrayStart(len int, baseType structform.BaseType) error {
    63  	if err := vs.optLen(majorArr, len); err != nil {
    64  		return err
    65  	}
    66  
    67  	vs.length.push(int64(len))
    68  	return nil
    69  }
    70  
    71  func (vs *Visitor) OnArrayFinished() error {
    72  	if vs.length.pop() < 0 {
    73  		return vs.writeByte(codeBreak)
    74  	}
    75  	return nil
    76  }
    77  
    78  func (vs *Visitor) OnNil() error {
    79  	return vs.writeByte(codeNull)
    80  }
    81  
    82  func (vs *Visitor) OnBool(b bool) error {
    83  	if b {
    84  		return vs.writeByte(codeTrue)
    85  	}
    86  	return vs.writeByte(codeFalse)
    87  }
    88  
    89  func (vs *Visitor) OnString(s string) error {
    90  	return vs.string(str2Bytes(s))
    91  }
    92  
    93  func (vs *Visitor) OnStringRef(s []byte) error {
    94  	return vs.string(s)
    95  }
    96  
    97  func (vs *Visitor) OnInt8(i int8) error {
    98  	return vs.int8(i)
    99  }
   100  
   101  func (vs *Visitor) OnInt16(i int16) error {
   102  	return vs.int16(i)
   103  }
   104  
   105  func (vs *Visitor) OnInt32(i int32) error {
   106  	return vs.int32(i)
   107  }
   108  
   109  func (vs *Visitor) OnInt64(i int64) error {
   110  	return vs.int64(i)
   111  }
   112  
   113  func (vs *Visitor) OnInt(i int) error {
   114  	return vs.int64(int64(i))
   115  }
   116  
   117  func (vs *Visitor) OnByte(b byte) error {
   118  	return vs.uint8(majorUint, b)
   119  }
   120  
   121  func (vs *Visitor) OnUint8(u uint8) error {
   122  	return vs.uint8(majorUint, u)
   123  }
   124  
   125  func (vs *Visitor) OnUint16(u uint16) error {
   126  	return vs.uint16(majorUint, u)
   127  }
   128  
   129  func (vs *Visitor) OnUint32(u uint32) error {
   130  	return vs.uint32(majorUint, u)
   131  }
   132  
   133  func (vs *Visitor) OnUint64(u uint64) error {
   134  	return vs.uint64(majorUint, u)
   135  }
   136  
   137  func (vs *Visitor) OnUint(u uint) error {
   138  	return vs.uint64(majorUint, uint64(u))
   139  }
   140  
   141  func (vs *Visitor) OnFloat32(f float32) error {
   142  	b := math.Float32bits(f)
   143  	vs.scratch[0] = codeSingleFloat
   144  	binary.BigEndian.PutUint32(vs.scratch[1:5], b)
   145  	return vs.w.write(vs.scratch[:5])
   146  }
   147  
   148  func (vs *Visitor) OnFloat64(f float64) error {
   149  	b := math.Float64bits(f)
   150  	vs.scratch[0] = codeDoubleFloat
   151  	binary.BigEndian.PutUint64(vs.scratch[1:9], b)
   152  	return vs.w.write(vs.scratch[:9])
   153  }
   154  
   155  func (vs *Visitor) OnBoolArray(a []bool) error {
   156  	if err := vs.arrLen(len(a)); err != nil {
   157  		return nil
   158  	}
   159  	for _, v := range a {
   160  		if err := vs.OnBool(v); err != nil {
   161  			return err
   162  		}
   163  	}
   164  
   165  	return nil
   166  }
   167  
   168  func (vs *Visitor) OnStringArray(a []string) error {
   169  	if err := vs.arrLen(len(a)); err != nil {
   170  		return nil
   171  	}
   172  	for _, v := range a {
   173  		if err := vs.OnString(v); err != nil {
   174  			return err
   175  		}
   176  	}
   177  	return nil
   178  }
   179  
   180  func (vs *Visitor) OnInt8Array(a []int8) error {
   181  	if err := vs.arrLen(len(a)); err != nil {
   182  		return nil
   183  	}
   184  	for _, v := range a {
   185  		if err := vs.OnInt8(v); err != nil {
   186  			return err
   187  		}
   188  	}
   189  	return nil
   190  }
   191  
   192  func (vs *Visitor) OnInt16Array(a []int16) error {
   193  	if err := vs.arrLen(len(a)); err != nil {
   194  		return nil
   195  	}
   196  	for _, v := range a {
   197  		if err := vs.OnInt16(v); err != nil {
   198  			return err
   199  		}
   200  	}
   201  	return nil
   202  }
   203  
   204  func (vs *Visitor) OnInt32Array(a []int32) error {
   205  	if err := vs.arrLen(len(a)); err != nil {
   206  		return nil
   207  	}
   208  	for _, v := range a {
   209  		if err := vs.OnInt32(v); err != nil {
   210  			return err
   211  		}
   212  	}
   213  	return nil
   214  }
   215  
   216  func (vs *Visitor) OnInt64Array(a []int64) error {
   217  	if err := vs.arrLen(len(a)); err != nil {
   218  		return nil
   219  	}
   220  	for _, v := range a {
   221  		if err := vs.OnInt64(v); err != nil {
   222  			return err
   223  		}
   224  	}
   225  	return nil
   226  }
   227  
   228  func (vs *Visitor) OnIntArray(a []int) error {
   229  	if err := vs.arrLen(len(a)); err != nil {
   230  		return nil
   231  	}
   232  	for _, v := range a {
   233  		if err := vs.OnInt(v); err != nil {
   234  			return err
   235  		}
   236  	}
   237  	return nil
   238  }
   239  
   240  func (vs *Visitor) OnBytes(a []byte) error {
   241  	return vs.bytes(majorBytes, a)
   242  }
   243  
   244  func (vs *Visitor) OnUint8Array(a []uint8) error {
   245  	return vs.bytes(majorBytes, a)
   246  }
   247  
   248  func (vs *Visitor) OnUint16Array(a []uint16) error {
   249  	if err := vs.arrLen(len(a)); err != nil {
   250  		return nil
   251  	}
   252  	for _, v := range a {
   253  		if err := vs.OnUint16(v); err != nil {
   254  			return err
   255  		}
   256  	}
   257  	return nil
   258  }
   259  
   260  func (vs *Visitor) OnUint32Array(a []uint32) error {
   261  	if err := vs.arrLen(len(a)); err != nil {
   262  		return nil
   263  	}
   264  	for _, v := range a {
   265  		if err := vs.OnUint32(v); err != nil {
   266  			return err
   267  		}
   268  	}
   269  	return nil
   270  }
   271  
   272  func (vs *Visitor) OnUint64Array(a []uint64) error {
   273  	if err := vs.arrLen(len(a)); err != nil {
   274  		return nil
   275  	}
   276  	for _, v := range a {
   277  		if err := vs.OnUint64(v); err != nil {
   278  			return err
   279  		}
   280  	}
   281  	return nil
   282  }
   283  
   284  func (vs *Visitor) OnUintArray(a []uint) error {
   285  	if err := vs.arrLen(len(a)); err != nil {
   286  		return nil
   287  	}
   288  	for _, v := range a {
   289  		if err := vs.OnUint(v); err != nil {
   290  			return err
   291  		}
   292  	}
   293  	return nil
   294  }
   295  
   296  func (vs *Visitor) OnFloat32Array(a []float32) error {
   297  	if err := vs.arrLen(len(a)); err != nil {
   298  		return nil
   299  	}
   300  	for _, v := range a {
   301  		if err := vs.OnFloat32(v); err != nil {
   302  			return err
   303  		}
   304  	}
   305  	return nil
   306  }
   307  
   308  func (vs *Visitor) OnFloat64Array(a []float64) error {
   309  	if err := vs.arrLen(len(a)); err != nil {
   310  		return nil
   311  	}
   312  	for _, v := range a {
   313  		if err := vs.OnFloat64(v); err != nil {
   314  			return err
   315  		}
   316  	}
   317  	return nil
   318  }
   319  
   320  func (vs *Visitor) string(s []byte) error {
   321  	return vs.bytes(majorText, s)
   322  }
   323  
   324  func (vs *Visitor) bytes(major uint8, buf []byte) error {
   325  	if err := vs.uint64(major, uint64(len(buf))); err != nil {
   326  		return err
   327  	}
   328  	return vs.w.write(buf)
   329  }
   330  
   331  func (vs *Visitor) arrLen(len int) error {
   332  	return vs.uint64(majorArr, uint64(len))
   333  }
   334  
   335  func (vs *Visitor) optLen(major uint8, len int) error {
   336  	if len < 0 {
   337  		return vs.writeByte(major | lenIndef)
   338  	}
   339  	return vs.uint64(major, uint64(len))
   340  }
   341  
   342  func (vs *Visitor) int8(v int8) error {
   343  	if v < 0 {
   344  		return vs.uint8(majorNeg, ^uint8(v))
   345  	}
   346  	return vs.uint8(majorUint, uint8(v))
   347  }
   348  
   349  func (vs *Visitor) int16(v int16) error {
   350  	if v < 0 {
   351  		return vs.uint16(majorNeg, ^uint16(v))
   352  	}
   353  	return vs.uint16(majorUint, uint16(v))
   354  }
   355  
   356  func (vs *Visitor) int32(v int32) error {
   357  	if v < 0 {
   358  		return vs.uint32(majorNeg, ^uint32(v))
   359  	}
   360  	return vs.uint32(majorUint, uint32(v))
   361  }
   362  
   363  func (vs *Visitor) int64(v int64) error {
   364  	if v < 0 {
   365  		return vs.uint64(majorNeg, ^uint64(v))
   366  	}
   367  	return vs.uint64(majorUint, uint64(v))
   368  }
   369  
   370  func (vs *Visitor) uint8(major uint8, v uint8) error {
   371  	if v < len8b {
   372  		return vs.writeByte(major | v)
   373  	}
   374  
   375  	vs.scratch[0], vs.scratch[1] = major|len8b, v
   376  	return vs.w.write(vs.scratch[:2])
   377  }
   378  
   379  func (vs *Visitor) uint16(major uint8, v uint16) error {
   380  	switch {
   381  	case v < uint16(len8b):
   382  		return vs.writeByte(major | uint8(v))
   383  	case v <= math.MaxUint8:
   384  		vs.scratch[0], vs.scratch[1] = major|len8b, uint8(v)
   385  		return vs.w.write(vs.scratch[:2])
   386  	default:
   387  		vs.scratch[0] = major | len16b
   388  		binary.BigEndian.PutUint16(vs.scratch[1:3], v)
   389  		return vs.w.write(vs.scratch[:3])
   390  	}
   391  }
   392  
   393  func (vs *Visitor) uint32(major uint8, v uint32) error {
   394  	switch {
   395  	case v < uint32(len8b):
   396  		return vs.writeByte(major | uint8(v))
   397  	case v <= math.MaxUint8:
   398  		vs.scratch[0], vs.scratch[1] = major|len8b, uint8(v)
   399  		return vs.w.write(vs.scratch[:2])
   400  	case v <= math.MaxUint16:
   401  		vs.scratch[0] = major | len16b
   402  		binary.BigEndian.PutUint16(vs.scratch[1:3], uint16(v))
   403  		return vs.w.write(vs.scratch[:3])
   404  	default:
   405  		vs.scratch[0] = major | len32b
   406  		binary.BigEndian.PutUint32(vs.scratch[1:5], v)
   407  		return vs.w.write(vs.scratch[:5])
   408  	}
   409  }
   410  
   411  func (vs *Visitor) uint64(major uint8, v uint64) error {
   412  	switch {
   413  	case v < uint64(len8b):
   414  		return vs.writeByte(major | uint8(v))
   415  	case v <= math.MaxUint8:
   416  		vs.scratch[0], vs.scratch[1] = major|len8b, uint8(v)
   417  		return vs.w.write(vs.scratch[:2])
   418  	case v <= math.MaxUint16:
   419  		vs.scratch[0] = major | len16b
   420  		binary.BigEndian.PutUint16(vs.scratch[1:3], uint16(v))
   421  		return vs.w.write(vs.scratch[:3])
   422  	case v <= math.MaxUint32:
   423  		vs.scratch[0] = major | len32b
   424  		binary.BigEndian.PutUint32(vs.scratch[1:5], uint32(v))
   425  		return vs.w.write(vs.scratch[:5])
   426  	default:
   427  		vs.scratch[0] = major | len64b
   428  		binary.BigEndian.PutUint64(vs.scratch[1:9], uint64(v))
   429  		return vs.w.write(vs.scratch[:9])
   430  	}
   431  }