All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.jena.atlas.lib.Bytes Maven / Gradle / Ivy

There is a newer version: 5.2.0
Show newest version
/*
 * 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) ;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy