001    /**
002     * Copyright (c) 2000-present 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 final String UNICODE_PREFIX = "\\u";
027    
028            public static String bytesToHex(byte[] bytes) {
029                    char[] array = new char[bytes.length * 2];
030    
031                    for (int i = 0; i < bytes.length; i++) {
032                            byte b = bytes[i];
033    
034                            array[(i * 2) + 0] = _HEX_DIGITS[(b >> 4) & 0x0f];
035                            array[(i * 2) + 1] = _HEX_DIGITS[b & 0x0f];
036                    }
037    
038                    return new String(array);
039            }
040    
041            public static String byteToHex(byte b) {
042                    char[] array = {_HEX_DIGITS[(b >> 4) & 0x0f], _HEX_DIGITS[b & 0x0f]};
043    
044                    return new String(array);
045            }
046    
047            public static char[] byteToHex(byte b, char[] hexes) {
048                    return byteToHex(b, hexes, false);
049            }
050    
051            public static char[] byteToHex(byte b, char[] hexes, boolean upperCase) {
052                    if (upperCase) {
053                            return _byteToHex(b, hexes, _HEX_DIGITS_UPPER_CASE);
054                    }
055                    else {
056                            return _byteToHex(b, hexes, _HEX_DIGITS);
057                    }
058            }
059    
060            public static String charToHex(char c) {
061                    byte hi = (byte)(c >>> 8);
062                    byte lo = (byte)(c & 0xff);
063    
064                    char[] array = {
065                            _HEX_DIGITS[(hi >> 4) & 0x0f], _HEX_DIGITS[hi & 0x0f],
066                            _HEX_DIGITS[(lo >> 4) & 0x0f], _HEX_DIGITS[lo & 0x0f]
067                    };
068    
069                    return new String(array);
070            }
071    
072            public static byte[] hexToBytes(String hexString) {
073                    if ((hexString.length() % 2) != 0) {
074                            return new byte[0];
075                    }
076    
077                    byte[] bytes = new byte[hexString.length() / 2];
078    
079                    for (int i = 0; i < hexString.length(); i = i + 2) {
080                            String s = hexString.substring(i, i + 2);
081    
082                            try {
083                                    bytes[i / 2] = (byte)Integer.parseInt(s, 16);
084                            }
085                            catch (NumberFormatException nfe) {
086                                    return new byte[0];
087                            }
088                    }
089    
090                    return bytes;
091            }
092    
093            public static String parseString(String hexString) {
094                    StringBuilder sb = new StringBuilder();
095    
096                    char[] array = hexString.toCharArray();
097    
098                    if ((array.length % 6) != 0) {
099                            _log.error("String is not in hex format");
100    
101                            return hexString;
102                    }
103    
104                    for (int i = 2; i < hexString.length(); i = i + 6) {
105                            String s = hexString.substring(i, i + 4);
106    
107                            try {
108                                    char c = (char)Integer.parseInt(s, 16);
109    
110                                    sb.append(c);
111                            }
112                            catch (Exception e) {
113                                    _log.error(e, e);
114    
115                                    return hexString;
116                            }
117                    }
118    
119                    return sb.toString();
120            }
121    
122            public static String toString(char[] array) {
123                    StringBuilder sb = new StringBuilder(array.length * 6);
124    
125                    char[] hexes = new char[4];
126    
127                    for (int i = 0; i < array.length; i++) {
128                            sb.append(UNICODE_PREFIX);
129                            sb.append(_charToHex(array[i], hexes));
130                    }
131    
132                    return sb.toString();
133            }
134    
135            public static String toString(String s) {
136                    if (s == null) {
137                            return null;
138                    }
139    
140                    StringBuilder sb = new StringBuilder(s.length() * 6);
141    
142                    char[] hexes = new char[4];
143    
144                    for (int i = 0; i < s.length(); i++) {
145                            sb.append(UNICODE_PREFIX);
146                            sb.append(_charToHex(s.charAt(i), hexes));
147                    }
148    
149                    return sb.toString();
150            }
151    
152            private static char[] _byteToHex(byte b, char[] hexes, char[] table) {
153                    hexes[0] = table[(b >> 4) & 0x0f];
154                    hexes[1] = table[b & 0x0f];
155    
156                    return hexes;
157            }
158    
159            private static char[] _charToHex(char c, char[] hexes) {
160                    byte hi = (byte)(c >>> 8);
161                    byte lo = (byte)(c & 0xff);
162    
163                    hexes[0] = _HEX_DIGITS[(hi >> 4) & 0x0f];
164                    hexes[1] = _HEX_DIGITS[hi & 0x0f];
165                    hexes[2] = _HEX_DIGITS[(lo >> 4) & 0x0f];
166                    hexes[3] = _HEX_DIGITS[lo & 0x0f];
167    
168                    return hexes;
169            }
170    
171            private static final char[] _HEX_DIGITS = {
172                    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
173                    'e', 'f'
174            };
175    
176            private static final char[] _HEX_DIGITS_UPPER_CASE = {
177                    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
178                    'E', 'F'
179            };
180    
181            private static final Log _log = LogFactoryUtil.getLog(
182                    UnicodeFormatter.class);
183    
184    }