github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/common/sink/zero_copy_source.go (about)

     1  package sink
     2  
     3  import (
     4  	"encoding/binary"
     5  	"errors"
     6  
     7  	"github.com/sixexorg/magnetic-ring/common"
     8  )
     9  
    10  var ErrIrregularData = errors.New("irregular data")
    11  
    12  type ZeroCopySource struct {
    13  	s   []byte
    14  	off uint64 // current reading index
    15  }
    16  
    17  func (self *ZeroCopySource) RestBytes() []byte {
    18  	return self.s[self.off:]
    19  }
    20  
    21  // Len returns the number of bytes of the unread portion of the
    22  // slice.
    23  func (self *ZeroCopySource) Len() uint64 {
    24  	length := uint64(len(self.s))
    25  	if self.off >= length {
    26  		return 0
    27  	}
    28  	return length - self.off
    29  }
    30  
    31  func (self *ZeroCopySource) Pos() uint64 {
    32  	return self.off
    33  }
    34  
    35  // Size returns the original length of the underlying byte slice.
    36  // Size is the number of bytes available for reading via ReadAt.
    37  // The returned value is always the same and is not affected by calls
    38  // to any other method.
    39  func (self *ZeroCopySource) Size() uint64 { return uint64(len(self.s)) }
    40  
    41  // Read implements the io.ZeroCopySource interface.
    42  func (self *ZeroCopySource) NextBytes(n uint64) (data []byte, eof bool) {
    43  	m := uint64(len(self.s))
    44  	end, overflow := SafeAdd(self.off, n)
    45  	if overflow || end > m {
    46  		end = m
    47  		eof = true
    48  	}
    49  	data = self.s[self.off:end]
    50  	self.off = end
    51  
    52  	return
    53  }
    54  
    55  func (self *ZeroCopySource) Skip(n uint64) (eof bool) {
    56  	m := uint64(len(self.s))
    57  	end, overflow := SafeAdd(self.off, n)
    58  	if overflow || end > m {
    59  		end = m
    60  		eof = true
    61  	}
    62  	self.off = end
    63  
    64  	return
    65  }
    66  
    67  // ReadByte implements the io.ByteReader interface.
    68  func (self *ZeroCopySource) NextByte() (data byte, eof bool) {
    69  	if self.off >= uint64(len(self.s)) {
    70  		return 0, true
    71  	}
    72  
    73  	b := self.s[self.off]
    74  	self.off++
    75  	return b, false
    76  }
    77  
    78  func (self *ZeroCopySource) NextUint8() (data uint8, eof bool) {
    79  	var val byte
    80  	val, eof = self.NextByte()
    81  	return uint8(val), eof
    82  }
    83  
    84  func (self *ZeroCopySource) NextBool() (data bool, irregular bool, eof bool) {
    85  	val, eof := self.NextByte()
    86  	if val == 0 {
    87  		data = false
    88  	} else if val == 1 {
    89  		data = true
    90  	} else {
    91  		data = true
    92  		irregular = true
    93  	}
    94  
    95  	return
    96  }
    97  
    98  // Backs up a number of bytes, so that the next call to NextXXX() returns data again
    99  // that was already returned by the last call to NextXXX().
   100  func (self *ZeroCopySource) BackUp(n uint64) {
   101  	self.off -= n
   102  }
   103  
   104  func (self *ZeroCopySource) NextUint16() (data uint16, eof bool) {
   105  	var buf []byte
   106  	buf, eof = self.NextBytes(2)
   107  	if eof {
   108  		return
   109  	}
   110  
   111  	return binary.LittleEndian.Uint16(buf), eof
   112  }
   113  
   114  func (self *ZeroCopySource) NextUint32() (data uint32, eof bool) {
   115  	var buf []byte
   116  	buf, eof = self.NextBytes(4)
   117  	if eof {
   118  		return
   119  	}
   120  
   121  	return binary.LittleEndian.Uint32(buf), eof
   122  }
   123  
   124  func (self *ZeroCopySource) NextUint64() (data uint64, eof bool) {
   125  	var buf []byte
   126  	buf, eof = self.NextBytes(8)
   127  	if eof {
   128  		return
   129  	}
   130  
   131  	return binary.LittleEndian.Uint64(buf), eof
   132  }
   133  
   134  func (self *ZeroCopySource) NextInt32() (data int32, eof bool) {
   135  	var val uint32
   136  	val, eof = self.NextUint32()
   137  	return int32(val), eof
   138  }
   139  
   140  func (self *ZeroCopySource) NextInt64() (data int64, eof bool) {
   141  	var val uint64
   142  	val, eof = self.NextUint64()
   143  	return int64(val), eof
   144  }
   145  
   146  func (self *ZeroCopySource) NextInt16() (data int16, eof bool) {
   147  	var val uint16
   148  	val, eof = self.NextUint16()
   149  	return int16(val), eof
   150  }
   151  
   152  func (self *ZeroCopySource) NextVarBytes() (data []byte, size uint64, irregular bool, eof bool) {
   153  	var count uint64
   154  	count, size, irregular, eof = self.NextVarUint()
   155  	size += count
   156  
   157  	data, eof = self.NextBytes(count)
   158  
   159  	return
   160  }
   161  
   162  func (self *ZeroCopySource) NextAddress() (data common.Address, eof bool) {
   163  	var buf []byte
   164  	buf, eof = self.NextBytes(common.AddrLength)
   165  	if eof {
   166  		return
   167  	}
   168  	copy(data[:], buf)
   169  	return
   170  }
   171  func (self *ZeroCopySource) NextSymbol() (data common.Symbol, eof bool) {
   172  	var buf []byte
   173  	buf, eof = self.NextBytes(common.SymbolLen)
   174  	if eof {
   175  		return
   176  	}
   177  	copy(data[:], buf)
   178  	return
   179  }
   180  
   181  func (self *ZeroCopySource) NextHash() (data common.Hash, eof bool) {
   182  	var buf []byte
   183  	buf, eof = self.NextBytes(common.HashLength)
   184  	if eof {
   185  		return
   186  	}
   187  	copy(data[:], buf)
   188  
   189  	return
   190  }
   191  
   192  func (self *ZeroCopySource) NextString() (data string, size uint64, irregular bool, eof bool) {
   193  	var val []byte
   194  	val, size, irregular, eof = self.NextVarBytes()
   195  	data = string(val)
   196  	return
   197  }
   198  
   199  func (self *ZeroCopySource) NextVarUint() (data uint64, size uint64, irregular bool, eof bool) {
   200  	var fb byte
   201  	fb, eof = self.NextByte()
   202  	if eof {
   203  		return
   204  	}
   205  
   206  	switch fb {
   207  	case 0xFD:
   208  		val, e := self.NextUint16()
   209  		if e {
   210  			return
   211  		}
   212  		data = uint64(val)
   213  		size = 3
   214  	case 0xFE:
   215  		val, e := self.NextUint32()
   216  		if e {
   217  			return
   218  		}
   219  		data = uint64(val)
   220  		size = 5
   221  	case 0xFF:
   222  		val, e := self.NextUint64()
   223  		if e {
   224  			return
   225  		}
   226  		data = uint64(val)
   227  		size = 9
   228  	default:
   229  		data = uint64(fb)
   230  		size = 1
   231  	}
   232  
   233  	irregular = size != getVarUintSize(data)
   234  
   235  	return
   236  }
   237  func (self *ZeroCopySource) NextComplex() (data *ComplexType, eof bool) {
   238  	data = &ComplexType{}
   239  	var (
   240  		sizeBuf []byte
   241  		typeBuf byte
   242  	)
   243  	sizeBuf, eof = self.NextBytes(2)
   244  	if eof {
   245  		return
   246  	}
   247  	data.Size = [2]byte{sizeBuf[0], sizeBuf[1]}
   248  	typeBuf, eof = self.NextByte()
   249  	if eof {
   250  		return
   251  	}
   252  	data.MType = typeBuf
   253  	u16 := common.BytesToUint16(sizeBuf)
   254  	data.Data, eof = self.NextBytes(uint64(u16))
   255  	return
   256  }
   257  
   258  func getVarUintSize(value uint64) uint64 {
   259  	if value < 0xfd {
   260  		return 1
   261  	} else if value <= 0xffff {
   262  		return 3
   263  	} else if value <= 0xFFFFFFFF {
   264  		return 5
   265  	} else {
   266  		return 9
   267  	}
   268  }
   269  
   270  // NewReader returns a new ZeroCopySource reading from b.
   271  func NewZeroCopySource(b []byte) *ZeroCopySource { return &ZeroCopySource{b, 0} }