jcifs.util.Encdec Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jcifs-ng Show documentation
Show all versions of jcifs-ng Show documentation
A pure-java CIFS/SMB client library
/* encdec - encode and decode integers, times, and
* internationalized strings to and from popular binary formats
* http://www.ioplex.com/~miallen/encdec/
* Copyright (c) 2003 Michael B. Allen
*
* The GNU Library General Public License
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
*/
package jcifs.util;
import java.io.IOException;
import java.util.Date;
import jcifs.SmbConstants;
@SuppressWarnings ( "javadoc" )
public final class Encdec {
private static final long SEC_BETWEEEN_1904_AND_1970 = 2082844800L;
private static final int TIME_1970_SEC_32BE = 1;
private static final int TIME_1970_SEC_32LE = 2;
private static final int TIME_1904_SEC_32BE = 3;
private static final int TIME_1904_SEC_32LE = 4;
private static final int TIME_1601_NANOS_64LE = 5;
private static final int TIME_1601_NANOS_64BE = 6;
private static final int TIME_1970_MILLIS_64BE = 7;
private static final int TIME_1970_MILLIS_64LE = 8;
/**
*
*/
private Encdec () {}
/*
* Encode integers
*/
public static int enc_uint16be ( short s, byte[] dst, int di ) {
dst[ di++ ] = (byte) ( ( s >> 8 ) & 0xFF );
dst[ di ] = (byte) ( s & 0xFF );
return 2;
}
public static int enc_uint32be ( int i, byte[] dst, int di ) {
dst[ di++ ] = (byte) ( ( i >> 24 ) & 0xFF );
dst[ di++ ] = (byte) ( ( i >> 16 ) & 0xFF );
dst[ di++ ] = (byte) ( ( i >> 8 ) & 0xFF );
dst[ di ] = (byte) ( i & 0xFF );
return 4;
}
public static int enc_uint16le ( short s, byte[] dst, int di ) {
dst[ di++ ] = (byte) ( s & 0xFF );
dst[ di ] = (byte) ( ( s >> 8 ) & 0xFF );
return 2;
}
public static int enc_uint32le ( int i, byte[] dst, int di ) {
dst[ di++ ] = (byte) ( i & 0xFF );
dst[ di++ ] = (byte) ( ( i >> 8 ) & 0xFF );
dst[ di++ ] = (byte) ( ( i >> 16 ) & 0xFF );
dst[ di ] = (byte) ( ( i >> 24 ) & 0xFF );
return 4;
}
/*
* Decode integers
*/
public static short dec_uint16be ( byte[] src, int si ) {
return (short) ( ( ( src[ si ] & 0xFF ) << 8 ) | ( src[ si + 1 ] & 0xFF ) );
}
public static int dec_uint32be ( byte[] src, int si ) {
return ( ( src[ si ] & 0xFF ) << 24 ) | ( ( src[ si + 1 ] & 0xFF ) << 16 ) | ( ( src[ si + 2 ] & 0xFF ) << 8 ) | ( src[ si + 3 ] & 0xFF );
}
public static short dec_uint16le ( byte[] src, int si ) {
return (short) ( ( src[ si ] & 0xFF ) | ( ( src[ si + 1 ] & 0xFF ) << 8 ) );
}
public static int dec_uint32le ( byte[] src, int si ) {
return ( src[ si ] & 0xFF ) | ( ( src[ si + 1 ] & 0xFF ) << 8 ) | ( ( src[ si + 2 ] & 0xFF ) << 16 ) | ( ( src[ si + 3 ] & 0xFF ) << 24 );
}
/*
* Encode and decode 64 bit integers
*/
public static int enc_uint64be ( long l, byte[] dst, int di ) {
enc_uint32be((int) ( l & 0xFFFFFFFFL ), dst, di + 4);
enc_uint32be((int) ( ( l >> 32L ) & 0xFFFFFFFFL ), dst, di);
return 8;
}
public static int enc_uint64le ( long l, byte[] dst, int di ) {
enc_uint32le((int) ( l & 0xFFFFFFFFL ), dst, di);
enc_uint32le((int) ( ( l >> 32L ) & 0xFFFFFFFFL ), dst, di + 4);
return 8;
}
public static long dec_uint64be ( byte[] src, int si ) {
long l;
l = dec_uint32be(src, si) & 0xFFFFFFFFL;
l <<= 32L;
l |= dec_uint32be(src, si + 4) & 0xFFFFFFFFL;
return l;
}
public static long dec_uint64le ( byte[] src, int si ) {
long l;
l = dec_uint32le(src, si + 4) & 0xFFFFFFFFL;
l <<= 32L;
l |= dec_uint32le(src, si) & 0xFFFFFFFFL;
return l;
}
/*
* Encode floats
*/
public static int enc_floatle ( float f, byte[] dst, int di ) {
return enc_uint32le(Float.floatToIntBits(f), dst, di);
}
public static int enc_floatbe ( float f, byte[] dst, int di ) {
return enc_uint32be(Float.floatToIntBits(f), dst, di);
}
/*
* Decode floating point numbers
*/
public static float dec_floatle ( byte[] src, int si ) {
return Float.intBitsToFloat(dec_uint32le(src, si));
}
public static float dec_floatbe ( byte[] src, int si ) {
return Float.intBitsToFloat(dec_uint32be(src, si));
}
/*
* Encode and decode doubles
*/
public static int enc_doublele ( double d, byte[] dst, int di ) {
return enc_uint64le(Double.doubleToLongBits(d), dst, di);
}
public static int enc_doublebe ( double d, byte[] dst, int di ) {
return enc_uint64be(Double.doubleToLongBits(d), dst, di);
}
public static double dec_doublele ( byte[] src, int si ) {
return Double.longBitsToDouble(dec_uint64le(src, si));
}
public static double dec_doublebe ( byte[] src, int si ) {
return Double.longBitsToDouble(dec_uint64be(src, si));
}
/*
* Encode times
*/
public static int enc_time ( Date date, byte[] dst, int di, int enc ) {
long t;
switch ( enc ) {
case TIME_1970_SEC_32BE:
return enc_uint32be((int) ( date.getTime() / 1000L ), dst, di);
case TIME_1970_SEC_32LE:
return enc_uint32le((int) ( date.getTime() / 1000L ), dst, di);
case TIME_1904_SEC_32BE:
return enc_uint32be((int) ( ( date.getTime() / 1000L + SEC_BETWEEEN_1904_AND_1970 ) & 0xFFFFFFFF ), dst, di);
case TIME_1904_SEC_32LE:
return enc_uint32le((int) ( ( date.getTime() / 1000L + SEC_BETWEEEN_1904_AND_1970 ) & 0xFFFFFFFF ), dst, di);
case TIME_1601_NANOS_64BE:
t = ( date.getTime() + SmbConstants.MILLISECONDS_BETWEEN_1970_AND_1601 ) * 10000L;
return enc_uint64be(t, dst, di);
case TIME_1601_NANOS_64LE:
t = ( date.getTime() + SmbConstants.MILLISECONDS_BETWEEN_1970_AND_1601 ) * 10000L;
return enc_uint64le(t, dst, di);
case TIME_1970_MILLIS_64BE:
return enc_uint64be(date.getTime(), dst, di);
case TIME_1970_MILLIS_64LE:
return enc_uint64le(date.getTime(), dst, di);
default:
throw new IllegalArgumentException("Unsupported time encoding");
}
}
/*
* Decode times
*/
public static Date dec_time ( byte[] src, int si, int enc ) {
long t;
switch ( enc ) {
case TIME_1970_SEC_32BE:
return new Date(dec_uint32be(src, si) * 1000L);
case TIME_1970_SEC_32LE:
return new Date(dec_uint32le(src, si) * 1000L);
case TIME_1904_SEC_32BE:
return new Date( ( ( dec_uint32be(src, si) & 0xFFFFFFFFL ) - SEC_BETWEEEN_1904_AND_1970 ) * 1000L);
case TIME_1904_SEC_32LE:
return new Date( ( ( dec_uint32le(src, si) & 0xFFFFFFFFL ) - SEC_BETWEEEN_1904_AND_1970 ) * 1000L);
case TIME_1601_NANOS_64BE:
t = dec_uint64be(src, si);
return new Date(t / 10000L - SmbConstants.MILLISECONDS_BETWEEN_1970_AND_1601);
case TIME_1601_NANOS_64LE:
t = dec_uint64le(src, si);
return new Date(t / 10000L - SmbConstants.MILLISECONDS_BETWEEN_1970_AND_1601);
case TIME_1970_MILLIS_64BE:
return new Date(dec_uint64be(src, si));
case TIME_1970_MILLIS_64LE:
return new Date(dec_uint64le(src, si));
default:
throw new IllegalArgumentException("Unsupported time encoding");
}
}
public static int enc_utf8 ( String str, byte[] dst, int di, int dlim ) {
int start = di, ch;
int strlen = str.length();
for ( int i = 0; di < dlim && i < strlen; i++ ) {
ch = str.charAt(i);
if ( ( ch >= 0x0001 ) && ( ch <= 0x007F ) ) {
dst[ di++ ] = (byte) ch;
}
else if ( ch > 0x07FF ) {
if ( ( dlim - di ) < 3 ) {
break;
}
dst[ di++ ] = (byte) ( 0xE0 | ( ( ch >> 12 ) & 0x0F ) );
dst[ di++ ] = (byte) ( 0x80 | ( ( ch >> 6 ) & 0x3F ) );
dst[ di++ ] = (byte) ( 0x80 | ( ( ch >> 0 ) & 0x3F ) );
}
else {
if ( ( dlim - di ) < 2 ) {
break;
}
dst[ di++ ] = (byte) ( 0xC0 | ( ( ch >> 6 ) & 0x1F ) );
dst[ di++ ] = (byte) ( 0x80 | ( ( ch >> 0 ) & 0x3F ) );
}
}
return di - start;
}
public static String dec_utf8 ( byte[] src, int si, int slim ) throws IOException {
char[] uni = new char[slim - si];
int ui, ch;
for ( ui = 0; si < slim && ( ch = src[ si++ ] & 0xFF ) != 0; ui++ ) {
if ( ch < 0x80 ) {
uni[ ui ] = (char) ch;
}
else if ( ( ch & 0xE0 ) == 0xC0 ) {
if ( ( slim - si ) < 2 ) {
break;
}
uni[ ui ] = (char) ( ( ch & 0x1F ) << 6 );
ch = src[ si++ ] & 0xFF;
uni[ ui ] |= ch & 0x3F;
if ( ( ch & 0xC0 ) != 0x80 || uni[ ui ] < 0x80 ) {
throw new IOException("Invalid UTF-8 sequence");
}
}
else if ( ( ch & 0xF0 ) == 0xE0 ) {
if ( ( slim - si ) < 3 ) {
break;
}
uni[ ui ] = (char) ( ( ch & 0x0F ) << 12 );
ch = src[ si++ ] & 0xFF;
if ( ( ch & 0xC0 ) != 0x80 ) {
throw new IOException("Invalid UTF-8 sequence");
}
uni[ ui ] |= ( ch & 0x3F ) << 6;
ch = src[ si++ ] & 0xFF;
uni[ ui ] |= ch & 0x3F;
if ( ( ch & 0xC0 ) != 0x80 || uni[ ui ] < 0x800 ) {
throw new IOException("Invalid UTF-8 sequence");
}
}
else {
throw new IOException("Unsupported UTF-8 sequence");
}
}
return new String(uni, 0, ui);
}
public static String dec_ucs2le ( byte[] src, int si, int slim, char[] buf ) {
int bi;
for ( bi = 0; ( si + 1 ) < slim; bi++, si += 2 ) {
buf[ bi ] = (char) dec_uint16le(src, si);
if ( buf[ bi ] == '\0' ) {
break;
}
}
return new String(buf, 0, bi);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy