001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.util;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    
020    /**
021     * @author Brian Wing Shun Chan
022     * @author Shuyang Zhou
023     */
024    public class UnicodeFormatter {
025    
026            public static String bytesToHex(byte[] bytes) {
027                    char[] array = new char[bytes.length * 2];
028    
029                    for (int i = 0; i < bytes.length; i++) {
030                            byte b = bytes[i];
031    
032                            array[(i * 2) + 0] = _HEX_DIGITS[(b >> 4) & 0x0f];
033                            array[(i * 2) + 1] = _HEX_DIGITS[b & 0x0f];
034                    }
035    
036                    return new String(array);
037            }
038    
039            public static String byteToHex(byte b) {
040                    char[] array = {_HEX_DIGITS[(b >> 4) & 0x0f], _HEX_DIGITS[b & 0x0f]};
041    
042                    return new String(array);
043            }
044    
045            public static char[] byteToHex(byte b, char[] hexes) {
046                    return byteToHex(b, hexes, false);
047            }
048    
049            public static char[] byteToHex(byte b, char[] hexes, boolean upperCase) {
050                    if (upperCase) {
051                            return _byteToHex(b, hexes, _HEX_DIGITS_UPPER_CASE);
052                    }
053                    else {
054                            return _byteToHex(b, hexes, _HEX_DIGITS);
055                    }
056            }
057    
058            public static String charToHex(char c) {
059                    byte hi = (byte)(c >>> 8);
060                    byte lo = (byte)(c & 0xff);
061    
062                    char[] array = {
063                            _HEX_DIGITS[(hi >> 4) & 0x0f], _HEX_DIGITS[hi & 0x0f],
064                            _HEX_DIGITS[(lo >> 4) & 0x0f], _HEX_DIGITS[lo & 0x0f]
065                    };
066    
067                    return new String(array);
068            }
069    
070            public static byte[] hexToBytes(String hexString) {
071                    if ((hexString.length() % 2) != 0) {
072                            return new byte[0];
073                    }
074    
075                    byte[] bytes = new byte[hexString.length() / 2];
076    
077                    for (int i = 0; i < hexString.length(); i = i + 2) {
078                            String s = hexString.substring(i, i + 2);
079    
080                            try {
081                                    bytes[i / 2] = (byte)Integer.parseInt(s, 16);
082                            }
083                            catch (NumberFormatException nfe) {
084                                    return new byte[0];
085                            }
086                    }
087    
088                    return bytes;
089            }
090    
091            public static String parseString(String hexString) {
092                    StringBuilder sb = new StringBuilder();
093    
094                    char[] array = hexString.toCharArray();
095    
096                    if ((array.length % 6) != 0) {
097                            _log.error("String is not in hex format");
098    
099                            return hexString;
100                    }
101    
102                    for (int i = 2; i < hexString.length(); i = i + 6) {
103                            String s = hexString.substring(i, i + 4);
104    
105                            try {
106                                    char c = (char)Integer.parseInt(s, 16);
107    
108                                    sb.append(c);
109                            }
110                            catch (Exception e) {
111                                    _log.error(e, e);
112    
113                                    return hexString;
114                            }
115                    }
116    
117                    return sb.toString();
118            }
119    
120            public static String toString(char[] array) {
121                    StringBuilder sb = new StringBuilder(array.length * 6);
122    
123                    char[] hexes = new char[4];
124    
125                    for (int i = 0; i < array.length; i++) {
126                            sb.append(_UNICODE_PREFIX);
127                            sb.append(_charToHex(array[i], hexes));
128                    }
129    
130                    return sb.toString();
131            }
132    
133            public static String toString(String s) {
134                    if (s == null) {
135                            return null;
136                    }
137    
138                    StringBuilder sb = new StringBuilder(s.length() * 6);
139    
140                    char[] hexes = new char[4];
141    
142                    for (int i = 0; i < s.length(); i++) {
143                            sb.append(_UNICODE_PREFIX);
144                            sb.append(_charToHex(s.charAt(i), hexes));
145                    }
146    
147                    return sb.toString();
148            }
149    
150            private static char[] _byteToHex(byte b, char[] hexes, char[] table) {
151                    hexes[0] = table[(b >> 4) & 0x0f];
152                    hexes[1] = table[b & 0x0f];
153    
154                    return hexes;
155            }
156    
157            private static char[] _charToHex(char c, char[] hexes) {
158                    byte hi = (byte)(c >>> 8);
159                    byte lo = (byte)(c & 0xff);
160    
161                    hexes[0] = _HEX_DIGITS[(hi >> 4) & 0x0f];
162                    hexes[1] = _HEX_DIGITS[hi & 0x0f];
163                    hexes[2] = _HEX_DIGITS[(lo >> 4) & 0x0f];
164                    hexes[3] = _HEX_DIGITS[lo & 0x0f];
165    
166                    return hexes;
167            }
168    
169            private static final char[] _HEX_DIGITS = {
170                    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
171                    'e', 'f'
172            };
173    
174            private static final char[] _HEX_DIGITS_UPPER_CASE = {
175                    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
176                    'E', 'F'
177            };
178    
179            private static final String _UNICODE_PREFIX = "\\u";
180    
181            private static Log _log = LogFactoryUtil.getLog(UnicodeFormatter.class);
182    
183    }