From 263d085885df024dca9250cc03c807912b0a7662 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 24 Apr 2012 22:33:21 +0000
Subject: [PATCH] Reformat to comply with new Checkstyle rules.
---
opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java | 4221 ++++++++++++++++++++++++++++-------------------------------
1 files changed, 2,016 insertions(+), 2,205 deletions(-)
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java
index 6edb99e..d892bf3 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/StaticUtils.java
@@ -6,17 +6,16 @@
* (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
@@ -28,8 +27,6 @@
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;
@@ -38,7 +35,14 @@
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;
@@ -55,2280 +59,2087 @@
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.
+ }
}
--
Gitblit v1.10.0