001 package gate.creole.annic.apache.lucene.store;
002
003 /**
004 * Copyright 2004 The Apache Software Foundation
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 import java.io.IOException;
020
021 /** Abstract class for output to a file in a Directory. A random-access output
022 * stream. Used for all Lucene index output operations.
023 * @see Directory
024 * @see InputStream
025 */
026 public abstract class OutputStream {
027 static final int BUFFER_SIZE = 1024;
028
029 private final byte[] buffer = new byte[BUFFER_SIZE];
030 private long bufferStart = 0; // position in file of buffer
031 private int bufferPosition = 0; // position in buffer
032
033 /** Writes a single byte.
034 * @see InputStream#readByte()
035 */
036 public final void writeByte(byte b) throws IOException {
037 if (bufferPosition >= BUFFER_SIZE)
038 flush();
039 buffer[bufferPosition++] = b;
040 }
041
042 /** Writes an array of bytes.
043 * @param b the bytes to write
044 * @param length the number of bytes to write
045 * @see InputStream#readBytes(byte[],int,int)
046 */
047 public final void writeBytes(byte[] b, int length) throws IOException {
048 for (int i = 0; i < length; i++)
049 writeByte(b[i]);
050 }
051
052 /** Writes an int as four bytes.
053 * @see InputStream#readInt()
054 */
055 public final void writeInt(int i) throws IOException {
056 writeByte((byte)(i >> 24));
057 writeByte((byte)(i >> 16));
058 writeByte((byte)(i >> 8));
059 writeByte((byte) i);
060 }
061
062 /** Writes an int in a variable-length format. Writes between one and
063 * five bytes. Smaller values take fewer bytes. Negative numbers are not
064 * supported.
065 * @see InputStream#readVInt()
066 */
067 public final void writeVInt(int i) throws IOException {
068 while ((i & ~0x7F) != 0) {
069 writeByte((byte)((i & 0x7f) | 0x80));
070 i >>>= 7;
071 }
072 writeByte((byte)i);
073 }
074
075 /** Writes a long as eight bytes.
076 * @see InputStream#readLong()
077 */
078 public final void writeLong(long i) throws IOException {
079 writeInt((int) (i >> 32));
080 writeInt((int) i);
081 }
082
083 /** Writes an long in a variable-length format. Writes between one and five
084 * bytes. Smaller values take fewer bytes. Negative numbers are not
085 * supported.
086 * @see InputStream#readVLong()
087 */
088 public final void writeVLong(long i) throws IOException {
089 while ((i & ~0x7F) != 0) {
090 writeByte((byte)((i & 0x7f) | 0x80));
091 i >>>= 7;
092 }
093 writeByte((byte)i);
094 }
095
096 /** Writes a string.
097 * @see InputStream#readString()
098 */
099 public final void writeString(String s) throws IOException {
100 int length = s.length();
101 writeVInt(length);
102 writeChars(s, 0, length);
103 }
104
105 /** Writes a sequence of UTF-8 encoded characters from a string.
106 * @param s the source of the characters
107 * @param start the first character in the sequence
108 * @param length the number of characters in the sequence
109 * @see InputStream#readChars(char[],int,int)
110 */
111 public final void writeChars(String s, int start, int length)
112 throws IOException {
113 final int end = start + length;
114 for (int i = start; i < end; i++) {
115 final int code = (int)s.charAt(i);
116 if (code >= 0x01 && code <= 0x7F)
117 writeByte((byte)code);
118 else if (((code >= 0x80) && (code <= 0x7FF)) || code == 0) {
119 writeByte((byte)(0xC0 | (code >> 6)));
120 writeByte((byte)(0x80 | (code & 0x3F)));
121 } else {
122 writeByte((byte)(0xE0 | (code >>> 12)));
123 writeByte((byte)(0x80 | ((code >> 6) & 0x3F)));
124 writeByte((byte)(0x80 | (code & 0x3F)));
125 }
126 }
127 }
128
129 /** Forces any buffered output to be written. */
130 protected final void flush() throws IOException {
131 flushBuffer(buffer, bufferPosition);
132 bufferStart += bufferPosition;
133 bufferPosition = 0;
134 }
135
136 /** Expert: implements buffer write. Writes bytes at the current position in
137 * the output.
138 * @param b the bytes to write
139 * @param len the number of bytes to write
140 */
141 protected abstract void flushBuffer(byte[] b, int len) throws IOException;
142
143 /** Closes this stream to further operations. */
144 public void close() throws IOException {
145 flush();
146 }
147
148 /** Returns the current position in this file, where the next write will
149 * occur.
150 * @see #seek(long)
151 */
152 public final long getFilePointer() throws IOException {
153 return bufferStart + bufferPosition;
154 }
155
156 /** Sets current position in this file, where the next write will occur.
157 * @see #getFilePointer()
158 */
159 public void seek(long pos) throws IOException {
160 flush();
161 bufferStart = pos;
162 }
163
164 /** The number of bytes in the file. */
165 public abstract long length() throws IOException;
166
167
168 }
|