package org.yamcs.utils;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.List;
import org.yamcs.protobuf.Yamcs.NamedObjectId;
import org.yamcs.protobuf.Yamcs.Value;
public class StringConverter {
static final BigInteger B64 = BigInteger.ZERO.setBit(64);
public static String toString(Value rv) {
switch(rv.getType()) {
case BINARY:
return "(BINARY)"+byteBufferToHexString(rv.getBinaryValue().asReadOnlyByteBuffer());
case DOUBLE:
return "(DOUBLE)"+rv.getDoubleValue();
case FLOAT:
return "(FLOAT)"+rv.getFloatValue();
case SINT32:
return "(SIGNED_INTEGER)"+rv.getSint32Value();
case UINT32:
return "(UNSIGNED_INTEGER)"+Long.toString(rv.getUint32Value()&0xFFFFFFFFL);
case SINT64:
return "(SIGNED_INTEGER)"+rv.getSint64Value();
case UINT64:
return "(UNSIGNED_INTEGER)"+rv.getUint64Value();
case STRING:
return "(STRING)"+rv.getStringValue();
case BOOLEAN:
return "(BOOLEAN)"+rv.getBooleanValue();
case TIMESTAMP:
return "(TIMESTAMP)"+TimeEncoding.toOrdinalDateTime(rv.getTimestampValue());
}
return null;
}
public static String toString(Value rv, boolean withType) {
if(withType)return toString(rv);
switch(rv.getType()) {
case BINARY:
return byteBufferToHexString(rv.getBinaryValue().asReadOnlyByteBuffer());
case DOUBLE:
return Double.toString(rv.getDoubleValue());
case FLOAT:
return Float.toString(rv.getFloatValue());
case SINT32:
return Integer.toString(rv.getSint32Value());
case UINT32:
return Long.toString(rv.getUint32Value()&0xFFFFFFFFL);
case SINT64:
return Long.toString(rv.getSint64Value());
case UINT64:
if (rv.getUint64Value() >= 0)
return Long.toString(rv.getUint64Value());
else
return BigInteger.valueOf(rv.getUint64Value()).add(B64).toString();
case STRING:
return rv.getStringValue();
case BOOLEAN:
return Boolean.toString(rv.getBooleanValue());
case TIMESTAMP:
return TimeEncoding.toOrdinalDateTime(rv.getTimestampValue());
}
return null;
}
public static String arrayToHexString(byte[] b){
StringBuilder sb =new StringBuilder();
for (int i=0;i<b.length;i++) {
String s=Integer.toString(b[i]&0xFF,16);
if(s.length()==1) s="0"+s;
sb.append(s.toUpperCase());
}
return sb.toString();
}
public static String byteBufferToHexString(ByteBuffer bb) {
bb.mark();
StringBuilder sb =new StringBuilder();
int offset=0;
while(bb.hasRemaining()) {
if(offset%33==0)sb.append("\n");
String s=Integer.toString(bb.get()&0xFF,16);
offset++;
if(s.length()==1) sb.append("0");
sb.append(s.toUpperCase());
}
bb.reset();
return sb.toString();
}
/**
* Convert a hex string into a byte array. No check is done if the string has an even number of
* hex digits. The last one is ignored in case the number is odd.
* @param s
* @return
*/
public static byte[] hexStringToArray(String s) {
byte[] b=new byte[s.length()/2];
for(int i=0;i<s.length()/2;i++) {
b[i]=(byte)(Integer.parseInt(s.substring(2*i,2*i+2),16)&0xFF);
}
return b;
}
/**
* Convert a NamedObjectId to a pretty string for use in log messages etc. This gives a
* better formatting than the default protobuf-generated toString.
*/
public static String idToString(NamedObjectId id) {
if (id == null) return "null";
if (id.hasNamespace()) {
return "'" + id.getName() + "' (namespace: '" + id.getNamespace() + "')";
} else {
return "'" + id.getName() + "' (no namespace)";
}
}
/**
* Convert a list of NamedObjectId to a pretty string for use in log messages etc. This gives a
* better formatting than the default protobuf-generated toString.
*/
public static String idListToString(List<NamedObjectId> idList) {
if (idList == null) return "null";
StringBuilder buf = new StringBuilder("[");
boolean first = true;
for (NamedObjectId id : idList) {
if (first) {
first = false;
} else {
buf.append(", ");
}
buf.append(idToString(id));
}
return buf.append("]").toString();
}
}