OutputStream.java
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 bthrows 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 lengththrows 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 ithrows IOException {
056     writeByte((byte)(i >> 24));
057     writeByte((byte)(i >> 16));
058     writeByte((byte)(i >>  8));
059     writeByte((bytei);
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 ithrows IOException {
068     while ((i & ~0x7F!= 0) {
069       writeByte((byte)((i & 0x7f0x80));
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 ithrows IOException {
079     writeInt((int) (i >> 32));
080     writeInt((inti);
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 ithrows IOException {
089     while ((i & ~0x7F!= 0) {
090       writeByte((byte)((i & 0x7f0x80));
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 sthrows 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 = 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 >> 60x3F)));
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 lenthrows 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 posthrows 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 }