20 using Lucene.Net.Support;
 
   21 using Lucene.Net.Util;
 
   23 using Lucene.Net.Documents;
 
   29 namespace Lucene.Net.Index
 
   42         private readonly 
IndexInput cloneableFieldsStream;
 
   48         private readonly 
IndexInput cloneableIndexStream;
 
   50         private readonly 
int numTotalDocs;
 
   51         private readonly 
int size;
 
   53         private readonly 
int format;
 
   54         private readonly 
int formatSize;
 
   58         private readonly 
int docStoreOffset;
 
   61         private readonly 
bool isOriginal = 
false;
 
   69         public System.Object Clone()
 
   72             return new FieldsReader(fieldInfos, numTotalDocs, size, format, formatSize, docStoreOffset, cloneableFieldsStream, cloneableIndexStream);
 
   78             this.fieldInfos = fieldInfos;
 
   79             this.numTotalDocs = numTotalDocs;
 
   82             this.formatSize = formatSize;
 
   83             this.docStoreOffset = docStoreOffset;
 
   84             this.cloneableFieldsStream = cloneableFieldsStream;
 
   85             this.cloneableIndexStream = cloneableIndexStream;
 
   87             indexStream = (
IndexInput) cloneableIndexStream.Clone();
 
   98         internal FieldsReader(
Directory d, System.String segment, FieldInfos fn, 
int readBufferSize, 
int docStoreOffset, 
int size)
 
  100             bool success = 
false;
 
  106                 cloneableFieldsStream = d.OpenInput(segment + 
"." + IndexFileNames.FIELDS_EXTENSION, readBufferSize);
 
  107                 cloneableIndexStream = d.OpenInput(segment + 
"." + IndexFileNames.FIELDS_INDEX_EXTENSION, readBufferSize);
 
  112                 int firstInt = cloneableIndexStream.ReadInt();
 
  113                 format = firstInt == 0 ? 0 : firstInt;
 
  115                 if (format > FieldsWriter.FORMAT_CURRENT)
 
  116                     throw new CorruptIndexException(
"Incompatible format version: " + format + 
" expected " + FieldsWriter.FORMAT_CURRENT + 
" or lower");
 
  118                 formatSize = format > FieldsWriter.FORMAT ? 4 : 0;
 
  120                 if (format < FieldsWriter.FORMAT_VERSION_UTF8_LENGTH_IN_BYTES)
 
  121                     cloneableFieldsStream.SetModifiedUTF8StringsMode();
 
  123                 fieldsStream = (
IndexInput) cloneableFieldsStream.Clone();
 
  125                 long indexSize = cloneableIndexStream.Length() - formatSize;
 
  127                 if (docStoreOffset != - 1)
 
  130                     this.docStoreOffset = docStoreOffset;
 
  135                     System.Diagnostics.Debug.Assert(((
int)(indexSize / 8)) >= size + this.docStoreOffset, 
"indexSize=" + indexSize + 
" size=" + size + 
" docStoreOffset=" + docStoreOffset);
 
  139                     this.docStoreOffset = 0;
 
  140                     this.size = (int) (indexSize >> 3);
 
  143                 indexStream = (
IndexInput) cloneableIndexStream.Clone();
 
  144                 numTotalDocs = (int) (indexSize >> 3);
 
  162         internal void  EnsureOpen()
 
  175         public void Dispose()
 
  180                 if (fieldsStream != null)
 
  182                     fieldsStream.Close();
 
  186                     if (cloneableFieldsStream != null)
 
  188                         cloneableFieldsStream.Close();
 
  190                     if (cloneableIndexStream != null)
 
  192                         cloneableIndexStream.Close();
 
  195                 if (indexStream != null)
 
  199                 fieldsStreamTL.Close();
 
  209         private void  SeekIndex(
int docID)
 
  211             indexStream.Seek(formatSize + (docID + docStoreOffset) * 8L);
 
  214         internal bool CanReadRawDocs()
 
  220             return format >= FieldsWriter.FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS;
 
  226             long position = indexStream.ReadLong();
 
  227             fieldsStream.Seek(position);
 
  230             int numFields = fieldsStream.ReadVInt();
 
  231             for (
int i = 0; i < numFields; i++)
 
  233                 int fieldNumber = fieldsStream.ReadVInt();
 
  234                 FieldInfo fi = fieldInfos.FieldInfo(fieldNumber);
 
  237                 byte bits = fieldsStream.ReadByte();
 
  240                 bool compressed = (bits & 
FieldsWriter.FIELD_IS_COMPRESSED) != 0;
 
  241                 System.Diagnostics.Debug.Assert(
 
  242                     (!compressed || (format < 
FieldsWriter.FORMAT_LUCENE_3_0_NO_COMPRESSED_FIELDS)),
 
  243                     "compressed fields are only allowed in indexes of version <= 2.9");
 
  244                 bool tokenize = (bits & 
FieldsWriter.FIELD_IS_TOKENIZED) != 0;
 
  245                 bool binary = (bits & 
FieldsWriter.FIELD_IS_BINARY) != 0;
 
  250                     AddField(doc, fi, binary, compressed, tokenize);
 
  254                     AddField(doc, fi, binary, compressed, tokenize);
 
  259                     AddFieldLazy(doc, fi, binary, compressed, tokenize);
 
  263                     SkipField(binary, compressed, AddFieldSize(doc, fi, binary, compressed));
 
  267                     AddFieldSize(doc, fi, binary, compressed);
 
  272                     SkipField(binary, compressed);
 
  284         internal IndexInput RawDocs(
int[] lengths, 
int startDocID, 
int numDocs)
 
  286             SeekIndex(startDocID);
 
  287             long startOffset = indexStream.ReadLong();
 
  288             long lastOffset = startOffset;
 
  290             while (count < numDocs)
 
  293                 int docID = docStoreOffset + startDocID + count + 1;
 
  294                 System.Diagnostics.Debug.Assert(docID <= numTotalDocs);
 
  295                 if (docID < numTotalDocs)
 
  296                     offset = indexStream.ReadLong();
 
  298                     offset = fieldsStream.Length();
 
  299                 lengths[count++] = (int) (offset - lastOffset);
 
  303             fieldsStream.Seek(startOffset);
 
  311         private void  SkipField(
bool binary, 
bool compressed)
 
  313             SkipField(binary, compressed, fieldsStream.ReadVInt());
 
  316         private void  SkipField(
bool binary, 
bool compressed, 
int toRead)
 
  318             if (format >= FieldsWriter.FORMAT_VERSION_UTF8_LENGTH_IN_BYTES || binary || compressed)
 
  320                 fieldsStream.Seek(fieldsStream.FilePointer + toRead);
 
  325                 fieldsStream.SkipChars(toRead);
 
  329         private void  AddFieldLazy(
Document doc, FieldInfo fi, 
bool binary, 
bool compressed, 
bool tokenize)
 
  333                 int toRead = fieldsStream.ReadVInt();
 
  334                 long pointer = fieldsStream.FilePointer;
 
  336                 doc.
Add(
new LazyField(
this, fi.name, 
Field.
Store.YES, toRead, pointer, binary, compressed));
 
  339                 fieldsStream.Seek(pointer + toRead);
 
  344                 Field.
Index index = FieldExtensions.ToIndex(fi.isIndexed, tokenize);
 
  345                 Field.
TermVector termVector = FieldExtensions.ToTermVector(fi.storeTermVector, fi.storeOffsetWithTermVector, fi.storePositionWithTermVector);
 
  350                     int toRead = fieldsStream.ReadVInt();
 
  351                     long pointer = fieldsStream.FilePointer;
 
  352                     f = 
new LazyField(
this, fi.name, store, toRead, pointer, binary, compressed);
 
  354                     fieldsStream.Seek(pointer + toRead);
 
  360                     int length = fieldsStream.ReadVInt();
 
  361                     long pointer = fieldsStream.FilePointer;
 
  363                     if (format >= FieldsWriter.FORMAT_VERSION_UTF8_LENGTH_IN_BYTES)
 
  365                         fieldsStream.Seek(pointer + length);
 
  369                         fieldsStream.SkipChars(length);
 
  371                     f = 
new LazyField(
this, fi.name, store, index, termVector, length, pointer, binary, compressed)
 
  372                             {OmitNorms = fi.omitNorms, OmitTermFreqAndPositions = fi.omitTermFreqAndPositions};
 
  379         private void AddField(
Document doc, FieldInfo fi, 
bool binary, 
bool compressed, 
bool tokenize)
 
  384                 int toRead = fieldsStream.ReadVInt();
 
  385                 var b = 
new byte[toRead];
 
  386                 fieldsStream.ReadBytes(b, 0, b.Length);
 
  392                 Field.
Index index = FieldExtensions.ToIndex(fi.isIndexed, tokenize);
 
  393                 Field.
TermVector termVector = FieldExtensions.ToTermVector(fi.storeTermVector, fi.storeOffsetWithTermVector, fi.storePositionWithTermVector);
 
  398                     int toRead = fieldsStream.ReadVInt();
 
  400                     var b = 
new byte[toRead];
 
  401                     fieldsStream.ReadBytes(b, 0, b.Length);
 
  402                     f = 
new Field(fi.name, 
false, System.Text.Encoding.GetEncoding(
"UTF-8").GetString(Uncompress(b)), store, index,
 
  403                                   termVector) {OmitTermFreqAndPositions = fi.omitTermFreqAndPositions, OmitNorms = fi.omitNorms};
 
  407                     f = 
new Field(fi.name, 
false, fieldsStream.ReadString(), store, index, termVector)
 
  408                             {OmitTermFreqAndPositions = fi.omitTermFreqAndPositions, OmitNorms = fi.omitNorms};
 
  418         private int AddFieldSize(
Document doc, FieldInfo fi, 
bool binary, 
bool compressed)
 
  420             int size = fieldsStream.ReadVInt(), bytesize = binary || compressed?size:2 * size;
 
  421             var sizebytes = 
