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; 025 026import org.apache.directory.mavibot.btree.comparator.CharArrayComparator; 027import org.apache.directory.mavibot.btree.exception.SerializerCreationException; 028 029 030/** 031 * A serializer for a char[]. 032 * 033 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 034 */ 035public class CharArraySerializer extends AbstractElementSerializer<char[]> 036{ 037 /** A static instance of a CharArraySerializer */ 038 public static final CharArraySerializer INSTANCE = new CharArraySerializer(); 039 040 /** 041 * Create a new instance of CharArraySerializer 042 */ 043 private CharArraySerializer() 044 { 045 super( CharArrayComparator.INSTANCE ); 046 } 047 048 049 /** 050 * {@inheritDoc} 051 */ 052 public byte[] serialize( char[] element ) 053 { 054 int len = -1; 055 056 if ( element != null ) 057 { 058 len = element.length; 059 } 060 061 byte[] bytes = null; 062 063 switch ( len ) 064 { 065 case 0: 066 bytes = new byte[4]; 067 068 bytes[0] = 0x00; 069 bytes[1] = 0x00; 070 bytes[2] = 0x00; 071 bytes[3] = 0x00; 072 073 break; 074 075 case -1: 076 bytes = new byte[4]; 077 078 bytes[0] = ( byte ) 0xFF; 079 bytes[1] = ( byte ) 0xFF; 080 bytes[2] = ( byte ) 0xFF; 081 bytes[3] = ( byte ) 0xFF; 082 083 break; 084 085 default: 086 bytes = new byte[len * 2 + 4]; 087 int pos = 4; 088 089 bytes[0] = ( byte ) ( len >>> 24 ); 090 bytes[1] = ( byte ) ( len >>> 16 ); 091 bytes[2] = ( byte ) ( len >>> 8 ); 092 bytes[3] = ( byte ) ( len ); 093 094 for ( char c : element ) 095 { 096 bytes[pos++] = ( byte ) ( c >>> 8 ); 097 bytes[pos++] = ( byte ) ( c ); 098 } 099 } 100 101 return bytes; 102 } 103 104 105 /** 106 * A static method used to deserialize a char array from a byte array. 107 * 108 * @param in The byte array containing the char array 109 * @return A char[] 110 */ 111 public static char[] deserialize( byte[] in ) 112 { 113 if ( ( in == null ) || ( in.length < 4 ) ) 114 { 115 throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" ); 116 } 117 118 int len = IntSerializer.deserialize( in ); 119 120 switch ( len ) 121 { 122 case 0: 123 return new char[] 124 {}; 125 126 case -1: 127 return null; 128 129 default: 130 char[] result = new char[len]; 131 132 for ( int i = 4; i < len * 2 + 4; i += 2 ) 133 { 134 result[i] = Character.valueOf( ( char ) ( ( in[i] << 8 ) + 135 ( in[i + 1] & 0xFF ) ) ); 136 } 137 138 return result; 139 } 140 } 141 142 143 /** 144 * A method used to deserialize a char array from a byte array. 145 * 146 * @param in The byte array containing the char array 147 * @return A char[] 148 */ 149 public char[] fromBytes( byte[] in, int start ) 150 { 151 if ( ( in == null ) || ( in.length - start < 4 ) ) 152 { 153 throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" ); 154 } 155 156 int len = IntSerializer.deserialize( in, start ); 157 158 switch ( len ) 159 { 160 case 0: 161 return new char[] 162 {}; 163 164 case -1: 165 return null; 166 167 default: 168 char[] result = new char[len]; 169 170 for ( int i = 4; i < len * 2 + 4; i += 2 ) 171 { 172 result[i] = Character.valueOf( ( char ) ( ( in[i] << 8 ) + 173 ( in[i + 1] & 0xFF ) ) ); 174 } 175 176 return result; 177 } 178 } 179 180 181 /** 182 * A method used to deserialize a char array from a byte array. 183 * 184 * @param in The byte array containing the char array 185 * @return A char[] 186 */ 187 public char[] fromBytes( byte[] in ) 188 { 189 if ( ( in == null ) || ( in.length < 4 ) ) 190 { 191 throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" ); 192 } 193 194 int len = IntSerializer.deserialize( in ); 195 196 switch ( len ) 197 { 198 case 0: 199 return new char[] 200 {}; 201 202 case -1: 203 return null; 204 205 default: 206 char[] result = new char[len]; 207 208 for ( int i = 4; i < len * 2 + 4; i += 2 ) 209 { 210 result[i] = Character.valueOf( ( char ) ( ( in[i] << 8 ) + 211 ( in[i + 1] & 0xFF ) ) ); 212 } 213 214 return result; 215 } 216 } 217 218 219 /** 220 * {@inheritDoc} 221 */ 222 public char[] deserialize( BufferHandler bufferHandler ) throws IOException 223 { 224 byte[] in = bufferHandler.read( 4 ); 225 226 int len = IntSerializer.deserialize( in ); 227 228 switch ( len ) 229 { 230 case 0: 231 return new char[] 232 {}; 233 234 case -1: 235 return null; 236 237 default: 238 char[] result = new char[len]; 239 byte[] buffer = bufferHandler.read( len * 2 ); 240 241 for ( int i = 0; i < len * 2; i += 2 ) 242 { 243 result[i] = Character.valueOf( ( char ) ( ( buffer[i] << 8 ) + 244 ( buffer[i + 1] & 0xFF ) ) ); 245 } 246 247 return result; 248 } 249 } 250 251 252 /** 253 * {@inheritDoc} 254 */ 255 public char[] deserialize( ByteBuffer buffer ) throws IOException 256 { 257 int len = buffer.getInt(); 258 259 switch ( len ) 260 { 261 case 0: 262 return new char[] 263 {}; 264 265 case -1: 266 return null; 267 268 default: 269 char[] result = new char[len]; 270 271 for ( int i = 0; i < len; i++ ) 272 { 273 result[i] = buffer.getChar(); 274 } 275 276 return result; 277 } 278 } 279}