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 019package org.apache.hadoop.record; 020 021import java.io.UnsupportedEncodingException; 022 023import org.apache.hadoop.classification.InterfaceAudience; 024import 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 036public 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 public int hashCode() { 191 int hash = 1; 192 byte[] b = this.get(); 193 for (int i = 0; i < count; i++) 194 hash = (31 * hash) + (int)b[i]; 195 return hash; 196 } 197 198 /** 199 * Define the sort order of the Buffer. 200 * 201 * @param other The other buffer 202 * @return Positive if this is bigger than other, 0 if they are equal, and 203 * negative if this is smaller than other. 204 */ 205 public int compareTo(Object other) { 206 Buffer right = ((Buffer) other); 207 byte[] lb = this.get(); 208 byte[] rb = right.get(); 209 for (int i = 0; i < count && i < right.count; i++) { 210 int a = (lb[i] & 0xff); 211 int b = (rb[i] & 0xff); 212 if (a != b) { 213 return a - b; 214 } 215 } 216 return count - right.count; 217 } 218 219 // inherit javadoc 220 public boolean equals(Object other) { 221 if (other instanceof Buffer && this != other) { 222 return compareTo(other) == 0; 223 } 224 return (this == other); 225 } 226 227 // inheric javadoc 228 public String toString() { 229 StringBuilder sb = new StringBuilder(2*count); 230 for(int idx = 0; idx < count; idx++) { 231 sb.append(Character.forDigit((bytes[idx] & 0xF0) >> 4, 16)); 232 sb.append(Character.forDigit(bytes[idx] & 0x0F, 16)); 233 } 234 return sb.toString(); 235 } 236 237 /** 238 * Convert the byte buffer to a string an specific character encoding 239 * 240 * @param charsetName Valid Java Character Set Name 241 */ 242 public String toString(String charsetName) 243 throws UnsupportedEncodingException { 244 return new String(this.get(), 0, this.getCount(), charsetName); 245 } 246 247 // inherit javadoc 248 public Object clone() throws CloneNotSupportedException { 249 Buffer result = (Buffer) super.clone(); 250 result.copy(this.get(), 0, this.getCount()); 251 return result; 252 } 253}