001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *  http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.directory.api.util;
020
021
022/**
023 * A class containing static methods used to serialize and deserialize base types
024 * 
025 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
026 */
027public final class Serialize
028{
029    /** The serialized value for TRUE */
030    public static final byte TRUE = 0x01;
031
032    /** The serialized value for FALSE */
033    public static final byte FALSE = 0x00;
034
035
036    private Serialize()
037    {
038    }
039
040
041    /**
042     * Write an integer into a buffer at a given position
043     * 
044     * @param value The value to serialize
045     * @param buffer The buffer to store the value into
046     * @param pos The position where we serialize the integer
047     * @return The new position in the byte[]
048     */
049    public static int serialize( int value, byte[] buffer, int pos )
050    {
051        if ( buffer.length - pos < 4 )
052        {
053            throw new ArrayIndexOutOfBoundsException();
054        }
055
056        buffer[pos++] = ( byte ) ( ( value >>> 24 ) & 0xFF );
057        buffer[pos++] = ( byte ) ( ( value >>> 16 ) & 0xFF );
058        buffer[pos++] = ( byte ) ( ( value >>> 8 ) & 0xFF );
059        buffer[pos++] = ( byte ) ( ( value >>> 0 ) & 0xFF );
060
061        return pos;
062    }
063
064
065    /**
066     * Write a byte[] into a buffer at a given position
067     * 
068     * @param value The value to serialize
069     * @param buffer The buffer to store the value into
070     * @param pos The position where we serialize the byte[]
071     * @return The new position in the byte[]
072     */
073    public static int serialize( byte[] value, byte[] buffer, int pos )
074    {
075        if ( buffer.length - pos < 4 + value.length )
076        {
077            throw new ArrayIndexOutOfBoundsException();
078        }
079
080        buffer[pos++] = ( byte ) ( ( value.length >>> 24 ) & 0xFF );
081        buffer[pos++] = ( byte ) ( ( value.length >>> 16 ) & 0xFF );
082        buffer[pos++] = ( byte ) ( ( value.length >>> 8 ) & 0xFF );
083        buffer[pos++] = ( byte ) ( ( value.length >>> 0 ) & 0xFF );
084
085        System.arraycopy( value, 0, buffer, pos, value.length );
086
087        return pos + value.length;
088    }
089
090
091    /**
092     * Read an integer from a buffer at a given position
093     * 
094     * @param buffer The buffer containing the serialized integer
095     * @param pos The position from which we will read an integer
096     * @return the deserialized integer
097     */
098    public static int deserializeInt( byte[] buffer, int pos )
099    {
100        if ( buffer.length - pos < 4 )
101        {
102            throw new ArrayIndexOutOfBoundsException();
103        }
104
105        return ( buffer[pos] << 24 ) + ( buffer[pos + 1] << 16 ) + ( buffer[pos + 2] << 8 ) + ( buffer[pos + 3] << 0 );
106    }
107
108
109    /**
110     * Read a byte[] from a buffer at a given position
111     * 
112     * @param buffer The buffer containing the serialized byte[]
113     * @param pos The position from which we will read a byte[]
114     * @return the deserialized byte[]
115     */
116    public static byte[] deserializeBytes( byte[] buffer, int pos )
117    {
118        if ( buffer.length - pos < 4 )
119        {
120            throw new ArrayIndexOutOfBoundsException();
121        }
122
123        int len = deserializeInt( buffer, pos );
124        pos += 4;
125
126        if ( len > 0 )
127        {
128            if ( buffer.length - pos < len )
129            {
130                throw new ArrayIndexOutOfBoundsException();
131            }
132
133            byte[] result = new byte[len];
134
135            System.arraycopy( buffer, pos, result, 0, len );
136
137            return result;
138        }
139        else
140        {
141            return Strings.EMPTY_BYTES;
142        }
143    }
144
145
146    /**
147     * Read a boolean from a buffer at a given position
148     * 
149     * @param buffer The buffer containing the serialized boolean
150     * @param pos The position from which we will read a boolean
151     * @return the deserialized boolean
152     */
153    public static boolean deserializeBoolean( byte[] buffer, int pos )
154    {
155        if ( buffer.length - pos < 1 )
156        {
157            throw new ArrayIndexOutOfBoundsException();
158        }
159
160        byte value = buffer[pos];
161
162        return ( value != 0x00 );
163    }
164}