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, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.mavibot.btree.serializer; 021 022 023import java.io.IOException; 024import java.nio.ByteBuffer; 025import java.util.Comparator; 026 027import org.apache.directory.mavibot.btree.comparator.ByteArrayComparator; 028import org.apache.directory.mavibot.btree.exception.SerializerCreationException; 029 030 031/** 032 * A serializer for a byte[]. 033 * 034 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 035 */ 036public class ByteArraySerializer extends AbstractElementSerializer<byte[]> 037{ 038 /** A static instance of a BytearraySerializer */ 039 public static final ByteArraySerializer INSTANCE = new ByteArraySerializer(); 040 041 /** 042 * Create a new instance of ByteArraySerializer 043 */ 044 private ByteArraySerializer() 045 { 046 super( ByteArrayComparator.INSTANCE ); 047 } 048 049 050 /** 051 * Create a new instance of ByteArraySerializer with custom comparator 052 */ 053 public ByteArraySerializer( Comparator<byte[]> comparator ) 054 { 055 super( comparator ); 056 } 057 058 059 /** 060 * {@inheritDoc} 061 */ 062 public byte[] serialize( byte[] element ) 063 { 064 int len = -1; 065 066 if ( element != null ) 067 { 068 len = element.length; 069 } 070 071 byte[] bytes = null; 072 073 switch ( len ) 074 { 075 case 0: 076 bytes = new byte[4]; 077 078 bytes[0] = 0x00; 079 bytes[1] = 0x00; 080 bytes[2] = 0x00; 081 bytes[3] = 0x00; 082 083 break; 084 085 case -1: 086 bytes = new byte[4]; 087 088 bytes[0] = ( byte ) 0xFF; 089 bytes[1] = ( byte ) 0xFF; 090 bytes[2] = ( byte ) 0xFF; 091 bytes[3] = ( byte ) 0xFF; 092 093 break; 094 095 default: 096 bytes = new byte[len + 4]; 097 098 System.arraycopy( element, 0, bytes, 4, len ); 099 100 bytes[0] = ( byte ) ( len >>> 24 ); 101 bytes[1] = ( byte ) ( len >>> 16 ); 102 bytes[2] = ( byte ) ( len >>> 8 ); 103 bytes[3] = ( byte ) ( len ); 104 } 105 106 return bytes; 107 } 108 109 110 /** 111 * Serialize a byte[] 112 * 113 * @param buffer the Buffer that will contain the serialized value 114 * @param start the position in the buffer we will store the serialized byte[] 115 * @param value the value to serialize 116 * @return The byte[] containing the serialized byte[] 117 */ 118 public static byte[] serialize( byte[] buffer, int start, byte[] element ) 119 { 120 int len = -1; 121 122 if ( element != null ) 123 { 124 len = element.length; 125 } 126 127 switch ( len ) 128 { 129 case 0: 130 buffer[start] = 0x00; 131 buffer[start + 1] = 0x00; 132 buffer[start + 2] = 0x00; 133 buffer[start + 3] = 0x00; 134 135 break; 136 137 case -1: 138 buffer[start] = ( byte ) 0xFF; 139 buffer[start + 1] = ( byte ) 0xFF; 140 buffer[start + 2] = ( byte ) 0xFF; 141 buffer[start + 3] = ( byte ) 0xFF; 142 143 break; 144 145 default: 146 147 buffer[start] = ( byte ) ( len >>> 24 ); 148 buffer[start + 1] = ( byte ) ( len >>> 16 ); 149 buffer[start + 2] = ( byte ) ( len >>> 8 ); 150 buffer[start + 3] = ( byte ) ( len ); 151 152 System.arraycopy( element, 0, buffer, 4 + start, len ); 153 } 154 155 return buffer; 156 157 } 158 159 160 /** 161 * A static method used to deserialize a byte array from a byte array. 162 * 163 * @param in The byte array containing the byte array 164 * @return A byte[] 165 */ 166 public static byte[] deserialize( byte[] in ) 167 { 168 if ( ( in == null ) || ( in.length < 4 ) ) 169 { 170 throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" ); 171 } 172 173 int len = IntSerializer.deserialize( in ); 174 175 switch ( len ) 176 { 177 case 0: 178 return new byte[] 179 {}; 180 181 case -1: 182 return null; 183 184 default: 185 byte[] result = new byte[len]; 186 System.arraycopy( in, 4, result, 0, len ); 187 188 return result; 189 } 190 } 191 192 193 /** 194 * A static method used to deserialize a byte array from a byte array. 195 * 196 * @param in The byte array containing the byte array 197 * @param start the position in the byte[] we will deserialize the byte[] from 198 * @return A byte[] 199 */ 200 public static byte[] deserialize( byte[] in, int start ) 201 { 202 if ( ( in == null ) || ( in.length < 4 + start ) ) 203 { 204 throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" ); 205 } 206 207 int len = IntSerializer.deserialize( in, start ); 208 209 switch ( len ) 210 { 211 case 0: 212 return new byte[] 213 {}; 214 215 case -1: 216 return null; 217 218 default: 219 byte[] result = new byte[len]; 220 System.arraycopy( in, 4 + start, result, 0, len ); 221 222 return result; 223 } 224 } 225 226 227 /** 228 * A method used to deserialize a byte array from a byte array. 229 * 230 * @param in The byte array containing the byte array 231 * @return A byte[] 232 */ 233 public byte[] fromBytes( byte[] in ) 234 { 235 if ( ( in == null ) || ( in.length < 4 ) ) 236 { 237 throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" ); 238 } 239 240 int len = IntSerializer.deserialize( in ); 241 242 switch ( len ) 243 { 244 case 0: 245 return new byte[] 246 {}; 247 248 case -1: 249 return null; 250 251 default: 252 byte[] result = new byte[len]; 253 System.arraycopy( in, 4, result, 0, len ); 254 255 return result; 256 } 257 } 258 259 260 /** 261 * A method used to deserialize a byte array from a byte array. 262 * 263 * @param in The byte array containing the byte array 264 * @param start the position in the byte[] we will deserialize the byte[] from 265 * @return A byte[] 266 */ 267 public byte[] fromBytes( byte[] in, int start ) 268 { 269 if ( ( in == null ) || ( in.length < 4 + start ) ) 270 { 271 throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" ); 272 } 273 274 int len = IntSerializer.deserialize( in, start ); 275 276 switch ( len ) 277 { 278 case 0: 279 return new byte[] 280 {}; 281 282 case -1: 283 return null; 284 285 default: 286 byte[] result = new byte[len]; 287 System.arraycopy( in, 4 + start, result, 0, len ); 288 289 return result; 290 } 291 } 292 293 294 /** 295 * {@inheritDoc} 296 */ 297 public byte[] deserialize( BufferHandler bufferHandler ) throws IOException 298 { 299 byte[] in = bufferHandler.read( 4 ); 300 301 int len = IntSerializer.deserialize( in ); 302 303 switch ( len ) 304 { 305 case 0: 306 return new byte[] 307 {}; 308 309 case -1: 310 return null; 311 312 default: 313 in = bufferHandler.read( len ); 314 315 return in; 316 } 317 } 318 319 320 /** 321 * {@inheritDoc} 322 */ 323 public byte[] deserialize( ByteBuffer buffer ) throws IOException 324 { 325 int len = buffer.getInt(); 326 327 switch ( len ) 328 { 329 case 0: 330 return new byte[] 331 {}; 332 333 case -1: 334 return null; 335 336 default: 337 byte[] bytes = new byte[len]; 338 339 buffer.get( bytes ); 340 341 return bytes; 342 } 343 } 344}