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  
26  import org.apache.directory.mavibot.btree.comparator.CharArrayComparator;
27  import org.apache.directory.mavibot.btree.exception.SerializerCreationException;
28  
29  
30  /**
31   * A serializer for a char[].
32   *
33   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
34   */
35  public class CharArraySerializer extends AbstractElementSerializer<char[]>
36  {
37      /** A static instance of a CharArraySerializer */
38      public static final CharArraySerializer INSTANCE = new CharArraySerializer();
39  
40      /**
41       * Create a new instance of CharArraySerializer
42       */
43      private CharArraySerializer()
44      {
45          super( CharArrayComparator.INSTANCE );
46      }
47  
48  
49      /**
50       * {@inheritDoc}
51       */
52      public byte[] serialize( char[] element )
53      {
54          int len = -1;
55  
56          if ( element != null )
57          {
58              len = element.length;
59          }
60  
61          byte[] bytes = null;
62  
63          switch ( len )
64          {
65              case 0:
66                  bytes = new byte[4];
67  
68                  bytes[0] = 0x00;
69                  bytes[1] = 0x00;
70                  bytes[2] = 0x00;
71                  bytes[3] = 0x00;
72  
73                  break;
74  
75              case -1:
76                  bytes = new byte[4];
77  
78                  bytes[0] = ( byte ) 0xFF;
79                  bytes[1] = ( byte ) 0xFF;
80                  bytes[2] = ( byte ) 0xFF;
81                  bytes[3] = ( byte ) 0xFF;
82  
83                  break;
84  
85              default:
86                  bytes = new byte[len * 2 + 4];
87                  int pos = 4;
88  
89                  bytes[0] = ( byte ) ( len >>> 24 );
90                  bytes[1] = ( byte ) ( len >>> 16 );
91                  bytes[2] = ( byte ) ( len >>> 8 );
92                  bytes[3] = ( byte ) ( len );
93  
94                  for ( char c : element )
95                  {
96                      bytes[pos++] = ( byte ) ( c >>> 8 );
97                      bytes[pos++] = ( byte ) ( c );
98                  }
99          }
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 }