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      /**
38       * Create a new instance of CharArraySerializer
39       */
40      public CharArraySerializer()
41      {
42          super( new CharArrayComparator() );
43      }
44  
45  
46      /**
47       * {@inheritDoc}
48       */
49      public byte[] serialize( char[] element )
50      {
51          int len = -1;
52  
53          if ( element != null )
54          {
55              len = element.length;
56          }
57  
58          byte[] bytes = null;
59  
60          switch ( len )
61          {
62              case 0:
63                  bytes = new byte[4];
64  
65                  bytes[0] = 0x00;
66                  bytes[1] = 0x00;
67                  bytes[2] = 0x00;
68                  bytes[3] = 0x00;
69  
70                  break;
71  
72              case -1:
73                  bytes = new byte[4];
74  
75                  bytes[0] = ( byte ) 0xFF;
76                  bytes[1] = ( byte ) 0xFF;
77                  bytes[2] = ( byte ) 0xFF;
78                  bytes[3] = ( byte ) 0xFF;
79  
80                  break;
81  
82              default:
83                  bytes = new byte[len * 2 + 4];
84                  int pos = 4;
85  
86                  bytes[0] = ( byte ) ( len >>> 24 );
87                  bytes[1] = ( byte ) ( len >>> 16 );
88                  bytes[2] = ( byte ) ( len >>> 8 );
89                  bytes[3] = ( byte ) ( len );
90  
91                  for ( char c : element )
92                  {
93                      bytes[pos++] = ( byte ) ( c >>> 8 );
94                      bytes[pos++] = ( byte ) ( c );
95                  }
96          }
97  
98          return bytes;
99      }
100 
101 
102     /**
103      * A static method used to deserialize a char array from a byte array.
104      *
105      * @param in The byte array containing the char array
106      * @return A char[]
107      */
108     public static char[] deserialize( byte[] in )
109     {
110         if ( ( in == null ) || ( in.length < 4 ) )
111         {
112             throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" );
113         }
114 
115         int len = IntSerializer.deserialize( in );
116 
117         switch ( len )
118         {
119             case 0:
120                 return new char[]
121                     {};
122 
123             case -1:
124                 return null;
125 
126             default:
127                 char[] result = new char[len];
128 
129                 for ( int i = 4; i < len * 2 + 4; i += 2 )
130                 {
131                     result[i] = Character.valueOf( ( char ) ( ( in[i] << 8 ) +
132                         ( in[i + 1] & 0xFF ) ) );
133                 }
134 
135                 return result;
136         }
137     }
138 
139 
140     /**
141      * A method used to deserialize a char array from a byte array.
142      *
143      * @param in The byte array containing the char array
144      * @return A char[]
145      */
146     public char[] fromBytes( byte[] in, int start )
147     {
148         if ( ( in == null ) || ( in.length - start < 4 ) )
149         {
150             throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" );
151         }
152 
153         int len = IntSerializer.deserialize( in, start );
154 
155         switch ( len )
156         {
157             case 0:
158                 return new char[]
159                     {};
160 
161             case -1:
162                 return null;
163 
164             default:
165                 char[] result = new char[len];
166 
167                 for ( int i = 4; i < len * 2 + 4; i += 2 )
168                 {
169                     result[i] = Character.valueOf( ( char ) ( ( in[i] << 8 ) +
170                         ( in[i + 1] & 0xFF ) ) );
171                 }
172 
173                 return result;
174         }
175     }
176 
177 
178     /**
179      * A method used to deserialize a char array from a byte array.
180      *
181      * @param in The byte array containing the char array
182      * @return A char[]
183      */
184     public char[] fromBytes( byte[] in )
185     {
186         if ( ( in == null ) || ( in.length < 4 ) )
187         {
188             throw new SerializerCreationException( "Cannot extract a byte[] from a buffer with not enough bytes" );
189         }
190 
191         int len = IntSerializer.deserialize( in );
192 
193         switch ( len )
194         {
195             case 0:
196                 return new char[]
197                     {};
198 
199             case -1:
200                 return null;
201 
202             default:
203                 char[] result = new char[len];
204 
205                 for ( int i = 4; i < len * 2 + 4; i += 2 )
206                 {
207                     result[i] = Character.valueOf( ( char ) ( ( in[i] << 8 ) +
208                         ( in[i + 1] & 0xFF ) ) );
209                 }
210 
211                 return result;
212         }
213     }
214 
215 
216     /**
217      * {@inheritDoc}
218      */
219     public char[] deserialize( BufferHandler bufferHandler ) throws IOException
220     {
221         byte[] in = bufferHandler.read( 4 );
222 
223         int len = IntSerializer.deserialize( in );
224 
225         switch ( len )
226         {
227             case 0:
228                 return new char[]
229                     {};
230 
231             case -1:
232                 return null;
233 
234             default:
235                 char[] result = new char[len];
236                 byte[] buffer = bufferHandler.read( len * 2 );
237 
238                 for ( int i = 0; i < len * 2; i += 2 )
239                 {
240                     result[i] = Character.valueOf( ( char ) ( ( buffer[i] << 8 ) +
241                         ( buffer[i + 1] & 0xFF ) ) );
242                 }
243 
244                 return result;
245         }
246     }
247 
248 
249     /**
250      * {@inheritDoc}
251      */
252     public char[] deserialize( ByteBuffer buffer ) throws IOException
253     {
254         int len = buffer.getInt();
255 
256         switch ( len )
257         {
258             case 0:
259                 return new char[]
260                     {};
261 
262             case -1:
263                 return null;
264 
265             default:
266                 char[] result = new char[len];
267 
268                 for ( int i = 0; i < len; i++ )
269                 {
270                     result[i] = buffer.getChar();
271                 }
272 
273                 return result;
274         }
275     }
276 }