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  }