package nbtool.util;
import java.awt.BorderLayout;
import java.awt.Component;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import nbtool.data.log.Block;
import nbtool.data.log.Log;
import nbtool.util.test.TestBase;
import nbtool.util.test.Tests;
public class Utility {
public static boolean isPureAscii2(String v) {
byte bytearray [] = v.getBytes();
CharsetDecoder d = Charset.forName("US-ASCII").newDecoder();
try {
CharBuffer r = d.decode(ByteBuffer.wrap(bytearray));
r.toString();
}
catch(CharacterCodingException e) {
return false;
}
return true;
}
static CharsetEncoder asciiEncoder =
Charset.forName("US-ASCII").newEncoder();
public static boolean isPureAscii(String v) {
return asciiEncoder.canEncode(v);
}
/* true if top, false if bot */
public static boolean camera(Log imageLog) {
assert(imageLog.blocks.size() > 0);
Block imageBlock = imageLog.blocks.get(0);
if (imageBlock.whereFrom.equals("camera_TOP")) {
return true;
}
if (imageBlock.whereFrom.equals("camera_BOT")) {
return false;
}
throw new RuntimeException("unknown camera: " + imageBlock.whereFrom);
}
/* for testing components standalone */
public static void display(Component comp) {
JFrame display = new JFrame("test of " + comp);
display.add(comp, BorderLayout.CENTER);
display.setSize(comp.getPreferredSize());
display.setVisible(true);
display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static String progressString(int characters, double fraction) {
if (fraction < 0 || fraction > 1.0) {
return "invalid fraction";
}
final String format = "[%s%s]";
int internal = characters - 2;
int left = (int) (fraction * internal);
int right = internal - left;
assert(left >= 0 && right >= 0);
char[] lc = new char[left];
Arrays.fill(lc, '|');
char[] rc = new char[right];
Arrays.fill(rc, ' ');
return String.format(format, new String(lc), new String(rc));
}
private static final Map<Class<?>, Long> indexMap = new HashMap<>();
public static final long getNextIndex(Object type) {
return getNextIndex(type.getClass());
}
public static final long getNextIndex(Class<?> type) {
synchronized(type) {
if (indexMap.containsKey(type)) {
long index = indexMap.get(type);
++index;
indexMap.put(type, index);
return index;
} else {
synchronized(indexMap) {
indexMap.put(type, 0L);
return 0L;
}
}
}
}
private static final Random hexRandom = new Random();
public static String getRandomHexString(int numchars){
StringBuffer sb = new StringBuffer();
while(sb.length() < numchars){
sb.append(Integer.toHexString(hexRandom.nextInt()).toUpperCase());
}
return sb.toString().substring(0, numchars);
}
public static class Pair<A,B> {
public A a;
public B b;
public Pair(A a, B b) {this.a = a; this.b = b;}
}
public static StackTraceElement codeLocation(int i) {
StackTraceElement[] stack = (new Throwable()).getStackTrace();
return stack[i];
}
public static byte[] subArray(byte[] ar, int start, int len) {
byte[] ret = new byte[len];
System.arraycopy(ar, start, ret, 0, len);
return ret;
}
// //Almost all image logs will have null or [Y8(U8/V8)] encoding, but this method should be extended if that changes.
// public static BufferedImage biFromLog(_Log log) {
// assert(log.primaryType().equalsIgnoreCase(ToolSettings.IMAGE_S));
// int width = log.primaryWidth();
// int height = log.primaryHeight();
// String encoding = log.primaryEncoding();
//
// ImageParent ip = null;
// if (encoding == null ) {
// //old image
// ip = new YUYV8888Image(width / 2, height, log.bytes);
// } else if (encoding.equalsIgnoreCase("[Y8(U8/V8)]")) {
// ip = new YUYV8888Image(2*width, height, log.bytes);
// } else if (encoding.equalsIgnoreCase("[Y16]")) {
// ip = new Y16Image(width , height, log.bytes);
// } else if (encoding.equalsIgnoreCase("[Y8]")) {
// ip = new Y8Image(width , height, log.bytes);
// } else {
// Debug.warn( "Cannot use image with encoding:" + encoding);
// return null;
// }
//
// return ip.toBufferedImage();
// }
public static final char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHexString(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int i = 0; i < bytes.length; ++i) {
int v = bytes[i] & 0xFF;
hexChars[i * 2] = hexArray[v >>> 4];
hexChars[i * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
//binary, not SI
public static final long bytesPerKB = (1 << 10);
public static final long bytesPerMB = (1 << 20);
public static final long bytesPerGB = (1 << 30);
public static String byteString( long bytes, boolean sepGig, boolean sepMeg, boolean sepKyb, boolean showByte ) {
String total = "";
long left = bytes;
if (sepGig) {
long gigs = left / bytesPerGB;
if (gigs > 0) {
total = total + String.format("%dGB ", gigs);
left = left % bytesPerGB;
}
}
if (sepMeg) {
long megs = left / bytesPerMB;
if (megs > 0) {
total = total + String.format("%dMB ", megs);
left = left % bytesPerMB;
}
}
if (sepKyb) {
long kbs = left / bytesPerKB;
if (kbs > 0) {
total = total + String.format("%dKB ", kbs);
left = left % bytesPerKB;
}
}
if (showByte && left > 0) {
total = total + String.format("%d bytes", left);
}
return total;
}
public static JPanel fieldWithlabel(JLabel l, JTextField f) {
JPanel p = new JPanel(new BorderLayout());
p.add(l,BorderLayout.WEST);
p.add(f,BorderLayout.CENTER);
return p;
}
public static JPanel fieldWithButton(JTextField f, JButton b) {
JPanel p = new JPanel(new BorderLayout());
p.add(b,BorderLayout.EAST);
p.add(f,BorderLayout.CENTER);
return p;
}
public static JPanel labelWithPanel(JLabel lbl, JPanel pnl) {
JPanel p = new JPanel(new BorderLayout());
p.add(lbl,BorderLayout.WEST);
p.add(pnl,BorderLayout.CENTER);
return p;
}
/*
* assuming the .proto files have the necessary java_options,
* this function can get the java class of an protobuf from its name
* (the type as used in c++)
* */
@SuppressWarnings("unchecked")
public static Class<? extends com.google.protobuf.Message> protobufClassFromType(String _type) {
assert(_type.startsWith(ToolSettings.PROTOBUF_TYPE_PREFIX));
String type = _type.substring(ToolSettings.PROTOBUF_TYPE_PREFIX.length()); //Remove prefix.
String classname = String.format("messages.%s", type);
try {
return (Class<? extends com.google.protobuf.Message>) Class.forName(classname);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
public static <T extends com.google.protobuf.Message>
T protobufInstanceForClassWithData(
Class<T> cls,
byte[] data)
{
T ret = null;
try {
Method m = cls.getDeclaredMethod("parseFrom", byte[].class);
ret = (T) m.invoke(null, data);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return ret;
}
public static String localizePath(String p) {
if (p.startsWith("~" + File.separator)) {
return System.getProperty("user.home")
+ p.substring(1);
} else return p;
}
public static void _NBL_ADD_TESTS_() {
Tests.add("Utility", new TestBase("getNextIndex"){
@Override
public boolean testBody() throws Exception {
class Temp{public long id = getNextIndex(this);}
Temp a = new Temp();
assert(a.id == 0);
Temp b = new Temp();
assert(a.id == 0 && b.id == 1);
return true;
}
}
//...
);
}
}