    001    package com.skype.util;
    002
    003    public class Log
    004    {
    005        /**
    006         * enable debug output by setting this property to true
    007         */
    008        public enum Severity {
    009            kNone,
    010            kDebug,
    011            kError
    012        }
    013        public static Severity level = Severity.kNone;
    014
    015        public static void cycleDebugLevel()
    016        {
    017            if (level == Severity.kNone) {
    018                level = Severity.kDebug;
    019            }
    020            else if (level == Severity.kDebug) {
    021                level = Severity.kError;
    022            }
    023            else {
    024                level = Severity.kNone;
    025            }
    026        }
    027
    028        public static String debugLevel()
    029        {
    030            if (level == Severity.kDebug)
    031                return "Debug";
    032            if (level == Severity.kError)
    033                return "Error";
    034            return "None";
    035        }
    036
    037        public static int d(String tag, String msg)
    038        {
    039            if (isDebug())
    040                write_log("DEBUG", tag, msg);
    041            return 0;
    042        }
    043
    044        public static int e(String tag, String msg)
    045        {
    046            if (isError())
    047                write_log("ERROR", tag, msg);
    048            return 0;
    049        }
    050
    051        public static int e(String tag, String msg, Throwable e)
    052        {
    053            if (isError()) {
    054                write_log("ERROR", tag, msg + " : " + e.getMessage());
    055            }
    056            return 0;
    057        }
    058
    059        /**
    060         * Write hex dump of a byte array, 16 bytes per line, with printable
    061         * characters displayed in a text block on the right
    062         *
    063         * @param buff
    064         *            - array of bytes to dump
    065         */
    066        public static void hexdump(byte[] buff)
    067        {
    068            hexdump(buff, buff.length);
    069        }
    070
    071        public static void hexdump(byte[] buff, int len)
    072        {
    073            if ( ! isDebug())
    074                return;
    075
    076            String hex = "", prn = "", ln;
    077            for (int r = 0; r < len; r += 16) {
    078                hex = "";
    079                prn = "";
    080                int maxcol = Math.min(16, len - r);
    081                for (int c = 0; c < maxcol; c++) {
    082                    int value = (int) buff[c + r] & 0xFF;
    083                    Character ch = (char) (buff[c + r]);
    084                    if (c % 2 == 0)
    085                        hex += " ";
    086                    hex += padLeft(Integer.toHexString(value), 2);
    087                    prn += isPrintableChar(ch) ? ch : '.';
    088                }
    089                ln = String.format("%-42s - %s", hex, prn);
    090                write_log("", padLeft(Integer.toHexString(r), 8), ln);
    091            }
    092        }
    093
    094        private static boolean isDebug()
    095        {
    096            return level == Severity.kDebug;
    097        }
    098
    099        private static boolean isError()
    100        {
    101            return level == Severity.kDebug || level == Severity.kError;
    102        }
    103
    104        private static void write_log(String lvl, String tag, String msg)
    105        {
    106            System.err.println(lvl + ":" + tag + ":" + msg);
    107        }
    108
    109        private static String padLeft(String s, int n)
    110        {
    111            String padded = "";
    112            for (int i = 0, im = n-s.length(); i < im; i++)
    113                padded += '0';
    114            return padded + s;
    115        }
    116
    117        private static boolean isPrintableChar(char c)
    118        {
    119            Character.UnicodeBlock block = Character.UnicodeBlock.of(c);
    120            return (!Character.isISOControl(c)) && block != null
    121                    && block != Character.UnicodeBlock.SPECIALS;
    122        }
    123    }