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    }