2 * Copyright 2004 The Apache Software Foundation
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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.
30 /// <author> Dmitry Serebrennikov
32 /// <version> $Id: CompoundFileReader.cs,v 1.2 2005/01/17 19:54:29 joeshaw Exp $
34 public class CompoundFileReader
: Directory
37 private sealed class FileEntry
45 private Directory directory
;
46 private System
.String fileName
;
51 private InputStream stream
;
52 private System
.Collections
.Hashtable entries
= new System
.Collections
.Hashtable();
55 public CompoundFileReader(Directory dir
, System
.String name
)
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();
76 // set length of the previous entry
77 entry
.length
= offset
- entry
.offset
;
80 entry
= new FileEntry();
81 entry
.offset
= offset
;
85 // set the length of the final entry
88 entry
.length
= stream
.Length() - entry
.offset
;
95 if (!success
&& (stream
!= null))
101 catch (System
.IO
.IOException e
)
108 public virtual Directory
GetDirectory()
113 public virtual System
.String
GetName()
118 public override void Close()
123 throw new System
.IO
.IOException("Already closed");
131 public override InputStream
OpenFile(System
.String id
)
136 throw new System
.IO
.IOException("Stream closed");
138 FileEntry entry
= (FileEntry
) entries
[id
];
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);
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.
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
];
192 throw new System
.IO
.IOException("File " + name
+ " does not exist");
196 /// <summary>Creates a new, empty file in the directory with the given name.
197 /// Returns a stream writing this file.
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
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.
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.
233 /// <param name="b">the array to read bytes into
235 /// <param name="offset">the offset in the array to start storing bytes
237 /// <param name="length">the number of bytes to read
239 public override void ReadInternal(byte[] b
, int offset
, int len
)
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.
254 /// <seealso cref="#ReadInternal(byte[],int,int)">
256 public override void SeekInternal(long pos
)
260 /// <summary>Closes the stream to futher operations. </summary>
261 public override void Close()