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      /** A static instance of a BytearraySerializer */
39      public static final ByteArraySerializer INSTANCE = new ByteArraySerializer();
40  
41      /**
42       * Create a new instance of ByteArraySerializer
43       */
44      private ByteArraySerializer()
45      {
46          super( ByteArrayComparator.INSTANCE );
47      }
48  
49  
50      /**
51       * Create a new instance of ByteArraySerializer with custom comparator
52       */
53      public ByteArraySerializer( Comparator<byte[]> comparator )
54      {
55          super( comparator );
56      }
57  
58  
59      /**
60       * {@inheritDoc}
61       */
62      public byte[] serialize( byte[] element )
63      {
64          int len = -1;
65  
66          if ( element != null )
67          {
68              len = element.length;
69          }
70  
71          byte[] bytes = null;
72  
73          switch ( len )
74          {
75              case 0:
76                  bytes = new byte[4];
77  
78                  bytes[0] = 0x00;
79                  bytes[1] = 0x00;
80                  bytes[2] = 0x00;
81                  bytes[3] = 0x00;
82  
83                  break;
84  
85              case -1:
86                  bytes = new byte[4];
87  
88                  bytes[0] = ( byte ) 0xFF;
89                  bytes[1] = ( byte ) 0xFF;
90                  bytes[2] = ( byte ) 0xFF;
91                  bytes[3] = ( byte ) 0xFF;
92  
93                  break;
94  
95              default:
96                  bytes = new byte[len + 4];
97  
98                  System.arraycopy( element, 0, bytes, 4, len );
99  
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 }