1 module draklib.util;
2 import std.conv;
3 import std.exception;
4 
5 /**
6  * Get the current time in milliseconds (since epoch).
7  * This method uses bindings to the C functions gettimeofday and
8  * GetSystemTime depending on the platform.
9  */
10 long getTimeMillis() {
11 	version(Posix) {
12 		pragma(msg, "Using core.sys.posix.sys.time.gettimeofday() for native getTimeMillis()");
13 		import core.sys.posix.sys.time;
14 		
15 		timeval t;
16 		gettimeofday(&t, null);
17 		
18 		return t.tv_sec * 1000 + t.tv_usec / 1000;
19 	} else version(Windows) {
20 		pragma(msg, "Using core.sys.windows.winbase.GetSystemTime() for native getTimeMillis()");
21 		import core.sys.windows.winbase;
22 		
23 		SYSTEMTIME time;
24 		GetSystemTime(&time);
25 		
26 		return (time.wSecond * 1000) + time.wMilliseconds;
27 	}
28 }
29 
30 /**
31  * Split a byte array into multiple arrays of sizes
32  * specified by "chunkSize"
33  */
34 byte[][] splitByteArray(byte[] array, in uint chunkSize) {
35 	//TODO: optimize to not use GC
36 	byte[][] splits = cast(byte[][]) [[]];
37 	uint chunks = 0;
38 	for(int i = 0; i < array.length; i += chunkSize) {
39 		if((array.length - i) > chunkSize) {
40 			splits[chunks] = array[i..i+chunkSize];
41 		} else {
42 			splits[chunks] = array[i..array.length];
43 		}
44 		chunks++;
45 	}
46 	
47 	return splits;
48 }
49 
50 ubyte writeBits(in bool[] bits) {
51 	byte val = 0;
52 	enforce(bits.length <= 8, new InvalidArgumentException(to!string(bits.length) ~ " bits can't fit into one byte!"));
53 	foreach(i, bit; bits) {
54 		val += bit ? (1 << i) : 0;
55 	}
56 	return val;
57 }
58 
59 bool[] readBits(in ubyte bits) {
60 	import std.stdio;
61 	bool[] vals = new bool[8];
62 	for(int i = 0; i < 8; i++) {
63 		if(((bits  >> i) & 1) > 0) {
64 			vals[i] = true;
65 		} else {
66 			vals[i] = false;
67 		}
68 	}
69 	return vals;
70 }
71 
72 class NotImplementedException : Exception {
73 	this() {
74 		super("Not implemented!");
75 	}
76 
77 	this(string message) {
78 		super(message);
79 	}
80 }
81 
82 class InvalidOperationException : Exception {
83 	this(string message) {
84 		super(message);
85 	}
86 }
87 
88 class InvalidArgumentException : Exception {
89 	this(string message) {
90 		super(message);
91 	}
92 }