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,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.directory.mavibot.btree.serializer;
21  
22  
23  import java.io.IOException;
24  import java.nio.ByteBuffer;
25  import java.util.Comparator;
26  
27  import org.apache.directory.mavibot.btree.comparator.ByteArrayComparator;
28  import org.apache.directory.mavibot.btree.exception.SerializerCreationException;
29  
30  
31  /**
32   * A serializer for a byte[].
33   *
34   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
35   */
36  public class ByteArraySerializer extends AbstractElementSerializer<byte[]>
37  {
38      /**
39       * Create a new instance of ByteArraySerializer
40       */
41      public ByteArraySerializer()
42      {
43          super( new ByteArrayComparator() );
44      }
45  
46  
47      /**
48       * Create a new instance of ByteArraySerializer with custom comparator
49       */
50      public ByteArraySerializer( Comparator<byte[]> comparator )
51      {
52          super( comparator );
53      }
54  
55  
56      /**
57       * {@inheritDoc}
58       */
59      public byte[] serialize( byte[] element )
60      {
61          int len = -1;
62  
63          if ( element != null )
64          {
65              len = element.length;
66          }
67  
68          byte[] bytes = null;
69  
70          switch ( len )
71          {
72              case 0:
73                  bytes = new byte[4];
74  
75                  bytes[0] = 0x00;
76                  bytes[1] = 0x00;
77                  bytes[2] = 0x00;
78                  bytes[3] = 0x00;
79  
80                  break;
81  
82              case -1:
83                  bytes = new byte[4];
84  
85                  bytes[0] = ( byte ) 0xFF;
86                  bytes[1] = ( byte ) 0xFF;
87                  bytes[2] = ( byte ) 0xFF;
88                  bytes[3] = ( byte ) 0xFF;
89  
90                  break;
91  
92              default:
93                  bytes = new byte[len + 4];
94  
95                  System.arraycopy( element, 0, bytes, 4, len );
96  
97                  bytes[0] = ( byte ) ( len >>> 24 );
98                  bytes[1] = ( byte ) ( len >>> 16 );
99                  bytes[2] = ( byte ) ( len >>> 8 );
100                 bytes[3] = ( byte ) ( len );
101         }
102 
103         return bytes;
104     }
105 
106 
107     /**
108      * Serialize a byte[]
109      *
110      * @param buffer the Buffer that will contain the serialized value
111      * @param start the position in the buffer we will store the serialized byte[]
112      * @param value the value to serialize
113      * @return The byte[] containing the serialized byte[]
114      */
115     public static byte[] serialize( byte[] buffer, int start, byte[] element )
116     {
117         int len = -1;
118 
119         if ( element != null )
120         {
121             len = element.length;
122         }
123 
124         switch ( len )
125         {
126             case 0:
127                 buffer[start] = 0x00;
128                 buffer[start + 1] = 0x00;
129                 buffer[start + 2] = 0x00;
130                 buffer[start + 3] = 0x00;
131 
132                 break;
133 
134             case -1:
135                 buffer[start] = ( byte ) 0xFF;
136                 buffer[start + 1] = ( byte ) 0xFF;
137                 buffer[start + 2] = ( byte ) 0xFF;
138                 buffer[start + 3] = ( byte ) 0xFF;
139 
140                 break;
141 
142             default:
143 
144                 buffer[start] = ( byte ) ( len >>> 24 );
145                 buffer[start + 1] = ( byte ) ( len >>> 16 );
146                 buffer[start + 2] = ( byte ) ( len >>> 8 );
147                 buffer[start + 3] = ( byte ) ( len );
148 
149                 System.arraycopy( element, 0, buffer, 4 + start, len );
150         }
151 
152         return buffer;
153 
154     }
155 
156 
157     /**
158      * A static method used to deserialize a byte array from a byte array.
159      *
160      * @param in The byte array containing the byte array
161      * @return A byte[]
162      */
163     public static byte[] deserialize( byte[] in )
164     {
165         if ( ( in == null ) || ( in.length < 4 ) )
166         {
167             throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" );
168         }
169 
170         int len = IntSerializer.deserialize( in );
171 
172         switch ( len )
173         {
174             case 0:
175                 return new byte[]
176                     {};
177 
178             case -1:
179                 return null;
180 
181             default:
182                 byte[] result = new byte[len];
183                 System.arraycopy( in, 4, result, 0, len );
184 
185                 return result;
186         }
187     }
188 
189 
190     /**
191      * A static method used to deserialize a byte array from a byte array.
192      *
193      * @param in The byte array containing the byte array
194      * @param start the position in the byte[] we will deserialize the byte[] from
195      * @return A byte[]
196      */
197     public static byte[] deserialize( byte[] in, int start )
198     {
199         if ( ( in == null ) || ( in.length < 4 + start ) )
200         {
201             throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" );
202         }
203 
204         int len = IntSerializer.deserialize( in, start );
205 
206         switch ( len )
207         {
208             case 0:
209                 return new byte[]
210                     {};
211 
212             case -1:
213                 return null;
214 
215             default:
216                 byte[] result = new byte[len];
217                 System.arraycopy( in, 4 + start, result, 0, len );
218 
219                 return result;
220         }
221     }
222 
223 
224     /**
225      * A method used to deserialize a byte array from a byte array.
226      *
227      * @param in The byte array containing the byte array
228      * @return A byte[]
229      */
230     public byte[] fromBytes( byte[] in )
231     {
232         if ( ( in == null ) || ( in.length < 4 ) )
233         {
234             throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" );
235         }
236 
237         int len = IntSerializer.deserialize( in );
238 
239         switch ( len )
240         {
241             case 0:
242                 return new byte[]
243                     {};
244 
245             case -1:
246                 return null;
247 
248             default:
249                 byte[] result = new byte[len];
250                 System.arraycopy( in, 4, result, 0, len );
251 
252                 return result;
253         }
254     }
255 
256 
257     /**
258      * A method used to deserialize a byte array from a byte array.
259      *
260      * @param in The byte array containing the byte array
261      * @param start the position in the byte[] we will deserialize the byte[] from
262      * @return A byte[]
263      */
264     public byte[] fromBytes( byte[] in, int start )
265     {
266         if ( ( in == null ) || ( in.length < 4 + start ) )
267         {
268             throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" );
269         }
270 
271         int len = IntSerializer.deserialize( in, start );
272 
273         switch ( len )
274         {
275             case 0:
276                 return new byte[]
277                     {};
278 
279             case -1:
280                 return null;
281 
282             default:
283                 byte[] result = new byte[len];
284                 System.arraycopy( in, 4 + start, result, 0, len );
285 
286                 return result;
287         }
288     }
289 
290 
291     /**
292      * {@inheritDoc}
293      */
294     public byte[] deserialize( BufferHandler bufferHandler ) throws IOException
295     {
296         byte[] in = bufferHandler.read( 4 );
297 
298         int len = IntSerializer.deserialize( in );
299 
300         switch ( len )
301         {
302             case 0:
303                 return new byte[]
304                     {};
305 
306             case -1:
307                 return null;
308 
309             default:
310                 in = bufferHandler.read( len );
311 
312                 return in;
313         }
314     }
315 
316 
317     /**
318      * {@inheritDoc}
319      */
320     public byte[] deserialize( ByteBuffer buffer ) throws IOException
321     {
322         int len = buffer.getInt();
323 
324         switch ( len )
325         {
326             case 0:
327                 return new byte[]
328                     {};
329 
330             case -1:
331                 return null;
332 
333             default:
334                 byte[] bytes = new byte[len];
335 
336                 buffer.get( bytes );
337 
338                 return bytes;
339         }
340     }
341 }