pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / java / org / apache / lucene / store / DataOutput.java
1 package org.apache.lucene.store;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.IOException;
21 import java.util.Map;
22
23 import org.apache.lucene.util.BytesRef;
24 import org.apache.lucene.util.UnicodeUtil;
25
26 /**
27  * Abstract base class for performing write operations of Lucene's low-level
28  * data types.
29  */
30 public abstract class DataOutput {
31
32   /** Writes a single byte.
33    * @see IndexInput#readByte()
34    */
35   public abstract void writeByte(byte b) throws IOException;
36
37   /** Writes an array of bytes.
38    * @param b the bytes to write
39    * @param length the number of bytes to write
40    * @see DataInput#readBytes(byte[],int,int)
41    */
42   public void writeBytes(byte[] b, int length) throws IOException {
43     writeBytes(b, 0, length);
44   }
45
46   /** Writes an array of bytes.
47    * @param b the bytes to write
48    * @param offset the offset in the byte array
49    * @param length the number of bytes to write
50    * @see DataInput#readBytes(byte[],int,int)
51    */
52   public abstract void writeBytes(byte[] b, int offset, int length) throws IOException;
53
54   /** Writes an int as four bytes.
55    * @see DataInput#readInt()
56    */
57   public void writeInt(int i) throws IOException {
58     writeByte((byte)(i >> 24));
59     writeByte((byte)(i >> 16));
60     writeByte((byte)(i >>  8));
61     writeByte((byte) i);
62   }
63
64   /** Writes an int in a variable-length format.  Writes between one and
65    * five bytes.  Smaller values take fewer bytes.  Negative numbers are not
66    * supported.
67    * @see DataInput#readVInt()
68    */
69   public final void writeVInt(int i) throws IOException {
70     while ((i & ~0x7F) != 0) {
71       writeByte((byte)((i & 0x7f) | 0x80));
72       i >>>= 7;
73     }
74     writeByte((byte)i);
75   }
76
77   /** Writes a long as eight bytes.
78    * @see DataInput#readLong()
79    */
80   public void writeLong(long i) throws IOException {
81     writeInt((int) (i >> 32));
82     writeInt((int) i);
83   }
84
85   /** Writes an long in a variable-length format.  Writes between one and nine
86    * bytes.  Smaller values take fewer bytes.  Negative numbers are not
87    * supported.
88    * @see DataInput#readVLong()
89    */
90   public final void writeVLong(long i) throws IOException {
91     while ((i & ~0x7F) != 0) {
92       writeByte((byte)((i & 0x7f) | 0x80));
93       i >>>= 7;
94     }
95     writeByte((byte)i);
96   }
97
98   /** Writes a string.
99    * @see DataInput#readString()
100    */
101   public void writeString(String s) throws IOException {
102     final BytesRef utf8Result = new BytesRef(10);
103     UnicodeUtil.UTF16toUTF8(s, 0, s.length(), utf8Result);
104     writeVInt(utf8Result.length);
105     writeBytes(utf8Result.bytes, 0, utf8Result.length);
106   }
107
108   private static int COPY_BUFFER_SIZE = 16384;
109   private byte[] copyBuffer;
110
111   /** Copy numBytes bytes from input to ourself. */
112   public void copyBytes(DataInput input, long numBytes) throws IOException {
113     assert numBytes >= 0: "numBytes=" + numBytes;
114     long left = numBytes;
115     if (copyBuffer == null)
116       copyBuffer = new byte[COPY_BUFFER_SIZE];
117     while(left > 0) {
118       final int toCopy;
119       if (left > COPY_BUFFER_SIZE)
120         toCopy = COPY_BUFFER_SIZE;
121       else
122         toCopy = (int) left;
123       input.readBytes(copyBuffer, 0, toCopy);
124       writeBytes(copyBuffer, 0, toCopy);
125       left -= toCopy;
126     }
127   }
128
129   /** Writes a sub sequence of characters from s as the old
130    *  format (modified UTF-8 encoded bytes).
131    * @param s the source of the characters
132    * @param start the first character in the sequence
133    * @param length the number of characters in the sequence
134    * @deprecated -- please pre-convert to utf8 bytes
135    * instead or use {@link #writeString}
136    */
137   @Deprecated
138   public void writeChars(String s, int start, int length)
139        throws IOException {
140     final int end = start + length;
141     for (int i = start; i < end; i++) {
142       final int code = s.charAt(i);
143       if (code >= 0x01 && code <= 0x7F)
144         writeByte((byte)code);
145       else if (((code >= 0x80) && (code <= 0x7FF)) || code == 0) {
146         writeByte((byte)(0xC0 | (code >> 6)));
147         writeByte((byte)(0x80 | (code & 0x3F)));
148       } else {
149         writeByte((byte)(0xE0 | (code >>> 12)));
150         writeByte((byte)(0x80 | ((code >> 6) & 0x3F)));
151         writeByte((byte)(0x80 | (code & 0x3F)));
152       }
153     }
154   }
155
156   /** Writes a sub sequence of characters from char[] as
157    *  the old format (modified UTF-8 encoded bytes).
158    * @param s the source of the characters
159    * @param start the first character in the sequence
160    * @param length the number of characters in the sequence
161    * @deprecated -- please pre-convert to utf8 bytes instead or use {@link #writeString}
162    */
163   @Deprecated
164   public void writeChars(char[] s, int start, int length)
165     throws IOException {
166     final int end = start + length;
167     for (int i = start; i < end; i++) {
168       final int code = s[i];
169       if (code >= 0x01 && code <= 0x7F)
170         writeByte((byte)code);
171       else if (((code >= 0x80) && (code <= 0x7FF)) || code == 0) {
172         writeByte((byte)(0xC0 | (code >> 6)));
173         writeByte((byte)(0x80 | (code & 0x3F)));
174       } else {
175         writeByte((byte)(0xE0 | (code >>> 12)));
176         writeByte((byte)(0x80 | ((code >> 6) & 0x3F)));
177         writeByte((byte)(0x80 | (code & 0x3F)));
178       }
179     }
180   }
181
182   public void writeStringStringMap(Map<String,String> map) throws IOException {
183     if (map == null) {
184       writeInt(0);
185     } else {
186       writeInt(map.size());
187       for(final Map.Entry<String, String> entry: map.entrySet()) {
188         writeString(entry.getKey());
189         writeString(entry.getValue());
190       }
191     }
192   }
193 }