| | |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opendj3/legal-notices/CDDLv1_0.txt |
| | | * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opendj3/legal-notices/CDDLv1_0.txt. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | |
| | | |
| | | package com.forgerock.opendj.util; |
| | | |
| | | |
| | | |
| | | import static org.forgerock.opendj.ldap.CoreMessages.ERR_HEX_DECODE_INVALID_CHARACTER; |
| | | import static org.forgerock.opendj.ldap.CoreMessages.ERR_HEX_DECODE_INVALID_LENGTH; |
| | | |
| | |
| | | import java.nio.CharBuffer; |
| | | import java.nio.charset.Charset; |
| | | import java.text.ParseException; |
| | | import java.util.*; |
| | | import java.util.Arrays; |
| | | import java.util.Calendar; |
| | | import java.util.Collection; |
| | | import java.util.Date; |
| | | import java.util.GregorianCalendar; |
| | | import java.util.Iterator; |
| | | import java.util.Locale; |
| | | import java.util.TimeZone; |
| | | import java.util.concurrent.Executors; |
| | | import java.util.concurrent.ScheduledExecutorService; |
| | | import java.util.concurrent.ThreadFactory; |
| | |
| | | import org.forgerock.opendj.ldap.ByteSequence; |
| | | import org.forgerock.opendj.ldap.ByteStringBuilder; |
| | | |
| | | |
| | | |
| | | /** |
| | | * Common utility methods. |
| | | */ |
| | | public final class StaticUtils |
| | | { |
| | | /** |
| | | * The debug logger which should be used by the SDK. |
| | | */ |
| | | public static final Logger DEBUG_LOG = Logger.getLogger("org.forgerock.opendj.ldap"); |
| | | public final class StaticUtils { |
| | | /** |
| | | * The debug logger which should be used by the SDK. |
| | | */ |
| | | public static final Logger DEBUG_LOG = Logger.getLogger("org.forgerock.opendj.ldap"); |
| | | |
| | | /** |
| | | * The end-of-line character for this platform. |
| | | */ |
| | | public static final String EOL = System.getProperty("line.separator"); |
| | | /** |
| | | * The end-of-line character for this platform. |
| | | */ |
| | | public static final String EOL = System.getProperty("line.separator"); |
| | | |
| | | /** |
| | | * A zero-length byte array. |
| | | */ |
| | | public static final byte[] EMPTY_BYTES = new byte[0]; |
| | | /** |
| | | * A zero-length byte array. |
| | | */ |
| | | public static final byte[] EMPTY_BYTES = new byte[0]; |
| | | |
| | | // The name of the time zone for universal coordinated time (UTC). |
| | | private static final String TIME_ZONE_UTC = "UTC"; |
| | | // The name of the time zone for universal coordinated time (UTC). |
| | | private static final String TIME_ZONE_UTC = "UTC"; |
| | | |
| | | // UTC TimeZone is assumed to never change over JVM lifetime |
| | | private static final TimeZone TIME_ZONE_UTC_OBJ = TimeZone |
| | | .getTimeZone(TIME_ZONE_UTC); |
| | | // UTC TimeZone is assumed to never change over JVM lifetime |
| | | private static final TimeZone TIME_ZONE_UTC_OBJ = TimeZone.getTimeZone(TIME_ZONE_UTC); |
| | | |
| | | private static ScheduledExecutorService defaultScheduler = null; |
| | | private static ScheduledExecutorService defaultScheduler = null; |
| | | |
| | | private static final Object DEFAULT_SCHEDULER_LOCK = new Object(); |
| | | private static final Object DEFAULT_SCHEDULER_LOCK = new Object(); |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a string representation of the provided byte in hexadecimal. |
| | | * |
| | | * @param b |
| | | * The byte for which to retrieve the hexadecimal string |
| | | * representation. |
| | | * @return The string representation of the provided byte in hexadecimal. |
| | | */ |
| | | public static String byteToHex(final byte b) |
| | | { |
| | | switch (b & 0xFF) |
| | | { |
| | | case 0x00: |
| | | return "00"; |
| | | case 0x01: |
| | | return "01"; |
| | | case 0x02: |
| | | return "02"; |
| | | case 0x03: |
| | | return "03"; |
| | | case 0x04: |
| | | return "04"; |
| | | case 0x05: |
| | | return "05"; |
| | | case 0x06: |
| | | return "06"; |
| | | case 0x07: |
| | | return "07"; |
| | | case 0x08: |
| | | return "08"; |
| | | case 0x09: |
| | | return "09"; |
| | | case 0x0A: |
| | | return "0A"; |
| | | case 0x0B: |
| | | return "0B"; |
| | | case 0x0C: |
| | | return "0C"; |
| | | case 0x0D: |
| | | return "0D"; |
| | | case 0x0E: |
| | | return "0E"; |
| | | case 0x0F: |
| | | return "0F"; |
| | | case 0x10: |
| | | return "10"; |
| | | case 0x11: |
| | | return "11"; |
| | | case 0x12: |
| | | return "12"; |
| | | case 0x13: |
| | | return "13"; |
| | | case 0x14: |
| | | return "14"; |
| | | case 0x15: |
| | | return "15"; |
| | | case 0x16: |
| | | return "16"; |
| | | case 0x17: |
| | | return "17"; |
| | | case 0x18: |
| | | return "18"; |
| | | case 0x19: |
| | | return "19"; |
| | | case 0x1A: |
| | | return "1A"; |
| | | case 0x1B: |
| | | return "1B"; |
| | | case 0x1C: |
| | | return "1C"; |
| | | case 0x1D: |
| | | return "1D"; |
| | | case 0x1E: |
| | | return "1E"; |
| | | case 0x1F: |
| | | return "1F"; |
| | | case 0x20: |
| | | return "20"; |
| | | case 0x21: |
| | | return "21"; |
| | | case 0x22: |
| | | return "22"; |
| | | case 0x23: |
| | | return "23"; |
| | | case 0x24: |
| | | return "24"; |
| | | case 0x25: |
| | | return "25"; |
| | | case 0x26: |
| | | return "26"; |
| | | case 0x27: |
| | | return "27"; |
| | | case 0x28: |
| | | return "28"; |
| | | case 0x29: |
| | | return "29"; |
| | | case 0x2A: |
| | | return "2A"; |
| | | case 0x2B: |
| | | return "2B"; |
| | | case 0x2C: |
| | | return "2C"; |
| | | case 0x2D: |
| | | return "2D"; |
| | | case 0x2E: |
| | | return "2E"; |
| | | case 0x2F: |
| | | return "2F"; |
| | | case 0x30: |
| | | return "30"; |
| | | case 0x31: |
| | | return "31"; |
| | | case 0x32: |
| | | return "32"; |
| | | case 0x33: |
| | | return "33"; |
| | | case 0x34: |
| | | return "34"; |
| | | case 0x35: |
| | | return "35"; |
| | | case 0x36: |
| | | return "36"; |
| | | case 0x37: |
| | | return "37"; |
| | | case 0x38: |
| | | return "38"; |
| | | case 0x39: |
| | | return "39"; |
| | | case 0x3A: |
| | | return "3A"; |
| | | case 0x3B: |
| | | return "3B"; |
| | | case 0x3C: |
| | | return "3C"; |
| | | case 0x3D: |
| | | return "3D"; |
| | | case 0x3E: |
| | | return "3E"; |
| | | case 0x3F: |
| | | return "3F"; |
| | | case 0x40: |
| | | return "40"; |
| | | case 0x41: |
| | | return "41"; |
| | | case 0x42: |
| | | return "42"; |
| | | case 0x43: |
| | | return "43"; |
| | | case 0x44: |
| | | return "44"; |
| | | case 0x45: |
| | | return "45"; |
| | | case 0x46: |
| | | return "46"; |
| | | case 0x47: |
| | | return "47"; |
| | | case 0x48: |
| | | return "48"; |
| | | case 0x49: |
| | | return "49"; |
| | | case 0x4A: |
| | | return "4A"; |
| | | case 0x4B: |
| | | return "4B"; |
| | | case 0x4C: |
| | | return "4C"; |
| | | case 0x4D: |
| | | return "4D"; |
| | | case 0x4E: |
| | | return "4E"; |
| | | case 0x4F: |
| | | return "4F"; |
| | | case 0x50: |
| | | return "50"; |
| | | case 0x51: |
| | | return "51"; |
| | | case 0x52: |
| | | return "52"; |
| | | case 0x53: |
| | | return "53"; |
| | | case 0x54: |
| | | return "54"; |
| | | case 0x55: |
| | | return "55"; |
| | | case 0x56: |
| | | return "56"; |
| | | case 0x57: |
| | | return "57"; |
| | | case 0x58: |
| | | return "58"; |
| | | case 0x59: |
| | | return "59"; |
| | | case 0x5A: |
| | | return "5A"; |
| | | case 0x5B: |
| | | return "5B"; |
| | | case 0x5C: |
| | | return "5C"; |
| | | case 0x5D: |
| | | return "5D"; |
| | | case 0x5E: |
| | | return "5E"; |
| | | case 0x5F: |
| | | return "5F"; |
| | | case 0x60: |
| | | return "60"; |
| | | case 0x61: |
| | | return "61"; |
| | | case 0x62: |
| | | return "62"; |
| | | case 0x63: |
| | | return "63"; |
| | | case 0x64: |
| | | return "64"; |
| | | case 0x65: |
| | | return "65"; |
| | | case 0x66: |
| | | return "66"; |
| | | case 0x67: |
| | | return "67"; |
| | | case 0x68: |
| | | return "68"; |
| | | case 0x69: |
| | | return "69"; |
| | | case 0x6A: |
| | | return "6A"; |
| | | case 0x6B: |
| | | return "6B"; |
| | | case 0x6C: |
| | | return "6C"; |
| | | case 0x6D: |
| | | return "6D"; |
| | | case 0x6E: |
| | | return "6E"; |
| | | case 0x6F: |
| | | return "6F"; |
| | | case 0x70: |
| | | return "70"; |
| | | case 0x71: |
| | | return "71"; |
| | | case 0x72: |
| | | return "72"; |
| | | case 0x73: |
| | | return "73"; |
| | | case 0x74: |
| | | return "74"; |
| | | case 0x75: |
| | | return "75"; |
| | | case 0x76: |
| | | return "76"; |
| | | case 0x77: |
| | | return "77"; |
| | | case 0x78: |
| | | return "78"; |
| | | case 0x79: |
| | | return "79"; |
| | | case 0x7A: |
| | | return "7A"; |
| | | case 0x7B: |
| | | return "7B"; |
| | | case 0x7C: |
| | | return "7C"; |
| | | case 0x7D: |
| | | return "7D"; |
| | | case 0x7E: |
| | | return "7E"; |
| | | case 0x7F: |
| | | return "7F"; |
| | | case 0x80: |
| | | return "80"; |
| | | case 0x81: |
| | | return "81"; |
| | | case 0x82: |
| | | return "82"; |
| | | case 0x83: |
| | | return "83"; |
| | | case 0x84: |
| | | return "84"; |
| | | case 0x85: |
| | | return "85"; |
| | | case 0x86: |
| | | return "86"; |
| | | case 0x87: |
| | | return "87"; |
| | | case 0x88: |
| | | return "88"; |
| | | case 0x89: |
| | | return "89"; |
| | | case 0x8A: |
| | | return "8A"; |
| | | case 0x8B: |
| | | return "8B"; |
| | | case 0x8C: |
| | | return "8C"; |
| | | case 0x8D: |
| | | return "8D"; |
| | | case 0x8E: |
| | | return "8E"; |
| | | case 0x8F: |
| | | return "8F"; |
| | | case 0x90: |
| | | return "90"; |
| | | case 0x91: |
| | | return "91"; |
| | | case 0x92: |
| | | return "92"; |
| | | case 0x93: |
| | | return "93"; |
| | | case 0x94: |
| | | return "94"; |
| | | case 0x95: |
| | | return "95"; |
| | | case 0x96: |
| | | return "96"; |
| | | case 0x97: |
| | | return "97"; |
| | | case 0x98: |
| | | return "98"; |
| | | case 0x99: |
| | | return "99"; |
| | | case 0x9A: |
| | | return "9A"; |
| | | case 0x9B: |
| | | return "9B"; |
| | | case 0x9C: |
| | | return "9C"; |
| | | case 0x9D: |
| | | return "9D"; |
| | | case 0x9E: |
| | | return "9E"; |
| | | case 0x9F: |
| | | return "9F"; |
| | | case 0xA0: |
| | | return "A0"; |
| | | case 0xA1: |
| | | return "A1"; |
| | | case 0xA2: |
| | | return "A2"; |
| | | case 0xA3: |
| | | return "A3"; |
| | | case 0xA4: |
| | | return "A4"; |
| | | case 0xA5: |
| | | return "A5"; |
| | | case 0xA6: |
| | | return "A6"; |
| | | case 0xA7: |
| | | return "A7"; |
| | | case 0xA8: |
| | | return "A8"; |
| | | case 0xA9: |
| | | return "A9"; |
| | | case 0xAA: |
| | | return "AA"; |
| | | case 0xAB: |
| | | return "AB"; |
| | | case 0xAC: |
| | | return "AC"; |
| | | case 0xAD: |
| | | return "AD"; |
| | | case 0xAE: |
| | | return "AE"; |
| | | case 0xAF: |
| | | return "AF"; |
| | | case 0xB0: |
| | | return "B0"; |
| | | case 0xB1: |
| | | return "B1"; |
| | | case 0xB2: |
| | | return "B2"; |
| | | case 0xB3: |
| | | return "B3"; |
| | | case 0xB4: |
| | | return "B4"; |
| | | case 0xB5: |
| | | return "B5"; |
| | | case 0xB6: |
| | | return "B6"; |
| | | case 0xB7: |
| | | return "B7"; |
| | | case 0xB8: |
| | | return "B8"; |
| | | case 0xB9: |
| | | return "B9"; |
| | | case 0xBA: |
| | | return "BA"; |
| | | case 0xBB: |
| | | return "BB"; |
| | | case 0xBC: |
| | | return "BC"; |
| | | case 0xBD: |
| | | return "BD"; |
| | | case 0xBE: |
| | | return "BE"; |
| | | case 0xBF: |
| | | return "BF"; |
| | | case 0xC0: |
| | | return "C0"; |
| | | case 0xC1: |
| | | return "C1"; |
| | | case 0xC2: |
| | | return "C2"; |
| | | case 0xC3: |
| | | return "C3"; |
| | | case 0xC4: |
| | | return "C4"; |
| | | case 0xC5: |
| | | return "C5"; |
| | | case 0xC6: |
| | | return "C6"; |
| | | case 0xC7: |
| | | return "C7"; |
| | | case 0xC8: |
| | | return "C8"; |
| | | case 0xC9: |
| | | return "C9"; |
| | | case 0xCA: |
| | | return "CA"; |
| | | case 0xCB: |
| | | return "CB"; |
| | | case 0xCC: |
| | | return "CC"; |
| | | case 0xCD: |
| | | return "CD"; |
| | | case 0xCE: |
| | | return "CE"; |
| | | case 0xCF: |
| | | return "CF"; |
| | | case 0xD0: |
| | | return "D0"; |
| | | case 0xD1: |
| | | return "D1"; |
| | | case 0xD2: |
| | | return "D2"; |
| | | case 0xD3: |
| | | return "D3"; |
| | | case 0xD4: |
| | | return "D4"; |
| | | case 0xD5: |
| | | return "D5"; |
| | | case 0xD6: |
| | | return "D6"; |
| | | case 0xD7: |
| | | return "D7"; |
| | | case 0xD8: |
| | | return "D8"; |
| | | case 0xD9: |
| | | return "D9"; |
| | | case 0xDA: |
| | | return "DA"; |
| | | case 0xDB: |
| | | return "DB"; |
| | | case 0xDC: |
| | | return "DC"; |
| | | case 0xDD: |
| | | return "DD"; |
| | | case 0xDE: |
| | | return "DE"; |
| | | case 0xDF: |
| | | return "DF"; |
| | | case 0xE0: |
| | | return "E0"; |
| | | case 0xE1: |
| | | return "E1"; |
| | | case 0xE2: |
| | | return "E2"; |
| | | case 0xE3: |
| | | return "E3"; |
| | | case 0xE4: |
| | | return "E4"; |
| | | case 0xE5: |
| | | return "E5"; |
| | | case 0xE6: |
| | | return "E6"; |
| | | case 0xE7: |
| | | return "E7"; |
| | | case 0xE8: |
| | | return "E8"; |
| | | case 0xE9: |
| | | return "E9"; |
| | | case 0xEA: |
| | | return "EA"; |
| | | case 0xEB: |
| | | return "EB"; |
| | | case 0xEC: |
| | | return "EC"; |
| | | case 0xED: |
| | | return "ED"; |
| | | case 0xEE: |
| | | return "EE"; |
| | | case 0xEF: |
| | | return "EF"; |
| | | case 0xF0: |
| | | return "F0"; |
| | | case 0xF1: |
| | | return "F1"; |
| | | case 0xF2: |
| | | return "F2"; |
| | | case 0xF3: |
| | | return "F3"; |
| | | case 0xF4: |
| | | return "F4"; |
| | | case 0xF5: |
| | | return "F5"; |
| | | case 0xF6: |
| | | return "F6"; |
| | | case 0xF7: |
| | | return "F7"; |
| | | case 0xF8: |
| | | return "F8"; |
| | | case 0xF9: |
| | | return "F9"; |
| | | case 0xFA: |
| | | return "FA"; |
| | | case 0xFB: |
| | | return "FB"; |
| | | case 0xFC: |
| | | return "FC"; |
| | | case 0xFD: |
| | | return "FD"; |
| | | case 0xFE: |
| | | return "FE"; |
| | | case 0xFF: |
| | | return "FF"; |
| | | default: |
| | | return "??"; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a string representation of the provided byte in hexadecimal. |
| | | * |
| | | * @param b |
| | | * The byte for which to retrieve the hexadecimal string |
| | | * representation. |
| | | * @return The string representation of the provided byte in hexadecimal using |
| | | * lowercase characters. |
| | | */ |
| | | public static String byteToLowerHex(final byte b) |
| | | { |
| | | switch (b & 0xFF) |
| | | { |
| | | case 0x00: |
| | | return "00"; |
| | | case 0x01: |
| | | return "01"; |
| | | case 0x02: |
| | | return "02"; |
| | | case 0x03: |
| | | return "03"; |
| | | case 0x04: |
| | | return "04"; |
| | | case 0x05: |
| | | return "05"; |
| | | case 0x06: |
| | | return "06"; |
| | | case 0x07: |
| | | return "07"; |
| | | case 0x08: |
| | | return "08"; |
| | | case 0x09: |
| | | return "09"; |
| | | case 0x0A: |
| | | return "0a"; |
| | | case 0x0B: |
| | | return "0b"; |
| | | case 0x0C: |
| | | return "0c"; |
| | | case 0x0D: |
| | | return "0d"; |
| | | case 0x0E: |
| | | return "0e"; |
| | | case 0x0F: |
| | | return "0f"; |
| | | case 0x10: |
| | | return "10"; |
| | | case 0x11: |
| | | return "11"; |
| | | case 0x12: |
| | | return "12"; |
| | | case 0x13: |
| | | return "13"; |
| | | case 0x14: |
| | | return "14"; |
| | | case 0x15: |
| | | return "15"; |
| | | case 0x16: |
| | | return "16"; |
| | | case 0x17: |
| | | return "17"; |
| | | case 0x18: |
| | | return "18"; |
| | | case 0x19: |
| | | return "19"; |
| | | case 0x1A: |
| | | return "1a"; |
| | | case 0x1B: |
| | | return "1b"; |
| | | case 0x1C: |
| | | return "1c"; |
| | | case 0x1D: |
| | | return "1d"; |
| | | case 0x1E: |
| | | return "1e"; |
| | | case 0x1F: |
| | | return "1f"; |
| | | case 0x20: |
| | | return "20"; |
| | | case 0x21: |
| | | return "21"; |
| | | case 0x22: |
| | | return "22"; |
| | | case 0x23: |
| | | return "23"; |
| | | case 0x24: |
| | | return "24"; |
| | | case 0x25: |
| | | return "25"; |
| | | case 0x26: |
| | | return "26"; |
| | | case 0x27: |
| | | return "27"; |
| | | case 0x28: |
| | | return "28"; |
| | | case 0x29: |
| | | return "29"; |
| | | case 0x2A: |
| | | return "2a"; |
| | | case 0x2B: |
| | | return "2b"; |
| | | case 0x2C: |
| | | return "2c"; |
| | | case 0x2D: |
| | | return "2d"; |
| | | case 0x2E: |
| | | return "2e"; |
| | | case 0x2F: |
| | | return "2f"; |
| | | case 0x30: |
| | | return "30"; |
| | | case 0x31: |
| | | return "31"; |
| | | case 0x32: |
| | | return "32"; |
| | | case 0x33: |
| | | return "33"; |
| | | case 0x34: |
| | | return "34"; |
| | | case 0x35: |
| | | return "35"; |
| | | case 0x36: |
| | | return "36"; |
| | | case 0x37: |
| | | return "37"; |
| | | case 0x38: |
| | | return "38"; |
| | | case 0x39: |
| | | return "39"; |
| | | case 0x3A: |
| | | return "3a"; |
| | | case 0x3B: |
| | | return "3b"; |
| | | case 0x3C: |
| | | return "3c"; |
| | | case 0x3D: |
| | | return "3d"; |
| | | case 0x3E: |
| | | return "3e"; |
| | | case 0x3F: |
| | | return "3f"; |
| | | case 0x40: |
| | | return "40"; |
| | | case 0x41: |
| | | return "41"; |
| | | case 0x42: |
| | | return "42"; |
| | | case 0x43: |
| | | return "43"; |
| | | case 0x44: |
| | | return "44"; |
| | | case 0x45: |
| | | return "45"; |
| | | case 0x46: |
| | | return "46"; |
| | | case 0x47: |
| | | return "47"; |
| | | case 0x48: |
| | | return "48"; |
| | | case 0x49: |
| | | return "49"; |
| | | case 0x4A: |
| | | return "4a"; |
| | | case 0x4B: |
| | | return "4b"; |
| | | case 0x4C: |
| | | return "4c"; |
| | | case 0x4D: |
| | | return "4d"; |
| | | case 0x4E: |
| | | return "4e"; |
| | | case 0x4F: |
| | | return "4f"; |
| | | case 0x50: |
| | | return "50"; |
| | | case 0x51: |
| | | return "51"; |
| | | case 0x52: |
| | | return "52"; |
| | | case 0x53: |
| | | return "53"; |
| | | case 0x54: |
| | | return "54"; |
| | | case 0x55: |
| | | return "55"; |
| | | case 0x56: |
| | | return "56"; |
| | | case 0x57: |
| | | return "57"; |
| | | case 0x58: |
| | | return "58"; |
| | | case 0x59: |
| | | return "59"; |
| | | case 0x5A: |
| | | return "5a"; |
| | | case 0x5B: |
| | | return "5b"; |
| | | case 0x5C: |
| | | return "5c"; |
| | | case 0x5D: |
| | | return "5d"; |
| | | case 0x5E: |
| | | return "5e"; |
| | | case 0x5F: |
| | | return "5f"; |
| | | case 0x60: |
| | | return "60"; |
| | | case 0x61: |
| | | return "61"; |
| | | case 0x62: |
| | | return "62"; |
| | | case 0x63: |
| | | return "63"; |
| | | case 0x64: |
| | | return "64"; |
| | | case 0x65: |
| | | return "65"; |
| | | case 0x66: |
| | | return "66"; |
| | | case 0x67: |
| | | return "67"; |
| | | case 0x68: |
| | | return "68"; |
| | | case 0x69: |
| | | return "69"; |
| | | case 0x6A: |
| | | return "6a"; |
| | | case 0x6B: |
| | | return "6b"; |
| | | case 0x6C: |
| | | return "6c"; |
| | | case 0x6D: |
| | | return "6d"; |
| | | case 0x6E: |
| | | return "6e"; |
| | | case 0x6F: |
| | | return "6f"; |
| | | case 0x70: |
| | | return "70"; |
| | | case 0x71: |
| | | return "71"; |
| | | case 0x72: |
| | | return "72"; |
| | | case 0x73: |
| | | return "73"; |
| | | case 0x74: |
| | | return "74"; |
| | | case 0x75: |
| | | return "75"; |
| | | case 0x76: |
| | | return "76"; |
| | | case 0x77: |
| | | return "77"; |
| | | case 0x78: |
| | | return "78"; |
| | | case 0x79: |
| | | return "79"; |
| | | case 0x7A: |
| | | return "7a"; |
| | | case 0x7B: |
| | | return "7b"; |
| | | case 0x7C: |
| | | return "7c"; |
| | | case 0x7D: |
| | | return "7d"; |
| | | case 0x7E: |
| | | return "7e"; |
| | | case 0x7F: |
| | | return "7f"; |
| | | case 0x80: |
| | | return "80"; |
| | | case 0x81: |
| | | return "81"; |
| | | case 0x82: |
| | | return "82"; |
| | | case 0x83: |
| | | return "83"; |
| | | case 0x84: |
| | | return "84"; |
| | | case 0x85: |
| | | return "85"; |
| | | case 0x86: |
| | | return "86"; |
| | | case 0x87: |
| | | return "87"; |
| | | case 0x88: |
| | | return "88"; |
| | | case 0x89: |
| | | return "89"; |
| | | case 0x8A: |
| | | return "8a"; |
| | | case 0x8B: |
| | | return "8b"; |
| | | case 0x8C: |
| | | return "8c"; |
| | | case 0x8D: |
| | | return "8d"; |
| | | case 0x8E: |
| | | return "8e"; |
| | | case 0x8F: |
| | | return "8f"; |
| | | case 0x90: |
| | | return "90"; |
| | | case 0x91: |
| | | return "91"; |
| | | case 0x92: |
| | | return "92"; |
| | | case 0x93: |
| | | return "93"; |
| | | case 0x94: |
| | | return "94"; |
| | | case 0x95: |
| | | return "95"; |
| | | case 0x96: |
| | | return "96"; |
| | | case 0x97: |
| | | return "97"; |
| | | case 0x98: |
| | | return "98"; |
| | | case 0x99: |
| | | return "99"; |
| | | case 0x9A: |
| | | return "9a"; |
| | | case 0x9B: |
| | | return "9b"; |
| | | case 0x9C: |
| | | return "9c"; |
| | | case 0x9D: |
| | | return "9d"; |
| | | case 0x9E: |
| | | return "9e"; |
| | | case 0x9F: |
| | | return "9f"; |
| | | case 0xA0: |
| | | return "a0"; |
| | | case 0xA1: |
| | | return "a1"; |
| | | case 0xA2: |
| | | return "a2"; |
| | | case 0xA3: |
| | | return "a3"; |
| | | case 0xA4: |
| | | return "a4"; |
| | | case 0xA5: |
| | | return "a5"; |
| | | case 0xA6: |
| | | return "a6"; |
| | | case 0xA7: |
| | | return "a7"; |
| | | case 0xA8: |
| | | return "a8"; |
| | | case 0xA9: |
| | | return "a9"; |
| | | case 0xAA: |
| | | return "aa"; |
| | | case 0xAB: |
| | | return "ab"; |
| | | case 0xAC: |
| | | return "ac"; |
| | | case 0xAD: |
| | | return "ad"; |
| | | case 0xAE: |
| | | return "ae"; |
| | | case 0xAF: |
| | | return "af"; |
| | | case 0xB0: |
| | | return "b0"; |
| | | case 0xB1: |
| | | return "b1"; |
| | | case 0xB2: |
| | | return "b2"; |
| | | case 0xB3: |
| | | return "b3"; |
| | | case 0xB4: |
| | | return "b4"; |
| | | case 0xB5: |
| | | return "b5"; |
| | | case 0xB6: |
| | | return "b6"; |
| | | case 0xB7: |
| | | return "b7"; |
| | | case 0xB8: |
| | | return "b8"; |
| | | case 0xB9: |
| | | return "b9"; |
| | | case 0xBA: |
| | | return "ba"; |
| | | case 0xBB: |
| | | return "bb"; |
| | | case 0xBC: |
| | | return "bc"; |
| | | case 0xBD: |
| | | return "bd"; |
| | | case 0xBE: |
| | | return "be"; |
| | | case 0xBF: |
| | | return "bf"; |
| | | case 0xC0: |
| | | return "c0"; |
| | | case 0xC1: |
| | | return "c1"; |
| | | case 0xC2: |
| | | return "c2"; |
| | | case 0xC3: |
| | | return "c3"; |
| | | case 0xC4: |
| | | return "c4"; |
| | | case 0xC5: |
| | | return "c5"; |
| | | case 0xC6: |
| | | return "c6"; |
| | | case 0xC7: |
| | | return "c7"; |
| | | case 0xC8: |
| | | return "c8"; |
| | | case 0xC9: |
| | | return "c9"; |
| | | case 0xCA: |
| | | return "ca"; |
| | | case 0xCB: |
| | | return "cb"; |
| | | case 0xCC: |
| | | return "cc"; |
| | | case 0xCD: |
| | | return "cd"; |
| | | case 0xCE: |
| | | return "ce"; |
| | | case 0xCF: |
| | | return "cf"; |
| | | case 0xD0: |
| | | return "d0"; |
| | | case 0xD1: |
| | | return "d1"; |
| | | case 0xD2: |
| | | return "d2"; |
| | | case 0xD3: |
| | | return "d3"; |
| | | case 0xD4: |
| | | return "d4"; |
| | | case 0xD5: |
| | | return "d5"; |
| | | case 0xD6: |
| | | return "d6"; |
| | | case 0xD7: |
| | | return "d7"; |
| | | case 0xD8: |
| | | return "d8"; |
| | | case 0xD9: |
| | | return "d9"; |
| | | case 0xDA: |
| | | return "da"; |
| | | case 0xDB: |
| | | return "db"; |
| | | case 0xDC: |
| | | return "dc"; |
| | | case 0xDD: |
| | | return "dd"; |
| | | case 0xDE: |
| | | return "de"; |
| | | case 0xDF: |
| | | return "df"; |
| | | case 0xE0: |
| | | return "e0"; |
| | | case 0xE1: |
| | | return "e1"; |
| | | case 0xE2: |
| | | return "e2"; |
| | | case 0xE3: |
| | | return "e3"; |
| | | case 0xE4: |
| | | return "e4"; |
| | | case 0xE5: |
| | | return "e5"; |
| | | case 0xE6: |
| | | return "e6"; |
| | | case 0xE7: |
| | | return "e7"; |
| | | case 0xE8: |
| | | return "e8"; |
| | | case 0xE9: |
| | | return "e9"; |
| | | case 0xEA: |
| | | return "ea"; |
| | | case 0xEB: |
| | | return "eb"; |
| | | case 0xEC: |
| | | return "ec"; |
| | | case 0xED: |
| | | return "ed"; |
| | | case 0xEE: |
| | | return "ee"; |
| | | case 0xEF: |
| | | return "ef"; |
| | | case 0xF0: |
| | | return "f0"; |
| | | case 0xF1: |
| | | return "f1"; |
| | | case 0xF2: |
| | | return "f2"; |
| | | case 0xF3: |
| | | return "f3"; |
| | | case 0xF4: |
| | | return "f4"; |
| | | case 0xF5: |
| | | return "f5"; |
| | | case 0xF6: |
| | | return "f6"; |
| | | case 0xF7: |
| | | return "f7"; |
| | | case 0xF8: |
| | | return "f8"; |
| | | case 0xF9: |
| | | return "f9"; |
| | | case 0xFA: |
| | | return "fa"; |
| | | case 0xFB: |
| | | return "fb"; |
| | | case 0xFC: |
| | | return "fc"; |
| | | case 0xFD: |
| | | return "fd"; |
| | | case 0xFE: |
| | | return "fe"; |
| | | case 0xFF: |
| | | return "ff"; |
| | | default: |
| | | return "??"; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Attempts to compress the data in the provided source array into the given |
| | | * destination array. If the compressed data will fit into the destination |
| | | * array, then this method will return the number of bytes of compressed data |
| | | * in the array. Otherwise, it will return -1 to indicate that the compression |
| | | * was not successful. Note that if -1 is returned, then the data in the |
| | | * destination array should be considered invalid. |
| | | * |
| | | * @param src |
| | | * The array containing the raw data to compress. |
| | | * @param srcOff |
| | | * The start offset of the source data. |
| | | * @param srcLen |
| | | * The maximum number of source data bytes to compress. |
| | | * @param dst |
| | | * The array into which the compressed data should be written. |
| | | * @param dstOff |
| | | * The start offset of the compressed data. |
| | | * @param dstLen |
| | | * The maximum number of bytes of compressed data. |
| | | * @return The number of bytes of compressed data, or -1 if it was not |
| | | * possible to actually compress the data. |
| | | */ |
| | | public static int compress(final byte[] src, final int srcOff, |
| | | final int srcLen, final byte[] dst, final int dstOff, final int dstLen) |
| | | { |
| | | final Deflater deflater = new Deflater(); |
| | | try |
| | | { |
| | | deflater.setInput(src, srcOff, srcLen); |
| | | deflater.finish(); |
| | | |
| | | final int compressedLength = deflater.deflate(dst, dstOff, dstLen); |
| | | if (deflater.finished()) |
| | | { |
| | | return compressedLength; |
| | | } |
| | | else |
| | | { |
| | | return -1; |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | deflater.end(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Attempts to compress the data in the provided byte sequence into the |
| | | * provided byte string builder. Note that if compression was not successful, |
| | | * then the byte string builder will be left unchanged. |
| | | * |
| | | * @param input |
| | | * The source data to be compressed. |
| | | * @param output |
| | | * The destination buffer to which the compressed data will be |
| | | * appended. |
| | | * @return <code>true</code> if compression was successful or |
| | | * <code>false</code> otherwise. |
| | | */ |
| | | public static boolean compress(final ByteSequence input, |
| | | final ByteStringBuilder output) |
| | | { |
| | | final byte[] inputBytes = input.toByteArray(); |
| | | final byte[] outputBytes = new byte[inputBytes.length]; |
| | | |
| | | final int compressedSize = compress(inputBytes, 0, inputBytes.length, |
| | | outputBytes, 0, outputBytes.length); |
| | | |
| | | if (compressedSize != -1) |
| | | { |
| | | if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE)) |
| | | { |
| | | StaticUtils.DEBUG_LOG.fine(String.format("Compression %d/%d%n", |
| | | compressedSize, inputBytes.length)); |
| | | } |
| | | |
| | | output.append(outputBytes, 0, compressedSize); |
| | | return true; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns a string containing provided date formatted using the generalized |
| | | * time syntax. |
| | | * |
| | | * @param date |
| | | * The date to be formated. |
| | | * @return The string containing provided date formatted using the generalized |
| | | * time syntax. |
| | | * @throws NullPointerException |
| | | * If {@code date} was {@code null}. |
| | | */ |
| | | public static String formatAsGeneralizedTime(final Date date) |
| | | { |
| | | return formatAsGeneralizedTime(date.getTime()); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns a string containing provided date formatted using the generalized |
| | | * time syntax. |
| | | * |
| | | * @param date |
| | | * The date to be formated. |
| | | * @return The string containing provided date formatted using the generalized |
| | | * time syntax. |
| | | * @throws IllegalArgumentException |
| | | * If {@code date} was invalid. |
| | | */ |
| | | public static String formatAsGeneralizedTime(final long date) |
| | | { |
| | | // Generalized time has the format yyyyMMddHHmmss.SSS'Z' |
| | | |
| | | // Do this in a thread-safe non-synchronized fashion. |
| | | // (Simple)DateFormat is neither fast nor thread-safe. |
| | | |
| | | final StringBuilder sb = new StringBuilder(19); |
| | | |
| | | final GregorianCalendar calendar = new GregorianCalendar(TIME_ZONE_UTC_OBJ); |
| | | calendar.setLenient(false); |
| | | calendar.setTimeInMillis(date); |
| | | |
| | | // Format the year yyyy. |
| | | int n = calendar.get(Calendar.YEAR); |
| | | if (n < 0) |
| | | { |
| | | final IllegalArgumentException e = new IllegalArgumentException( |
| | | "Year cannot be < 0:" + n); |
| | | StaticUtils.DEBUG_LOG.throwing("GeneralizedTimeSyntax", "format", e); |
| | | throw e; |
| | | } |
| | | else if (n < 10) |
| | | { |
| | | sb.append("000"); |
| | | } |
| | | else if (n < 100) |
| | | { |
| | | sb.append("00"); |
| | | } |
| | | else if (n < 1000) |
| | | { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the month MM. |
| | | n = calendar.get(Calendar.MONTH) + 1; |
| | | if (n < 10) |
| | | { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the day dd. |
| | | n = calendar.get(Calendar.DAY_OF_MONTH); |
| | | if (n < 10) |
| | | { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the hour HH. |
| | | n = calendar.get(Calendar.HOUR_OF_DAY); |
| | | if (n < 10) |
| | | { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the minute mm. |
| | | n = calendar.get(Calendar.MINUTE); |
| | | if (n < 10) |
| | | { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the seconds ss. |
| | | n = calendar.get(Calendar.SECOND); |
| | | if (n < 10) |
| | | { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the milli-seconds. |
| | | sb.append('.'); |
| | | n = calendar.get(Calendar.MILLISECOND); |
| | | if (n < 10) |
| | | { |
| | | sb.append("00"); |
| | | } |
| | | else if (n < 100) |
| | | { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the timezone (always Z). |
| | | sb.append('Z'); |
| | | |
| | | return sb.toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Construct a byte array containing the UTF-8 encoding of the provided |
| | | * character array. |
| | | * |
| | | * @param chars |
| | | * The character array to convert to a UTF-8 byte array. |
| | | * @return A byte array containing the UTF-8 encoding of the provided |
| | | * character array. |
| | | */ |
| | | public static byte[] getBytes(final char[] chars) |
| | | { |
| | | final Charset utf8 = Charset.forName("UTF-8"); |
| | | final ByteBuffer buffer = utf8.encode(CharBuffer.wrap(chars)); |
| | | final byte[] bytes = new byte[buffer.remaining()]; |
| | | buffer.get(bytes); |
| | | return bytes; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Construct a byte array containing the UTF-8 encoding of the provided |
| | | * string. This is significantly faster than calling |
| | | * {@link String#getBytes(String)} for ASCII strings. |
| | | * |
| | | * @param s |
| | | * The string to convert to a UTF-8 byte array. |
| | | * @return Returns a byte array containing the UTF-8 encoding of the provided |
| | | * string. |
| | | */ |
| | | public static byte[] getBytes(final String s) |
| | | { |
| | | if (s == null) |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | try |
| | | { |
| | | char c; |
| | | final int length = s.length(); |
| | | final byte[] returnArray = new byte[length]; |
| | | for (int i = 0; i < length; i++) |
| | | { |
| | | c = s.charAt(i); |
| | | returnArray[i] = (byte) (c & 0x0000007F); |
| | | if (c != returnArray[i]) |
| | | { |
| | | return s.getBytes("UTF-8"); |
| | | /** |
| | | * Retrieves a string representation of the provided byte in hexadecimal. |
| | | * |
| | | * @param b |
| | | * The byte for which to retrieve the hexadecimal string |
| | | * representation. |
| | | * @return The string representation of the provided byte in hexadecimal. |
| | | */ |
| | | public static String byteToHex(final byte b) { |
| | | switch (b & 0xFF) { |
| | | case 0x00: |
| | | return "00"; |
| | | case 0x01: |
| | | return "01"; |
| | | case 0x02: |
| | | return "02"; |
| | | case 0x03: |
| | | return "03"; |
| | | case 0x04: |
| | | return "04"; |
| | | case 0x05: |
| | | return "05"; |
| | | case 0x06: |
| | | return "06"; |
| | | case 0x07: |
| | | return "07"; |
| | | case 0x08: |
| | | return "08"; |
| | | case 0x09: |
| | | return "09"; |
| | | case 0x0A: |
| | | return "0A"; |
| | | case 0x0B: |
| | | return "0B"; |
| | | case 0x0C: |
| | | return "0C"; |
| | | case 0x0D: |
| | | return "0D"; |
| | | case 0x0E: |
| | | return "0E"; |
| | | case 0x0F: |
| | | return "0F"; |
| | | case 0x10: |
| | | return "10"; |
| | | case 0x11: |
| | | return "11"; |
| | | case 0x12: |
| | | return "12"; |
| | | case 0x13: |
| | | return "13"; |
| | | case 0x14: |
| | | return "14"; |
| | | case 0x15: |
| | | return "15"; |
| | | case 0x16: |
| | | return "16"; |
| | | case 0x17: |
| | | return "17"; |
| | | case 0x18: |
| | | return "18"; |
| | | case 0x19: |
| | | return "19"; |
| | | case 0x1A: |
| | | return "1A"; |
| | | case 0x1B: |
| | | return "1B"; |
| | | case 0x1C: |
| | | return "1C"; |
| | | case 0x1D: |
| | | return "1D"; |
| | | case 0x1E: |
| | | return "1E"; |
| | | case 0x1F: |
| | | return "1F"; |
| | | case 0x20: |
| | | return "20"; |
| | | case 0x21: |
| | | return "21"; |
| | | case 0x22: |
| | | return "22"; |
| | | case 0x23: |
| | | return "23"; |
| | | case 0x24: |
| | | return "24"; |
| | | case 0x25: |
| | | return "25"; |
| | | case 0x26: |
| | | return "26"; |
| | | case 0x27: |
| | | return "27"; |
| | | case 0x28: |
| | | return "28"; |
| | | case 0x29: |
| | | return "29"; |
| | | case 0x2A: |
| | | return "2A"; |
| | | case 0x2B: |
| | | return "2B"; |
| | | case 0x2C: |
| | | return "2C"; |
| | | case 0x2D: |
| | | return "2D"; |
| | | case 0x2E: |
| | | return "2E"; |
| | | case 0x2F: |
| | | return "2F"; |
| | | case 0x30: |
| | | return "30"; |
| | | case 0x31: |
| | | return "31"; |
| | | case 0x32: |
| | | return "32"; |
| | | case 0x33: |
| | | return "33"; |
| | | case 0x34: |
| | | return "34"; |
| | | case 0x35: |
| | | return "35"; |
| | | case 0x36: |
| | | return "36"; |
| | | case 0x37: |
| | | return "37"; |
| | | case 0x38: |
| | | return "38"; |
| | | case 0x39: |
| | | return "39"; |
| | | case 0x3A: |
| | | return "3A"; |
| | | case 0x3B: |
| | | return "3B"; |
| | | case 0x3C: |
| | | return "3C"; |
| | | case 0x3D: |
| | | return "3D"; |
| | | case 0x3E: |
| | | return "3E"; |
| | | case 0x3F: |
| | | return "3F"; |
| | | case 0x40: |
| | | return "40"; |
| | | case 0x41: |
| | | return "41"; |
| | | case 0x42: |
| | | return "42"; |
| | | case 0x43: |
| | | return "43"; |
| | | case 0x44: |
| | | return "44"; |
| | | case 0x45: |
| | | return "45"; |
| | | case 0x46: |
| | | return "46"; |
| | | case 0x47: |
| | | return "47"; |
| | | case 0x48: |
| | | return "48"; |
| | | case 0x49: |
| | | return "49"; |
| | | case 0x4A: |
| | | return "4A"; |
| | | case 0x4B: |
| | | return "4B"; |
| | | case 0x4C: |
| | | return "4C"; |
| | | case 0x4D: |
| | | return "4D"; |
| | | case 0x4E: |
| | | return "4E"; |
| | | case 0x4F: |
| | | return "4F"; |
| | | case 0x50: |
| | | return "50"; |
| | | case 0x51: |
| | | return "51"; |
| | | case 0x52: |
| | | return "52"; |
| | | case 0x53: |
| | | return "53"; |
| | | case 0x54: |
| | | return "54"; |
| | | case 0x55: |
| | | return "55"; |
| | | case 0x56: |
| | | return "56"; |
| | | case 0x57: |
| | | return "57"; |
| | | case 0x58: |
| | | return "58"; |
| | | case 0x59: |
| | | return "59"; |
| | | case 0x5A: |
| | | return "5A"; |
| | | case 0x5B: |
| | | return "5B"; |
| | | case 0x5C: |
| | | return "5C"; |
| | | case 0x5D: |
| | | return "5D"; |
| | | case 0x5E: |
| | | return "5E"; |
| | | case 0x5F: |
| | | return "5F"; |
| | | case 0x60: |
| | | return "60"; |
| | | case 0x61: |
| | | return "61"; |
| | | case 0x62: |
| | | return "62"; |
| | | case 0x63: |
| | | return "63"; |
| | | case 0x64: |
| | | return "64"; |
| | | case 0x65: |
| | | return "65"; |
| | | case 0x66: |
| | | return "66"; |
| | | case 0x67: |
| | | return "67"; |
| | | case 0x68: |
| | | return "68"; |
| | | case 0x69: |
| | | return "69"; |
| | | case 0x6A: |
| | | return "6A"; |
| | | case 0x6B: |
| | | return "6B"; |
| | | case 0x6C: |
| | | return "6C"; |
| | | case 0x6D: |
| | | return "6D"; |
| | | case 0x6E: |
| | | return "6E"; |
| | | case 0x6F: |
| | | return "6F"; |
| | | case 0x70: |
| | | return "70"; |
| | | case 0x71: |
| | | return "71"; |
| | | case 0x72: |
| | | return "72"; |
| | | case 0x73: |
| | | return "73"; |
| | | case 0x74: |
| | | return "74"; |
| | | case 0x75: |
| | | return "75"; |
| | | case 0x76: |
| | | return "76"; |
| | | case 0x77: |
| | | return "77"; |
| | | case 0x78: |
| | | return "78"; |
| | | case 0x79: |
| | | return "79"; |
| | | case 0x7A: |
| | | return "7A"; |
| | | case 0x7B: |
| | | return "7B"; |
| | | case 0x7C: |
| | | return "7C"; |
| | | case 0x7D: |
| | | return "7D"; |
| | | case 0x7E: |
| | | return "7E"; |
| | | case 0x7F: |
| | | return "7F"; |
| | | case 0x80: |
| | | return "80"; |
| | | case 0x81: |
| | | return "81"; |
| | | case 0x82: |
| | | return "82"; |
| | | case 0x83: |
| | | return "83"; |
| | | case 0x84: |
| | | return "84"; |
| | | case 0x85: |
| | | return "85"; |
| | | case 0x86: |
| | | return "86"; |
| | | case 0x87: |
| | | return "87"; |
| | | case 0x88: |
| | | return "88"; |
| | | case 0x89: |
| | | return "89"; |
| | | case 0x8A: |
| | | return "8A"; |
| | | case 0x8B: |
| | | return "8B"; |
| | | case 0x8C: |
| | | return "8C"; |
| | | case 0x8D: |
| | | return "8D"; |
| | | case 0x8E: |
| | | return "8E"; |
| | | case 0x8F: |
| | | return "8F"; |
| | | case 0x90: |
| | | return "90"; |
| | | case 0x91: |
| | | return "91"; |
| | | case 0x92: |
| | | return "92"; |
| | | case 0x93: |
| | | return "93"; |
| | | case 0x94: |
| | | return "94"; |
| | | case 0x95: |
| | | return "95"; |
| | | case 0x96: |
| | | return "96"; |
| | | case 0x97: |
| | | return "97"; |
| | | case 0x98: |
| | | return "98"; |
| | | case 0x99: |
| | | return "99"; |
| | | case 0x9A: |
| | | return "9A"; |
| | | case 0x9B: |
| | | return "9B"; |
| | | case 0x9C: |
| | | return "9C"; |
| | | case 0x9D: |
| | | return "9D"; |
| | | case 0x9E: |
| | | return "9E"; |
| | | case 0x9F: |
| | | return "9F"; |
| | | case 0xA0: |
| | | return "A0"; |
| | | case 0xA1: |
| | | return "A1"; |
| | | case 0xA2: |
| | | return "A2"; |
| | | case 0xA3: |
| | | return "A3"; |
| | | case 0xA4: |
| | | return "A4"; |
| | | case 0xA5: |
| | | return "A5"; |
| | | case 0xA6: |
| | | return "A6"; |
| | | case 0xA7: |
| | | return "A7"; |
| | | case 0xA8: |
| | | return "A8"; |
| | | case 0xA9: |
| | | return "A9"; |
| | | case 0xAA: |
| | | return "AA"; |
| | | case 0xAB: |
| | | return "AB"; |
| | | case 0xAC: |
| | | return "AC"; |
| | | case 0xAD: |
| | | return "AD"; |
| | | case 0xAE: |
| | | return "AE"; |
| | | case 0xAF: |
| | | return "AF"; |
| | | case 0xB0: |
| | | return "B0"; |
| | | case 0xB1: |
| | | return "B1"; |
| | | case 0xB2: |
| | | return "B2"; |
| | | case 0xB3: |
| | | return "B3"; |
| | | case 0xB4: |
| | | return "B4"; |
| | | case 0xB5: |
| | | return "B5"; |
| | | case 0xB6: |
| | | return "B6"; |
| | | case 0xB7: |
| | | return "B7"; |
| | | case 0xB8: |
| | | return "B8"; |
| | | case 0xB9: |
| | | return "B9"; |
| | | case 0xBA: |
| | | return "BA"; |
| | | case 0xBB: |
| | | return "BB"; |
| | | case 0xBC: |
| | | return "BC"; |
| | | case 0xBD: |
| | | return "BD"; |
| | | case 0xBE: |
| | | return "BE"; |
| | | case 0xBF: |
| | | return "BF"; |
| | | case 0xC0: |
| | | return "C0"; |
| | | case 0xC1: |
| | | return "C1"; |
| | | case 0xC2: |
| | | return "C2"; |
| | | case 0xC3: |
| | | return "C3"; |
| | | case 0xC4: |
| | | return "C4"; |
| | | case 0xC5: |
| | | return "C5"; |
| | | case 0xC6: |
| | | return "C6"; |
| | | case 0xC7: |
| | | return "C7"; |
| | | case 0xC8: |
| | | return "C8"; |
| | | case 0xC9: |
| | | return "C9"; |
| | | case 0xCA: |
| | | return "CA"; |
| | | case 0xCB: |
| | | return "CB"; |
| | | case 0xCC: |
| | | return "CC"; |
| | | case 0xCD: |
| | | return "CD"; |
| | | case 0xCE: |
| | | return "CE"; |
| | | case 0xCF: |
| | | return "CF"; |
| | | case 0xD0: |
| | | return "D0"; |
| | | case 0xD1: |
| | | return "D1"; |
| | | case 0xD2: |
| | | return "D2"; |
| | | case 0xD3: |
| | | return "D3"; |
| | | case 0xD4: |
| | | return "D4"; |
| | | case 0xD5: |
| | | return "D5"; |
| | | case 0xD6: |
| | | return "D6"; |
| | | case 0xD7: |
| | | return "D7"; |
| | | case 0xD8: |
| | | return "D8"; |
| | | case 0xD9: |
| | | return "D9"; |
| | | case 0xDA: |
| | | return "DA"; |
| | | case 0xDB: |
| | | return "DB"; |
| | | case 0xDC: |
| | | return "DC"; |
| | | case 0xDD: |
| | | return "DD"; |
| | | case 0xDE: |
| | | return "DE"; |
| | | case 0xDF: |
| | | return "DF"; |
| | | case 0xE0: |
| | | return "E0"; |
| | | case 0xE1: |
| | | return "E1"; |
| | | case 0xE2: |
| | | return "E2"; |
| | | case 0xE3: |
| | | return "E3"; |
| | | case 0xE4: |
| | | return "E4"; |
| | | case 0xE5: |
| | | return "E5"; |
| | | case 0xE6: |
| | | return "E6"; |
| | | case 0xE7: |
| | | return "E7"; |
| | | case 0xE8: |
| | | return "E8"; |
| | | case 0xE9: |
| | | return "E9"; |
| | | case 0xEA: |
| | | return "EA"; |
| | | case 0xEB: |
| | | return "EB"; |
| | | case 0xEC: |
| | | return "EC"; |
| | | case 0xED: |
| | | return "ED"; |
| | | case 0xEE: |
| | | return "EE"; |
| | | case 0xEF: |
| | | return "EF"; |
| | | case 0xF0: |
| | | return "F0"; |
| | | case 0xF1: |
| | | return "F1"; |
| | | case 0xF2: |
| | | return "F2"; |
| | | case 0xF3: |
| | | return "F3"; |
| | | case 0xF4: |
| | | return "F4"; |
| | | case 0xF5: |
| | | return "F5"; |
| | | case 0xF6: |
| | | return "F6"; |
| | | case 0xF7: |
| | | return "F7"; |
| | | case 0xF8: |
| | | return "F8"; |
| | | case 0xF9: |
| | | return "F9"; |
| | | case 0xFA: |
| | | return "FA"; |
| | | case 0xFB: |
| | | return "FB"; |
| | | case 0xFC: |
| | | return "FC"; |
| | | case 0xFD: |
| | | return "FD"; |
| | | case 0xFE: |
| | | return "FE"; |
| | | case 0xFF: |
| | | return "FF"; |
| | | default: |
| | | return "??"; |
| | | } |
| | | } |
| | | |
| | | return returnArray; |
| | | } |
| | | catch (final Exception e) |
| | | { |
| | | DEBUG_LOG.warning("Unable to encode UTF-8 string " + s); |
| | | |
| | | return s.getBytes(); |
| | | /** |
| | | * Retrieves a string representation of the provided byte in hexadecimal. |
| | | * |
| | | * @param b |
| | | * The byte for which to retrieve the hexadecimal string |
| | | * representation. |
| | | * @return The string representation of the provided byte in hexadecimal |
| | | * using lowercase characters. |
| | | */ |
| | | public static String byteToLowerHex(final byte b) { |
| | | switch (b & 0xFF) { |
| | | case 0x00: |
| | | return "00"; |
| | | case 0x01: |
| | | return "01"; |
| | | case 0x02: |
| | | return "02"; |
| | | case 0x03: |
| | | return "03"; |
| | | case 0x04: |
| | | return "04"; |
| | | case 0x05: |
| | | return "05"; |
| | | case 0x06: |
| | | return "06"; |
| | | case 0x07: |
| | | return "07"; |
| | | case 0x08: |
| | | return "08"; |
| | | case 0x09: |
| | | return "09"; |
| | | case 0x0A: |
| | | return "0a"; |
| | | case 0x0B: |
| | | return "0b"; |
| | | case 0x0C: |
| | | return "0c"; |
| | | case 0x0D: |
| | | return "0d"; |
| | | case 0x0E: |
| | | return "0e"; |
| | | case 0x0F: |
| | | return "0f"; |
| | | case 0x10: |
| | | return "10"; |
| | | case 0x11: |
| | | return "11"; |
| | | case 0x12: |
| | | return "12"; |
| | | case 0x13: |
| | | return "13"; |
| | | case 0x14: |
| | | return "14"; |
| | | case 0x15: |
| | | return "15"; |
| | | case 0x16: |
| | | return "16"; |
| | | case 0x17: |
| | | return "17"; |
| | | case 0x18: |
| | | return "18"; |
| | | case 0x19: |
| | | return "19"; |
| | | case 0x1A: |
| | | return "1a"; |
| | | case 0x1B: |
| | | return "1b"; |
| | | case 0x1C: |
| | | return "1c"; |
| | | case 0x1D: |
| | | return "1d"; |
| | | case 0x1E: |
| | | return "1e"; |
| | | case 0x1F: |
| | | return "1f"; |
| | | case 0x20: |
| | | return "20"; |
| | | case 0x21: |
| | | return "21"; |
| | | case 0x22: |
| | | return "22"; |
| | | case 0x23: |
| | | return "23"; |
| | | case 0x24: |
| | | return "24"; |
| | | case 0x25: |
| | | return "25"; |
| | | case 0x26: |
| | | return "26"; |
| | | case 0x27: |
| | | return "27"; |
| | | case 0x28: |
| | | return "28"; |
| | | case 0x29: |
| | | return "29"; |
| | | case 0x2A: |
| | | return "2a"; |
| | | case 0x2B: |
| | | return "2b"; |
| | | case 0x2C: |
| | | return "2c"; |
| | | case 0x2D: |
| | | return "2d"; |
| | | case 0x2E: |
| | | return "2e"; |
| | | case 0x2F: |
| | | return "2f"; |
| | | case 0x30: |
| | | return "30"; |
| | | case 0x31: |
| | | return "31"; |
| | | case 0x32: |
| | | return "32"; |
| | | case 0x33: |
| | | return "33"; |
| | | case 0x34: |
| | | return "34"; |
| | | case 0x35: |
| | | return "35"; |
| | | case 0x36: |
| | | return "36"; |
| | | case 0x37: |
| | | return "37"; |
| | | case 0x38: |
| | | return "38"; |
| | | case 0x39: |
| | | return "39"; |
| | | case 0x3A: |
| | | return "3a"; |
| | | case 0x3B: |
| | | return "3b"; |
| | | case 0x3C: |
| | | return "3c"; |
| | | case 0x3D: |
| | | return "3d"; |
| | | case 0x3E: |
| | | return "3e"; |
| | | case 0x3F: |
| | | return "3f"; |
| | | case 0x40: |
| | | return "40"; |
| | | case 0x41: |
| | | return "41"; |
| | | case 0x42: |
| | | return "42"; |
| | | case 0x43: |
| | | return "43"; |
| | | case 0x44: |
| | | return "44"; |
| | | case 0x45: |
| | | return "45"; |
| | | case 0x46: |
| | | return "46"; |
| | | case 0x47: |
| | | return "47"; |
| | | case 0x48: |
| | | return "48"; |
| | | case 0x49: |
| | | return "49"; |
| | | case 0x4A: |
| | | return "4a"; |
| | | case 0x4B: |
| | | return "4b"; |
| | | case 0x4C: |
| | | return "4c"; |
| | | case 0x4D: |
| | | return "4d"; |
| | | case 0x4E: |
| | | return "4e"; |
| | | case 0x4F: |
| | | return "4f"; |
| | | case 0x50: |
| | | return "50"; |
| | | case 0x51: |
| | | return "51"; |
| | | case 0x52: |
| | | return "52"; |
| | | case 0x53: |
| | | return "53"; |
| | | case 0x54: |
| | | return "54"; |
| | | case 0x55: |
| | | return "55"; |
| | | case 0x56: |
| | | return "56"; |
| | | case 0x57: |
| | | return "57"; |
| | | case 0x58: |
| | | return "58"; |
| | | case 0x59: |
| | | return "59"; |
| | | case 0x5A: |
| | | return "5a"; |
| | | case 0x5B: |
| | | return "5b"; |
| | | case 0x5C: |
| | | return "5c"; |
| | | case 0x5D: |
| | | return "5d"; |
| | | case 0x5E: |
| | | return "5e"; |
| | | case 0x5F: |
| | | return "5f"; |
| | | case 0x60: |
| | | return "60"; |
| | | case 0x61: |
| | | return "61"; |
| | | case 0x62: |
| | | return "62"; |
| | | case 0x63: |
| | | return "63"; |
| | | case 0x64: |
| | | return "64"; |
| | | case 0x65: |
| | | return "65"; |
| | | case 0x66: |
| | | return "66"; |
| | | case 0x67: |
| | | return "67"; |
| | | case 0x68: |
| | | return "68"; |
| | | case 0x69: |
| | | return "69"; |
| | | case 0x6A: |
| | | return "6a"; |
| | | case 0x6B: |
| | | return "6b"; |
| | | case 0x6C: |
| | | return "6c"; |
| | | case 0x6D: |
| | | return "6d"; |
| | | case 0x6E: |
| | | return "6e"; |
| | | case 0x6F: |
| | | return "6f"; |
| | | case 0x70: |
| | | return "70"; |
| | | case 0x71: |
| | | return "71"; |
| | | case 0x72: |
| | | return "72"; |
| | | case 0x73: |
| | | return "73"; |
| | | case 0x74: |
| | | return "74"; |
| | | case 0x75: |
| | | return "75"; |
| | | case 0x76: |
| | | return "76"; |
| | | case 0x77: |
| | | return "77"; |
| | | case 0x78: |
| | | return "78"; |
| | | case 0x79: |
| | | return "79"; |
| | | case 0x7A: |
| | | return "7a"; |
| | | case 0x7B: |
| | | return "7b"; |
| | | case 0x7C: |
| | | return "7c"; |
| | | case 0x7D: |
| | | return "7d"; |
| | | case 0x7E: |
| | | return "7e"; |
| | | case 0x7F: |
| | | return "7f"; |
| | | case 0x80: |
| | | return "80"; |
| | | case 0x81: |
| | | return "81"; |
| | | case 0x82: |
| | | return "82"; |
| | | case 0x83: |
| | | return "83"; |
| | | case 0x84: |
| | | return "84"; |
| | | case 0x85: |
| | | return "85"; |
| | | case 0x86: |
| | | return "86"; |
| | | case 0x87: |
| | | return "87"; |
| | | case 0x88: |
| | | return "88"; |
| | | case 0x89: |
| | | return "89"; |
| | | case 0x8A: |
| | | return "8a"; |
| | | case 0x8B: |
| | | return "8b"; |
| | | case 0x8C: |
| | | return "8c"; |
| | | case 0x8D: |
| | | return "8d"; |
| | | case 0x8E: |
| | | return "8e"; |
| | | case 0x8F: |
| | | return "8f"; |
| | | case 0x90: |
| | | return "90"; |
| | | case 0x91: |
| | | return "91"; |
| | | case 0x92: |
| | | return "92"; |
| | | case 0x93: |
| | | return "93"; |
| | | case 0x94: |
| | | return "94"; |
| | | case 0x95: |
| | | return "95"; |
| | | case 0x96: |
| | | return "96"; |
| | | case 0x97: |
| | | return "97"; |
| | | case 0x98: |
| | | return "98"; |
| | | case 0x99: |
| | | return "99"; |
| | | case 0x9A: |
| | | return "9a"; |
| | | case 0x9B: |
| | | return "9b"; |
| | | case 0x9C: |
| | | return "9c"; |
| | | case 0x9D: |
| | | return "9d"; |
| | | case 0x9E: |
| | | return "9e"; |
| | | case 0x9F: |
| | | return "9f"; |
| | | case 0xA0: |
| | | return "a0"; |
| | | case 0xA1: |
| | | return "a1"; |
| | | case 0xA2: |
| | | return "a2"; |
| | | case 0xA3: |
| | | return "a3"; |
| | | case 0xA4: |
| | | return "a4"; |
| | | case 0xA5: |
| | | return "a5"; |
| | | case 0xA6: |
| | | return "a6"; |
| | | case 0xA7: |
| | | return "a7"; |
| | | case 0xA8: |
| | | return "a8"; |
| | | case 0xA9: |
| | | return "a9"; |
| | | case 0xAA: |
| | | return "aa"; |
| | | case 0xAB: |
| | | return "ab"; |
| | | case 0xAC: |
| | | return "ac"; |
| | | case 0xAD: |
| | | return "ad"; |
| | | case 0xAE: |
| | | return "ae"; |
| | | case 0xAF: |
| | | return "af"; |
| | | case 0xB0: |
| | | return "b0"; |
| | | case 0xB1: |
| | | return "b1"; |
| | | case 0xB2: |
| | | return "b2"; |
| | | case 0xB3: |
| | | return "b3"; |
| | | case 0xB4: |
| | | return "b4"; |
| | | case 0xB5: |
| | | return "b5"; |
| | | case 0xB6: |
| | | return "b6"; |
| | | case 0xB7: |
| | | return "b7"; |
| | | case 0xB8: |
| | | return "b8"; |
| | | case 0xB9: |
| | | return "b9"; |
| | | case 0xBA: |
| | | return "ba"; |
| | | case 0xBB: |
| | | return "bb"; |
| | | case 0xBC: |
| | | return "bc"; |
| | | case 0xBD: |
| | | return "bd"; |
| | | case 0xBE: |
| | | return "be"; |
| | | case 0xBF: |
| | | return "bf"; |
| | | case 0xC0: |
| | | return "c0"; |
| | | case 0xC1: |
| | | return "c1"; |
| | | case 0xC2: |
| | | return "c2"; |
| | | case 0xC3: |
| | | return "c3"; |
| | | case 0xC4: |
| | | return "c4"; |
| | | case 0xC5: |
| | | return "c5"; |
| | | case 0xC6: |
| | | return "c6"; |
| | | case 0xC7: |
| | | return "c7"; |
| | | case 0xC8: |
| | | return "c8"; |
| | | case 0xC9: |
| | | return "c9"; |
| | | case 0xCA: |
| | | return "ca"; |
| | | case 0xCB: |
| | | return "cb"; |
| | | case 0xCC: |
| | | return "cc"; |
| | | case 0xCD: |
| | | return "cd"; |
| | | case 0xCE: |
| | | return "ce"; |
| | | case 0xCF: |
| | | return "cf"; |
| | | case 0xD0: |
| | | return "d0"; |
| | | case 0xD1: |
| | | return "d1"; |
| | | case 0xD2: |
| | | return "d2"; |
| | | case 0xD3: |
| | | return "d3"; |
| | | case 0xD4: |
| | | return "d4"; |
| | | case 0xD5: |
| | | return "d5"; |
| | | case 0xD6: |
| | | return "d6"; |
| | | case 0xD7: |
| | | return "d7"; |
| | | case 0xD8: |
| | | return "d8"; |
| | | case 0xD9: |
| | | return "d9"; |
| | | case 0xDA: |
| | | return "da"; |
| | | case 0xDB: |
| | | return "db"; |
| | | case 0xDC: |
| | | return "dc"; |
| | | case 0xDD: |
| | | return "dd"; |
| | | case 0xDE: |
| | | return "de"; |
| | | case 0xDF: |
| | | return "df"; |
| | | case 0xE0: |
| | | return "e0"; |
| | | case 0xE1: |
| | | return "e1"; |
| | | case 0xE2: |
| | | return "e2"; |
| | | case 0xE3: |
| | | return "e3"; |
| | | case 0xE4: |
| | | return "e4"; |
| | | case 0xE5: |
| | | return "e5"; |
| | | case 0xE6: |
| | | return "e6"; |
| | | case 0xE7: |
| | | return "e7"; |
| | | case 0xE8: |
| | | return "e8"; |
| | | case 0xE9: |
| | | return "e9"; |
| | | case 0xEA: |
| | | return "ea"; |
| | | case 0xEB: |
| | | return "eb"; |
| | | case 0xEC: |
| | | return "ec"; |
| | | case 0xED: |
| | | return "ed"; |
| | | case 0xEE: |
| | | return "ee"; |
| | | case 0xEF: |
| | | return "ef"; |
| | | case 0xF0: |
| | | return "f0"; |
| | | case 0xF1: |
| | | return "f1"; |
| | | case 0xF2: |
| | | return "f2"; |
| | | case 0xF3: |
| | | return "f3"; |
| | | case 0xF4: |
| | | return "f4"; |
| | | case 0xF5: |
| | | return "f5"; |
| | | case 0xF6: |
| | | return "f6"; |
| | | case 0xF7: |
| | | return "f7"; |
| | | case 0xF8: |
| | | return "f8"; |
| | | case 0xF9: |
| | | return "f9"; |
| | | case 0xFA: |
| | | return "fa"; |
| | | case 0xFB: |
| | | return "fb"; |
| | | case 0xFC: |
| | | return "fc"; |
| | | case 0xFD: |
| | | return "fd"; |
| | | case 0xFE: |
| | | return "fe"; |
| | | case 0xFF: |
| | | return "ff"; |
| | | default: |
| | | return "??"; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Attempts to compress the data in the provided source array into the given |
| | | * destination array. If the compressed data will fit into the destination |
| | | * array, then this method will return the number of bytes of compressed |
| | | * data in the array. Otherwise, it will return -1 to indicate that the |
| | | * compression was not successful. Note that if -1 is returned, then the |
| | | * data in the destination array should be considered invalid. |
| | | * |
| | | * @param src |
| | | * The array containing the raw data to compress. |
| | | * @param srcOff |
| | | * The start offset of the source data. |
| | | * @param srcLen |
| | | * The maximum number of source data bytes to compress. |
| | | * @param dst |
| | | * The array into which the compressed data should be written. |
| | | * @param dstOff |
| | | * The start offset of the compressed data. |
| | | * @param dstLen |
| | | * The maximum number of bytes of compressed data. |
| | | * @return The number of bytes of compressed data, or -1 if it was not |
| | | * possible to actually compress the data. |
| | | */ |
| | | public static int compress(final byte[] src, final int srcOff, final int srcLen, |
| | | final byte[] dst, final int dstOff, final int dstLen) { |
| | | final Deflater deflater = new Deflater(); |
| | | try { |
| | | deflater.setInput(src, srcOff, srcLen); |
| | | deflater.finish(); |
| | | |
| | | |
| | | /** |
| | | * Returns the default scheduler which should be used by the SDK. |
| | | * |
| | | * @return The default scheduler. |
| | | */ |
| | | public static ScheduledExecutorService getDefaultScheduler() |
| | | { |
| | | synchronized (DEFAULT_SCHEDULER_LOCK) |
| | | { |
| | | if (defaultScheduler == null) |
| | | { |
| | | final ThreadFactory factory = newThreadFactory(null, |
| | | "OpenDJ SDK Default Scheduler", true); |
| | | defaultScheduler = Executors.newSingleThreadScheduledExecutor(factory); |
| | | } |
| | | final int compressedLength = deflater.deflate(dst, dstOff, dstLen); |
| | | if (deflater.finished()) { |
| | | return compressedLength; |
| | | } else { |
| | | return -1; |
| | | } |
| | | } finally { |
| | | deflater.end(); |
| | | } |
| | | } |
| | | return defaultScheduler; |
| | | } |
| | | |
| | | /** |
| | | * Attempts to compress the data in the provided byte sequence into the |
| | | * provided byte string builder. Note that if compression was not |
| | | * successful, then the byte string builder will be left unchanged. |
| | | * |
| | | * @param input |
| | | * The source data to be compressed. |
| | | * @param output |
| | | * The destination buffer to which the compressed data will be |
| | | * appended. |
| | | * @return <code>true</code> if compression was successful or |
| | | * <code>false</code> otherwise. |
| | | */ |
| | | public static boolean compress(final ByteSequence input, final ByteStringBuilder output) { |
| | | final byte[] inputBytes = input.toByteArray(); |
| | | final byte[] outputBytes = new byte[inputBytes.length]; |
| | | |
| | | final int compressedSize = |
| | | compress(inputBytes, 0, inputBytes.length, outputBytes, 0, outputBytes.length); |
| | | |
| | | /** |
| | | * Retrieves the best human-readable message for the provided exception. For |
| | | * exceptions defined in the OpenDJ project, it will attempt to use the |
| | | * message (combining it with the message ID if available). For some |
| | | * exceptions that use encapsulation (e.g., InvocationTargetException), it |
| | | * will be unwrapped and the cause will be treated. For all others, the |
| | | * |
| | | * @param t |
| | | * The {@code Throwable} object for which to retrieve the message. |
| | | * @return The human-readable message generated for the provided exception. |
| | | */ |
| | | public static LocalizableMessage getExceptionMessage(final Throwable t) |
| | | { |
| | | if (t instanceof LocalizableException) |
| | | { |
| | | final LocalizableException ie = (LocalizableException) t; |
| | | return ie.getMessageObject(); |
| | | if (compressedSize != -1) { |
| | | if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINE)) { |
| | | StaticUtils.DEBUG_LOG.fine(String.format("Compression %d/%d%n", compressedSize, |
| | | inputBytes.length)); |
| | | } |
| | | |
| | | output.append(outputBytes, 0, compressedSize); |
| | | return true; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | else if (t instanceof NullPointerException) |
| | | { |
| | | final StackTraceElement[] stackElements = t.getStackTrace(); |
| | | |
| | | final LocalizableMessageBuilder message = new LocalizableMessageBuilder(); |
| | | message.append("NullPointerException("); |
| | | message.append(stackElements[0].getFileName()); |
| | | message.append(":"); |
| | | message.append(stackElements[0].getLineNumber()); |
| | | message.append(")"); |
| | | return message.toMessage(); |
| | | /** |
| | | * Returns a string containing provided date formatted using the generalized |
| | | * time syntax. |
| | | * |
| | | * @param date |
| | | * The date to be formated. |
| | | * @return The string containing provided date formatted using the |
| | | * generalized time syntax. |
| | | * @throws NullPointerException |
| | | * If {@code date} was {@code null}. |
| | | */ |
| | | public static String formatAsGeneralizedTime(final Date date) { |
| | | return formatAsGeneralizedTime(date.getTime()); |
| | | } |
| | | else if (t instanceof InvocationTargetException && t.getCause() != null) |
| | | { |
| | | return getExceptionMessage(t.getCause()); |
| | | |
| | | /** |
| | | * Returns a string containing provided date formatted using the generalized |
| | | * time syntax. |
| | | * |
| | | * @param date |
| | | * The date to be formated. |
| | | * @return The string containing provided date formatted using the |
| | | * generalized time syntax. |
| | | * @throws IllegalArgumentException |
| | | * If {@code date} was invalid. |
| | | */ |
| | | public static String formatAsGeneralizedTime(final long date) { |
| | | // Generalized time has the format yyyyMMddHHmmss.SSS'Z' |
| | | |
| | | // Do this in a thread-safe non-synchronized fashion. |
| | | // (Simple)DateFormat is neither fast nor thread-safe. |
| | | |
| | | final StringBuilder sb = new StringBuilder(19); |
| | | |
| | | final GregorianCalendar calendar = new GregorianCalendar(TIME_ZONE_UTC_OBJ); |
| | | calendar.setLenient(false); |
| | | calendar.setTimeInMillis(date); |
| | | |
| | | // Format the year yyyy. |
| | | int n = calendar.get(Calendar.YEAR); |
| | | if (n < 0) { |
| | | final IllegalArgumentException e = |
| | | new IllegalArgumentException("Year cannot be < 0:" + n); |
| | | StaticUtils.DEBUG_LOG.throwing("GeneralizedTimeSyntax", "format", e); |
| | | throw e; |
| | | } else if (n < 10) { |
| | | sb.append("000"); |
| | | } else if (n < 100) { |
| | | sb.append("00"); |
| | | } else if (n < 1000) { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the month MM. |
| | | n = calendar.get(Calendar.MONTH) + 1; |
| | | if (n < 10) { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the day dd. |
| | | n = calendar.get(Calendar.DAY_OF_MONTH); |
| | | if (n < 10) { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the hour HH. |
| | | n = calendar.get(Calendar.HOUR_OF_DAY); |
| | | if (n < 10) { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the minute mm. |
| | | n = calendar.get(Calendar.MINUTE); |
| | | if (n < 10) { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the seconds ss. |
| | | n = calendar.get(Calendar.SECOND); |
| | | if (n < 10) { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the milli-seconds. |
| | | sb.append('.'); |
| | | n = calendar.get(Calendar.MILLISECOND); |
| | | if (n < 10) { |
| | | sb.append("00"); |
| | | } else if (n < 100) { |
| | | sb.append("0"); |
| | | } |
| | | sb.append(n); |
| | | |
| | | // Format the timezone (always Z). |
| | | sb.append('Z'); |
| | | |
| | | return sb.toString(); |
| | | } |
| | | else |
| | | { |
| | | final StringBuilder message = new StringBuilder(); |
| | | |
| | | final String className = t.getClass().getName(); |
| | | final int periodPos = className.lastIndexOf('.'); |
| | | if (periodPos > 0) |
| | | { |
| | | message.append(className.substring(periodPos + 1)); |
| | | } |
| | | else |
| | | { |
| | | message.append(className); |
| | | } |
| | | /** |
| | | * Construct a byte array containing the UTF-8 encoding of the provided |
| | | * character array. |
| | | * |
| | | * @param chars |
| | | * The character array to convert to a UTF-8 byte array. |
| | | * @return A byte array containing the UTF-8 encoding of the provided |
| | | * character array. |
| | | */ |
| | | public static byte[] getBytes(final char[] chars) { |
| | | final Charset utf8 = Charset.forName("UTF-8"); |
| | | final ByteBuffer buffer = utf8.encode(CharBuffer.wrap(chars)); |
| | | final byte[] bytes = new byte[buffer.remaining()]; |
| | | buffer.get(bytes); |
| | | return bytes; |
| | | } |
| | | |
| | | message.append("("); |
| | | if (t.getMessage() == null) |
| | | { |
| | | final StackTraceElement[] stackElements = t.getStackTrace(); |
| | | message.append(stackElements[0].getFileName()); |
| | | message.append(":"); |
| | | message.append(stackElements[0].getLineNumber()); |
| | | /** |
| | | * Construct a byte array containing the UTF-8 encoding of the provided |
| | | * string. This is significantly faster than calling |
| | | * {@link String#getBytes(String)} for ASCII strings. |
| | | * |
| | | * @param s |
| | | * The string to convert to a UTF-8 byte array. |
| | | * @return Returns a byte array containing the UTF-8 encoding of the |
| | | * provided string. |
| | | */ |
| | | public static byte[] getBytes(final String s) { |
| | | if (s == null) { |
| | | return null; |
| | | } |
| | | |
| | | // FIXME Temporary to debug issue 2256. |
| | | if (t instanceof IllegalStateException) |
| | | { |
| | | for (int i = 1; i < stackElements.length; i++) |
| | | { |
| | | message.append(' '); |
| | | message.append(stackElements[i].getFileName()); |
| | | try { |
| | | char c; |
| | | final int length = s.length(); |
| | | final byte[] returnArray = new byte[length]; |
| | | for (int i = 0; i < length; i++) { |
| | | c = s.charAt(i); |
| | | returnArray[i] = (byte) (c & 0x0000007F); |
| | | if (c != returnArray[i]) { |
| | | return s.getBytes("UTF-8"); |
| | | } |
| | | } |
| | | |
| | | return returnArray; |
| | | } catch (final Exception e) { |
| | | DEBUG_LOG.warning("Unable to encode UTF-8 string " + s); |
| | | |
| | | return s.getBytes(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Returns the default scheduler which should be used by the SDK. |
| | | * |
| | | * @return The default scheduler. |
| | | */ |
| | | public static ScheduledExecutorService getDefaultScheduler() { |
| | | synchronized (DEFAULT_SCHEDULER_LOCK) { |
| | | if (defaultScheduler == null) { |
| | | final ThreadFactory factory = |
| | | newThreadFactory(null, "OpenDJ SDK Default Scheduler", true); |
| | | defaultScheduler = Executors.newSingleThreadScheduledExecutor(factory); |
| | | } |
| | | } |
| | | return defaultScheduler; |
| | | } |
| | | |
| | | /** |
| | | * Retrieves the best human-readable message for the provided exception. For |
| | | * exceptions defined in the OpenDJ project, it will attempt to use the |
| | | * message (combining it with the message ID if available). For some |
| | | * exceptions that use encapsulation (e.g., InvocationTargetException), it |
| | | * will be unwrapped and the cause will be treated. For all others, the |
| | | * |
| | | * @param t |
| | | * The {@code Throwable} object for which to retrieve the |
| | | * message. |
| | | * @return The human-readable message generated for the provided exception. |
| | | */ |
| | | public static LocalizableMessage getExceptionMessage(final Throwable t) { |
| | | if (t instanceof LocalizableException) { |
| | | final LocalizableException ie = (LocalizableException) t; |
| | | return ie.getMessageObject(); |
| | | } else if (t instanceof NullPointerException) { |
| | | final StackTraceElement[] stackElements = t.getStackTrace(); |
| | | |
| | | final LocalizableMessageBuilder message = new LocalizableMessageBuilder(); |
| | | message.append("NullPointerException("); |
| | | message.append(stackElements[0].getFileName()); |
| | | message.append(":"); |
| | | message.append(stackElements[i].getLineNumber()); |
| | | } |
| | | message.append(stackElements[0].getLineNumber()); |
| | | message.append(")"); |
| | | return message.toMessage(); |
| | | } else if (t instanceof InvocationTargetException && t.getCause() != null) { |
| | | return getExceptionMessage(t.getCause()); |
| | | } else { |
| | | final StringBuilder message = new StringBuilder(); |
| | | |
| | | final String className = t.getClass().getName(); |
| | | final int periodPos = className.lastIndexOf('.'); |
| | | if (periodPos > 0) { |
| | | message.append(className.substring(periodPos + 1)); |
| | | } else { |
| | | message.append(className); |
| | | } |
| | | |
| | | message.append("("); |
| | | if (t.getMessage() == null) { |
| | | final StackTraceElement[] stackElements = t.getStackTrace(); |
| | | message.append(stackElements[0].getFileName()); |
| | | message.append(":"); |
| | | message.append(stackElements[0].getLineNumber()); |
| | | |
| | | // FIXME Temporary to debug issue 2256. |
| | | if (t instanceof IllegalStateException) { |
| | | for (int i = 1; i < stackElements.length; i++) { |
| | | message.append(' '); |
| | | message.append(stackElements[i].getFileName()); |
| | | message.append(":"); |
| | | message.append(stackElements[i].getLineNumber()); |
| | | } |
| | | } |
| | | } else { |
| | | message.append(t.getMessage()); |
| | | } |
| | | |
| | | message.append(")"); |
| | | |
| | | return LocalizableMessage.raw(message.toString()); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | message.append(t.getMessage()); |
| | | } |
| | | |
| | | message.append(")"); |
| | | |
| | | return LocalizableMessage.raw(message.toString()); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Converts the provided hexadecimal string to a byte array. |
| | | * |
| | | * @param hexString |
| | | * The hexadecimal string to convert to a byte array. |
| | | * @return The byte array containing the binary representation of the provided |
| | | * hex string. |
| | | * @throws java.text.ParseException |
| | | * If the provided string contains invalid hexadecimal digits or |
| | | * does not contain an even number of digits. |
| | | */ |
| | | public static byte[] hexStringToByteArray(final String hexString) |
| | | throws ParseException |
| | | { |
| | | int length; |
| | | if (hexString == null || (length = hexString.length()) == 0) |
| | | { |
| | | return new byte[0]; |
| | | } |
| | | |
| | | if (length % 2 != 0) |
| | | { |
| | | final LocalizableMessage message = ERR_HEX_DECODE_INVALID_LENGTH |
| | | .get(hexString); |
| | | throw new ParseException(message.toString(), 0); |
| | | } |
| | | |
| | | final int arrayLength = length / 2; |
| | | final byte[] returnArray = new byte[arrayLength]; |
| | | for (int i = 0; i < arrayLength; i++) |
| | | { |
| | | returnArray[i] = hexToByte(hexString.charAt(i * 2), hexString |
| | | .charAt(i * 2 + 1)); |
| | | } |
| | | |
| | | return returnArray; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Converts the provided pair of characters to a byte. |
| | | * |
| | | * @param c1 |
| | | * The first hexadecimal character. |
| | | * @param c2 |
| | | * The second hexadecimal character. |
| | | * @return The byte containing the binary representation of the provided hex |
| | | * characters. |
| | | * @throws ParseException |
| | | * If the provided string contains invalid hexadecimal digits or |
| | | * does not contain an even number of digits. |
| | | */ |
| | | public static byte hexToByte(final char c1, final char c2) |
| | | throws ParseException |
| | | { |
| | | byte b; |
| | | switch (c1) |
| | | { |
| | | case '0': |
| | | b = 0x00; |
| | | break; |
| | | case '1': |
| | | b = 0x10; |
| | | break; |
| | | case '2': |
| | | b = 0x20; |
| | | break; |
| | | case '3': |
| | | b = 0x30; |
| | | break; |
| | | case '4': |
| | | b = 0x40; |
| | | break; |
| | | case '5': |
| | | b = 0x50; |
| | | break; |
| | | case '6': |
| | | b = 0x60; |
| | | break; |
| | | case '7': |
| | | b = 0x70; |
| | | break; |
| | | case '8': |
| | | b = (byte) 0x80; |
| | | break; |
| | | case '9': |
| | | b = (byte) 0x90; |
| | | break; |
| | | case 'A': |
| | | case 'a': |
| | | b = (byte) 0xA0; |
| | | break; |
| | | case 'B': |
| | | case 'b': |
| | | b = (byte) 0xB0; |
| | | break; |
| | | case 'C': |
| | | case 'c': |
| | | b = (byte) 0xC0; |
| | | break; |
| | | case 'D': |
| | | case 'd': |
| | | b = (byte) 0xD0; |
| | | break; |
| | | case 'E': |
| | | case 'e': |
| | | b = (byte) 0xE0; |
| | | break; |
| | | case 'F': |
| | | case 'f': |
| | | b = (byte) 0xF0; |
| | | break; |
| | | default: |
| | | final LocalizableMessage message = ERR_HEX_DECODE_INVALID_CHARACTER.get( |
| | | new String(new char[] { c1, c2 }), c1); |
| | | throw new ParseException(message.toString(), 0); |
| | | } |
| | | |
| | | switch (c2) |
| | | { |
| | | case '0': |
| | | // No action required. |
| | | break; |
| | | case '1': |
| | | b |= 0x01; |
| | | break; |
| | | case '2': |
| | | b |= 0x02; |
| | | break; |
| | | case '3': |
| | | b |= 0x03; |
| | | break; |
| | | case '4': |
| | | b |= 0x04; |
| | | break; |
| | | case '5': |
| | | b |= 0x05; |
| | | break; |
| | | case '6': |
| | | b |= 0x06; |
| | | break; |
| | | case '7': |
| | | b |= 0x07; |
| | | break; |
| | | case '8': |
| | | b |= 0x08; |
| | | break; |
| | | case '9': |
| | | b |= 0x09; |
| | | break; |
| | | case 'A': |
| | | case 'a': |
| | | b |= 0x0A; |
| | | break; |
| | | case 'B': |
| | | case 'b': |
| | | b |= 0x0B; |
| | | break; |
| | | case 'C': |
| | | case 'c': |
| | | b |= 0x0C; |
| | | break; |
| | | case 'D': |
| | | case 'd': |
| | | b |= 0x0D; |
| | | break; |
| | | case 'E': |
| | | case 'e': |
| | | b |= 0x0E; |
| | | break; |
| | | case 'F': |
| | | case 'f': |
| | | b |= 0x0F; |
| | | break; |
| | | default: |
| | | final LocalizableMessage message = ERR_HEX_DECODE_INVALID_CHARACTER.get( |
| | | new String(new char[] { c1, c2 }), c1); |
| | | throw new ParseException(message.toString(), 0); |
| | | } |
| | | |
| | | return b; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided character is an ASCII alphabetic character. |
| | | * |
| | | * @param c |
| | | * The character for which to make the determination. |
| | | * @return <CODE>true</CODE> if the provided value is an uppercase or |
| | | * lowercase ASCII alphabetic character, or <CODE>false</CODE> if it |
| | | * is not. |
| | | */ |
| | | public static boolean isAlpha(final char c) |
| | | { |
| | | final ASCIICharProp cp = ASCIICharProp.valueOf(c); |
| | | return cp != null ? cp.isLetter() : false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided character is a numeric digit. |
| | | * |
| | | * @param c |
| | | * The character for which to make the determination. |
| | | * @return <CODE>true</CODE> if the provided character represents a numeric |
| | | * digit, or <CODE>false</CODE> if not. |
| | | */ |
| | | public static boolean isDigit(final char c) |
| | | { |
| | | final ASCIICharProp cp = ASCIICharProp.valueOf(c); |
| | | return cp != null ? cp.isDigit() : false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided character is a hexadecimal digit. |
| | | * |
| | | * @param c |
| | | * The character for which to make the determination. |
| | | * @return <CODE>true</CODE> if the provided character represents a |
| | | * hexadecimal digit, or <CODE>false</CODE> if not. |
| | | */ |
| | | public static boolean isHexDigit(final char c) |
| | | { |
| | | final ASCIICharProp cp = ASCIICharProp.valueOf(c); |
| | | return cp != null ? cp.isHexDigit() : false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided character is a keychar. |
| | | * |
| | | * @param c |
| | | * The character for which to make the determination. |
| | | * @param allowCompatChars |
| | | * {@code true} if certain illegal characters should be allowed for |
| | | * compatibility reasons. |
| | | * @return <CODE>true</CODE> if the provided character represents a |
| | | * keychar, or <CODE>false</CODE> if not. |
| | | */ |
| | | public static boolean isKeyChar(final char c, final boolean allowCompatChars) |
| | | { |
| | | final ASCIICharProp cp = ASCIICharProp.valueOf(c); |
| | | return cp != null ? cp.isKeyChar(allowCompatChars) : false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns a string whose content is the string representation of the objects |
| | | * contained in the provided collection concatenated together using the |
| | | * provided separator. |
| | | * |
| | | * @param c |
| | | * The collection whose elements are to be joined. |
| | | * @param separator |
| | | * The separator string. |
| | | * @return A string whose content is the string representation of the objects |
| | | * contained in the provided collection concatenated together using |
| | | * the provided separator. |
| | | * @throws NullPointerException |
| | | * If {@code c} or {@code separator} were {@code null}. |
| | | */ |
| | | public static String joinCollection(Collection<?> c, String separator) |
| | | { |
| | | Validator.ensureNotNull(c, separator); |
| | | |
| | | switch (c.size()) |
| | | { |
| | | case 0: |
| | | return ""; |
| | | case 1: |
| | | return String.valueOf(c.iterator().next()); |
| | | default: |
| | | StringBuilder builder = new StringBuilder(); |
| | | Iterator<?> i = c.iterator(); |
| | | builder.append(i.next()); |
| | | while (i.hasNext()) |
| | | { |
| | | builder.append(separator); |
| | | builder.append(i.next()); |
| | | } |
| | | String s = builder.toString(); |
| | | return s; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new thread factory which will create threads using the specified |
| | | * thread group, naming template, and daemon status. |
| | | * |
| | | * @param group |
| | | * The thread group, which may be {@code null}. |
| | | * @param nameTemplate |
| | | * The thread name format string which may contain a "%d" format |
| | | * option which will be substituted with the thread count. |
| | | * @param isDaemon |
| | | * Indicates whether or not threads should be daemon threads. |
| | | * @return The new thread factory. |
| | | */ |
| | | public static ThreadFactory newThreadFactory(final ThreadGroup group, |
| | | final String nameTemplate, final boolean isDaemon) |
| | | { |
| | | return new ThreadFactory() |
| | | { |
| | | private final AtomicInteger count = new AtomicInteger(); |
| | | |
| | | |
| | | |
| | | public Thread newThread(Runnable r) |
| | | { |
| | | final String name = String |
| | | .format(nameTemplate, count.getAndIncrement()); |
| | | final Thread t = new Thread(group, r, name); |
| | | t.setDaemon(isDaemon); |
| | | return t; |
| | | } |
| | | }; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Returns a string representation of the contents of the provided byte |
| | | * sequence using hexadecimal characters and a space between each byte. |
| | | * |
| | | * @param bytes |
| | | * The byte sequence. |
| | | * @return A string representation of the contents of the provided byte |
| | | * sequence using hexadecimal characters. |
| | | */ |
| | | public static String toHex(final ByteSequence bytes) |
| | | { |
| | | return toHex(bytes, new StringBuilder((bytes.length() - 1) * 3 + 2)) |
| | | .toString(); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Appends the string representation of the contents of the provided byte |
| | | * sequence to a string builder using hexadecimal characters and a space |
| | | * between each byte. |
| | | * |
| | | * @param bytes |
| | | * The byte sequence. |
| | | * @param builder |
| | | * The string builder to which the hexadecimal representation of |
| | | * {@code bytes} should be appended. |
| | | * @return The string builder. |
| | | */ |
| | | public static StringBuilder toHex(final ByteSequence bytes, |
| | | final StringBuilder builder) |
| | | { |
| | | final int length = bytes.length(); |
| | | builder.ensureCapacity(builder.length() + (length - 1) * 3 + 2); |
| | | builder.append(StaticUtils.byteToHex(bytes.byteAt(0))); |
| | | for (int i = 1; i < length; i++) |
| | | { |
| | | builder.append(" "); |
| | | builder.append(StaticUtils.byteToHex(bytes.byteAt(i))); |
| | | } |
| | | return builder; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Appends a string representation of the data in the provided byte sequence |
| | | * to the given string builder using the specified indent. |
| | | * <p> |
| | | * The data will be formatted with sixteen hex bytes in a row followed by the |
| | | * ASCII representation, then wrapping to a new line as necessary. The state |
| | | * of the byte buffer is not changed. |
| | | * |
| | | * @param bytes |
| | | * The byte sequence. |
| | | * @param builder |
| | | * The string builder to which the information is to be appended. |
| | | * @param indent |
| | | * The number of spaces to indent the output. |
| | | * @return The string builder. |
| | | */ |
| | | public static StringBuilder toHexPlusAscii(final ByteSequence bytes, |
| | | final StringBuilder builder, final int indent) |
| | | { |
| | | final StringBuilder indentBuf = new StringBuilder(indent); |
| | | for (int i = 0; i < indent; i++) |
| | | { |
| | | indentBuf.append(' '); |
| | | } |
| | | |
| | | final int length = bytes.length(); |
| | | int pos = 0; |
| | | while (length - pos >= 16) |
| | | { |
| | | final StringBuilder asciiBuf = new StringBuilder(17); |
| | | |
| | | byte currentByte = bytes.byteAt(pos); |
| | | builder.append(indentBuf); |
| | | builder.append(StaticUtils.byteToHex(currentByte)); |
| | | asciiBuf.append(byteToASCII(currentByte)); |
| | | pos++; |
| | | |
| | | for (int i = 1; i < 16; i++, pos++) |
| | | { |
| | | currentByte = bytes.byteAt(pos); |
| | | builder.append(' '); |
| | | builder.append(StaticUtils.byteToHex(currentByte)); |
| | | asciiBuf.append(byteToASCII(currentByte)); |
| | | |
| | | if (i == 7) |
| | | { |
| | | builder.append(" "); |
| | | asciiBuf.append(' '); |
| | | } |
| | | } |
| | | |
| | | builder.append(" "); |
| | | builder.append(asciiBuf); |
| | | builder.append(EOL); |
| | | } |
| | | |
| | | final int remaining = length - pos; |
| | | if (remaining > 0) |
| | | { |
| | | final StringBuilder asciiBuf = new StringBuilder(remaining + 1); |
| | | |
| | | byte currentByte = bytes.byteAt(pos); |
| | | builder.append(indentBuf); |
| | | builder.append(StaticUtils.byteToHex(currentByte)); |
| | | asciiBuf.append(byteToASCII(currentByte)); |
| | | pos++; |
| | | |
| | | for (int i = 1; i < 16; i++, pos++) |
| | | { |
| | | builder.append(' '); |
| | | |
| | | if (i < remaining) |
| | | { |
| | | currentByte = bytes.byteAt(pos); |
| | | builder.append(StaticUtils.byteToHex(currentByte)); |
| | | asciiBuf.append(byteToASCII(currentByte)); |
| | | } |
| | | else |
| | | { |
| | | builder.append(" "); |
| | | /** |
| | | * Converts the provided hexadecimal string to a byte array. |
| | | * |
| | | * @param hexString |
| | | * The hexadecimal string to convert to a byte array. |
| | | * @return The byte array containing the binary representation of the |
| | | * provided hex string. |
| | | * @throws java.text.ParseException |
| | | * If the provided string contains invalid hexadecimal digits or |
| | | * does not contain an even number of digits. |
| | | */ |
| | | public static byte[] hexStringToByteArray(final String hexString) throws ParseException { |
| | | int length; |
| | | if (hexString == null || (length = hexString.length()) == 0) { |
| | | return new byte[0]; |
| | | } |
| | | |
| | | if (i == 7) |
| | | { |
| | | builder.append(" "); |
| | | |
| | | if (i < remaining) |
| | | { |
| | | asciiBuf.append(' '); |
| | | } |
| | | if (length % 2 != 0) { |
| | | final LocalizableMessage message = ERR_HEX_DECODE_INVALID_LENGTH.get(hexString); |
| | | throw new ParseException(message.toString(), 0); |
| | | } |
| | | } |
| | | |
| | | builder.append(" "); |
| | | builder.append(asciiBuf); |
| | | builder.append(EOL); |
| | | final int arrayLength = length / 2; |
| | | final byte[] returnArray = new byte[arrayLength]; |
| | | for (int i = 0; i < arrayLength; i++) { |
| | | returnArray[i] = hexToByte(hexString.charAt(i * 2), hexString.charAt(i * 2 + 1)); |
| | | } |
| | | |
| | | return returnArray; |
| | | } |
| | | |
| | | return builder; |
| | | } |
| | | /** |
| | | * Converts the provided pair of characters to a byte. |
| | | * |
| | | * @param c1 |
| | | * The first hexadecimal character. |
| | | * @param c2 |
| | | * The second hexadecimal character. |
| | | * @return The byte containing the binary representation of the provided hex |
| | | * characters. |
| | | * @throws ParseException |
| | | * If the provided string contains invalid hexadecimal digits or |
| | | * does not contain an even number of digits. |
| | | */ |
| | | public static byte hexToByte(final char c1, final char c2) throws ParseException { |
| | | byte b; |
| | | switch (c1) { |
| | | case '0': |
| | | b = 0x00; |
| | | break; |
| | | case '1': |
| | | b = 0x10; |
| | | break; |
| | | case '2': |
| | | b = 0x20; |
| | | break; |
| | | case '3': |
| | | b = 0x30; |
| | | break; |
| | | case '4': |
| | | b = 0x40; |
| | | break; |
| | | case '5': |
| | | b = 0x50; |
| | | break; |
| | | case '6': |
| | | b = 0x60; |
| | | break; |
| | | case '7': |
| | | b = 0x70; |
| | | break; |
| | | case '8': |
| | | b = (byte) 0x80; |
| | | break; |
| | | case '9': |
| | | b = (byte) 0x90; |
| | | break; |
| | | case 'A': |
| | | case 'a': |
| | | b = (byte) 0xA0; |
| | | break; |
| | | case 'B': |
| | | case 'b': |
| | | b = (byte) 0xB0; |
| | | break; |
| | | case 'C': |
| | | case 'c': |
| | | b = (byte) 0xC0; |
| | | break; |
| | | case 'D': |
| | | case 'd': |
| | | b = (byte) 0xD0; |
| | | break; |
| | | case 'E': |
| | | case 'e': |
| | | b = (byte) 0xE0; |
| | | break; |
| | | case 'F': |
| | | case 'f': |
| | | b = (byte) 0xF0; |
| | | break; |
| | | default: |
| | | final LocalizableMessage message = |
| | | ERR_HEX_DECODE_INVALID_CHARACTER.get(new String(new char[] { c1, c2 }), c1); |
| | | throw new ParseException(message.toString(), 0); |
| | | } |
| | | |
| | | switch (c2) { |
| | | case '0': |
| | | // No action required. |
| | | break; |
| | | case '1': |
| | | b |= 0x01; |
| | | break; |
| | | case '2': |
| | | b |= 0x02; |
| | | break; |
| | | case '3': |
| | | b |= 0x03; |
| | | break; |
| | | case '4': |
| | | b |= 0x04; |
| | | break; |
| | | case '5': |
| | | b |= 0x05; |
| | | break; |
| | | case '6': |
| | | b |= 0x06; |
| | | break; |
| | | case '7': |
| | | b |= 0x07; |
| | | break; |
| | | case '8': |
| | | b |= 0x08; |
| | | break; |
| | | case '9': |
| | | b |= 0x09; |
| | | break; |
| | | case 'A': |
| | | case 'a': |
| | | b |= 0x0A; |
| | | break; |
| | | case 'B': |
| | | case 'b': |
| | | b |= 0x0B; |
| | | break; |
| | | case 'C': |
| | | case 'c': |
| | | b |= 0x0C; |
| | | break; |
| | | case 'D': |
| | | case 'd': |
| | | b |= 0x0D; |
| | | break; |
| | | case 'E': |
| | | case 'e': |
| | | b |= 0x0E; |
| | | break; |
| | | case 'F': |
| | | case 'f': |
| | | b |= 0x0F; |
| | | break; |
| | | default: |
| | | final LocalizableMessage message = |
| | | ERR_HEX_DECODE_INVALID_CHARACTER.get(new String(new char[] { c1, c2 }), c1); |
| | | throw new ParseException(message.toString(), 0); |
| | | } |
| | | |
| | | return b; |
| | | } |
| | | |
| | | /** |
| | | * Appends a lowercase string representation of the contents of the given byte |
| | | * array to the provided buffer. This implementation presumes that the |
| | | * provided string will contain only ASCII characters and is optimized for |
| | | * that case. However, if a non-ASCII character is encountered it will fall |
| | | * back on a more expensive algorithm that will work properly for non-ASCII |
| | | * characters. |
| | | * |
| | | * @param b |
| | | * The byte array for which to obtain the lowercase string |
| | | * representation. |
| | | * @param builder |
| | | * The buffer to which the lowercase form of the string should be |
| | | * appended. |
| | | * @return The updated {@code StringBuilder}. |
| | | */ |
| | | public static StringBuilder toLowerCase(final ByteSequence b, |
| | | final StringBuilder builder) |
| | | { |
| | | Validator.ensureNotNull(b, builder); |
| | | /** |
| | | * Indicates whether the provided character is an ASCII alphabetic |
| | | * character. |
| | | * |
| | | * @param c |
| | | * The character for which to make the determination. |
| | | * @return <CODE>true</CODE> if the provided value is an uppercase or |
| | | * lowercase ASCII alphabetic character, or <CODE>false</CODE> if it |
| | | * is not. |
| | | */ |
| | | public static boolean isAlpha(final char c) { |
| | | final ASCIICharProp cp = ASCIICharProp.valueOf(c); |
| | | return cp != null ? cp.isLetter() : false; |
| | | } |
| | | |
| | | // FIXME: What locale should we use for non-ASCII characters? I |
| | | // think we should use default to the Unicode StringPrep. |
| | | /** |
| | | * Indicates whether the provided character is a numeric digit. |
| | | * |
| | | * @param c |
| | | * The character for which to make the determination. |
| | | * @return <CODE>true</CODE> if the provided character represents a numeric |
| | | * digit, or <CODE>false</CODE> if not. |
| | | */ |
| | | public static boolean isDigit(final char c) { |
| | | final ASCIICharProp cp = ASCIICharProp.valueOf(c); |
| | | return cp != null ? cp.isDigit() : false; |
| | | } |
| | | |
| | | final int origBufferLen = builder.length(); |
| | | final int length = b.length(); |
| | | /** |
| | | * Indicates whether the provided character is a hexadecimal digit. |
| | | * |
| | | * @param c |
| | | * The character for which to make the determination. |
| | | * @return <CODE>true</CODE> if the provided character represents a |
| | | * hexadecimal digit, or <CODE>false</CODE> if not. |
| | | */ |
| | | public static boolean isHexDigit(final char c) { |
| | | final ASCIICharProp cp = ASCIICharProp.valueOf(c); |
| | | return cp != null ? cp.isHexDigit() : false; |
| | | } |
| | | |
| | | for (int i = 0; i < length; i++) |
| | | { |
| | | final int c = b.byteAt(i); |
| | | /** |
| | | * Indicates whether the provided character is a keychar. |
| | | * |
| | | * @param c |
| | | * The character for which to make the determination. |
| | | * @param allowCompatChars |
| | | * {@code true} if certain illegal characters should be allowed |
| | | * for compatibility reasons. |
| | | * @return <CODE>true</CODE> if the provided character represents a keychar, |
| | | * or <CODE>false</CODE> if not. |
| | | */ |
| | | public static boolean isKeyChar(final char c, final boolean allowCompatChars) { |
| | | final ASCIICharProp cp = ASCIICharProp.valueOf(c); |
| | | return cp != null ? cp.isKeyChar(allowCompatChars) : false; |
| | | } |
| | | |
| | | if (c < 0) |
| | | { |
| | | builder.replace(origBufferLen, builder.length(), b.toString() |
| | | .toLowerCase(Locale.ENGLISH)); |
| | | /** |
| | | * Returns a string whose content is the string representation of the |
| | | * objects contained in the provided collection concatenated together using |
| | | * the provided separator. |
| | | * |
| | | * @param c |
| | | * The collection whose elements are to be joined. |
| | | * @param separator |
| | | * The separator string. |
| | | * @return A string whose content is the string representation of the |
| | | * objects contained in the provided collection concatenated |
| | | * together using the provided separator. |
| | | * @throws NullPointerException |
| | | * If {@code c} or {@code separator} were {@code null}. |
| | | */ |
| | | public static String joinCollection(Collection<?> c, String separator) { |
| | | Validator.ensureNotNull(c, separator); |
| | | |
| | | switch (c.size()) { |
| | | case 0: |
| | | return ""; |
| | | case 1: |
| | | return String.valueOf(c.iterator().next()); |
| | | default: |
| | | StringBuilder builder = new StringBuilder(); |
| | | Iterator<?> i = c.iterator(); |
| | | builder.append(i.next()); |
| | | while (i.hasNext()) { |
| | | builder.append(separator); |
| | | builder.append(i.next()); |
| | | } |
| | | String s = builder.toString(); |
| | | return s; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Creates a new thread factory which will create threads using the |
| | | * specified thread group, naming template, and daemon status. |
| | | * |
| | | * @param group |
| | | * The thread group, which may be {@code null}. |
| | | * @param nameTemplate |
| | | * The thread name format string which may contain a "%d" format |
| | | * option which will be substituted with the thread count. |
| | | * @param isDaemon |
| | | * Indicates whether or not threads should be daemon threads. |
| | | * @return The new thread factory. |
| | | */ |
| | | public static ThreadFactory newThreadFactory(final ThreadGroup group, |
| | | final String nameTemplate, final boolean isDaemon) { |
| | | return new ThreadFactory() { |
| | | private final AtomicInteger count = new AtomicInteger(); |
| | | |
| | | public Thread newThread(Runnable r) { |
| | | final String name = String.format(nameTemplate, count.getAndIncrement()); |
| | | final Thread t = new Thread(group, r, name); |
| | | t.setDaemon(isDaemon); |
| | | return t; |
| | | } |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * Returns a string representation of the contents of the provided byte |
| | | * sequence using hexadecimal characters and a space between each byte. |
| | | * |
| | | * @param bytes |
| | | * The byte sequence. |
| | | * @return A string representation of the contents of the provided byte |
| | | * sequence using hexadecimal characters. |
| | | */ |
| | | public static String toHex(final ByteSequence bytes) { |
| | | return toHex(bytes, new StringBuilder((bytes.length() - 1) * 3 + 2)).toString(); |
| | | } |
| | | |
| | | /** |
| | | * Appends the string representation of the contents of the provided byte |
| | | * sequence to a string builder using hexadecimal characters and a space |
| | | * between each byte. |
| | | * |
| | | * @param bytes |
| | | * The byte sequence. |
| | | * @param builder |
| | | * The string builder to which the hexadecimal representation of |
| | | * {@code bytes} should be appended. |
| | | * @return The string builder. |
| | | */ |
| | | public static StringBuilder toHex(final ByteSequence bytes, final StringBuilder builder) { |
| | | final int length = bytes.length(); |
| | | builder.ensureCapacity(builder.length() + (length - 1) * 3 + 2); |
| | | builder.append(StaticUtils.byteToHex(bytes.byteAt(0))); |
| | | for (int i = 1; i < length; i++) { |
| | | builder.append(" "); |
| | | builder.append(StaticUtils.byteToHex(bytes.byteAt(i))); |
| | | } |
| | | return builder; |
| | | } |
| | | |
| | | // At this point 0 <= 'c' <= 128. |
| | | final ASCIICharProp cp = ASCIICharProp.valueOf(c); |
| | | builder.append(cp.toLowerCase()); |
| | | } |
| | | |
| | | return builder; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a lower-case representation of the given string. This |
| | | * implementation presumes that the provided string will contain only ASCII |
| | | * characters and is optimized for that case. However, if a non-ASCII |
| | | * character is encountered it will fall back on a more expensive algorithm |
| | | * that will work properly for non-ASCII characters. |
| | | * |
| | | * @param s |
| | | * The string for which to obtain the lower-case representation. |
| | | * @return The lower-case representation of the given string. |
| | | */ |
| | | public static String toLowerCase(final String s) |
| | | { |
| | | Validator.ensureNotNull(s); |
| | | |
| | | // FIXME: What locale should we use for non-ASCII characters? I |
| | | // think we should use default to the Unicode StringPrep. |
| | | |
| | | // This code is optimized for the case where the input string 's' |
| | | // has already been converted to lowercase. |
| | | final int length = s.length(); |
| | | int i = 0; |
| | | ASCIICharProp cp = null; |
| | | |
| | | // Scan for non lowercase ASCII. |
| | | while (i < length) |
| | | { |
| | | cp = ASCIICharProp.valueOf(s.charAt(i)); |
| | | if (cp == null || cp.isUpperCase()) |
| | | { |
| | | break; |
| | | } |
| | | i++; |
| | | } |
| | | |
| | | if (i == length) |
| | | { |
| | | // String was already lowercase ASCII. |
| | | return s; |
| | | } |
| | | |
| | | // Found non lowercase ASCII. |
| | | final StringBuilder builder = new StringBuilder(length); |
| | | builder.append(s, 0, i); |
| | | |
| | | if (cp != null) |
| | | { |
| | | // Upper-case ASCII. |
| | | builder.append(cp.toLowerCase()); |
| | | i++; |
| | | while (i < length) |
| | | { |
| | | cp = ASCIICharProp.valueOf(s.charAt(i)); |
| | | if (cp == null) |
| | | { |
| | | break; |
| | | /** |
| | | * Appends a string representation of the data in the provided byte sequence |
| | | * to the given string builder using the specified indent. |
| | | * <p> |
| | | * The data will be formatted with sixteen hex bytes in a row followed by |
| | | * the ASCII representation, then wrapping to a new line as necessary. The |
| | | * state of the byte buffer is not changed. |
| | | * |
| | | * @param bytes |
| | | * The byte sequence. |
| | | * @param builder |
| | | * The string builder to which the information is to be appended. |
| | | * @param indent |
| | | * The number of spaces to indent the output. |
| | | * @return The string builder. |
| | | */ |
| | | public static StringBuilder toHexPlusAscii(final ByteSequence bytes, |
| | | final StringBuilder builder, final int indent) { |
| | | final StringBuilder indentBuf = new StringBuilder(indent); |
| | | for (int i = 0; i < indent; i++) { |
| | | indentBuf.append(' '); |
| | | } |
| | | builder.append(cp.toLowerCase()); |
| | | i++; |
| | | } |
| | | } |
| | | |
| | | if (i < length) |
| | | { |
| | | builder.append(s.substring(i).toLowerCase(Locale.ENGLISH)); |
| | | } |
| | | final int length = bytes.length(); |
| | | int pos = 0; |
| | | while (length - pos >= 16) { |
| | | final StringBuilder asciiBuf = new StringBuilder(17); |
| | | |
| | | return builder.toString(); |
| | | } |
| | | byte currentByte = bytes.byteAt(pos); |
| | | builder.append(indentBuf); |
| | | builder.append(StaticUtils.byteToHex(currentByte)); |
| | | asciiBuf.append(byteToASCII(currentByte)); |
| | | pos++; |
| | | |
| | | for (int i = 1; i < 16; i++, pos++) { |
| | | currentByte = bytes.byteAt(pos); |
| | | builder.append(' '); |
| | | builder.append(StaticUtils.byteToHex(currentByte)); |
| | | asciiBuf.append(byteToASCII(currentByte)); |
| | | |
| | | if (i == 7) { |
| | | builder.append(" "); |
| | | asciiBuf.append(' '); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Appends a lower-case representation of the given string to the provided |
| | | * buffer. This implementation presumes that the provided string will contain |
| | | * only ASCII characters and is optimized for that case. However, if a |
| | | * non-ASCII character is encountered it will fall back on a more expensive |
| | | * algorithm that will work properly for non-ASCII characters. |
| | | * |
| | | * @param s |
| | | * The string for which to obtain the lower-case representation. |
| | | * @param builder |
| | | * The {@code StringBuilder} to which the lower-case form of the |
| | | * string should be appended. |
| | | * @return The updated {@code StringBuilder}. |
| | | */ |
| | | public static StringBuilder toLowerCase(final String s, |
| | | final StringBuilder builder) |
| | | { |
| | | Validator.ensureNotNull(s, builder); |
| | | builder.append(" "); |
| | | builder.append(asciiBuf); |
| | | builder.append(EOL); |
| | | } |
| | | |
| | | // FIXME: What locale should we use for non-ASCII characters? I |
| | | // think we should use default to the Unicode StringPrep. |
| | | final int remaining = length - pos; |
| | | if (remaining > 0) { |
| | | final StringBuilder asciiBuf = new StringBuilder(remaining + 1); |
| | | |
| | | final int length = s.length(); |
| | | builder.ensureCapacity(builder.length() + length); |
| | | byte currentByte = bytes.byteAt(pos); |
| | | builder.append(indentBuf); |
| | | builder.append(StaticUtils.byteToHex(currentByte)); |
| | | asciiBuf.append(byteToASCII(currentByte)); |
| | | pos++; |
| | | |
| | | for (int i = 0; i < length; i++) |
| | | { |
| | | final ASCIICharProp cp = ASCIICharProp.valueOf(s.charAt(i)); |
| | | if (cp != null) |
| | | { |
| | | builder.append(cp.toLowerCase()); |
| | | } |
| | | else |
| | | { |
| | | // Non-ASCII. |
| | | builder.append(s.substring(i).toLowerCase(Locale.ENGLISH)); |
| | | for (int i = 1; i < 16; i++, pos++) { |
| | | builder.append(' '); |
| | | |
| | | if (i < remaining) { |
| | | currentByte = bytes.byteAt(pos); |
| | | builder.append(StaticUtils.byteToHex(currentByte)); |
| | | asciiBuf.append(byteToASCII(currentByte)); |
| | | } else { |
| | | builder.append(" "); |
| | | } |
| | | |
| | | if (i == 7) { |
| | | builder.append(" "); |
| | | |
| | | if (i < remaining) { |
| | | asciiBuf.append(' '); |
| | | } |
| | | } |
| | | } |
| | | |
| | | builder.append(" "); |
| | | builder.append(asciiBuf); |
| | | builder.append(EOL); |
| | | } |
| | | |
| | | return builder; |
| | | } |
| | | } |
| | | |
| | | return builder; |
| | | } |
| | | /** |
| | | * Appends a lowercase string representation of the contents of the given |
| | | * byte array to the provided buffer. This implementation presumes that the |
| | | * provided string will contain only ASCII characters and is optimized for |
| | | * that case. However, if a non-ASCII character is encountered it will fall |
| | | * back on a more expensive algorithm that will work properly for non-ASCII |
| | | * characters. |
| | | * |
| | | * @param b |
| | | * The byte array for which to obtain the lowercase string |
| | | * representation. |
| | | * @param builder |
| | | * The buffer to which the lowercase form of the string should be |
| | | * appended. |
| | | * @return The updated {@code StringBuilder}. |
| | | */ |
| | | public static StringBuilder toLowerCase(final ByteSequence b, final StringBuilder builder) { |
| | | Validator.ensureNotNull(b, builder); |
| | | |
| | | // FIXME: What locale should we use for non-ASCII characters? I |
| | | // think we should use default to the Unicode StringPrep. |
| | | |
| | | final int origBufferLen = builder.length(); |
| | | final int length = b.length(); |
| | | |
| | | /** |
| | | * Attempts to uncompress the data in the provided source array into the given |
| | | * destination array. If the uncompressed data will fit into the given |
| | | * destination array, then this method will return the number of bytes of |
| | | * uncompressed data written into the destination buffer. Otherwise, it will |
| | | * return a negative value to indicate that the destination buffer was not |
| | | * large enough. The absolute value of that negative return value will |
| | | * indicate the buffer size required to fully decompress the data. Note that |
| | | * if a negative value is returned, then the data in the destination array |
| | | * should be considered invalid. |
| | | * |
| | | * @param src |
| | | * The array containing the raw data to compress. |
| | | * @param srcOff |
| | | * The start offset of the source data. |
| | | * @param srcLen |
| | | * The maximum number of source data bytes to compress. |
| | | * @param dst |
| | | * The array into which the compressed data should be written. |
| | | * @param dstOff |
| | | * The start offset of the compressed data. |
| | | * @param dstLen |
| | | * The maximum number of bytes of compressed data. |
| | | * @return A positive value containing the number of bytes of uncompressed |
| | | * data written into the destination buffer, or a negative value whose |
| | | * absolute value is the size of the destination buffer required to |
| | | * fully decompress the provided data. |
| | | * @throws java.util.zip.DataFormatException |
| | | * If a problem occurs while attempting to uncompress the data. |
| | | */ |
| | | public static int uncompress(final byte[] src, final int srcOff, |
| | | final int srcLen, final byte[] dst, final int dstOff, final int dstLen) |
| | | throws DataFormatException |
| | | { |
| | | final Inflater inflater = new Inflater(); |
| | | try |
| | | { |
| | | inflater.setInput(src, srcOff, srcLen); |
| | | for (int i = 0; i < length; i++) { |
| | | final int c = b.byteAt(i); |
| | | |
| | | final int decompressedLength = inflater.inflate(dst, dstOff, dstLen); |
| | | if (inflater.finished()) |
| | | { |
| | | return decompressedLength; |
| | | } |
| | | else |
| | | { |
| | | int totalLength = decompressedLength; |
| | | if (c < 0) { |
| | | builder.replace(origBufferLen, builder.length(), b.toString().toLowerCase( |
| | | Locale.ENGLISH)); |
| | | return builder; |
| | | } |
| | | |
| | | while (!inflater.finished()) |
| | | { |
| | | totalLength += inflater.inflate(dst, dstOff, dstLen); |
| | | // At this point 0 <= 'c' <= 128. |
| | | final ASCIICharProp cp = ASCIICharProp.valueOf(c); |
| | | builder.append(cp.toLowerCase()); |
| | | } |
| | | |
| | | return -totalLength; |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | inflater.end(); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Attempts to uncompress the data in the provided byte sequence into the |
| | | * provided byte string builder. Note that if uncompression was not |
| | | * successful, then the data in the destination buffer should be considered |
| | | * invalid. |
| | | * |
| | | * @param input |
| | | * The source data to be uncompressed. |
| | | * @param output |
| | | * The destination buffer to which the uncompressed data will be |
| | | * appended. |
| | | * @param uncompressedSize |
| | | * The uncompressed size of the data if known or 0 otherwise. |
| | | * @return <code>true</code> if decompression was successful or |
| | | * <code>false</code> otherwise. |
| | | * @throws java.util.zip.DataFormatException |
| | | * If a problem occurs while attempting to uncompress the data. |
| | | */ |
| | | public static boolean uncompress(final ByteSequence input, |
| | | final ByteStringBuilder output, final int uncompressedSize) |
| | | throws DataFormatException |
| | | { |
| | | final byte[] inputBytes = input.toByteArray(); |
| | | byte[] outputBytes = new byte[uncompressedSize > 0 ? uncompressedSize : 0]; |
| | | |
| | | int decompressResult = uncompress(inputBytes, 0, inputBytes.length, |
| | | outputBytes, 0, outputBytes.length); |
| | | |
| | | if (decompressResult < 0) |
| | | { |
| | | // The destination buffer wasn't big enough. Resize and retry. |
| | | outputBytes = new byte[-decompressResult]; |
| | | decompressResult = uncompress(inputBytes, 0, inputBytes.length, |
| | | outputBytes, 0, outputBytes.length); |
| | | return builder; |
| | | } |
| | | |
| | | if (decompressResult >= 0) |
| | | { |
| | | // It was successful. |
| | | output.append(outputBytes, 0, decompressResult); |
| | | return true; |
| | | /** |
| | | * Retrieves a lower-case representation of the given string. This |
| | | * implementation presumes that the provided string will contain only ASCII |
| | | * characters and is optimized for that case. However, if a non-ASCII |
| | | * character is encountered it will fall back on a more expensive algorithm |
| | | * that will work properly for non-ASCII characters. |
| | | * |
| | | * @param s |
| | | * The string for which to obtain the lower-case representation. |
| | | * @return The lower-case representation of the given string. |
| | | */ |
| | | public static String toLowerCase(final String s) { |
| | | Validator.ensureNotNull(s); |
| | | |
| | | // FIXME: What locale should we use for non-ASCII characters? I |
| | | // think we should use default to the Unicode StringPrep. |
| | | |
| | | // This code is optimized for the case where the input string 's' |
| | | // has already been converted to lowercase. |
| | | final int length = s.length(); |
| | | int i = 0; |
| | | ASCIICharProp cp = null; |
| | | |
| | | // Scan for non lowercase ASCII. |
| | | while (i < length) { |
| | | cp = ASCIICharProp.valueOf(s.charAt(i)); |
| | | if (cp == null || cp.isUpperCase()) { |
| | | break; |
| | | } |
| | | i++; |
| | | } |
| | | |
| | | if (i == length) { |
| | | // String was already lowercase ASCII. |
| | | return s; |
| | | } |
| | | |
| | | // Found non lowercase ASCII. |
| | | final StringBuilder builder = new StringBuilder(length); |
| | | builder.append(s, 0, i); |
| | | |
| | | if (cp != null) { |
| | | // Upper-case ASCII. |
| | | builder.append(cp.toLowerCase()); |
| | | i++; |
| | | while (i < length) { |
| | | cp = ASCIICharProp.valueOf(s.charAt(i)); |
| | | if (cp == null) { |
| | | break; |
| | | } |
| | | builder.append(cp.toLowerCase()); |
| | | i++; |
| | | } |
| | | } |
| | | |
| | | if (i < length) { |
| | | builder.append(s.substring(i).toLowerCase(Locale.ENGLISH)); |
| | | } |
| | | |
| | | return builder.toString(); |
| | | } |
| | | |
| | | // Still unsuccessful. Give up. |
| | | return false; |
| | | } |
| | | /** |
| | | * Appends a lower-case representation of the given string to the provided |
| | | * buffer. This implementation presumes that the provided string will |
| | | * contain only ASCII characters and is optimized for that case. However, if |
| | | * a non-ASCII character is encountered it will fall back on a more |
| | | * expensive algorithm that will work properly for non-ASCII characters. |
| | | * |
| | | * @param s |
| | | * The string for which to obtain the lower-case representation. |
| | | * @param builder |
| | | * The {@code StringBuilder} to which the lower-case form of the |
| | | * string should be appended. |
| | | * @return The updated {@code StringBuilder}. |
| | | */ |
| | | public static StringBuilder toLowerCase(final String s, final StringBuilder builder) { |
| | | Validator.ensureNotNull(s, builder); |
| | | |
| | | // FIXME: What locale should we use for non-ASCII characters? I |
| | | // think we should use default to the Unicode StringPrep. |
| | | |
| | | final int length = s.length(); |
| | | builder.ensureCapacity(builder.length() + length); |
| | | |
| | | /** |
| | | * Returns a copy of the provided byte array. |
| | | * |
| | | * @param bytes |
| | | * The byte array to be copied. |
| | | * @return A copy of the provided byte array. |
| | | */ |
| | | public static byte[] copyOfBytes(final byte[] bytes) |
| | | { |
| | | return Arrays.copyOf(bytes, bytes.length); |
| | | } |
| | | for (int i = 0; i < length; i++) { |
| | | final ASCIICharProp cp = ASCIICharProp.valueOf(s.charAt(i)); |
| | | if (cp != null) { |
| | | builder.append(cp.toLowerCase()); |
| | | } else { |
| | | // Non-ASCII. |
| | | builder.append(s.substring(i).toLowerCase(Locale.ENGLISH)); |
| | | return builder; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the printable ASCII representation of the provided byte. |
| | | * |
| | | * @param b |
| | | * The byte for which to retrieve the printable ASCII representation. |
| | | * @return The printable ASCII representation of the provided byte, or a space |
| | | * if the provided byte does not have printable ASCII representation. |
| | | */ |
| | | private static char byteToASCII(final byte b) |
| | | { |
| | | if (b >= 32 && b <= 126) |
| | | { |
| | | return (char) b; |
| | | return builder; |
| | | } |
| | | |
| | | return ' '; |
| | | } |
| | | /** |
| | | * Attempts to uncompress the data in the provided source array into the |
| | | * given destination array. If the uncompressed data will fit into the given |
| | | * destination array, then this method will return the number of bytes of |
| | | * uncompressed data written into the destination buffer. Otherwise, it will |
| | | * return a negative value to indicate that the destination buffer was not |
| | | * large enough. The absolute value of that negative return value will |
| | | * indicate the buffer size required to fully decompress the data. Note that |
| | | * if a negative value is returned, then the data in the destination array |
| | | * should be considered invalid. |
| | | * |
| | | * @param src |
| | | * The array containing the raw data to compress. |
| | | * @param srcOff |
| | | * The start offset of the source data. |
| | | * @param srcLen |
| | | * The maximum number of source data bytes to compress. |
| | | * @param dst |
| | | * The array into which the compressed data should be written. |
| | | * @param dstOff |
| | | * The start offset of the compressed data. |
| | | * @param dstLen |
| | | * The maximum number of bytes of compressed data. |
| | | * @return A positive value containing the number of bytes of uncompressed |
| | | * data written into the destination buffer, or a negative value |
| | | * whose absolute value is the size of the destination buffer |
| | | * required to fully decompress the provided data. |
| | | * @throws java.util.zip.DataFormatException |
| | | * If a problem occurs while attempting to uncompress the data. |
| | | */ |
| | | public static int uncompress(final byte[] src, final int srcOff, final int srcLen, |
| | | final byte[] dst, final int dstOff, final int dstLen) throws DataFormatException { |
| | | final Inflater inflater = new Inflater(); |
| | | try { |
| | | inflater.setInput(src, srcOff, srcLen); |
| | | |
| | | final int decompressedLength = inflater.inflate(dst, dstOff, dstLen); |
| | | if (inflater.finished()) { |
| | | return decompressedLength; |
| | | } else { |
| | | int totalLength = decompressedLength; |
| | | |
| | | while (!inflater.finished()) { |
| | | totalLength += inflater.inflate(dst, dstOff, dstLen); |
| | | } |
| | | |
| | | // Prevent instantiation. |
| | | private StaticUtils() |
| | | { |
| | | // No implementation required. |
| | | } |
| | | return -totalLength; |
| | | } |
| | | } finally { |
| | | inflater.end(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Attempts to uncompress the data in the provided byte sequence into the |
| | | * provided byte string builder. Note that if uncompression was not |
| | | * successful, then the data in the destination buffer should be considered |
| | | * invalid. |
| | | * |
| | | * @param input |
| | | * The source data to be uncompressed. |
| | | * @param output |
| | | * The destination buffer to which the uncompressed data will be |
| | | * appended. |
| | | * @param uncompressedSize |
| | | * The uncompressed size of the data if known or 0 otherwise. |
| | | * @return <code>true</code> if decompression was successful or |
| | | * <code>false</code> otherwise. |
| | | * @throws java.util.zip.DataFormatException |
| | | * If a problem occurs while attempting to uncompress the data. |
| | | */ |
| | | public static boolean uncompress(final ByteSequence input, final ByteStringBuilder output, |
| | | final int uncompressedSize) throws DataFormatException { |
| | | final byte[] inputBytes = input.toByteArray(); |
| | | byte[] outputBytes = new byte[uncompressedSize > 0 ? uncompressedSize : 0]; |
| | | |
| | | int decompressResult = |
| | | uncompress(inputBytes, 0, inputBytes.length, outputBytes, 0, outputBytes.length); |
| | | |
| | | if (decompressResult < 0) { |
| | | // The destination buffer wasn't big enough. Resize and retry. |
| | | outputBytes = new byte[-decompressResult]; |
| | | decompressResult = |
| | | uncompress(inputBytes, 0, inputBytes.length, outputBytes, 0, outputBytes.length); |
| | | } |
| | | |
| | | if (decompressResult >= 0) { |
| | | // It was successful. |
| | | output.append(outputBytes, 0, decompressResult); |
| | | return true; |
| | | } |
| | | |
| | | // Still unsuccessful. Give up. |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * Returns a copy of the provided byte array. |
| | | * |
| | | * @param bytes |
| | | * The byte array to be copied. |
| | | * @return A copy of the provided byte array. |
| | | */ |
| | | public static byte[] copyOfBytes(final byte[] bytes) { |
| | | return Arrays.copyOf(bytes, bytes.length); |
| | | } |
| | | |
| | | /** |
| | | * Retrieves the printable ASCII representation of the provided byte. |
| | | * |
| | | * @param b |
| | | * The byte for which to retrieve the printable ASCII |
| | | * representation. |
| | | * @return The printable ASCII representation of the provided byte, or a |
| | | * space if the provided byte does not have printable ASCII |
| | | * representation. |
| | | */ |
| | | private static char byteToASCII(final byte b) { |
| | | if (b >= 32 && b <= 126) { |
| | | return (char) b; |
| | | } |
| | | |
| | | return ' '; |
| | | } |
| | | |
| | | // Prevent instantiation. |
| | | private StaticUtils() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | } |