github.com/matrixorigin/matrixone@v1.2.0/pkg/frontend/iopackage.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package frontend 16 17 import ( 18 "encoding/binary" 19 ) 20 21 const ( 22 DefaultReadBufferSize int = 512 23 DefaultWriteBufferSize int = 512 24 ) 25 26 type IOPackage interface { 27 // IsLittleEndian the byte order 28 //true - littleEndian; false - littleEndian 29 IsLittleEndian() bool 30 31 // WriteUint8 writes an uint8 into the buffer at the position 32 // returns position + 1 33 WriteUint8([]byte, int, uint8) int 34 35 // WriteUint16 writes an uint16 into the buffer at the position 36 // returns position + 2 37 WriteUint16([]byte, int, uint16) int 38 39 // WriteUint32 writes an uint32 into the buffer at the position 40 // returns position + 4 41 WriteUint32([]byte, int, uint32) int 42 43 // WriteUint64 writes an uint64 into the buffer at the position 44 // returns position + 8 45 WriteUint64([]byte, int, uint64) int 46 47 // AppendUint8 appends an uint8 to the buffer 48 // returns the buffer 49 AppendUint8([]byte, uint8) []byte 50 51 // AppendUint16 appends an uint16 to the buffer 52 // returns the buffer 53 AppendUint16([]byte, uint16) []byte 54 55 // AppendUint32 appends an uint32 to the buffer 56 // returns the buffer 57 AppendUint32([]byte, uint32) []byte 58 59 // AppendUint64 appends an uint64 to the buffer 60 // returns the buffer 61 AppendUint64([]byte, uint64) []byte 62 63 // ReadUint8 reads an uint8 from the buffer at the position 64 // returns uint8 value ; pos+1 ; true - decoded successfully or false - failed 65 ReadUint8([]byte, int) (uint8, int, bool) 66 67 // ReadUint16 reads an uint16 from the buffer at the position 68 // returns uint16 value ; pos+2 ; true - decoded successfully or false - failed 69 ReadUint16([]byte, int) (uint16, int, bool) 70 71 // ReadUint32 reads an uint32 from the buffer at the position 72 // returns uint32 value ; pos+4 ; true - decoded successfully or false - failed 73 ReadUint32([]byte, int) (uint32, int, bool) 74 75 // ReadUint64 reads an uint64 from the buffer at the position 76 // returns uint64 value ; pos+8 ; true - decoded successfully or false - failed 77 ReadUint64([]byte, int) (uint64, int, bool) 78 } 79 80 // IOPackageImpl implements the IOPackage for the basic interaction in the connection 81 type IOPackageImpl struct { 82 //true - littleEndian; false - bigEndian 83 endian bool 84 } 85 86 func NewIOPackage(littleEndian bool) *IOPackageImpl { 87 return &IOPackageImpl{ 88 endian: littleEndian, 89 } 90 } 91 92 func (bio *IOPackageImpl) IsLittleEndian() bool { 93 return bio.endian 94 } 95 96 func (bio *IOPackageImpl) WriteUint8(data []byte, pos int, value uint8) int { 97 data[pos] = value 98 return pos + 1 99 } 100 101 func (bio *IOPackageImpl) WriteUint16(data []byte, pos int, value uint16) int { 102 if bio.endian { 103 binary.LittleEndian.PutUint16(data[pos:], value) 104 } else { 105 binary.BigEndian.PutUint16(data[pos:], value) 106 } 107 return pos + 2 108 } 109 110 func (bio *IOPackageImpl) WriteUint32(data []byte, pos int, value uint32) int { 111 if bio.endian { 112 binary.LittleEndian.PutUint32(data[pos:], value) 113 } else { 114 binary.BigEndian.PutUint32(data[pos:], value) 115 } 116 return pos + 4 117 } 118 119 func (bio *IOPackageImpl) WriteUint64(data []byte, pos int, value uint64) int { 120 if bio.endian { 121 binary.LittleEndian.PutUint64(data[pos:], value) 122 } else { 123 binary.BigEndian.PutUint64(data[pos:], value) 124 } 125 return pos + 8 126 } 127 128 func (bio *IOPackageImpl) AppendUint8(data []byte, value uint8) []byte { 129 return append(data, value) 130 } 131 132 func (bio *IOPackageImpl) AppendUint16(data []byte, value uint16) []byte { 133 tmp := make([]byte, 2) 134 bio.WriteUint16(tmp, 0, value) 135 return append(data, tmp...) 136 } 137 138 func (bio *IOPackageImpl) AppendUint32(data []byte, value uint32) []byte { 139 tmp := make([]byte, 4) 140 bio.WriteUint32(tmp, 0, value) 141 return append(data, tmp...) 142 } 143 144 func (bio *IOPackageImpl) AppendUint64(data []byte, value uint64) []byte { 145 tmp := make([]byte, 8) 146 bio.WriteUint64(tmp, 0, value) 147 return append(data, tmp...) 148 } 149 150 func (bio *IOPackageImpl) ReadUint8(data []byte, pos int) (uint8, int, bool) { 151 if pos >= len(data) { 152 return 0, 0, false 153 } 154 return data[pos], pos + 1, true 155 } 156 157 func (bio *IOPackageImpl) ReadUint16(data []byte, pos int) (uint16, int, bool) { 158 if pos+1 >= len(data) { 159 return 0, 0, false 160 } 161 if bio.endian { 162 return binary.LittleEndian.Uint16(data[pos : pos+2]), pos + 2, true 163 } else { 164 return binary.BigEndian.Uint16(data[pos : pos+2]), pos + 2, true 165 } 166 } 167 168 func (bio *IOPackageImpl) ReadUint32(data []byte, pos int) (uint32, int, bool) { 169 if pos+3 >= len(data) { 170 return 0, 0, false 171 } 172 if bio.endian { 173 return binary.LittleEndian.Uint32(data[pos : pos+4]), pos + 4, true 174 } else { 175 return binary.BigEndian.Uint32(data[pos : pos+4]), pos + 4, true 176 } 177 } 178 179 func (bio *IOPackageImpl) ReadUint64(data []byte, pos int) (uint64, int, bool) { 180 if pos+7 >= len(data) { 181 return 0, 0, false 182 } 183 if bio.endian { 184 return binary.LittleEndian.Uint64(data[pos : pos+8]), pos + 8, true 185 } else { 186 return binary.BigEndian.Uint64(data[pos : pos+8]), pos + 8, true 187 } 188 }