1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tools.layoutlib.java; 18 19 /** 20 * Defines the same class as the java.lang.IntegralToString which was added in 21 * Dalvik VM. This hack, provides a replacement for that class which can't be 22 * loaded in the standard JVM since it's in the java package and standard JVM 23 * doesn't have it. Since it's no longer in java.lang, access to package 24 * private methods and classes has been replaced by the closes matching public 25 * implementation. 26 * <p/> 27 * Extracted from API level 18, file: 28 * platform/libcore/luni/src/main/java/java/lang/IntegralToString.java 29 */ 30 public final class IntegralToString { 31 /** 32 * When appending to an AbstractStringBuilder, this thread-local char[] lets us avoid 33 * allocation of a temporary array. (We can't write straight into the AbstractStringBuilder 34 * because it's almost as expensive to work out the exact length of the result as it is to 35 * do the formatting. We could try being conservative and "delete"-ing the unused space 36 * afterwards, but then we'd need to duplicate convertInt and convertLong rather than share 37 * the code.) 38 */ 39 private static final ThreadLocal<char[]> BUFFER = new ThreadLocal<char[]>() { 40 @Override protected char[] initialValue() { 41 return new char[20]; // Maximum length of a base-10 long. 42 } 43 }; 44 45 /** 46 * These tables are used to special-case toString computation for 47 * small values. This serves three purposes: it reduces memory usage; 48 * it increases performance for small values; and it decreases the 49 * number of comparisons required to do the length computation. 50 * Elements of this table are lazily initialized on first use. 51 * No locking is necessary, i.e., we use the non-volatile, racy 52 * single-check idiom. 53 */ 54 private static final String[] SMALL_NONNEGATIVE_VALUES = new String[100]; 55 private static final String[] SMALL_NEGATIVE_VALUES = new String[100]; 56 57 /** TENS[i] contains the tens digit of the number i, 0 <= i <= 99. */ 58 private static final char[] TENS = { 59 '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 60 '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', 61 '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', 62 '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', 63 '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', 64 '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', 65 '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', 66 '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', 67 '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', 68 '9', '9', '9', '9', '9', '9', '9', '9', '9', '9' 69 }; 70 71 /** Ones [i] contains the tens digit of the number i, 0 <= i <= 99. */ 72 private static final char[] ONES = { 73 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 74 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 75 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 76 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 77 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 78 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 79 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 80 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 81 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 82 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 83 }; 84 85 /** 86 * Table for MOD / DIV 10 computation described in Section 10-21 87 * of Hank Warren's "Hacker's Delight" online addendum. 88 * http://www.hackersdelight.org/divcMore.pdf 89 */ 90 private static final char[] MOD_10_TABLE = { 91 0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 0 92 }; 93 94 /** 95 * The digits for every supported radix. 96 */ 97 private static final char[] DIGITS = { 98 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 99 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 100 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 101 'u', 'v', 'w', 'x', 'y', 'z' 102 }; 103 104 private static final char[] UPPER_CASE_DIGITS = { 105 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 106 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 107 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 108 'U', 'V', 'W', 'X', 'Y', 'Z' 109 }; 110 IntegralToString()111 private IntegralToString() { 112 } 113 114 /** 115 * Equivalent to Integer.toString(i, radix). 116 */ intToString(int i, int radix)117 public static String intToString(int i, int radix) { 118 if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { 119 radix = 10; 120 } 121 if (radix == 10) { 122 return intToString(i); 123 } 124 125 /* 126 * If i is positive, negate it. This is the opposite of what one might 127 * expect. It is necessary because the range of the negative values is 128 * strictly larger than that of the positive values: there is no 129 * positive value corresponding to Integer.MIN_VALUE. 130 */ 131 boolean negative = false; 132 if (i < 0) { 133 negative = true; 134 } else { 135 i = -i; 136 } 137 138 int bufLen = radix < 8 ? 33 : 12; // Max chars in result (conservative) 139 char[] buf = new char[bufLen]; 140 int cursor = bufLen; 141 142 do { 143 int q = i / radix; 144 buf[--cursor] = DIGITS[radix * q - i]; 145 i = q; 146 } while (i != 0); 147 148 if (negative) { 149 buf[--cursor] = '-'; 150 } 151 152 return new String(buf, cursor, bufLen - cursor); 153 } 154 155 /** 156 * Equivalent to Integer.toString(i). 157 */ 158 public static String intToString(int i) { 159 return convertInt(null, i); 160 } 161 162 /** 163 * Equivalent to sb.append(Integer.toString(i)). 164 */ 165 public static void appendInt(StringBuilder sb, int i) { 166 convertInt(sb, i); 167 } 168 169 /** 170 * Returns the string representation of i and leaves sb alone if sb is null. 171 * Returns null and appends the string representation of i to sb if sb is non-null. 172 */ 173 private static String convertInt(StringBuilder sb, int i) { 174 boolean negative = false; 175 String quickResult = null; 176 if (i < 0) { 177 negative = true; 178 i = -i; 179 if (i < 100) { 180 if (i < 0) { 181 // If -n is still negative, n is Integer.MIN_VALUE 182 quickResult = "-2147483648"; 183 } else { 184 quickResult = SMALL_NEGATIVE_VALUES[i]; 185 if (quickResult == null) { 186 SMALL_NEGATIVE_VALUES[i] = quickResult = 187 i < 10 ? stringOf('-', ONES[i]) : stringOf('-', TENS[i], ONES[i]); 188 } 189 } 190 } 191 } else { 192 if (i < 100) { 193 quickResult = SMALL_NONNEGATIVE_VALUES[i]; 194 if (quickResult == null) { 195 SMALL_NONNEGATIVE_VALUES[i] = quickResult = 196 i < 10 ? stringOf(ONES[i]) : stringOf(TENS[i], ONES[i]); 197 } 198 } 199 } 200 if (quickResult != null) { 201 if (sb != null) { 202 sb.append(quickResult); 203 return null; 204 } 205 return quickResult; 206 } 207 208 int bufLen = 11; // Max number of chars in result 209 char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen]; 210 int cursor = bufLen; 211 212 // Calculate digits two-at-a-time till remaining digits fit in 16 bits 213 while (i >= (1 << 16)) { 214 // Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8 215 int q = (int) ((0x51EB851FL * i) >>> 37); 216 int r = i - 100*q; 217 buf[--cursor] = ONES[r]; 218 buf[--cursor] = TENS[r]; 219 i = q; 220 } 221 222 // Calculate remaining digits one-at-a-time for performance 223 while (i != 0) { 224 // Compute q = n/10 and r = n % 10 as per "Hacker's Delight" 10-8 225 int q = (0xCCCD * i) >>> 19; 226 int r = i - 10*q; 227 buf[--cursor] = DIGITS[r]; 228 i = q; 229 } 230 231 if (negative) { 232 buf[--cursor] = '-'; 233 } 234 235 if (sb != null) { 236 sb.append(buf, cursor, bufLen - cursor); 237 return null; 238 } else { 239 return new String(buf, cursor, bufLen - cursor); 240 } 241 } 242 243 /** 244 * Equivalent to Long.toString(v, radix). 245 */ 246 public static String longToString(long v, int radix) { 247 int i = (int) v; 248 if (i == v) { 249 return intToString(i, radix); 250 } 251 252 if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { 253 radix = 10; 254 } 255 if (radix == 10) { 256 return longToString(v); 257 } 258 259 /* 260 * If v is positive, negate it. This is the opposite of what one might 261 * expect. It is necessary because the range of the negative values is 262 * strictly larger than that of the positive values: there is no 263 * positive value corresponding to Integer.MIN_VALUE. 264 */ 265 boolean negative = false; 266 if (v < 0) { 267 negative = true; 268 } else { 269 v = -v; 270 } 271 272 int bufLen = radix < 8 ? 65 : 23; // Max chars in result (conservative) 273 char[] buf = new char[bufLen]; 274 int cursor = bufLen; 275 276 do { 277 long q = v / radix; 278 buf[--cursor] = DIGITS[(int) (radix * q - v)]; 279 v = q; 280 } while (v != 0); 281 282 if (negative) { 283 buf[--cursor] = '-'; 284 } 285 286 return new String(buf, cursor, bufLen - cursor); 287 } 288 289 /** 290 * Equivalent to Long.toString(l). 291 */ 292 public static String longToString(long l) { 293 return convertLong(null, l); 294 } 295 296 /** 297 * Equivalent to sb.append(Long.toString(l)). 298 */ 299 public static void appendLong(StringBuilder sb, long l) { 300 convertLong(sb, l); 301 } 302 303 /** 304 * Returns the string representation of n and leaves sb alone if sb is null. 305 * Returns null and appends the string representation of n to sb if sb is non-null. 306 */ 307 private static String convertLong(StringBuilder sb, long n) { 308 int i = (int) n; 309 if (i == n) { 310 return convertInt(sb, i); 311 } 312 313 boolean negative = (n < 0); 314 if (negative) { 315 n = -n; 316 if (n < 0) { 317 // If -n is still negative, n is Long.MIN_VALUE 318 String quickResult = "-9223372036854775808"; 319 if (sb != null) { 320 sb.append(quickResult); 321 return null; 322 } 323 return quickResult; 324 } 325 } 326 327 int bufLen = 20; // Maximum number of chars in result 328 char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen]; 329 330 int low = (int) (n % 1000000000); // Extract low-order 9 digits 331 int cursor = intIntoCharArray(buf, bufLen, low); 332 333 // Zero-pad Low order part to 9 digits 334 while (cursor != (bufLen - 9)) { 335 buf[--cursor] = '0'; 336 } 337 338 /* 339 * The remaining digits are (n - low) / 1,000,000,000. This 340 * "exact division" is done as per the online addendum to Hank Warren's 341 * "Hacker's Delight" 10-20, http://www.hackersdelight.org/divcMore.pdf 342 */ 343 n = ((n - low) >>> 9) * 0x8E47CE423A2E9C6DL; 344 345 /* 346 * If the remaining digits fit in an int, emit them using a 347 * single call to intIntoCharArray. Otherwise, strip off the 348 * low-order digit, put it in buf, and then call intIntoCharArray 349 * on the remaining digits (which now fit in an int). 350 */ 351 if ((n & (-1L << 32)) == 0) { 352 cursor = intIntoCharArray(buf, cursor, (int) n); 353 } else { 354 /* 355 * Set midDigit to n % 10 356 */ 357 int lo32 = (int) n; 358 int hi32 = (int) (n >>> 32); 359 360 // midDigit = ((unsigned) low32) % 10, per "Hacker's Delight" 10-21 361 int midDigit = MOD_10_TABLE[(0x19999999 * lo32 + (lo32 >>> 1) + (lo32 >>> 3)) >>> 28]; 362 363 // Adjust midDigit for hi32. (assert hi32 == 1 || hi32 == 2) 364 midDigit -= hi32 << 2; // 1L << 32 == -4 MOD 10 365 if (midDigit < 0) { 366 midDigit += 10; 367 } 368 buf[--cursor] = DIGITS[midDigit]; 369 370 // Exact division as per Warren 10-20 371 int rest = ((int) ((n - midDigit) >>> 1)) * 0xCCCCCCCD; 372 cursor = intIntoCharArray(buf, cursor, rest); 373 } 374 375 if (negative) { 376 buf[--cursor] = '-'; 377 } 378 if (sb != null) { sb.append(buf, cursor, bufLen - cursor)379 sb.append(buf, cursor, bufLen - cursor); 380 return null; 381 } else { 382 return new String(buf, cursor, bufLen - cursor); 383 } 384 } 385 386 /** 387 * Inserts the unsigned decimal integer represented by n into the specified 388 * character array starting at position cursor. Returns the index after 389 * the last character inserted (i.e., the value to pass in as cursor the 390 * next time this method is called). Note that n is interpreted as a large 391 * positive integer (not a negative integer) if its sign bit is set. 392 */ intIntoCharArray(char[] buf, int cursor, int n)393 private static int intIntoCharArray(char[] buf, int cursor, int n) { 394 // Calculate digits two-at-a-time till remaining digits fit in 16 bits 395 while ((n & 0xffff0000) != 0) { 396 /* 397 * Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8. 398 * This computation is slightly different from the corresponding 399 * computation in intToString: the shifts before and after 400 * multiply can't be combined, as that would yield the wrong result 401 * if n's sign bit were set. 402 */ 403 int q = (int) ((0x51EB851FL * (n >>> 2)) >>> 35); 404 int r = n - 100*q; 405 buf[--cursor] = ONES[r]; 406 buf[--cursor] = TENS[r]; 407 n = q; 408 } 409 410 // Calculate remaining digits one-at-a-time for performance 411 while (n != 0) { 412 // Compute q = n / 10 and r = n % 10 as per "Hacker's Delight" 10-8 413 int q = (0xCCCD * n) >>> 19; 414 int r = n - 10*q; 415 buf[--cursor] = DIGITS[r]; 416 n = q; 417 } 418 return cursor; 419 } 420 intToBinaryString(int i)421 public static String intToBinaryString(int i) { 422 int bufLen = 32; // Max number of binary digits in an int 423 char[] buf = new char[bufLen]; 424 int cursor = bufLen; 425 426 do { 427 buf[--cursor] = DIGITS[i & 1]; 428 } while ((i >>>= 1) != 0); 429 430 return new String(buf, cursor, bufLen - cursor); 431 } 432 longToBinaryString(long v)433 public static String longToBinaryString(long v) { 434 int i = (int) v; 435 if (v >= 0 && i == v) { 436 return intToBinaryString(i); 437 } 438 439 int bufLen = 64; // Max number of binary digits in a long 440 char[] buf = new char[bufLen]; 441 int cursor = bufLen; 442 443 do { 444 buf[--cursor] = DIGITS[((int) v) & 1]; 445 } while ((v >>>= 1) != 0); 446 447 return new String(buf, cursor, bufLen - cursor); 448 } 449 appendByteAsHex(StringBuilder sb, byte b, boolean upperCase)450 public static StringBuilder appendByteAsHex(StringBuilder sb, byte b, boolean upperCase) { 451 char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS; 452 sb.append(digits[(b >> 4) & 0xf]); 453 sb.append(digits[b & 0xf]); 454 return sb; 455 } 456 byteToHexString(byte b, boolean upperCase)457 public static String byteToHexString(byte b, boolean upperCase) { 458 char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS; 459 char[] buf = new char[2]; // We always want two digits. 460 buf[0] = digits[(b >> 4) & 0xf]; 461 buf[1] = digits[b & 0xf]; 462 return new String(buf, 0, 2); 463 } 464 bytesToHexString(byte[] bytes, boolean upperCase)465 public static String bytesToHexString(byte[] bytes, boolean upperCase) { 466 char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS; 467 char[] buf = new char[bytes.length * 2]; 468 int c = 0; 469 for (byte b : bytes) { 470 buf[c++] = digits[(b >> 4) & 0xf]; 471 buf[c++] = digits[b & 0xf]; 472 } 473 return new String(buf); 474 } 475 intToHexString(int i, boolean upperCase, int minWidth)476 public static String intToHexString(int i, boolean upperCase, int minWidth) { 477 int bufLen = 8; // Max number of hex digits in an int 478 char[] buf = new char[bufLen]; 479 int cursor = bufLen; 480 481 char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS; 482 do { 483 buf[--cursor] = digits[i & 0xf]; 484 } while ((i >>>= 4) != 0 || (bufLen - cursor < minWidth)); 485 486 return new String(buf, cursor, bufLen - cursor); 487 } 488 longToHexString(long v)489 public static String longToHexString(long v) { 490 int i = (int) v; 491 if (v >= 0 && i == v) { 492 return intToHexString(i, false, 0); 493 } 494 495 int bufLen = 16; // Max number of hex digits in a long 496 char[] buf = new char[bufLen]; 497 int cursor = bufLen; 498 499 do { 500 buf[--cursor] = DIGITS[((int) v) & 0xF]; 501 } while ((v >>>= 4) != 0); 502 503 return new String(buf, cursor, bufLen - cursor); 504 } 505 intToOctalString(int i)506 public static String intToOctalString(int i) { 507 int bufLen = 11; // Max number of octal digits in an int 508 char[] buf = new char[bufLen]; 509 int cursor = bufLen; 510 511 do { 512 buf[--cursor] = DIGITS[i & 7]; 513 } while ((i >>>= 3) != 0); 514 515 return new String(buf, cursor, bufLen - cursor); 516 } 517 longToOctalString(long v)518 public static String longToOctalString(long v) { 519 int i = (int) v; 520 if (v >= 0 && i == v) { 521 return intToOctalString(i); 522 } 523 int bufLen = 22; // Max number of octal digits in a long 524 char[] buf = new char[bufLen]; 525 int cursor = bufLen; 526 527 do { 528 buf[--cursor] = DIGITS[((int) v) & 7]; 529 } while ((v >>>= 3) != 0); 530 531 return new String(buf, cursor, bufLen - cursor); 532 } 533 stringOf(char... args)534 private static String stringOf(char... args) { 535 return new String(args, 0, args.length); 536 } 537 } 538