В общем имеется код на языке JAVA(язык оригинала другой, но было портированно в JAVA), необходимо понять как именно он работает.. Суть примерно такая: чтобы не использовать каждый раз 1 байт на передачу значения типа boolean было предложено использовать карту этих boolean и потом вычитывать по очереди их, таким образом в 1 байт влезает 8 boolean значений(1 бит = 1 boolean). Сетевой пакет примерно такой структуры: Карта значений boolean-ов, сами данные.
МОМЕНТ НОМЕР ОДИН Модификация позиций.
Следующий фрагмент кода присутствует в двух методах(getBit/setBit) представленных ниже. Мне понятно, что это преобразование(сдвиг?) позиций, но не могу понять зачем.
int _local2 = (position >> 3);
int _local3 = (7 ^ (position & 7));
Вопрос: Что именно делает первая и вторая строка,
и зачем?
МОМЕНТ НОМЕР ДВА Чтение 1 бита(boolean) из буффера.
boolean getBit(int position) {
*КОПИПАСТ ИЗ МОМЕНТА НОМЕР ОДИН*
*тут ставится позиция буффера в _local2*
return !(((this.map.readByte() & (1 << _local3)) == 0));
}
Вопрос: Что делает последняя строка
и зачем?
МОМЕНТ НОМЕР ТРИ Запись boolean в буффер.
void setBit(int position, Boolean value) {
*ТУТ ТОЖЕ КОПИПАСТ ИЗ МОМЕНТА НОМЕР ОДИН*
*ТУТ ВЫПОЛНЯЕТСЯ ПРОВЕРКА, ЕСЛИ В БУФФЕРЕ НЕТ МЕСТА ДЛЯ ЗАПИСИ СЛЕДУЮЩЕГО БИТА, ТО АЛЛОЦИРУЕТСЯ 1 БАЙТ*
*тут ставится позиция буффера в _local2*
if (value) {
this.map.writeByte((byte) ((this.map.readByte(_local2) | (1 << _local3))));
} else {
this.map.writeByte((byte) ((this.map.readByte(_local2) & (0xFF ^ (1 << _local3)))));
}
}
Вопрос: Что делает последний блок IF и его бранчи,
и зачем?
Заранее Спасибо, за развернутые ответы!
Решением отмечу только то, что реально поможет максимально упростить код при этом, чтобы результат кодирования был понятен удаленному серверу(к нему НЕТ доступа). Спасибо.
АП: Могу предоставить код кодека, кодирующего эту карту. Но задача стоит именно понять как сама карта работает, кодек просто получает байты из этой карты булаенов и дописывает ее длинну в первых битах, все.
=========================================================
Упрощенный вариант кода(вместо буффера - массив из 2 байт), есть сравнение с BitSet.
private static boolean getBit(byte[] ba, int position) {
int _local2 = (position >> 3);
int _local3 = (7 ^ (position & 7));
byte b = ba[_local2];
return !((b & (1 << _local3)) == 0);
}
private static byte[] setBit(byte[] ba, int position, boolean value) {
int _local2 = (position >> 3);
int _local3 = (7 ^ (position & 7));
if (value) {
ba[_local2] = (byte) (ba[_local2] | (1 << _local3));
} else {
ba[_local2] = (byte) (ba[_local2] & (0xFF ^ (1 << _local3)));
}
return ba;
}
static String toBinary(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length * Byte.SIZE);
for (int i = 0; i < Byte.SIZE * bytes.length; i++)
sb.append((bytes[i / Byte.SIZE] << i % Byte.SIZE & 0x80) == 0 ? '0' : '1');
return sb.toString();
}
public static void main(String[] args) {
byte[] map = new byte[2];
map = setBit(map, 0, true);
map = setBit(map, 1, false);
map = setBit(map, 2, true);
map = setBit(map, 3, true);
map = setBit(map, 4, true);
map = setBit(map, 14, false);
map = setBit(map, 15, true);
System.out.println(toBinary(map));// 1011100000000001 RIGHT!
System.out.println(getBit(map, 0));// true
System.out.println(getBit(map, 1));// false
System.out.println(getBit(map, 2));// true
System.out.println(getBit(map, 3));// true
System.out.println(getBit(map, 4));// true
System.out.println(getBit(map, 14));// false
System.out.println(getBit(map, 15));// true
BitSet bitSet = new BitSet();
bitSet.set(0, true);
bitSet.set(1, false);
bitSet.set(2, true);
bitSet.set(3, true);
bitSet.set(4, true);
bitSet.set(14, false);
bitSet.set(15, true);
System.out.println(toBinary(bitSet.toByteArray()));//0001110110000000 WTF??
}