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;
21  
22  
23  import java.io.IOException;
24  import java.nio.ByteBuffer;
25  
26  import org.apache.directory.mavibot.btree.exception.SerializerCreationException;
27  import org.apache.directory.mavibot.btree.serializer.AbstractElementSerializer;
28  import org.apache.directory.mavibot.btree.serializer.BufferHandler;
29  import org.apache.directory.mavibot.btree.serializer.ByteArraySerializer;
30  import org.apache.directory.mavibot.btree.serializer.IntSerializer;
31  import org.apache.directory.mavibot.btree.serializer.LongSerializer;
32  import org.apache.directory.mavibot.btree.serializer.StringSerializer;
33  import org.apache.directory.mavibot.btree.util.Strings;
34  
35  
36  /**
37   * A serializer for the NameRevision object. The NameRevision will be serialized
38   * as a String ( the Name) followed by the revision as a Long.
39   *
40   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
41   */
42  /* no qualifier*/class NameRevisionSerializer extends AbstractElementSerializer<NameRevision>
43  {
44      /** A static instance of a NameRevisionSerializer */
45      /*No qualifier*/ final static NameRevisionSerializer INSTANCE = new NameRevisionSerializer();
46  
47      /**
48       * Create a new instance of a NameRevisionSerializer
49       */
50      private NameRevisionSerializer()
51      {
52          super( NameRevisionComparator.INSTANCE );
53      }
54  
55  
56      /**
57       * A static method used to deserialize a NameRevision from a byte array.
58       *
59       * @param in The byte array containing the NameRevision
60       * @return A NameRevision instance
61       */
62      /* no qualifier*/static NameRevision deserialize( byte[] in )
63      {
64          return deserialize( in, 0 );
65      }
66  
67  
68      /**
69       * A static method used to deserialize a NameRevision from a byte array.
70       *
71       * @param in The byte array containing the NameRevision
72       * @param start the position in the byte[] we will deserialize the NameRevision from
73       * @return A NameRevision instance
74       */
75      /* no qualifier*/static NameRevision deserialize( byte[] in, int start )
76      {
77          // The buffer must be 8 bytes plus 4 bytes long (the revision is a long, and the name is a String
78          if ( ( in == null ) || ( in.length < 12 + start ) )
79          {
80              throw new SerializerCreationException( "Cannot extract a NameRevision from a buffer with not enough bytes" );
81          }
82  
83          long revision = LongSerializer.deserialize( in, start );
84          String name = StringSerializer.deserialize( in, 8 + start );
85  
86          NameRevision revisionName = new NameRevision( name, revision );
87  
88          return revisionName;
89      }
90  
91  
92      /**
93       * A static method used to deserialize a NameRevision from a byte array.
94       *
95       * @param in The byte array containing the NameRevision
96       * @return A NameRevision instance
97       */
98      public NameRevision fromBytes( byte[] in )
99      {
100         return deserialize( in, 0 );
101     }
102 
103 
104     /**
105      * A static method used to deserialize a NameRevision from a byte array.
106      *
107      * @param in The byte array containing the NameRevision
108      * @param start the position in the byte[] we will deserialize the NameRevision from
109      * @return A NameRevision instance
110      */
111     public NameRevision fromBytes( byte[] in, int start )
112     {
113         // The buffer must be 8 bytes plus 4 bytes long (the revision is a long, and the name is a String
114         if ( ( in == null ) || ( in.length < 12 + start ) )
115         {
116             throw new SerializerCreationException( "Cannot extract a NameRevision from a buffer with not enough bytes" );
117         }
118 
119         long revision = LongSerializer.deserialize( in, start );
120         String name = StringSerializer.deserialize( in, 8 + start );
121 
122         NameRevision revisionName = new NameRevision( name, revision );
123 
124         return revisionName;
125     }
126 
127 
128     /**
129      * {@inheritDoc}
130      */
131     @Override
132     public byte[] serialize( NameRevision revisionName )
133     {
134         if ( revisionName == null )
135         {
136             throw new SerializerCreationException( "The revisionName instance should not be null " );
137         }
138 
139         byte[] result = null;
140 
141         if ( revisionName.getName() != null )
142         {
143             byte[] stringBytes = Strings.getBytesUtf8( revisionName.getName() );
144             int stringLen = stringBytes.length;
145             result = new byte[8 + 4 + stringBytes.length];
146             LongSerializer.serialize( result, 0, revisionName.getRevision() );
147 
148             if ( stringLen > 0 )
149             {
150                 ByteArraySerializer.serialize( result, 8, stringBytes );
151             }
152         }
153         else
154         {
155             result = new byte[8 + 4];
156             LongSerializer.serialize( result, 0, revisionName.getRevision() );
157             StringSerializer.serialize( result, 8, null );
158         }
159 
160         return result;
161     }
162 
163 
164     /**
165      * Serialize a NameRevision
166      *
167      * @param buffer the Buffer that will contain the serialized value
168      * @param start the position in the buffer we will store the serialized NameRevision
169      * @param value the value to serialize
170      * @return The byte[] containing the serialized NameRevision
171      */
172     /* no qualifier*/static byte[] serialize( byte[] buffer, int start, NameRevision revisionName )
173     {
174         if ( revisionName.getName() != null )
175         {
176             byte[] stringBytes = Strings.getBytesUtf8( revisionName.getName() );
177             int stringLen = stringBytes.length;
178             LongSerializer.serialize( buffer, start, revisionName.getRevision() );
179             IntSerializer.serialize( buffer, 8 + start, stringLen );
180             ByteArraySerializer.serialize( buffer, 12 + start, stringBytes );
181         }
182         else
183         {
184             LongSerializer.serialize( buffer, start, revisionName.getRevision() );
185             StringSerializer.serialize( buffer, 8, null );
186         }
187 
188         return buffer;
189     }
190 
191 
192     /**
193      * {@inheritDoc}
194      */
195     @Override
196     public NameRevision deserialize( BufferHandler bufferHandler ) throws IOException
197     {
198         byte[] revisionBytes = bufferHandler.read( 8 );
199         long revision = LongSerializer.deserialize( revisionBytes );
200 
201         byte[] lengthBytes = bufferHandler.read( 4 );
202 
203         int len = IntSerializer.deserialize( lengthBytes );
204 
205         switch ( len )
206         {
207             case 0:
208                 return new NameRevision( "", revision );
209 
210             case -1:
211                 return new NameRevision( null, revision );
212 
213             default:
214                 byte[] nameBytes = bufferHandler.read( len );
215 
216                 return new NameRevision( Strings.utf8ToString( nameBytes ), revision );
217         }
218     }
219 
220 
221     /**
222      * {@inheritDoc}
223      */
224     @Override
225     public NameRevision deserialize( ByteBuffer buffer ) throws IOException
226     {
227         // The revision
228         long revision = buffer.getLong();
229 
230         // The name's length
231         int len = buffer.getInt();
232 
233         switch ( len )
234         {
235             case 0:
236                 return new NameRevision( "", revision );
237 
238             case -1:
239                 return new NameRevision( null, revision );
240 
241             default:
242                 byte[] nameBytes = new byte[len];
243                 buffer.get( nameBytes );
244 
245                 return new NameRevision( Strings.utf8ToString( nameBytes ), revision );
246         }
247     }
248 }