Thumbnail file hits. Based on a patch from D Bera
[beagle.git] / beagled / Lucene.Net / Index / CompoundFileReader.cs
blob92fe18fcb68f27408a9097abe1b70bba66ae89ee
1 /*
2 * Copyright 2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 using System;
17 using Directory = Lucene.Net.Store.Directory;
18 using InputStream = Lucene.Net.Store.InputStream;
19 using Lock = Lucene.Net.Store.Lock;
20 using OutputStream = Lucene.Net.Store.OutputStream;
21 namespace Lucene.Net.Index
25 /// <summary> Class for accessing a compound stream.
26 /// This class implements a directory, but is limited to only read operations.
27 /// Directory methods that would normally modify data throw an exception.
28 ///
29 /// </summary>
30 /// <author> Dmitry Serebrennikov
31 /// </author>
32 /// <version> $Id: CompoundFileReader.cs,v 1.2 2005/01/17 19:54:29 joeshaw Exp $
33 /// </version>
34 public class CompoundFileReader : Directory
37 private sealed class FileEntry
39 internal long offset;
40 internal long length;
44 // Base info
45 private Directory directory;
46 private System.String fileName;
48 // Reference count
49 private bool open;
51 private InputStream stream;
52 private System.Collections.Hashtable entries = new System.Collections.Hashtable();
55 public CompoundFileReader(Directory dir, System.String name)
57 directory = dir;
58 fileName = name;
60 bool success = false;
62 try
64 stream = dir.OpenFile(name);
66 // read the directory and init files
67 int count = stream.ReadVInt();
68 FileEntry entry = null;
69 for (int i = 0; i < count; i++)
71 long offset = stream.ReadLong();
72 System.String id = stream.ReadString();
74 if (entry != null)
76 // set length of the previous entry
77 entry.length = offset - entry.offset;
80 entry = new FileEntry();
81 entry.offset = offset;
82 entries[id] = entry;
85 // set the length of the final entry
86 if (entry != null)
88 entry.length = stream.Length() - entry.offset;
91 success = true;
93 finally
95 if (!success && (stream != null))
97 try
99 stream.Close();
101 catch (System.IO.IOException e)
108 public virtual Directory GetDirectory()
110 return directory;
113 public virtual System.String GetName()
115 return fileName;
118 public override void Close()
120 lock (this)
122 if (stream == null)
123 throw new System.IO.IOException("Already closed");
125 entries.Clear();
126 stream.Close();
127 stream = null;
131 public override InputStream OpenFile(System.String id)
133 lock (this)
135 if (stream == null)
136 throw new System.IO.IOException("Stream closed");
138 FileEntry entry = (FileEntry) entries[id];
139 if (entry == null)
140 throw new System.IO.IOException("No sub-file with id " + id + " found");
142 return new CSInputStream(stream, entry.offset, entry.length);
146 /// <summary>Returns an array of strings, one for each file in the directory. </summary>
147 public override System.String[] List()
149 System.String[] res = new System.String[entries.Count];
150 entries.Keys.CopyTo(res, 0);
151 return res;
154 /// <summary>Returns true iff a file with the given name exists. </summary>
155 public override bool FileExists(System.String name)
157 return entries.ContainsKey(name);
160 /// <summary>Returns the time the named file was last modified. </summary>
161 public override long FileModified(System.String name)
163 return directory.FileModified(fileName);
166 /// <summary>Set the modified time of an existing file to now. </summary>
167 public override void TouchFile(System.String name)
169 directory.TouchFile(fileName);
172 /// <summary>Removes an existing file in the directory. </summary>
173 public override void DeleteFile(System.String name)
175 throw new System.NotSupportedException();
178 /// <summary>Renames an existing file in the directory.
179 /// If a file already exists with the new name, then it is replaced.
180 /// This replacement should be atomic.
181 /// </summary>
182 public override void RenameFile(System.String from, System.String to)
184 throw new System.NotSupportedException();
187 /// <summary>Returns the length of a file in the directory. </summary>
188 public override long FileLength(System.String name)
190 FileEntry e = (FileEntry) entries[name];
191 if (e == null)
192 throw new System.IO.IOException("File " + name + " does not exist");
193 return e.length;
196 /// <summary>Creates a new, empty file in the directory with the given name.
197 /// Returns a stream writing this file.
198 /// </summary>
199 public override OutputStream CreateFile(System.String name)
201 throw new System.NotSupportedException();
204 /// <summary>Construct a {@link Lock}.</summary>
205 /// <param name="name">the name of the lock file
206 /// </param>
207 public override Lock MakeLock(System.String name)
209 throw new System.NotSupportedException();
212 /// <summary>Implementation of an InputStream that reads from a portion of the
213 /// compound file. The visibility is left as "package" *only* because
214 /// this helps with testing since JUnit test cases in a different class
215 /// can then access package fields of this class.
216 /// </summary>
217 public /*internal*/ sealed class CSInputStream : InputStream
220 public /*internal*/ InputStream base_Renamed;
221 internal long fileOffset;
223 internal CSInputStream(InputStream base_Renamed, long fileOffset, long length)
225 this.base_Renamed = base_Renamed;
226 this.fileOffset = fileOffset;
227 this.length = length; // variable in the superclass
230 /// <summary>Expert: implements buffer refill. Reads bytes from the current
231 /// position in the input.
232 /// </summary>
233 /// <param name="b">the array to read bytes into
234 /// </param>
235 /// <param name="offset">the offset in the array to start storing bytes
236 /// </param>
237 /// <param name="length">the number of bytes to read
238 /// </param>
239 public override void ReadInternal(byte[] b, int offset, int len)
241 lock (base_Renamed)
243 long start = GetFilePointer();
244 if (start + len > length)
245 throw new System.IO.IOException("read past EOF");
246 base_Renamed.Seek(fileOffset + start);
247 base_Renamed.ReadBytes(b, offset, len);
251 /// <summary>Expert: implements seek. Sets current position in this file, where
252 /// the next {@link #ReadInternal(byte[],int,int)} will occur.
253 /// </summary>
254 /// <seealso cref="#ReadInternal(byte[],int,int)">
255 /// </seealso>
256 public override void SeekInternal(long pos)
260 /// <summary>Closes the stream to futher operations. </summary>
261 public override void Close()