org.apache.jena.atlas.lib.Bytes Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jena-base Show documentation
Show all versions of jena-base Show documentation
This module contains non-RDF library code and the common system runtime.
/*
* 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.jena.atlas.lib;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.UnsupportedEncodingException ;
import java.nio.ByteBuffer ;
import java.nio.CharBuffer ;
import java.nio.charset.CharsetDecoder ;
import java.nio.charset.CharsetEncoder ;
import java.nio.charset.CoderResult ;
/** Byte-oriented operations. Packing and unpacking integers
* is in network order (Big endian - which is the preferred order in Java).
* See wikipedia Endianness.
*/
public class Bytes
{
private Bytes() {}
/** String to UTF8 bytes */
public static byte[] asUTF8bytes(String s) {
return s.getBytes(UTF_8) ;
}
/** String from UTF8 bytes */
public static String fromUTF8bytes(byte[] bytes) {
return new String(bytes, UTF_8) ;
}
/** Compare two byte arrays which may be of different lengths */
public static int compare(byte[] x1, byte[] x2)
{
int n = Math.min(x1.length, x2.length) ;
for ( int i = 0 ; i < n ; i++ )
{
byte b1 = x1[i] ;
byte b2 = x2[i] ;
if ( b1 == b2 )
continue ;
// Treat as unsigned values in the bytes.
return (b1&0xFF) - (b2&0xFF) ;
}
return x1.length - x2.length ;
}
public static int compareByte(byte b1, byte b2)
{
return (b1&0xFF) - (b2&0xFF) ;
}
public static byte[] copyOf(byte[] bytes)
{
return copyOf(bytes, 0, bytes.length) ;
}
public static byte[] copyOf(byte[] bytes, int start)
{
return copyOf(bytes, start, bytes.length-start) ;
}
public static byte[] copyOf(byte[] bytes, int start, int length)
{
byte[] newByteArray = new byte[length] ;
System.arraycopy(bytes, start, newByteArray, 0, length) ;
return newByteArray ;
}
final public static byte[] hexDigitsUC = {
'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' ,
'9' , 'A' , 'B' , 'C' , 'D' , 'E' , 'F' };
final public static byte[] hexDigitsLC = {
'0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' ,
'9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' };
/** Put an int value into an allocated byte array.
* @param v
* @return byte[] array
* @see Integer#SIZE
*/
public static byte[] intToBytes(int v) {
byte[] bytes = new byte[Integer.BYTES] ;
setInt(v, bytes);
return bytes ;
}
/** Put a long value into an allocated byte array.
* @param v
* @return byte[] array
* @see Long#SIZE
*/
public static byte[] longToBytes(long v) {
byte[] bytes = new byte[Long.BYTES] ;
setLong(v, bytes);
return bytes ;
}
/** Get an int from a byte array (network order)
* @param b Byte Array
*/
public static final int getInt(byte[]b)
{ return getInt(b, 0) ; }
/** Get an int from a byte array (network order)
* @param b Byte Array
* @param idx Starting point of bytes
*/
public static final int getInt(byte[]b, int idx)
{
return assembleInt(b[idx+0],
b[idx+1],
b[idx+2],
b[idx+3]) ;
}
/** Get a long from a byte array (network order)
* @param b Byte Array
*/
public static final long getLong(byte[]b)
{ return getLong(b, 0) ; }
/** Get a long from a byte array (network order)
* @param b Byte Array
* @param idx Starting point of bytes
*/
public static final long getLong(byte[]b, int idx)
{
return assembleLong(b[idx+0],
b[idx+1],
b[idx+2],
b[idx+3],
b[idx+4],
b[idx+5],
b[idx+6],
b[idx+7]) ;
}
/** Put an int into a byte array
* @param value The integer
* @param b byte array
*/
public static final void setInt(int value, byte[]b)
{ setInt(value, b, 0) ; }
/** Put an int into a byte array from a given position
* @param x The integer
* @param b byte array
* @param idx starting point
*/
public static final void setInt(int x, byte[]b, int idx)
{
// b[idx+0] = byte3(value) ;
// b[idx+1] = byte2(value) ;
// b[idx+2] = byte1(value) ;
// b[idx+3] = byte0(value) ;
b[idx+0] = (byte)((x >> 24)&0xFF) ;
b[idx+1] = (byte)((x >> 16)&0xFF);
b[idx+2] = (byte)((x >> 8)&0xFF);
b[idx+3] = (byte)(x &0xFF);
}
/** Put a long into a byte array
* @param value The integer
* @param b byte array
*/
public static final void setLong(long value, byte[]b)
{ setLong(value, b, 0) ; }
/** Put a long into a byte array from a given position
* @param value The integer
* @param b byte array
* @param idx starting point
*/
public static final void setLong(long value, byte[] b, int idx) {
int lo = (int)(value & 0xFFFFFFFFL) ;
int hi = (int)(value >>> 32) ;
setInt(hi, b, idx) ;
setInt(lo, b, idx + 4) ;
}
/** int to byte array */
public static byte[] packInt(int val) {
byte[] valBytes = new byte[Integer.SIZE / Byte.SIZE] ;
setInt(val, valBytes, 0) ;
return valBytes ;
}
/** long to byte array */
public static byte[] packLong(long val) {
byte[] valBytes = new byte[Long.SIZE / Byte.SIZE] ;
setLong(val, valBytes, 0) ;
return valBytes ;
}
/** Make an int order of args -- high to low */
static private int assembleInt(byte b3, byte b2, byte b1, byte b0) {
return ((b3 & 0xFF) << 24) |
((b2 & 0xFF) << 16) |
((b1 & 0xFF) << 8) |
((b0 & 0xFF) << 0) ;
}
/** Make a long order of args -- high to low */
static private Long assembleLong(byte b7, byte b6, byte b5, byte b4, byte b3, byte b2, byte b1, byte b0) {
return ((b7 & 0xFFL) << 56) |
((b6 & 0xFFL) << 48) |
((b5 & 0xFFL) << 40) |
((b4 & 0xFFL) << 32) |
((b3 & 0xFFL) << 24) |
((b2 & 0xFFL) << 16) |
((b1 & 0xFFL) << 8) |
((b0 & 0xFFL) << 0) ;
}
private static byte byte3(int x) { return (byte)(x >> 24); }
private static byte byte2(int x) { return (byte)(x >> 16); }
private static byte byte1(int x) { return (byte)(x >> 8); }
private static byte byte0(int x) { return (byte)(x >> 0); }
/** Return the UTF-8 bytes for a string */
public static byte[] string2bytes(String x) {
try {
return x.getBytes("UTF-8") ;
}
catch (UnsupportedEncodingException ex) {
// Impossible.
ex.printStackTrace() ;
return null ;
}
}
/** Return the string for some UTF-8 bytes */
public static String bytes2string(byte[] x) {
try {
return new String(x, "UTF-8") ;
}
catch (UnsupportedEncodingException ex) {
// Impossible-ish.
ex.printStackTrace() ;
return null ;
}
}
/** Encode a string into a ByteBuffer : on return position is the end of the encoding */
public static int toByteBuffer(CharSequence s, ByteBuffer bb) {
//BlockUTF8.fromChars(s, bb) ;
CharsetEncoder enc = Chars.allocEncoder();
int x = toByteBuffer(s, bb, enc) ;
Chars.deallocEncoder(enc) ;
return x ;
}
/** Encode a string into a ByteBuffer : on return position is the end of the encoding */
public static int toByteBuffer(CharSequence s, ByteBuffer bb, CharsetEncoder enc) {
int start = bb.position() ;
CharBuffer cBuff = CharBuffer.wrap(s);
enc.reset();
CoderResult r = enc.encode(cBuff, bb, true) ;
if ( r.isOverflow() )
throw new InternalErrorException("Bytes.toByteBuffer: encode overflow (1)") ;
r = enc.flush(bb) ;
if ( r.isOverflow() )
throw new InternalErrorException("Bytes.toByteBuffer: encode overflow (2)") ;
// if ( r.isUnderflow() )
// throw new InternalErrorException("Bytes.toByteBuffer: encode underflow") ;
int finish = bb.position() ;
return finish-start ;
}
/** Decode a string into a ByteBuffer */
public static String fromByteBuffer(ByteBuffer bb)
{
//return BlockUTF8.toString(bb) ;
// To be removed (Dec 2011)
CharsetDecoder dec = Chars.allocDecoder();
String x = fromByteBuffer(bb, dec) ;
Chars.deallocDecoder(dec) ;
return x ;
}
/** Decode a string into a ByteBuffer */
public static String fromByteBuffer(ByteBuffer bb, CharsetDecoder dec) {
if ( bb.remaining() == 0 )
return "" ;
dec.reset() ;
CharBuffer cBuff = CharBuffer.allocate(bb.remaining()) ;
CoderResult r = dec.decode(bb, cBuff, true) ;
if ( r.isOverflow() )
throw new InternalErrorException("fromByteBuffer: decode overflow (1)") ;
r = dec.flush(cBuff) ;
if ( r.isOverflow() )
throw new InternalErrorException("fromByteBuffer: decode overflow (2)") ;
cBuff.flip() ;
return cBuff.toString() ;
}
/**
* Return a hex string representing the bytes, zero padded to length of byte
* array.
*/
public static String asHex(byte[] bytes) {
return asHexUC(bytes) ;
}
public static String asHexUC(byte[] bytes) {
return asHex(bytes, 0, bytes.length, Chars.hexDigitsUC) ;
}
public static String asHexLC(byte[] bytes) {
return asHex(bytes, 0, bytes.length, Chars.hexDigitsLC) ;
}
public static String asHex(byte[] bytes, int start, int finish, char[] hexDigits) {
StringBuilder sw = new StringBuilder(bytes.length*2) ;
for ( int i = start ; i < finish ; i++ ) {
byte b = bytes[i] ;
int hi = (b & 0xF0) >> 4 ;
int lo = b & 0xF ;
// if ( i != start ) sw.append(' ') ;
sw.append(hexDigits[hi]) ;
sw.append(hexDigits[lo]) ;
}
return sw.toString() ;
}
/** Return a hex string representing the byte. */
public static String asHex(byte b)
{
return asHexUC(b) ;
}
public static String asHexUC(byte b)
{
return asHex(b, Chars.hexDigitsUC) ;
}
public static String asHexLC(byte b)
{
return asHex(b, Chars.hexDigitsLC) ;
}
private static String asHex(byte b, char[] hexDigits)
{
int hi = (b & 0xF0) >> 4 ;
int lo = b & 0xF ;
char[] chars = new char[2] ;
chars[0] = hexDigits[hi] ;
chars[1] = hexDigits[lo] ;
return new String(chars) ;
}
public static int hexCharToInt(char c)
{
if ( '0' <= c && c <= '9' )
return c-'0' ;
else if ( 'A' <= c && c <= 'F' )
return c-'A'+10 ;
else if ( 'a' <= c && c <= 'f' )
return c-'a'+10 ;
else
throw new IllegalArgumentException("Bad index char : "+c) ;
}
}