This project has retired. For details please refer to its Attic page.
UnsafeReads xref
View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.giraph.utils;
20  
21  import com.esotericsoftware.kryo.io.Input;
22  
23  import java.io.IOException;
24  import java.io.UTFDataFormatException;
25  
26  /**
27   * Byte array input stream that uses Unsafe methods to deserialize
28   * much faster
29   */
30  @edu.umd.cs.findbugs.annotations.SuppressWarnings(
31    "RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT")
32  public abstract class UnsafeReads extends Input implements ExtendedDataInput {
33  
34    /**
35     * Constructor
36     *
37     * @param length buf length
38     */
39    public UnsafeReads(int length) {
40      limit = length;
41    }
42  
43    /**
44     * Constructor with offset
45     *
46     * @param offset offset in memory
47     * @param length buf length
48     */
49    public UnsafeReads(long offset, int length) {
50      position = (int) offset;
51      limit = length;
52    }
53  
54    /**
55     * How many bytes are still available?
56     *
57     * @return Number of bytes available
58     */
59    public abstract int available();
60  
61    /**
62     * What position in the stream?
63     *
64     * @return Position
65     */
66    public abstract int getPos();
67  
68    /**
69     * Check whether there are enough remaining bytes for an operation
70     *
71     * @param requiredBytes Bytes required to read
72     */
73    @Override
74    protected int require(int requiredBytes) {
75      if (available() < requiredBytes) {
76        throw new IndexOutOfBoundsException("require: Only " +
77            available() + " bytes remaining, trying to read " + requiredBytes);
78      }
79      return available();
80    }
81  
82    @Override
83    public int skipBytes(int n) {
84      require(n);
85      position += n;
86      return n;
87    }
88  
89    @Override
90    public String readLine() throws IOException {
91      // Note that this code is mostly copied from DataInputStream
92      char[] tmpBuf = new char[128];
93  
94      int room = tmpBuf.length;
95      int offset = 0;
96      int c;
97  
98    loop:
99      while (true) {
100       c = readByte();
101       switch (c) {
102       case -1:
103       case '\n':
104         break loop;
105       case '\r':
106         int c2 = readByte();
107         if ((c2 != '\n') && (c2 != -1)) {
108           position -= 1;
109         }
110         break loop;
111       default:
112         if (--room < 0) {
113           char[] replacebuf = new char[offset + 128];
114           room = replacebuf.length - offset - 1;
115           System.arraycopy(tmpBuf, 0, replacebuf, 0, offset);
116           tmpBuf = replacebuf;
117         }
118         tmpBuf[offset++] = (char) c;
119         break;
120       }
121     }
122     if ((c == -1) && (offset == 0)) {
123       return null;
124     }
125     return String.copyValueOf(tmpBuf, 0, offset);
126   }
127 
128   @Override
129   public String readUTF() throws IOException {
130     // Note that this code is mostly copied from DataInputStream
131     int utflen = readUnsignedShort();
132 
133     byte[] bytearr = new byte[utflen];
134     char[] chararr = new char[utflen];
135 
136     int c;
137     int char2;
138     int char3;
139     int count = 0;
140     int chararrCount = 0;
141 
142     readFully(bytearr, 0, utflen);
143 
144     while (count < utflen) {
145       c = (int) bytearr[count] & 0xff;
146       if (c > 127) {
147         break;
148       }
149       count++;
150       chararr[chararrCount++] = (char) c;
151     }
152 
153     while (count < utflen) {
154       c = (int) bytearr[count] & 0xff;
155       switch (c >> 4) {
156       case 0:
157       case 1:
158       case 2:
159       case 3:
160       case 4:
161       case 5:
162       case 6:
163       case 7:
164       /* 0xxxxxxx */
165         count++;
166         chararr[chararrCount++] = (char) c;
167         break;
168       case 12:
169       case 13:
170       /* 110x xxxx   10xx xxxx*/
171         count += 2;
172         if (count > utflen) {
173           throw new UTFDataFormatException(
174               "malformed input: partial character at end");
175         }
176         char2 = (int) bytearr[count - 1];
177         if ((char2 & 0xC0) != 0x80) {
178           throw new UTFDataFormatException(
179               "malformed input around byte " + count);
180         }
181         chararr[chararrCount++] = (char) (((c & 0x1F) << 6) |
182             (char2 & 0x3F));
183         break;
184       case 14:
185       /* 1110 xxxx  10xx xxxx  10xx xxxx */
186         count += 3;
187         if (count > utflen) {
188           throw new UTFDataFormatException(
189               "malformed input: partial character at end");
190         }
191         char2 = (int) bytearr[count - 2];
192         char3 = (int) bytearr[count - 1];
193         if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) {
194           throw new UTFDataFormatException(
195               "malformed input around byte " + (count - 1));
196         }
197         chararr[chararrCount++] = (char) (((c & 0x0F) << 12) |
198             ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
199         break;
200       default:
201       /* 10xx xxxx,  1111 xxxx */
202         throw new UTFDataFormatException(
203             "malformed input around byte " + count);
204       }
205     }
206     // The number of chars produced may be less than utflen
207     return new String(chararr, 0, chararrCount);
208   }
209 }