github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/util/input.go (about) 1 package util 2 3 import ( 4 "errors" 5 ) 6 7 // store/DataInput.java 8 9 /* 10 Abstract base class for performing read operations of Lucene's low-level 11 data types. 12 13 DataInput may only be used from one thread, because it is not thread safe 14 (it keeps internal state like file position). To allow multithreaded use, 15 every DataInput instance must be cloned before used in another thread. 16 Subclases must therefore implement Clone(), returning a new DataInput which 17 operates on the same underlying resource, but positioned independently. 18 */ 19 type DataInput interface { 20 ReadByte() (b byte, err error) 21 ReadBytes(buf []byte) error 22 ReadShort() (n int16, err error) 23 ReadInt() (n int32, err error) 24 ReadVInt() (n int32, err error) 25 ReadLong() (n int64, err error) 26 ReadVLong() (n int64, err error) 27 ReadString() (s string, err error) 28 ReadStringStringMap() (m map[string]string, err error) 29 ReadStringSet() (m map[string]bool, err error) 30 } 31 32 type DataReader interface { 33 /* Reads and returns a single byte. */ 34 ReadByte() (b byte, err error) 35 /* Reads a specified number of bytes into an array */ 36 ReadBytes(buf []byte) error 37 /** Reads a specified number of bytes into an array at the 38 * specified offset with control over whether the read 39 * should be buffered (callers who have their own buffer 40 * should pass in "false" for useBuffer). Currently only 41 * {@link BufferedIndexInput} respects this parameter. 42 */ 43 // ReadBytesBuffered(buf []byte, useBuffer bool) error 44 } 45 46 const SKIP_BUFFER_SIZE = 1024 47 48 type DataInputImpl struct { 49 Reader DataReader 50 // This buffer is used to skip over bytes with the default 51 // implementation of skipBytes. The reason why we need to use an 52 // instance member instead of sharing a single instance across 53 // routines is that some delegating implementations of DataInput 54 // might want to reuse the provided buffer in order to e.g. update 55 // the checksum. If we shared the same buffer across routines, then 56 // another routine might update the buffer while the checksum is 57 // being computed, making it invalid. See LUCENE-5583 for more 58 // information. 59 skipBuffer []byte 60 } 61 62 func NewDataInput(spi DataReader) *DataInputImpl { 63 return &DataInputImpl{Reader: spi} 64 } 65 66 func (in *DataInputImpl) ReadBytesBuffered(buf []byte, useBuffer bool) error { 67 return in.Reader.ReadBytes(buf) 68 } 69 70 func (in *DataInputImpl) ReadShort() (n int16, err error) { 71 if b1, err := in.Reader.ReadByte(); err == nil { 72 if b2, err := in.Reader.ReadByte(); err == nil { 73 return (int16(b1) << 8) | int16(b2), nil 74 } 75 } 76 return 0, err 77 } 78 79 func (in *DataInputImpl) ReadInt() (n int32, err error) { 80 if b1, err := in.Reader.ReadByte(); err == nil { 81 if b2, err := in.Reader.ReadByte(); err == nil { 82 if b3, err := in.Reader.ReadByte(); err == nil { 83 if b4, err := in.Reader.ReadByte(); err == nil { 84 return (int32(b1) << 24) | (int32(b2) << 16) | (int32(b3) << 8) | int32(b4), nil 85 } 86 } 87 } 88 } 89 return 0, err 90 } 91 92 func (in *DataInputImpl) ReadVInt() (n int32, err error) { 93 if b, err := in.Reader.ReadByte(); err == nil { 94 n = int32(b) & 0x7F 95 if b < 128 { 96 return n, nil 97 } 98 if b, err = in.Reader.ReadByte(); err == nil { 99 n |= (int32(b) & 0x7F) << 7 100 if b < 128 { 101 return n, nil 102 } 103 if b, err = in.Reader.ReadByte(); err == nil { 104 n |= (int32(b) & 0x7F) << 14 105 if b < 128 { 106 return n, nil 107 } 108 if b, err = in.Reader.ReadByte(); err == nil { 109 n |= (int32(b) & 0x7F) << 21 110 if b < 128 { 111 return n, nil 112 } 113 if b, err = in.Reader.ReadByte(); err == nil { 114 // Warning: the next ands use 0x0F / 0xF0 - beware copy/paste errors: 115 n |= (int32(b) & 0x0F) << 28 116 117 if int32(b)&0xF0 == 0 { 118 return n, nil 119 } 120 return 0, errors.New("Invalid vInt detected (too many bits)") 121 } 122 } 123 } 124 } 125 } 126 return 0, err 127 } 128 129 func (in *DataInputImpl) ReadLong() (n int64, err error) { 130 d1, err := in.ReadInt() 131 if err != nil { 132 return 0, err 133 } 134 d2, err := in.ReadInt() 135 if err != nil { 136 return 0, err 137 } 138 return (int64(d1) << 32) | int64(d2)&0xFFFFFFFF, nil 139 } 140 141 func (in *DataInputImpl) ReadVLong() (int64, error) { 142 return in.readVLong(false) 143 } 144 145 func (in *DataInputImpl) readVLong(allowNegative bool) (n int64, err error) { 146 if b, err := in.Reader.ReadByte(); err == nil { 147 n = int64(b & 0x7F) 148 if b < 128 { 149 return n, nil 150 } 151 if b, err = in.Reader.ReadByte(); err == nil { 152 n |= (int64(b&0x7F) << 7) 153 if b < 128 { 154 return n, nil 155 } 156 if b, err = in.Reader.ReadByte(); err == nil { 157 n |= (int64(b&0x7F) << 14) 158 if b < 128 { 159 return n, nil 160 } 161 if b, err = in.Reader.ReadByte(); err == nil { 162 n |= (int64(b&0x7F) << 21) 163 if b < 128 { 164 return n, nil 165 } 166 if b, err = in.Reader.ReadByte(); err == nil { 167 n |= (int64(b&0x7F) << 28) 168 if b < 128 { 169 return n, nil 170 } 171 if b, err = in.Reader.ReadByte(); err == nil { 172 n |= (int64(b&0x7F) << 35) 173 if b < 128 { 174 return n, nil 175 } 176 if b, err = in.Reader.ReadByte(); err == nil { 177 n |= (int64(b&0x7F) << 42) 178 if b < 128 { 179 return n, nil 180 } 181 if b, err = in.Reader.ReadByte(); err == nil { 182 n |= (int64(b&0x7F) << 49) 183 if b < 128 { 184 return n, nil 185 } 186 if b, err = in.Reader.ReadByte(); err == nil { 187 n |= (int64(b&0x7F) << 56) 188 if b < 128 { 189 return n, nil 190 } 191 if allowNegative { 192 panic("niy") 193 } 194 return 0, errors.New("Invalid vLong detected (negative values disallowed)") 195 } 196 } 197 } 198 } 199 } 200 } 201 } 202 } 203 } 204 return 0, err 205 } 206 207 func (in *DataInputImpl) ReadString() (s string, err error) { 208 length, err := in.ReadVInt() 209 if err != nil { 210 return "", err 211 } 212 bytes := make([]byte, length) 213 err = in.Reader.ReadBytes(bytes) 214 return string(bytes), nil 215 } 216 217 func (in *DataInputImpl) ReadStringStringMap() (m map[string]string, err error) { 218 count, err := in.ReadInt() 219 if err != nil { 220 return nil, err 221 } 222 m = make(map[string]string) 223 for i := int32(0); i < count; i++ { 224 key, err := in.ReadString() 225 if err != nil { 226 return nil, err 227 } 228 value, err := in.ReadString() 229 if err != nil { 230 return nil, err 231 } 232 m[key] = value 233 } 234 return m, nil 235 } 236 237 func (in *DataInputImpl) ReadStringSet() (s map[string]bool, err error) { 238 count, err := in.ReadInt() 239 if err != nil { 240 return nil, err 241 } 242 s = make(map[string]bool) 243 for i := int32(0); i < count; i++ { 244 key, err := in.ReadString() 245 if err != nil { 246 return nil, err 247 } 248 s[key] = true 249 } 250 return s, nil 251 } 252 253 /* 254 Skip over numBytes bytes. The contract on this method is that it 255 should have the same behavior as reading the same number of bytes 256 into a buffer and discarding its content. Negative values of numBytes 257 are not supported. 258 */ 259 func (in *DataInputImpl) SkipBytes(numBytes int64) (err error) { 260 assert2(numBytes >= 0, "numBytes must be >= 0, got %v", numBytes) 261 if in.skipBuffer == nil { 262 in.skipBuffer = make([]byte, SKIP_BUFFER_SIZE) 263 } 264 assert(len(in.skipBuffer) == SKIP_BUFFER_SIZE) 265 var step int 266 for skipped := int64(0); skipped < numBytes; { 267 step = int(numBytes - skipped) 268 if SKIP_BUFFER_SIZE < step { 269 step = SKIP_BUFFER_SIZE 270 } 271 if err = in.ReadBytesBuffered(in.skipBuffer[:step], false); err != nil { 272 return 273 } 274 skipped += int64(step) 275 } 276 return nil 277 }