001: package org.apache.lucene.store;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import java.io.IOException;
021:
022: /** Abstract base class for output to a file in a Directory. A random-access
023: * output stream. Used for all Lucene index output operations.
024: * @see Directory
025: * @see IndexInput
026: */
027: public abstract class IndexOutput {
028:
029: /** Writes a single byte.
030: * @see IndexInput#readByte()
031: */
032: public abstract void writeByte(byte b) throws IOException;
033:
034: /** Writes an array of bytes.
035: * @param b the bytes to write
036: * @param length the number of bytes to write
037: * @see IndexInput#readBytes(byte[],int,int)
038: */
039: public void writeBytes(byte[] b, int length) throws IOException {
040: writeBytes(b, 0, length);
041: }
042:
043: /** Writes an array of bytes.
044: * @param b the bytes to write
045: * @param offset the offset in the byte array
046: * @param length the number of bytes to write
047: * @see IndexInput#readBytes(byte[],int,int)
048: */
049: public abstract void writeBytes(byte[] b, int offset, int length)
050: throws IOException;
051:
052: /** Writes an int as four bytes.
053: * @see IndexInput#readInt()
054: */
055: public 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 IndexInput#readVInt()
066: */
067: public 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 IndexInput#readLong()
077: */
078: public 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 IndexInput#readVLong()
087: */
088: public 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 IndexInput#readString()
098: */
099: public 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 IndexInput#readChars(char[],int,int)
110: */
111: public 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: /** Writes a sequence of UTF-8 encoded characters from a char[].
130: * @param s the source of the characters
131: * @param start the first character in the sequence
132: * @param length the number of characters in the sequence
133: * @see IndexInput#readChars(char[],int,int)
134: */
135: public void writeChars(char[] s, int start, int length)
136: throws IOException {
137: final int end = start + length;
138: for (int i = start; i < end; i++) {
139: final int code = (int) s[i];
140: if (code >= 0x01 && code <= 0x7F)
141: writeByte((byte) code);
142: else if (((code >= 0x80) && (code <= 0x7FF)) || code == 0) {
143: writeByte((byte) (0xC0 | (code >> 6)));
144: writeByte((byte) (0x80 | (code & 0x3F)));
145: } else {
146: writeByte((byte) (0xE0 | (code >>> 12)));
147: writeByte((byte) (0x80 | ((code >> 6) & 0x3F)));
148: writeByte((byte) (0x80 | (code & 0x3F)));
149: }
150: }
151: }
152:
153: private static int COPY_BUFFER_SIZE = 16384;
154: private byte[] copyBuffer;
155:
156: /** Copy numBytes bytes from input to ourself. */
157: public void copyBytes(IndexInput input, long numBytes)
158: throws IOException {
159: long left = numBytes;
160: if (copyBuffer == null)
161: copyBuffer = new byte[COPY_BUFFER_SIZE];
162: while (left > 0) {
163: final int toCopy;
164: if (left > COPY_BUFFER_SIZE)
165: toCopy = COPY_BUFFER_SIZE;
166: else
167: toCopy = (int) left;
168: input.readBytes(copyBuffer, 0, toCopy);
169: writeBytes(copyBuffer, 0, toCopy);
170: left -= toCopy;
171: }
172: }
173:
174: /** Forces any buffered output to be written. */
175: public abstract void flush() throws IOException;
176:
177: /** Closes this stream to further operations. */
178: public abstract void close() throws IOException;
179:
180: /** Returns the current position in this file, where the next write will
181: * occur.
182: * @see #seek(long)
183: */
184: public abstract long getFilePointer();
185:
186: /** Sets current position in this file, where the next write will occur.
187: * @see #getFilePointer()
188: */
189: public abstract void seek(long pos) throws IOException;
190:
191: /** The number of bytes in the file. */
192: public abstract long length() throws IOException;
193:
194: }
|