2015-01-21 21:58:35 +01:00
|
|
|
/*******************************************************************************
|
2015-10-22 00:25:12 +02:00
|
|
|
* Copyright (c) 2015 MINRES Technologies GmbH and others.
|
2015-01-21 21:58:35 +01:00
|
|
|
* All rights reserved. This program and the accompanying materials
|
|
|
|
* are made available under the terms of the Eclipse Public License v1.0
|
|
|
|
* which accompanies this distribution, and is available at
|
|
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
*
|
|
|
|
* Contributors:
|
|
|
|
* MINRES Technologies GmbH - initial API and implementation
|
|
|
|
*******************************************************************************/
|
2015-01-09 09:16:40 +01:00
|
|
|
package com.minres.scviewer.database;
|
|
|
|
|
|
|
|
public class BitVector {
|
|
|
|
|
|
|
|
private final int width;
|
|
|
|
|
2018-11-05 18:21:54 +01:00
|
|
|
private int[] packedValues;
|
2015-01-09 09:16:40 +01:00
|
|
|
|
|
|
|
public BitVector(int netWidth) {
|
|
|
|
this.width=netWidth;
|
2018-11-05 18:21:54 +01:00
|
|
|
packedValues = new int[(netWidth+15)/16];
|
|
|
|
for(int i=0; i<packedValues.length; i++) packedValues[i]=0;
|
2015-01-09 09:16:40 +01:00
|
|
|
}
|
|
|
|
|
2018-11-05 18:21:54 +01:00
|
|
|
public void setValue(int i, BitValue value) {
|
|
|
|
int bitIndex = i*2;
|
|
|
|
int wordOffset = bitIndex >> 5;
|
|
|
|
int bitOffset = bitIndex & 31;
|
|
|
|
packedValues[wordOffset] &= ~(3 << bitOffset);
|
|
|
|
packedValues[wordOffset] |= value.ordinal() << bitOffset;
|
2015-01-09 09:16:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public char[] getValue() {
|
2018-11-05 18:21:54 +01:00
|
|
|
int bitOffset = 0;
|
|
|
|
int wordOffset = 0;
|
|
|
|
char[] res = new char[width];
|
|
|
|
// Copy values out of packed array
|
|
|
|
for (int i = 0; i < width; i++) {
|
|
|
|
int currentWord = (packedValues[wordOffset] >> bitOffset)&3;
|
|
|
|
res[width-i-1]=BitValue.fromInt(currentWord).toChar();
|
|
|
|
bitOffset += 2;
|
|
|
|
if (bitOffset == 32) {
|
|
|
|
wordOffset++;
|
|
|
|
bitOffset = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
2015-01-09 09:16:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setValue(char[] value) {
|
2018-11-05 18:21:54 +01:00
|
|
|
int bitIndex = width;
|
|
|
|
int wordOffset = bitIndex >> 4;
|
|
|
|
int bitOffset = (bitIndex * 2) % 32;
|
|
|
|
for (int i = Math.min(value.length, width) - 1; i >= 0; i--) {
|
|
|
|
packedValues[wordOffset] |= BitValue.fromChar(value[i]).ordinal() << bitOffset;
|
|
|
|
bitOffset += 2;
|
|
|
|
if (bitOffset == 32) {
|
|
|
|
wordOffset++;
|
|
|
|
bitOffset = 0;
|
|
|
|
}
|
|
|
|
}
|
2015-01-09 09:16:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public int getWidth() {
|
|
|
|
return width;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String toString(){
|
2018-11-05 18:21:54 +01:00
|
|
|
return new String(getValue());
|
2015-01-09 09:16:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public String toHexString(){
|
|
|
|
int resWidth=(width-1)/4+1;
|
2018-11-05 18:21:54 +01:00
|
|
|
char[] value=getValue();
|
2015-01-09 09:16:40 +01:00
|
|
|
char[] res = new char[resWidth];
|
|
|
|
for(int i=resWidth-1; i>=0; i--){
|
|
|
|
int digit=0;
|
|
|
|
for(int j=3; j>=0; j--){
|
2018-11-05 18:21:54 +01:00
|
|
|
BitValue val = BitValue.fromChar(value[4*i+j]);
|
|
|
|
switch(val) {
|
|
|
|
case X:
|
|
|
|
case Z:
|
|
|
|
res[i]=val.toChar();
|
|
|
|
continue;
|
|
|
|
case ONE:
|
2015-01-09 09:16:40 +01:00
|
|
|
digit+=1<<(3-j);
|
2018-11-05 18:21:54 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2015-01-09 09:16:40 +01:00
|
|
|
}
|
2018-11-05 18:21:54 +01:00
|
|
|
res[i]=Character.forDigit(digit, 16); //((digit < 10) ? '0' + digit : 'a' + digit -10)
|
2015-01-09 09:16:40 +01:00
|
|
|
}
|
|
|
|
return new String(res);
|
|
|
|
}
|
2018-10-14 08:59:17 +02:00
|
|
|
|
|
|
|
public long toUnsignedValue() {
|
|
|
|
long res = 0;
|
2018-11-05 18:21:54 +01:00
|
|
|
int bitOffset = width * 2;
|
|
|
|
int wordOffset = bitOffset >> 5;
|
|
|
|
bitOffset &= 31;
|
|
|
|
int currentWord = packedValues[wordOffset] >> bitOffset;
|
|
|
|
// Copy values out of packed array
|
|
|
|
for (int i = 0; i < width; i++) {
|
2018-10-14 08:59:17 +02:00
|
|
|
res<<=1;
|
2018-11-05 18:21:54 +01:00
|
|
|
switch (currentWord & 3) {
|
|
|
|
case 1:
|
2018-10-14 08:59:17 +02:00
|
|
|
res++;
|
|
|
|
break;
|
2018-11-05 18:21:54 +01:00
|
|
|
case 2:
|
|
|
|
case 3:
|
2018-10-14 08:59:17 +02:00
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2018-11-05 18:21:54 +01:00
|
|
|
bitOffset += 2;
|
|
|
|
if (bitOffset == 32) {
|
|
|
|
wordOffset++;
|
|
|
|
currentWord = packedValues[wordOffset];
|
|
|
|
bitOffset = 0;
|
|
|
|
} else {
|
|
|
|
currentWord >>= 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
2018-10-14 08:59:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public long toSignedValue() {
|
|
|
|
Boolean negative=null;
|
|
|
|
long res = 0;
|
2018-11-05 18:21:54 +01:00
|
|
|
int bitOffset = width * 2;
|
|
|
|
int wordOffset = bitOffset >> 5;
|
|
|
|
bitOffset &= 31;
|
|
|
|
int currentWord = packedValues[wordOffset] >> bitOffset;
|
|
|
|
// Copy values out of packed array
|
|
|
|
for (int i = 0; i < width; i++) {
|
2018-10-14 08:59:17 +02:00
|
|
|
if(negative == null) {
|
2018-11-05 18:21:54 +01:00
|
|
|
switch (currentWord & 3) {
|
|
|
|
case 1: negative=true; break;
|
|
|
|
case 0: negative=false; break;
|
|
|
|
case 2:
|
|
|
|
case 3: return 0;
|
2018-10-14 08:59:17 +02:00
|
|
|
default:
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
res<<=1;
|
2018-11-05 18:21:54 +01:00
|
|
|
switch (currentWord & 3) {
|
|
|
|
case 1: if(!negative) res++; break;
|
|
|
|
case 0: if(negative) res++; break;
|
|
|
|
case 2:
|
|
|
|
case 3: return 0;
|
2018-10-14 08:59:17 +02:00
|
|
|
default:
|
|
|
|
}
|
|
|
|
}
|
2018-11-05 18:21:54 +01:00
|
|
|
bitOffset += 2;
|
|
|
|
if (bitOffset == 32) {
|
|
|
|
wordOffset++;
|
|
|
|
currentWord = packedValues[wordOffset];
|
|
|
|
bitOffset = 0;
|
|
|
|
} else {
|
|
|
|
currentWord >>= 2;
|
|
|
|
}
|
|
|
|
}
|
2018-10-14 08:59:17 +02:00
|
|
|
return negative?-1*(res+1):res;
|
|
|
|
}
|
2015-01-09 09:16:40 +01:00
|
|
|
}
|
2018-10-14 08:59:17 +02:00
|
|
|
|