1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/* 2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project 3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License"); 5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License. 6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at 7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * http://www.apache.org/licenses/LICENSE-2.0 9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software 11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS, 12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and 14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License. 15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.util; 18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/** 20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Utilities for treating {@code int[]}s as bit sets. 21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class Bits { 23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * This class is uninstantiable. 25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private Bits() { 27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul // This space intentionally left blank. 28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs a bit set to contain bits up to the given index (exclusive). 32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param max {@code >= 0;} the maximum bit index (exclusive) 34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} an appropriately-constructed instance 35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static int[] makeBitSet(int max) { 37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int size = (max + 0x1f) >> 5; 38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return new int[size]; 39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the maximum index (exclusive) for the given bit set. 43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param bits {@code non-null;} bit set in question 45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= 0;} the maximum index (exclusive) that may be set 46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static int getMax(int[] bits) { 48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return bits.length * 0x20; 49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the value of the bit at the given index. 53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param bits {@code non-null;} bit set to operate on 55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param idx {@code >= 0, < getMax(set);} which bit 56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return the value of the indicated bit 57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static boolean get(int[] bits, int idx) { 59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int arrayIdx = idx >> 5; 60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int bit = 1 << (idx & 0x1f); 61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return (bits[arrayIdx] & bit) != 0; 62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Sets the given bit to the given value. 66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param bits {@code non-null;} bit set to operate on 68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param idx {@code >= 0, < getMax(set);} which bit 69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param value the new value for the bit 70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static void set(int[] bits, int idx, boolean value) { 72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int arrayIdx = idx >> 5; 73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int bit = 1 << (idx & 0x1f); 74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (value) { 76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul bits[arrayIdx] |= bit; 77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } else { 78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul bits[arrayIdx] &= ~bit; 79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Sets the given bit to {@code true}. 84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param bits {@code non-null;} bit set to operate on 86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param idx {@code >= 0, < getMax(set);} which bit 87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static void set(int[] bits, int idx) { 89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int arrayIdx = idx >> 5; 90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int bit = 1 << (idx & 0x1f); 91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul bits[arrayIdx] |= bit; 92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Sets the given bit to {@code false}. 96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param bits {@code non-null;} bit set to operate on 98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param idx {@code >= 0, < getMax(set);} which bit 99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static void clear(int[] bits, int idx) { 101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int arrayIdx = idx >> 5; 102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int bit = 1 << (idx & 0x1f); 103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul bits[arrayIdx] &= ~bit; 104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns whether or not the given bit set is empty, that is, whether 108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * no bit is set to {@code true}. 109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param bits {@code non-null;} bit set to operate on 111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code true} iff all bits are {@code false} 112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static boolean isEmpty(int[] bits) { 114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int len = bits.length; 115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < len; i++) { 117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (bits[i] != 0) { 118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return false; 119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return true; 123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the number of bits set to {@code true} in the given bit set. 127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param bits {@code non-null;} bit set to operate on 129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= 0;} the bit count (aka population count) of the set 130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static int bitCount(int[] bits) { 132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int len = bits.length; 133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int count = 0; 134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < len; i++) { 136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul count += Integer.bitCount(bits[i]); 137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return count; 140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns whether any bits are set to {@code true} in the 144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * specified range. 145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param bits {@code non-null;} bit set to operate on 147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param start {@code >= 0;} index of the first bit in the range (inclusive) 148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param end {@code >= 0;} index of the last bit in the range (exclusive) 149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code true} if any bit is set to {@code true} in 150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * the indicated range 151917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 152917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static boolean anyInRange(int[] bits, int start, int end) { 153917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int idx = findFirst(bits, start); 154917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return (idx >= 0) && (idx < end); 155917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 156917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 157917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 158917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Finds the lowest-order bit set at or after the given index in the 159917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * given bit set. 160917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 161917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param bits {@code non-null;} bit set to operate on 162917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param idx {@code >= 0;} minimum index to return 163917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= -1;} lowest-order bit set at or after {@code idx}, 164917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * or {@code -1} if there is no appropriate bit index to return 165917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 166917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static int findFirst(int[] bits, int idx) { 167917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int len = bits.length; 168917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int minBit = idx & 0x1f; 169917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 170917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int arrayIdx = idx >> 5; arrayIdx < len; arrayIdx++) { 171917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int word = bits[arrayIdx]; 172917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (word != 0) { 173917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int bitIdx = findFirst(word, minBit); 174917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (bitIdx >= 0) { 175917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return (arrayIdx << 5) + bitIdx; 176917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 177917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 178917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul minBit = 0; 179917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 180917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 181917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return -1; 182917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 183917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 184917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 185917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Finds the lowest-order bit set at or after the given index in the 186917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * given {@code int}. 187917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 188917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param value the value in question 189917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param idx 0..31 the minimum bit index to return 190917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= -1;} lowest-order bit set at or after {@code idx}, 191917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * or {@code -1} if there is no appropriate bit index to return 192917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 193917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static int findFirst(int value, int idx) { 194917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul value &= ~((1 << idx) - 1); // Mask off too-low bits. 195917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int result = Integer.numberOfTrailingZeros(value); 196917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return (result == 32) ? -1 : result; 197917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 198917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 199917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 200917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Ors bit array {@code b} into bit array {@code a}. 201917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code a.length} must be greater than or equal to 202917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code b.length}. 203917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 204917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param a {@code non-null;} int array to be ored with other argument. This 205917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * argument is modified. 206917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param b {@code non-null;} int array to be ored into {@code a}. This 207917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * argument is not modified. 208917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 209917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static void or(int[] a, int[] b) { 210917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < b.length; i++) { 211917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul a[i] |= b[i]; 212917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 213917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 214917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 215917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static String toHuman(int[] bits) { 216917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul StringBuilder sb = new StringBuilder(); 217917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 218917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul boolean needsComma = false; 219917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 220917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul sb.append('{'); 221917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 222917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int bitsLength = 32 * bits.length; 223917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (int i = 0; i < bitsLength; i++) { 224917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (Bits.get(bits, i)) { 225917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (needsComma) { 226917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul sb.append(','); 227917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 228917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul needsComma = true; 229917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul sb.append(i); 230917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 231917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 232917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul sb.append('}'); 233917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 234917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return sb.toString(); 235917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 236917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul} 237