001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. 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 package org.apache.hadoop.record; 020 021 import java.io.UnsupportedEncodingException; 022 023 import org.apache.hadoop.classification.InterfaceAudience; 024 import org.apache.hadoop.classification.InterfaceStability; 025 026 /** 027 * A byte sequence that is used as a Java native type for buffer. 028 * It is resizable and distinguishes between the count of the seqeunce and 029 * the current capacity. 030 * 031 * @deprecated Replaced by <a href="https://hadoop.apache.org/avro/">Avro</a>. 032 */ 033 @Deprecated 034 @InterfaceAudience.Public 035 @InterfaceStability.Stable 036 public class Buffer implements Comparable, Cloneable { 037 /** Number of valid bytes in this.bytes. */ 038 private int count; 039 /** Backing store for Buffer. */ 040 private byte[] bytes = null; 041 042 /** 043 * Create a zero-count sequence. 044 */ 045 public Buffer() { 046 this.count = 0; 047 } 048 049 /** 050 * Create a Buffer using the byte array as the initial value. 051 * 052 * @param bytes This array becomes the backing storage for the object. 053 */ 054 public Buffer(byte[] bytes) { 055 this.bytes = bytes; 056 this.count = (bytes == null) ? 0 : bytes.length; 057 } 058 059 /** 060 * Create a Buffer using the byte range as the initial value. 061 * 062 * @param bytes Copy of this array becomes the backing storage for the object. 063 * @param offset offset into byte array 064 * @param length length of data 065 */ 066 public Buffer(byte[] bytes, int offset, int length) { 067 copy(bytes, offset, length); 068 } 069 070 071 /** 072 * Use the specified bytes array as underlying sequence. 073 * 074 * @param bytes byte sequence 075 */ 076 public void set(byte[] bytes) { 077 this.count = (bytes == null) ? 0 : bytes.length; 078 this.bytes = bytes; 079 } 080 081 /** 082 * Copy the specified byte array to the Buffer. Replaces the current buffer. 083 * 084 * @param bytes byte array to be assigned 085 * @param offset offset into byte array 086 * @param length length of data 087 */ 088 public final void copy(byte[] bytes, int offset, int length) { 089 if (this.bytes == null || this.bytes.length < length) { 090 this.bytes = new byte[length]; 091 } 092 System.arraycopy(bytes, offset, this.bytes, 0, length); 093 this.count = length; 094 } 095 096 /** 097 * Get the data from the Buffer. 098 * 099 * @return The data is only valid between 0 and getCount() - 1. 100 */ 101 public byte[] get() { 102 if (bytes == null) { 103 bytes = new byte[0]; 104 } 105 return bytes; 106 } 107 108 /** 109 * Get the current count of the buffer. 110 */ 111 public int getCount() { 112 return count; 113 } 114 115 /** 116 * Get the capacity, which is the maximum count that could handled without 117 * resizing the backing storage. 118 * 119 * @return The number of bytes 120 */ 121 public int getCapacity() { 122 return this.get().length; 123 } 124 125 /** 126 * Change the capacity of the backing storage. 127 * The data is preserved if newCapacity >= getCount(). 128 * @param newCapacity The new capacity in bytes. 129 */ 130 public void setCapacity(int newCapacity) { 131 if (newCapacity < 0) { 132 throw new IllegalArgumentException("Invalid capacity argument "+newCapacity); 133 } 134 if (newCapacity == 0) { 135 this.bytes = null; 136 this.count = 0; 137 return; 138 } 139 if (newCapacity != getCapacity()) { 140 byte[] data = new byte[newCapacity]; 141 if (newCapacity < count) { 142 count = newCapacity; 143 } 144 if (count != 0) { 145 System.arraycopy(this.get(), 0, data, 0, count); 146 } 147 bytes = data; 148 } 149 } 150 151 /** 152 * Reset the buffer to 0 size 153 */ 154 public void reset() { 155 setCapacity(0); 156 } 157 158 /** 159 * Change the capacity of the backing store to be the same as the current 160 * count of buffer. 161 */ 162 public void truncate() { 163 setCapacity(count); 164 } 165 166 /** 167 * Append specified bytes to the buffer. 168 * 169 * @param bytes byte array to be appended 170 * @param offset offset into byte array 171 * @param length length of data 172 173 */ 174 public void append(byte[] bytes, int offset, int length) { 175 setCapacity(count+length); 176 System.arraycopy(bytes, offset, this.get(), count, length); 177 count = count + length; 178 } 179 180 /** 181 * Append specified bytes to the buffer 182 * 183 * @param bytes byte array to be appended 184 */ 185 public void append(byte[] bytes) { 186 append(bytes, 0, bytes.length); 187 } 188 189 // inherit javadoc 190 @Override 191 public int hashCode() { 192 int hash = 1; 193 byte[] b = this.get(); 194 for (int i = 0; i < count; i++) 195 hash = (31 * hash) + b[i]; 196 return hash; 197 } 198 199 /** 200 * Define the sort order of the Buffer. 201 * 202 * @param other The other buffer 203 * @return Positive if this is bigger than other, 0 if they are equal, and 204 * negative if this is smaller than other. 205 */ 206 @Override 207 public int compareTo(Object other) { 208 Buffer right = ((Buffer) other); 209 byte[] lb = this.get(); 210 byte[] rb = right.get(); 211 for (int i = 0; i < count && i < right.count; i++) { 212 int a = (lb[i] & 0xff); 213 int b = (rb[i] & 0xff); 214 if (a != b) { 215 return a - b; 216 } 217 } 218 return count - right.count; 219 } 220 221 // inherit javadoc 222 @Override 223 public boolean equals(Object other) { 224 if (other instanceof Buffer && this != other) { 225 return compareTo(other) == 0; 226 } 227 return (this == other); 228 } 229 230 // inheric javadoc 231 @Override 232 public String toString() { 233 StringBuilder sb = new StringBuilder(2*count); 234 for(int idx = 0; idx < count; idx++) { 235 sb.append(Character.forDigit((bytes[idx] & 0xF0) >> 4, 16)); 236 sb.append(Character.forDigit(bytes[idx] & 0x0F, 16)); 237 } 238 return sb.toString(); 239 } 240 241 /** 242 * Convert the byte buffer to a string an specific character encoding 243 * 244 * @param charsetName Valid Java Character Set Name 245 */ 246 public String toString(String charsetName) 247 throws UnsupportedEncodingException { 248 return new String(this.get(), 0, this.getCount(), charsetName); 249 } 250 251 // inherit javadoc 252 @Override 253 public Object clone() throws CloneNotSupportedException { 254 Buffer result = (Buffer) super.clone(); 255 result.copy(this.get(), 0, this.getCount()); 256 return result; 257 } 258 }