net.devbase.jfreesteel.Utils.java Source code

Java tutorial

Introduction

Here is the source code for net.devbase.jfreesteel.Utils.java

Source

/*
 * jfreesteel: Serbian eID Viewer Library (GNU LGPLv3)
 * Copyright (C) 2011 Goran Rakic
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version
 * 3.0 as published by the Free Software Foundation.
 *
 * This software 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, see
 * http://www.gnu.org/licenses/.
 */

package net.devbase.jfreesteel;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;

/**
 * Functions to print and convert bytes into strings.
 *
 * @author Goran Rakic (grakic@devbase.net)
 */
public class Utils {

    private static final Logger log = LoggerFactory.getLogger(Utils.class);

    private Utils() {
    } // No instantiation, please.

    /**
     * Formats an integer as a hex string of little-endian, non-zero-padded
     * bytes.
     *
     * @param i the integer to format
     * @return the formatted string representing the integer
     */
    public static String int2HexString(final int i) {
        return bytes2HexString(asByteArray(i >>> 24, i >>> 16, i >>> 8, i));
    }

    /**
     * Formats an array of bytes as a string.
     * <p>
     * Silently skips leading zero bytes.
     * <p>
     * TODO(filmil): Silent zero-skipping is weird, check if this is the right thing to do.
     *
     * @param bytes the bytes to print
     * @return formatted byte string, e.g. an array of 0x00, 0x01, 0x02, 0x03
     *         gets printed as: "01:02:03"
     */
    public static String bytes2HexString(byte... bytes) {
        ImmutableList.Builder<String> builder = ImmutableList.builder();
        boolean skipZeros = true;
        for (byte b : bytes) {
            if (skipZeros && b == 0x00) {
                continue;
            }
            skipZeros = false;
            builder.add(String.format("%02X", b));
        }
        return Joiner.on(":").join(builder.build());
    }

    /**
     * Formats a map of integer to byte arrays for printing.
     * <p>
     * Each map entry is written out as a string line, map key first, then an
     * equals sign, then an UTF-8 string interpreted from the bytes.
     * <p>
     * The keys are written out in random order (due to set iteration).
     * <p>
     * TODO(filmil): Why are they written out randomly?
     *
     * @param map the map to format
     * @return the formatted string, one line each.
     */
    public static String map2UTF8String(Map<Integer, byte[]> map) {
        StringBuilder builder = new StringBuilder();
        for (Map.Entry<Integer, byte[]> entry : map.entrySet()) {
            builder.append(String.format("%d = %s\n", entry.getKey(), bytes2UTF8String(entry.getValue())));
        }
        return builder.toString();
    }

    /**
     * Interprets an array of bytes as an UTF-8 string.
     * <p>
     * Failing that, interprets as ISO-8859-1.
     *
     * @param bytes the bytes to convert to string
     */
    public static String bytes2UTF8String(byte... bytes) {
        if (bytes == null) {
            return "";
        }
        try {
            return new String(bytes, Charsets.UTF_8);
        } catch (RuntimeException ex) {
            log.warn(String.format("Could not convert bytes to UTF-8: %s, %s", bytes2HexString(bytes), ex));
            return new String(bytes, Charsets.ISO_8859_1);
        }
    }

    private static byte asByte(int value) {
        return (byte) (value & 0xFF);
    }

    private static byte[] asByteArray(int... values) {
        byte[] valueBytes = new byte[values.length];
        for (int i = 0; i < values.length; i++) {
            valueBytes[i] = asByte(values[i]);
        }
        return valueBytes;
    }
}