new byte[4];
 
  425             sizebytes[3] = (byte) bytesize;
 
  436             private void  InitBlock(FieldsReader enclosingInstance)
 
  438                 this.Enclosing_Instance = enclosingInstance;
 
  441             private FieldsReader Enclosing_Instance { 
get; 
set; }
 
  444             private long pointer;
 
  445             [Obsolete(
"Only kept for backward-compatbility with <3.0 indexes. Will be removed in 4.0.")]
 
  446             private readonly Boolean isCompressed;
 
  448             public LazyField(FieldsReader enclosingInstance, System.String name, 
Field.
Store store, 
int toRead, 
long pointer, 
bool isBinary, 
bool isCompressed):base(name, store, 
Field.Index.NO, 
Field.TermVector.NO)
 
  450                 InitBlock(enclosingInstance);
 
  451                 this.toRead = toRead;
 
  452                 this.pointer = pointer;
 
  453                 this.internalIsBinary = isBinary;
 
  455                     internalBinaryLength = toRead;
 
  457                 this.isCompressed = isCompressed;
 
  460             public LazyField(FieldsReader enclosingInstance, System.String name, 
Field.
Store store, 
Field.
Index index, 
Field.
TermVector termVector, 
int toRead, 
long pointer, 
bool isBinary, 
bool isCompressed):base(name, store, index, termVector)
 
  462                 InitBlock(enclosingInstance);
 
  463                 this.toRead = toRead;
 
  464                 this.pointer = pointer;
 
  465                 this.internalIsBinary = isBinary;
 
  467                     internalBinaryLength = toRead;
 
  469                 this.isCompressed = isCompressed;
 
  474                 IndexInput localFieldsStream = Enclosing_Instance.fieldsStreamTL.Get();
 
  475                 if (localFieldsStream == null)
 
  477                     localFieldsStream = (
IndexInput) Enclosing_Instance.cloneableFieldsStream.Clone();
 
  478                     Enclosing_Instance.fieldsStreamTL.Set(localFieldsStream);
 
  480                 return localFieldsStream;
 
  487             public override TextReader ReaderValue
 
  491                     Enclosing_Instance.EnsureOpen();
 
  504                     Enclosing_Instance.EnsureOpen();
 
  513             public override string StringValue
 
  517                     Enclosing_Instance.EnsureOpen();
 
  518                     if (internalIsBinary)
 
  521                     if (fieldsData == null)
 
  523                         IndexInput localFieldsStream = GetFieldStream();
 
  526                             localFieldsStream.Seek(pointer);
 
  529                                 var b = 
new byte[toRead];
 
  530                                 localFieldsStream.ReadBytes(b, 0, b.Length);
 
  532                                     System.Text.Encoding.GetEncoding(
"UTF-8").GetString(Enclosing_Instance.Uncompress(b));
 
  536                                 if (Enclosing_Instance.format >= FieldsWriter.FORMAT_VERSION_UTF8_LENGTH_IN_BYTES)
 
  538                                     var bytes = 
new byte[toRead];
 
  539                                     localFieldsStream.ReadBytes(bytes, 0, toRead);
 
  540                                     fieldsData = System.Text.Encoding.GetEncoding(
"UTF-8").GetString(bytes);
 
  545                                     var chars = 
new char[toRead];
 
  546                                     localFieldsStream.ReadChars(chars, 0, toRead);
 
  547                                     fieldsData = 
new System.String(chars);
 
  551                         catch (System.IO.IOException e)
 
  553                             throw new FieldReaderException(e);
 
  556                     return (System.String) fieldsData;
 
  564                     Enclosing_Instance.EnsureOpen();
 
  569                     Enclosing_Instance.EnsureOpen();
 
  570                     this.pointer = value;
 
  578                     Enclosing_Instance.EnsureOpen();
 
  583                     Enclosing_Instance.EnsureOpen();
 
  588             public override byte[] GetBinaryValue(byte[] result)
 
  590                 Enclosing_Instance.EnsureOpen();
 
  592                 if (internalIsBinary)
 
  594                     if (fieldsData == null)
 
  598                         if (result == null || result.Length < toRead)
 
  599                             b = 
new byte[toRead];
 
  603                         IndexInput localFieldsStream = GetFieldStream();
 
  609                             localFieldsStream.Seek(pointer);
 
  610                             localFieldsStream.ReadBytes(b, 0, toRead);
 
  611                             fieldsData = isCompressed ? Enclosing_Instance.Uncompress(b) : b;
 
  613                         catch (IOException e)
 
  615                             throw new FieldReaderException(e);
 
  618                         internalbinaryOffset = 0;
 
  619                         internalBinaryLength = toRead;
 
  622                     return (byte[]) fieldsData;
 
  628         private byte[] Uncompress(byte[] b)