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.hadoop.hbase.util.vint;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.OutputStream;
24  
25  import org.apache.hadoop.hbase.classification.InterfaceAudience;
26  import org.apache.hadoop.hbase.nio.ByteBuff;
27  
28  /**
29   * Simple Variable Length Integer encoding.  Left bit of 0 means we are on the last byte.  If left
30   * bit of the current byte is 1, then there is at least one more byte.
31   */
32  @InterfaceAudience.Private
33  public class UVIntTool {
34  
35    public static final byte
36      BYTE_7_RIGHT_BITS_SET = 127,
37      BYTE_LEFT_BIT_SET = -128;
38  
39    public static final long
40      INT_7_RIGHT_BITS_SET = 127,
41      INT_8TH_BIT_SET = 128;
42  
43    public static final byte[]
44      MAX_VALUE_BYTES = new byte[] { -1, -1, -1, -1, 7 };
45  
46    /********************* int -> bytes **************************/
47  
48    public static int numBytes(int in) {
49      if (in == 0) {
50        // doesn't work with the formula below
51        return 1;
52      }
53      return (38 - Integer.numberOfLeadingZeros(in)) / 7;// 38 comes from 32+(7-1)
54    }
55  
56    public static byte[] getBytes(int value) {
57      int numBytes = numBytes(value);
58      byte[] bytes = new byte[numBytes];
59      int remainder = value;
60      for (int i = 0; i < numBytes - 1; ++i) {
61        // set the left bit
62        bytes[i] = (byte) ((remainder & INT_7_RIGHT_BITS_SET) | INT_8TH_BIT_SET);
63        remainder >>= 7;
64      }
65      // do not set the left bit
66      bytes[numBytes - 1] = (byte) (remainder & INT_7_RIGHT_BITS_SET);
67      return bytes;
68    }
69  
70    public static int writeBytes(int value, OutputStream os) throws IOException {
71      int numBytes = numBytes(value);
72      int remainder = value;
73      for (int i = 0; i < numBytes - 1; ++i) {
74        // set the left bit
75        os.write((byte) ((remainder & INT_7_RIGHT_BITS_SET) | INT_8TH_BIT_SET));
76        remainder >>= 7;
77      }
78      // do not set the left bit
79      os.write((byte) (remainder & INT_7_RIGHT_BITS_SET));
80      return numBytes;
81    }
82  
83    /******************** bytes -&gt; int **************************/
84  
85    public static int getInt(ByteBuff buffer, int offset) {
86      int value = 0;
87      for (int i = 0;; ++i) {
88        byte b = buffer.get(offset + i);
89        int shifted = BYTE_7_RIGHT_BITS_SET & b;// kill leftmost bit
90        shifted <<= 7 * i;
91        value |= shifted;
92        if (b >= 0) {
93          break;
94        }
95      }
96      return value;
97    }
98  
99    public static int getInt(InputStream is) throws IOException {
100     int value = 0;
101     int i = 0;
102     int b;
103     do{
104       b = is.read();
105       int shifted = BYTE_7_RIGHT_BITS_SET & b;// kill leftmost bit
106       shifted <<= 7 * i;
107       value |= shifted;
108       ++i;
109     }while(b > Byte.MAX_VALUE);
110     return value;
111   }
112 }