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