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    }