1 module osc.timetag;
2 import std.datetime;
3 
4 /++
5 +/
6 struct TimeTag {
7     public{
8         ///
9         this(in SysTime utcSysTime, in bool isImmediately = false){
10             if(isImmediately){
11                 _data = [0, 0, 0, 0, 0, 0, 0, 1];
12             }else{
13                 _data = generatedTimeTagData(utcSysTime);
14             }
15         }
16         
17         ///
18         this(in ubyte[] timeTag){
19             _data = timeTag;
20         }
21         
22         ///
23         string toString()const{
24             import std.conv:to;
25             import std.algorithm;
26             return _data.map!(c => c.to!char).to!string;
27         }
28         
29         ///
30         ubyte[] opCast(T:ubyte[])()const{
31             return _data.dup;
32         }
33         
34         ///
35         size_t size()const{
36             return 8;
37         }
38     }//public
39 
40     private{
41         ubyte[] generatedTimeTagData(in SysTime utcSysTime)const{
42             immutable origin = DateTime(1900, 1, 1);
43             immutable timeStamp = utcSysTime - SysTime(origin, UTC());
44             
45             immutable integer = timeStamp.total!"seconds";
46             immutable fraction = (timeStamp.total!"nsecs"%(10^^9));
47             
48             import std.bitmanip;
49             import std.conv;
50             ubyte[] buffer = [0, 0, 0, 0, 0, 0, 0, 0];
51             buffer.write!uint(integer.to!uint, 0);
52             buffer.write!uint(fraction.to!uint, 4);
53             return buffer;
54         }
55         
56         const ubyte[] _data;
57     }//private
58 }//struct TimeTag
59 unittest{
60     //should generate TimeTag from arbitrary SysTime in UTC.
61     import std.bitmanip;
62     import std.conv;
63     auto timeTag = TimeTag(SysTime(DateTime(1900, 1, 2), UTC()));
64     ubyte[] tomorrow = [0, 0, 0, 0, 0, 0, 0, 0];
65     tomorrow.write!uint(60*60*24, 0);
66     assert(timeTag.to!(ubyte[]) == tomorrow);
67 }