1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2007 The Android Open Source Project 3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License. 6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at 7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and 14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License. 15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.util; 18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Utilities for treating {@code int[]}s as bit sets. 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class Bits { 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * This class is uninstantiable. 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private Bits() { 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // This space intentionally left blank. 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs a bit set to contain bits up to the given index (exclusive). 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param max {@code >= 0;} the maximum bit index (exclusive) 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} an appropriately-constructed instance 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static int[] makeBitSet(int max) { 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int size = (max + 0x1f) >> 5; 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return new int[size]; 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the maximum index (exclusive) for the given bit set. 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param bits {@code non-null;} bit set in question 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= 0;} the maximum index (exclusive) that may be set 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static int getMax(int[] bits) { 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return bits.length * 0x20; 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the value of the bit at the given index. 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param bits {@code non-null;} bit set to operate on 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param idx {@code >= 0, < getMax(set);} which bit 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return the value of the indicated bit 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static boolean get(int[] bits, int idx) { 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int arrayIdx = idx >> 5; 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int bit = 1 << (idx & 0x1f); 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (bits[arrayIdx] & bit) != 0; 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Sets the given bit to the given value. 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param bits {@code non-null;} bit set to operate on 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param idx {@code >= 0, < getMax(set);} which bit 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param value the new value for the bit 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static void set(int[] bits, int idx, boolean value) { 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int arrayIdx = idx >> 5; 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int bit = 1 << (idx & 0x1f); 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (value) { 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson bits[arrayIdx] |= bit; 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson bits[arrayIdx] &= ~bit; 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Sets the given bit to {@code true}. 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param bits {@code non-null;} bit set to operate on 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param idx {@code >= 0, < getMax(set);} which bit 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static void set(int[] bits, int idx) { 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int arrayIdx = idx >> 5; 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int bit = 1 << (idx & 0x1f); 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson bits[arrayIdx] |= bit; 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Sets the given bit to {@code false}. 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param bits {@code non-null;} bit set to operate on 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param idx {@code >= 0, < getMax(set);} which bit 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static void clear(int[] bits, int idx) { 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int arrayIdx = idx >> 5; 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int bit = 1 << (idx & 0x1f); 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson bits[arrayIdx] &= ~bit; 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns whether or not the given bit set is empty, that is, whether 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * no bit is set to {@code true}. 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param bits {@code non-null;} bit set to operate on 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code true} iff all bits are {@code false} 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static boolean isEmpty(int[] bits) { 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int len = bits.length; 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < len; i++) { 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (bits[i] != 0) { 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return false; 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return true; 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the number of bits set to {@code true} in the given bit set. 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param bits {@code non-null;} bit set to operate on 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= 0;} the bit count (aka population count) of the set 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static int bitCount(int[] bits) { 132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int len = bits.length; 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int count = 0; 134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < len; i++) { 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson count += Integer.bitCount(bits[i]); 137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return count; 140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns whether any bits are set to {@code true} in the 144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * specified range. 145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param bits {@code non-null;} bit set to operate on 147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param start {@code >= 0;} index of the first bit in the range (inclusive) 148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param end {@code >= 0;} index of the last bit in the range (exclusive) 149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code true} if any bit is set to {@code true} in 150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * the indicated range 151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static boolean anyInRange(int[] bits, int start, int end) { 153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int idx = findFirst(bits, start); 154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (idx >= 0) && (idx < end); 155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Finds the lowest-order bit set at or after the given index in the 159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * given bit set. 160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param bits {@code non-null;} bit set to operate on 162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param idx {@code >= 0;} minimum index to return 163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= -1;} lowest-order bit set at or after {@code idx}, 164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * or {@code -1} if there is no appropriate bit index to return 165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static int findFirst(int[] bits, int idx) { 167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int len = bits.length; 168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int minBit = idx & 0x1f; 169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int arrayIdx = idx >> 5; arrayIdx < len; arrayIdx++) { 171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int word = bits[arrayIdx]; 172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (word != 0) { 173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int bitIdx = findFirst(word, minBit); 174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (bitIdx >= 0) { 175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (arrayIdx << 5) + bitIdx; 176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson minBit = 0; 179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return -1; 182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Finds the lowest-order bit set at or after the given index in the 186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * given {@code int}. 187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param value the value in question 189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param idx 0..31 the minimum bit index to return 190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= -1;} lowest-order bit set at or after {@code idx}, 191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * or {@code -1} if there is no appropriate bit index to return 192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static int findFirst(int value, int idx) { 194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson value &= ~((1 << idx) - 1); // Mask off too-low bits. 195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int result = Integer.numberOfTrailingZeros(value); 196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return (result == 32) ? -1 : result; 197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Ors bit array {@code b} into bit array {@code a}. 201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code a.length} must be greater than or equal to 202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code b.length}. 203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param a {@code non-null;} int array to be ored with other argument. This 205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * argument is modified. 206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param b {@code non-null;} int array to be ored into {@code a}. This 207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * argument is not modified. 208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static void or(int[] a, int[] b) { 210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < b.length; i++) { 211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson a[i] |= b[i]; 212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static String toHuman(int[] bits) { 216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson StringBuilder sb = new StringBuilder(); 217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson boolean needsComma = false; 219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson sb.append('{'); 221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int bitsLength = 32 * bits.length; 223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (int i = 0; i < bitsLength; i++) { 224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (Bits.get(bits, i)) { 225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (needsComma) { 226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson sb.append(','); 227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson needsComma = true; 229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson sb.append(i); 230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson sb.append('}'); 233579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 234579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return sb.toString(); 235579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 236579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 237