Lucene.Net  3.0.3
Lucene.Net is a .NET port of the Java Lucene Indexing Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties
CompoundFileReader.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System.Linq;
19 using Lucene.Net.Support;
20 using BufferedIndexInput = Lucene.Net.Store.BufferedIndexInput;
21 using Directory = Lucene.Net.Store.Directory;
22 using IndexInput = Lucene.Net.Store.IndexInput;
23 using IndexOutput = Lucene.Net.Store.IndexOutput;
24 using Lock = Lucene.Net.Store.Lock;
25 
26 namespace Lucene.Net.Index
27 {
28 
29 
35  {
36 
37  private readonly int readBufferSize;
38 
39  private sealed class FileEntry
40  {
41  internal long offset;
42  internal long length;
43  }
44 
45  private bool isDisposed;
46 
47  // Base info
48  private readonly Directory directory;
49  private readonly System.String fileName;
50 
51  private IndexInput stream;
52  private HashMap<string, FileEntry> entries = new HashMap<string, FileEntry>();
53 
54 
55  public CompoundFileReader(Directory dir, System.String name):this(dir, name, BufferedIndexInput.BUFFER_SIZE)
56  {
57  }
58 
59  public CompoundFileReader(Directory dir, System.String name, int readBufferSize)
60  {
61  directory = dir;
62  fileName = name;
63  this.readBufferSize = readBufferSize;
64 
65  bool success = false;
66 
67  try
68  {
69  stream = dir.OpenInput(name, readBufferSize);
70 
71  // read the directory and init files
72  int count = stream.ReadVInt();
73  FileEntry entry = null;
74  for (int i = 0; i < count; i++)
75  {
76  long offset = stream.ReadLong();
77  System.String id = stream.ReadString();
78 
79  if (entry != null)
80  {
81  // set length of the previous entry
82  entry.length = offset - entry.offset;
83  }
84 
85  entry = new FileEntry {offset = offset};
86  entries[id] = entry;
87  }
88 
89  // set the length of the final entry
90  if (entry != null)
91  {
92  entry.length = stream.Length() - entry.offset;
93  }
94 
95  success = true;
96  }
97  finally
98  {
99  if (!success && (stream != null))
100  {
101  try
102  {
103  stream.Close();
104  }
105  catch (System.IO.IOException)
106  {
107  }
108  }
109  }
110  }
111 
112  public virtual Directory Directory
113  {
114  get { return directory; }
115  }
116 
117  public virtual string Name
118  {
119  get { return fileName; }
120  }
121 
122  protected override void Dispose(bool disposing)
123  {
124  lock (this)
125  {
126  if (isDisposed) return;
127  if (disposing)
128  {
129  if (entries != null)
130  {
131  entries.Clear();
132  }
133  if (stream != null)
134  {
135  stream.Close();
136  }
137  }
138 
139  entries = null;
140  stream = null;
141  isDisposed = true;
142  }
143  }
144 
145  public override IndexInput OpenInput(System.String id)
146  {
147  lock (this)
148  {
149  // Default to readBufferSize passed in when we were opened
150  return OpenInput(id, readBufferSize);
151  }
152  }
153 
154  public override IndexInput OpenInput(System.String id, int readBufferSize)
155  {
156  lock (this)
157  {
158  if (stream == null)
159  throw new System.IO.IOException("Stream closed");
160 
161  FileEntry entry = entries[id];
162  if (entry == null)
163  throw new System.IO.IOException("No sub-file with id " + id + " found");
164 
165  return new CSIndexInput(stream, entry.offset, entry.length, readBufferSize);
166  }
167  }
168 
170  public override System.String[] ListAll()
171  {
172  return entries.Keys.ToArray();
173  }
174 
176  public override bool FileExists(System.String name)
177  {
178  return entries.ContainsKey(name);
179  }
180 
182  public override long FileModified(System.String name)
183  {
184  return directory.FileModified(fileName);
185  }
186 
188  public override void TouchFile(System.String name)
189  {
190  directory.TouchFile(fileName);
191  }
192 
195  public override void DeleteFile(System.String name)
196  {
197  throw new System.NotSupportedException();
198  }
199 
202  public void RenameFile(System.String from, System.String to)
203  {
204  throw new System.NotSupportedException();
205  }
206 
209  public override long FileLength(System.String name)
210  {
211  FileEntry e = entries[name];
212  if (e == null)
213  throw new System.IO.IOException("File " + name + " does not exist");
214  return e.length;
215  }
216 
219  public override IndexOutput CreateOutput(System.String name)
220  {
221  throw new System.NotSupportedException();
222  }
223 
226  public override Lock MakeLock(System.String name)
227  {
228  throw new System.NotSupportedException();
229  }
230 
236  public /*internal*/ sealed class CSIndexInput : BufferedIndexInput
237  {
238  internal IndexInput base_Renamed;
239  internal long fileOffset;
240  internal long length;
241 
242  private bool isDisposed;
243 
244  internal CSIndexInput(IndexInput @base, long fileOffset, long length):this(@base, fileOffset, length, BufferedIndexInput.BUFFER_SIZE)
245  {
246  }
247 
248  internal CSIndexInput(IndexInput @base, long fileOffset, long length, int readBufferSize):base(readBufferSize)
249  {
250  this.base_Renamed = (IndexInput) @base.Clone();
251  this.fileOffset = fileOffset;
252  this.length = length;
253  }
254 
255  public override System.Object Clone()
256  {
257  var clone = (CSIndexInput) base.Clone();
258  clone.base_Renamed = (IndexInput) base_Renamed.Clone();
259  clone.fileOffset = fileOffset;
260  clone.length = length;
261  return clone;
262  }
263 
273  public override void ReadInternal(byte[] b, int offset, int len)
274  {
275  long start = FilePointer;
276  if (start + len > length)
277  throw new System.IO.IOException("read past EOF");
278  base_Renamed.Seek(fileOffset + start);
279  base_Renamed.ReadBytes(b, offset, len, false);
280  }
281 
287  public override void SeekInternal(long pos)
288  {
289  }
290 
291  protected override void Dispose(bool disposing)
292  {
293  if (isDisposed) return;
294 
295  if (disposing)
296  {
297  if (base_Renamed != null)
298  {
299  base_Renamed.Close();
300  }
301  }
302 
303  isDisposed = true;
304  }
305 
306  public override long Length()
307  {
308  return length;
309  }
310 
311  public IndexInput base_Renamed_ForNUnit
312  {
313  get { return base_Renamed; }
314  }
315  }
316  }
317 }