blob: 4e32b36a76d31da01f10a25b1033f4d57ce3b26f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.directory.mavibot.btree.serializer;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.apache.directory.mavibot.btree.comparator.LongArrayComparator;
/**
* A serializer for a Long[].
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public class LongArraySerializer extends AbstractElementSerializer<long[]>
{
/** A static instance of a LongArraySerializer */
public static final LongArraySerializer INSTANCE = new LongArraySerializer();
/**
* Create a new instance of LongSerializer
*/
private LongArraySerializer()
{
super( LongArrayComparator.INSTANCE );
}
/**
* {@inheritDoc}
*/
public byte[] serialize( long[] element )
{
int len = -1;
if ( element != null )
{
len = element.length;
}
byte[] bytes = null;
int pos = 0;
switch ( len )
{
case 0:
bytes = new byte[4];
// The number of Long. Here, 0
bytes[pos++] = 0x00;
bytes[pos++] = 0x00;
bytes[pos++] = 0x00;
bytes[pos++] = 0x00;
break;
case -1:
bytes = new byte[4];
// The number of Long. Here, null
bytes[pos++] = ( byte ) 0xFF;
bytes[pos++] = ( byte ) 0xFF;
bytes[pos++] = ( byte ) 0xFF;
bytes[pos++] = ( byte ) 0xFF;
break;
default:
int dataLen = len * 8 + 4;
bytes = new byte[dataLen];
// The number of longs
bytes[pos++] = ( byte ) ( len >>> 24 );
bytes[pos++] = ( byte ) ( len >>> 16 );
bytes[pos++] = ( byte ) ( len >>> 8 );
bytes[pos++] = ( byte ) ( len );
// Serialize the longs now
for ( long value : element )
{
bytes[pos++] = ( byte ) ( value >>> 56 );
bytes[pos++] = ( byte ) ( value >>> 48 );
bytes[pos++] = ( byte ) ( value >>> 40 );
bytes[pos++] = ( byte ) ( value >>> 32 );
bytes[pos++] = ( byte ) ( value >>> 24 );
bytes[pos++] = ( byte ) ( value >>> 16 );
bytes[pos++] = ( byte ) ( value >>> 8 );
bytes[pos++] = ( byte ) ( value );
}
}
return bytes;
}
/**
* {@inheritDoc}
*/
public long[] deserialize( BufferHandler bufferHandler ) throws IOException
{
// Read the DataLength first. Note that we don't use it here.
byte[] in = bufferHandler.read( 4 );
IntSerializer.deserialize( in );
// Now, read the number of Longs
in = bufferHandler.read( 4 );
int nbLongs = IntSerializer.deserialize( in );
switch ( nbLongs )
{
case 0:
return new long[]
{};
case -1:
return null;
default:
long[] longs = new long[nbLongs];
in = bufferHandler.read( nbLongs * 8 );
int pos = 0;
for ( int i = 0; i < nbLongs; i++ )
{
longs[i] = ( ( long ) in[pos++] << 56 ) +
( ( in[pos++] & 0xFFL ) << 48 ) +
( ( in[pos++] & 0xFFL ) << 40 ) +
( ( in[pos++] & 0xFFL ) << 32 ) +
( ( in[pos++] & 0xFFL ) << 24 ) +
( ( in[pos++] & 0xFFL ) << 16 ) +
( ( in[pos++] & 0xFFL ) << 8 ) +
( in[pos++] & 0xFFL );
}
return longs;
}
}
/**
* {@inheritDoc}
*/
public long[] deserialize( ByteBuffer buffer ) throws IOException
{
// Read the dataLength. Note that we don't use it here.
buffer.getInt();
// The number of longs
int nbLongs = buffer.getInt();
switch ( nbLongs )
{
case 0:
return new long[]
{};
case -1:
return null;
default:
long[] longs = new long[nbLongs];
for ( int i = 0; i < nbLongs; i++ )
{
longs[i] = buffer.getLong();
}
return longs;
}
}
/**
* {@inheritDoc}
*/
@Override
public int compare( long[] type1, long[] type2 )
{
if ( type1 == type2 )
{
return 0;
}
if ( type1 == null )
{
if ( type2 == null )
{
return 0;
}
else
{
return -1;
}
}
else
{
if ( type2 == null )
{
return 1;
}
else
{
if ( type1.length < type2.length )
{
int pos = 0;
for ( long b1 : type1 )
{
long b2 = type2[pos];
if ( b1 == b2 )
{
pos++;
}
else if ( b1 < b2 )
{
return -1;
}
else
{
return 1;
}
}
return 1;
}
else
{
int pos = 0;
for ( long b2 : type2 )
{
long b1 = type1[pos];
if ( b1 == b2 )
{
pos++;
}
else if ( b1 < b2 )
{
return -1;
}
else
{
return 1;
}
}
return -11;
}
}
}
}
@Override
public long[] fromBytes( byte[] buffer ) throws IOException
{
int len = IntSerializer.deserialize( buffer );
int pos = 4;
switch ( len )
{
case 0:
return new long[]
{};
case -1:
return null;
default:
long[] longs = new long[len];
for ( int i = 0; i < len; i++ )
{
longs[i] = LongSerializer.deserialize( buffer, pos );
pos += 8;
}
return longs;
}
}
@Override
public long[] fromBytes( byte[] buffer, int pos ) throws IOException
{
int newPos = pos;
int len = IntSerializer.deserialize( buffer, newPos );
switch ( len )
{
case 0:
return new long[]
{};
case -1:
return null;
default:
long[] longs = new long[len];
for ( int i = 0; i < len; i++ )
{
longs[i] = LongSerializer.deserialize( buffer, newPos );
newPos += 8;
}
return longs;
}
}
}