2 using System
.Collections
;
3 using System
.Runtime
.CompilerServices
;
5 using Lucene
.Net
.Store
;
7 namespace Lucene
.Net
.Index
9 /* ====================================================================
10 * The Apache Software License, Version 1.1
12 * Copyright (c) 2001 The Apache Software Foundation. All rights
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in
24 * the documentation and/or other materials provided with the
27 * 3. The end-user documentation included with the redistribution,
28 * if any, must include the following acknowledgment:
29 * "This product includes software developed by the
30 * Apache Software Foundation (http://www.apache.org/)."
31 * Alternately, this acknowledgment may appear in the software itself,
32 * if and wherever such third-party acknowledgments normally appear.
34 * 4. The names "Apache" and "Apache Software Foundation" and
35 * "Apache Lucene" must not be used to endorse or promote products
36 * derived from this software without prior written permission. For
37 * written permission, please contact apache@apache.org.
39 * 5. Products derived from this software may not be called "Apache",
40 * "Apache Lucene", nor may "Apache" appear in their name, without
41 * prior written permission of the Apache Software Foundation.
43 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
44 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
45 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
47 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
50 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
52 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
53 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * ====================================================================
57 * This software consists of voluntary contributions made by many
58 * individuals on behalf of the Apache Software Foundation. For more
59 * information on the Apache Software Foundation, please see
60 * <http://www.apache.org/>.
64 /// Class for accessing a compound stream.
65 /// This class implements a directory, but is limited to only read operations.
66 /// Directory methods that would normally modify data throw an exception.
67 /// @author Dmitry Serebrennikov
68 /// @version $Id: CompoundFileReader.cs,v 1.1.1.1 2004/04/29 22:53:51 trow Exp $
70 public class CompoundFileReader
: Directory
73 private sealed class FileEntry
80 private Directory directory
;
81 private String fileName
;
86 private InputStream stream
;
87 private Hashtable entries
= new Hashtable();
90 public CompoundFileReader(Directory dir
, String name
)
99 stream
= dir
.OpenFile(name
);
101 // read the directory and init files
102 int count
= stream
.ReadVInt();
103 FileEntry entry
= null;
105 for (int i
=0; i
<count
; i
++)
107 long offset
= stream
.ReadLong();
108 String id
= stream
.ReadString();
112 // set length of the previous entry
113 entry
.length
= offset
- entry
.offset
;
116 entry
= new FileEntry();
117 entry
.offset
= offset
;
118 entries
.Add(id
, entry
);
121 // set the length of the final entry
124 entry
.length
= stream
.Length() - entry
.offset
;
138 catch (System
.IO
.IOException
) { }
143 public Directory
GetDirectory()
148 public String
GetName()
153 [MethodImpl(MethodImplOptions
.Synchronized
)]
154 public override void Close()
157 throw new System
.IO
.IOException("Already closed");
164 [MethodImpl(MethodImplOptions
.Synchronized
)]
165 public override InputStream
OpenFile(String id
)
168 throw new System
.IO
.IOException("Stream closed");
170 FileEntry entry
= (FileEntry
) entries
[id
];
172 throw new System
.IO
.IOException("No sub-file with id " + id
+ " found");
174 return new CSInputStream(stream
, entry
.offset
, entry
.length
);
178 /// Returns an array of strings, one for each file in the directory.
180 public override String
[] List()
182 String
[] res
= new String
[entries
.Count
];
183 entries
.Keys
.CopyTo(res
, 0);
188 /// Returns true iff a file with the given name exists.
190 public override bool FileExists(String name
)
192 return entries
.ContainsKey(name
);
196 /// Returns the time the named file was last modified.
198 public override long FileModified(String name
)
200 return directory
.FileModified(fileName
);
204 /// Set the modified time of an existing file to now.
206 /// <param name="name"></param>
207 public override void TouchFile(String name
)
209 directory
.TouchFile(fileName
);
213 /// Removes an existing file in the directory.
215 public override void DeleteFile(String name
)
217 throw new InvalidOperationException();
221 /// Renames an existing file in the directory.
222 /// If a file already exists with the new name, then it is replaced.
223 /// This replacement should be atomic. */
225 public override void RenameFile(String
from, String to
)
227 throw new InvalidOperationException();
231 /// Returns the length of a file in the directory.
233 public override long FileLength(String name
)
235 FileEntry e
= (FileEntry
) entries
[name
];
237 throw new System
.IO
.IOException("File " + name
+ " does not exist");
242 /// Creates a new, empty file in the directory with the given name.
244 /// <param name="name"></param>
245 /// <returns>a stream writing the file.</returns>
246 public override OutputStream
CreateFile(String name
)
248 throw new InvalidOperationException();
252 /// Construct a {@link Lock}.
254 /// <param name="name"></param>
255 /// <returns>the name of the lock file</returns>
256 public override Lock
MakeLock(String name
)
258 throw new InvalidOperationException();
262 /// Implementation of an InputStream that reads from a portion of the
263 /// compound file. The visibility is left as "package" *only* because
264 /// this helps with testing since JUnit test cases in a different class
265 /// can then access package fields of this class.
267 public sealed class CSInputStream
: InputStream
270 internal InputStream _base
;
271 internal long fileOffset
;
273 internal CSInputStream( InputStream _base
,
277 this._base
= (InputStream
) _base
.Clone();
278 this.fileOffset
= fileOffset
;
279 this.length
= length
; // variable in the superclass
280 SeekInternal(0); // position to the adjusted 0th byte
284 /// Expert: implements buffer refill. Reads bytes from the current position in the input.
286 /// <param name="b">the array to read bytes into</param>
287 /// <param name="offset">the offset in the array to start storing bytes</param>
288 /// <param name="len">the number of bytes to read</param>
289 protected override void ReadInternal(byte[] b
, int offset
, int len
)
291 _base
.ReadBytes(b
, offset
, len
);
295 /// Expert: implements seek. Sets current position in this file, where
296 /// the next ReadInternal(byte[],int,int) will occur.
297 /// <see>ReadInternal(byte[],int,int)</see>
299 /// <param name="pos"></param>
300 protected override void SeekInternal(long pos
)
302 if (pos
> 0 && pos
>= length
)
303 throw new System
.IO
.IOException("Seek past the end of file");
306 throw new System
.IO
.IOException("Seek to a negative offset");
308 _base
.Seek(fileOffset
+ pos
);
312 /// Closes the stream to futher operations.
314 public override void Close()
320 /// <p>Clones of a stream access the same data, and are positioned at the same
321 /// point as the stream they were cloned from.</p>p>
323 /// <p>Expert: Subclasses must ensure that clones may be positioned at
324 /// different points in the input from each other and from the stream they
325 /// were cloned from.</p>p>
327 /// <returns>clone of this stream</returns>
328 public override Object
Clone()
330 CSInputStream other
= (CSInputStream
) base.Clone();
331 other
._base
= (InputStream
) _base
.Clone();