MODULE OSC;
IMPORT
SYSTEM ,
Dates, Strings, KernelLog,
Network ,
Reals ,
WMGraphics ,
Clock, Kernel ;
CONST
OSCMessageDefaultArgsCount = 4;
OSCBundleDefaultMsgCount = 4;
One32Zero = 100000000H;
OSCTimeTagOneMS = 418937H;
H = 4; L = 0;
WrngClassUsedOrFunNotOverl* = 99;
Trace* = FALSE;
VAR
MonthToDays : ARRAY 13 OF INTEGER;
SysStartSeconds-: LONGINT;
TicksArePositive-: BOOLEAN;
TYPE
String* = Strings.String;
VAR
OSCBundleIdent: String;
TYPE
Blob* = POINTER TO ARRAY OF CHAR;
OSCParamObject* = OBJECT
VAR
tag-: CHAR;
PROCEDURE GetSize*(): LONGINT; BEGIN HALT(WrngClassUsedOrFunNotOverl); END GetSize;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR pos: LONGINT); BEGIN HALT(WrngClassUsedOrFunNotOverl); END export;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamObject { }'); KernelLog.Ln;
END dump;
END OSCParamObject;
ParamArray* = POINTER TO ARRAY OF OSCParamObject;
OSCParamAbsInteger = OBJECT(OSCParamObject)
VAR
integer-: LONGINT;
PROCEDURE GetSize*(): LONGINT;
BEGIN
RETURN 4;
END GetSize;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR pos: LONGINT);
BEGIN
Network.PutNet4(packet, pos, integer);
INC(pos, 4);
END export;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamAbsInteger{ }'); KernelLog.Ln;
END dump;
END OSCParamAbsInteger;
OSCParamInteger* = OBJECT(OSCParamAbsInteger)
PROCEDURE &InitInteger*(i: LONGINT);
BEGIN
integer := i;
tag := 'i';
END InitInteger;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamInt { ');
KernelLog.Int(integer, 1); KernelLog.String(' ('); KernelLog.Hex(integer, 1); KernelLog.String(') }'); KernelLog.Ln;
END dump;
END OSCParamInteger;
OSCParamFloat* = OBJECT(OSCParamObject)
VAR
float-: REAL;
PROCEDURE &InitFloat*(f: REAL);
BEGIN
float := f;
tag := 'f';
END InitFloat;
PROCEDURE GetSize*(): LONGINT;
BEGIN
RETURN 4;
END GetSize;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR pos: LONGINT);
BEGIN
Network.PutNet4(packet, pos, Reals.Int(float));
INC(pos, 4);
END export;
PROCEDURE dump*(indent: LONGINT);
VAR
l, hi, lo: LONGINT;
BEGIN
indentDump(indent); KernelLog.String('OSCParamFloat { ');
l := Reals.RoundL(float*1000);
hi := l DIV 1000;
lo := l - hi*1000;
KernelLog.Int(hi, 1); KernelLog.String('.'); KernelLog.Int(lo, 4);
KernelLog.String(' }'); KernelLog.Ln;
END dump;
END OSCParamFloat;
OSCParamAbsString = OBJECT(OSCParamObject)
VAR
string-: String;
PROCEDURE GetSize*(): LONGINT;
BEGIN
RETURN(padsize(Strings.Length(string^)+1));
END GetSize;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR pos: LONGINT);
BEGIN
ASSERT(string # NIL);
exportString(string, packet, pos);
END export;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamAbsString { '); KernelLog.String(' }'); KernelLog.Ln;
END dump;
END OSCParamAbsString;
OSCParamString* = OBJECT(OSCParamAbsString)
PROCEDURE &InitString*(s: String);
BEGIN
ASSERT(s # NIL);
string := s;
tag := 's';
END InitString;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamString{ ');
KernelLog.String(string^); KernelLog.String(' }'); KernelLog.Ln;
END dump;
END OSCParamString;
OSCParamBlob* = OBJECT(OSCParamObject)
VAR
blob-: Blob;
size-: LONGINT;
PROCEDURE &InitBlob*(b: Blob; s: LONGINT);
BEGIN
ASSERT(b # NIL);
blob := b;
size := s;
tag := 'b';
END InitBlob;
PROCEDURE GetSize*(): LONGINT;
BEGIN
RETURN(padsize(size)+4);
END GetSize;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR pos: LONGINT);
VAR i: LONGINT;
BEGIN
Network.PutNet4(packet, pos, size); INC(pos, 4);
FOR i:=0 TO size-1 DO
packet[pos+i] := blob[i];
END;
INC(pos, size);
WHILE (i MOD 4) # 0 DO
packet[pos] := 0X; INC(pos);
END;
END export;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamBlob { '); KernelLog.Buffer(blob^, 0, size); KernelLog.String(' }'); KernelLog.Ln;
END dump;
END OSCParamBlob;
OSCParamInteger64* = OBJECT(OSCParamObject)
VAR
integer: HUGEINT;
PROCEDURE &InitInt64*(i: HUGEINT);
BEGIN
integer := i;
tag := 'h';
END InitInt64;
PROCEDURE GetSize*(): LONGINT;
BEGIN
RETURN 8;
END GetSize;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR pos: LONGINT);
VAR
l, h: LONGINT;
BEGIN
SYSTEM.GET(SYSTEM.ADR(integer)+H, h);
Network.PutNet4(packet, pos, h); INC(pos, 4);
SYSTEM.GET(SYSTEM.ADR(integer)+L, l);
Network.PutNet4(packet, pos, l); INC(pos, 4);
END export;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamInteger64 { '); KernelLog.HIntHex(integer, 16); KernelLog.String(' }'); KernelLog.Ln;
END dump;
END OSCParamInteger64;
OSCParamTT* = OBJECT(OSCParamObject)
VAR
tt: OSCTimeTag;
PROCEDURE &InitTT*(tt: OSCTimeTag);
BEGIN
ASSERT(tt # NIL);
tag := 't';
END InitTT;
PROCEDURE GetSize*(): LONGINT;
BEGIN
RETURN tt.GetSize();
END GetSize;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR pos: LONGINT);
BEGIN
tt.export(packet, pos);
END export;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamTT { '); KernelLog.Ln;
tt.dump(indent+1);
indentDump(indent); KernelLog.String(' }'); KernelLog.Ln;
END dump;
END OSCParamTT;
OSCParamFloat64* = OBJECT(OSCParamObject)
VAR
float: LONGREAL;
PROCEDURE &InitFloat64*(f: LONGREAL);
BEGIN
float := f;
tag := 'd';
END InitFloat64;
PROCEDURE GetSize*(): LONGINT;
BEGIN
RETURN 8;
END GetSize;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR pos: LONGINT);
VAR
l, h: LONGINT;
BEGIN
Reals.IntL(float, h, l);
Network.PutNet4(packet, pos, h); INC(pos, 4);
Network.PutNet4(packet, pos, l); INC(pos, 4);
END export;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamFloat64 { '); KernelLog.String(' }'); KernelLog.Ln;
END dump;
END OSCParamFloat64;
OSCParamAltString* = OBJECT(OSCParamString)
PROCEDURE &InitAltString*(s: String);
BEGIN
ASSERT(s # NIL);
string := s;
tag := 'S';
END InitAltString;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamAltString { '); KernelLog.String(string^); KernelLog.String(' }'); KernelLog.Ln;
END dump;
END OSCParamAltString;
OSCParamChar* = OBJECT(OSCParamObject)
VAR
char: CHAR;
PROCEDURE &InitChar*(c: CHAR);
BEGIN
char := c;
tag := 'c';
END InitChar;
PROCEDURE GetSize*(): LONGINT;
BEGIN
RETURN 4;
END GetSize;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR pos: LONGINT);
BEGIN
Network.PutNet4(packet, pos, ORD(char)); INC(pos, 4);
END export;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamChar { '); KernelLog.Char(char); KernelLog.String(' }'); KernelLog.Ln;
END dump;
END OSCParamChar;
OSCParamRGBAColor* = OBJECT(OSCParamAbsInteger);
PROCEDURE &InitRGBAColor*(c: WMGraphics.Color);
BEGIN
tag := 'r';
integer := c;
END InitRGBAColor;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamRGBAColor { '); KernelLog.Int(integer, 4); KernelLog.String(' }'); KernelLog.Ln;
END dump;
END OSCParamRGBAColor;
OSCParamEmpty = OBJECT(OSCParamObject)
PROCEDURE GetSize*(): LONGINT;
BEGIN
RETURN 0;
END GetSize;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR pos: LONGINT);
END export;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamEmpty { }'); KernelLog.Ln;
END dump;
END OSCParamEmpty;
OSCParamTrue* = OBJECT(OSCParamEmpty)
PROCEDURE &InitTrue*;
BEGIN
tag := 'T';
END InitTrue;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamTrue { }'); KernelLog.Ln;
END dump;
END OSCParamTrue;
OSCParamFalse* = OBJECT(OSCParamEmpty)
PROCEDURE &InitFalse*;
BEGIN
tag := 'F';
END InitFalse;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamFalse { }'); KernelLog.Ln;
END dump;
END OSCParamFalse;
OSCParamNil* = OBJECT(OSCParamEmpty)
PROCEDURE &InitNil*;
BEGIN
tag := 'N';
END InitNil;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamNil { }'); KernelLog.Ln;
END dump;
END OSCParamNil;
OSCParamInf* = OBJECT(OSCParamEmpty)
PROCEDURE &InitInf*;
BEGIN
tag := 'I';
END InitInf;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCParamNil { }'); KernelLog.Ln;
END dump;
END OSCParamInf;
OSCTimeTag* = OBJECT
VAR
seconds-: LONGINT;
miliseconds-: LONGINT;
imm-: BOOLEAN;
PROCEDURE &Init*;
BEGIN
seconds := 0; miliseconds := 0; imm := FALSE;
END Init;
PROCEDURE GetSize*(): LONGINT; BEGIN RETURN 8; END GetSize;
PROCEDURE SetImmediately*; BEGIN imm := TRUE; END SetImmediately;
PROCEDURE Set*(sec, msec: LONGINT);
BEGIN
seconds := sec; miliseconds := msec MOD 1000; imm := FALSE;
END Set;
PROCEDURE SetLow*(year , month , day ,
hour , min , sec , msec : INTEGER);
BEGIN
seconds := TTGetSecondsLow(year, month, day, hour, min, sec);
miliseconds := msec;
END SetLow;
PROCEDURE dump*(indent: LONGINT);
BEGIN
IF imm THEN
indentDump(indent); KernelLog.String('TT { imm: TRUE } '); KernelLog.Ln;
ELSE
indentDump(indent); KernelLog.String('TT { sec: ');
KernelLog.Int(seconds, 12); KernelLog.String('('); KernelLog.Hex(seconds, 1); KernelLog.String(') ');
KernelLog.String(' msec: '); KernelLog.Int(miliseconds, 4); KernelLog.String(' }'); KernelLog.Ln;
END;
END dump;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR pos: LONGINT);
VAR
i: LONGINT;
fraction: LONGINT;
BEGIN
IF imm THEN
FOR i := 0 TO 6 DO
packet[pos+i] := 0X;
END;
packet[pos+7] := CHR(1);
ELSE
Network.PutNet4(packet, pos, seconds);
fraction := miliseconds * OSCTimeTagOneMS;
Network.PutNet4(packet, pos+4, fraction);
END;
INC(pos, 8);
END export;
END OSCTimeTag;
OSCPacket* = OBJECT
VAR
bytearray: String;
returner: OSCReturnProc;
returnerdata: OBJECT;
PROCEDURE &Init*;
BEGIN
bytearray := NIL;
returner := NIL; returnerdata:= NIL;
END Init;
PROCEDURE GetSize*(): LONGINT; BEGIN HALT(WrngClassUsedOrFunNotOverl); END GetSize;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR position: LONGINT); BEGIN HALT(WrngClassUsedOrFunNotOverl); END export;
PROCEDURE GetBytes*(): String;
BEGIN
assemble();
RETURN bytearray;
END GetBytes;
PROCEDURE IsReturnable*(): BOOLEAN;
BEGIN
RETURN returner # NIL;
END IsReturnable;
PROCEDURE Return*(p: OSCPacket): LONGINT;
BEGIN
IF returner # NIL THEN
RETURN returner(p, returnerdata);
ELSE
RETURN -1;
END;
END Return;
PROCEDURE SetReturner*(s: OSCReturnProc; data: OBJECT);
BEGIN
returner := s;
returnerdata := data;
END SetReturner;
PROCEDURE dump*(indent: LONGINT);
BEGIN
indentDump(indent); KernelLog.String('OSCPacket { bytearray: ');
KernelLog.Buffer(bytearray^, 0, LEN(bytearray^)); KernelLog.String(' }'); KernelLog.Ln;
END dump;
PROCEDURE assemble;
VAR
p: LONGINT;
BEGIN
NEW(bytearray, GetSize());
ASSERT(bytearray # NIL);
p := 0;
export(bytearray^, p);
END assemble;
END OSCPacket;
OSCPacketArray* = POINTER TO ARRAY OF OSCPacket;
OSCReturnProc* = PROCEDURE {DELEGATE} (p: OSCPacket; data: OBJECT): LONGINT;
OSCMessage* = OBJECT(OSCPacket)
VAR
address-: String;
argumentcount-: INTEGER;
arguments-: ParamArray;
noTypeTagString-: BOOLEAN;
argumentData-: Blob;
PROCEDURE &InitMessage*(adr: String);
BEGIN
Init();
address := adr;
NEW(arguments, OSCMessageDefaultArgsCount);
argumentcount := 0;
noTypeTagString := FALSE;
argumentData := NIL;
END InitMessage;
PROCEDURE grow;
VAR
newargs: ParamArray;
i: INTEGER;
BEGIN
NEW(newargs, LEN(arguments)*2);
FOR i:=0 TO argumentcount-1 DO
newargs[i] := arguments[i];
END;
arguments := newargs;
END grow;
PROCEDURE GetSize*(): LONGINT;
VAR
i, argsize: LONGINT;
BEGIN
argsize := 0;
FOR i:=0 TO argumentcount-1 DO
argsize := argsize + arguments[i].GetSize();
END;
IF noTypeTagString THEN
ASSERT(argumentData # NIL);
RETURN oscStrSize(address)+LEN(argumentData);
ELSE
RETURN
oscStrSize(address)+
padsize(1+argumentcount+1)+
argsize;
END;
END GetSize;
PROCEDURE AddArgument*(a: OSCParamObject);
BEGIN
IF argumentcount = LEN(arguments) THEN grow; END;
arguments[argumentcount] := a;
INC(argumentcount);
END AddArgument;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR pos: LONGINT);
VAR
i: LONGINT;
BEGIN
exportString(address, packet, pos);
IF noTypeTagString THEN
FOR i:=0 TO LEN(argumentData)-1 DO
packet[pos+i] := argumentData[i];
END;
INC(pos, LEN(argumentData));
RETURN;
END;
packet[pos] := ','; INC(pos);
FOR i:=0 TO argumentcount-1 DO
ASSERT(arguments[i] # NIL);
packet[pos] := arguments[i].tag; INC(pos);
END;
i := argumentcount+1;
WHILE (i MOD 4) # 0 DO
packet[pos] := 0X; INC(i); INC(pos);
END;
FOR i := 0 TO argumentcount-1 DO
arguments[i].export(packet, pos);
END;
END export;
PROCEDURE dump*(indent: LONGINT);
VAR i: LONGINT;
BEGIN
indentDump(indent); KernelLog.String('OSCMessage { address: '); KernelLog.String(address^); KernelLog.String(' noTypeTagString: ');
KernelLog.Boolean(noTypeTagString); KernelLog.Ln;
FOR i:=0 TO argumentcount-1 DO
arguments[i].dump(indent+1);
END;
IF noTypeTagString THEN
indentDump(indent); KernelLog.String(' argumentData: '); KernelLog.Buffer(argumentData^, 0, LEN(argumentData^));
END;
indentDump(indent); KernelLog.String('}'); KernelLog.Ln;
END dump;
END OSCMessage;
OSCBundle* = OBJECT(OSCPacket)
VAR
timetag-: OSCTimeTag;
messages-: OSCPacketArray;
messagescount-: INTEGER;
PROCEDURE &InitBundle*(tt: OSCTimeTag; msgs: OSCPacketArray; msgcount: INTEGER);
BEGIN
Init();
timetag := tt;
messages := msgs;
IF messages = NIL THEN
NEW(messages, OSCBundleDefaultMsgCount);
messagescount := 0;
ELSE
messagescount := msgcount;
END;
END InitBundle;
PROCEDURE AddPacket*(p: OSCPacket);
BEGIN
IF LEN(messages) = messagescount THEN grow; END;
messages[messagescount] := p;
INC(messagescount);
END AddPacket;
PROCEDURE GetSize*(): LONGINT;
VAR
s: LONGINT;
i: INTEGER;
BEGIN
s := 16;
FOR i:= 0 TO messagescount-1 DO
INC(s, messages[i].GetSize()+4);
END;
RETURN s;
END GetSize;
PROCEDURE IsBeforeEqual*(rhs: OSCBundle): BOOLEAN;
BEGIN
RETURN TTSmaller(SELF.timetag, rhs.timetag) OR TTEqual(SELF.timetag, rhs.timetag);
END IsBeforeEqual;
PROCEDURE IsBefore*(rhs: OSCBundle): BOOLEAN;
BEGIN
RETURN TTSmaller(SELF.timetag, rhs.timetag);
END IsBefore;
PROCEDURE GetTimeout*(): LONGINT;
VAR
nowseconds, nowms: LONGINT;
ticks: LONGINT;
diff, diffms: LONGINT;
overflowdiff: LONGINT;
timeout: LONGINT;
BEGIN
IF timetag.imm THEN RETURN 0 END;
ticks := Kernel.GetTicks ();
IF (ticks > 0) # TicksArePositive THEN updateBootup; END;
nowseconds := SysStartSeconds + (ticks DIV Kernel.Second);
IF Trace THEN KernelLog.String('GetTimeout.nowseconds '); KernelLog.Hex(nowseconds, 4); KernelLog.Ln; END;
nowms := ((ticks MOD Kernel.Second) * 1000) DIV Kernel.Second;
IF Trace THEN KernelLog.String('GetTimeout.nowms '); KernelLog.Int(nowms, 4); KernelLog.Ln;END;
overflowdiff := MAX(LONGINT) DIV 1000;
diff := timetag.seconds - nowseconds;
diffms := timetag.miliseconds - nowms;
IF diff < 0 THEN RETURN 0; END;
IF Trace THEN KernelLog.String('GetTimeout.diff '); KernelLog.Int(diff, 4); KernelLog.Ln;END;
IF Trace THEN KernelLog.String('GetTimeout.diffms '); KernelLog.Int(diffms, 4); KernelLog.Ln;END;
IF(diffms < 0) THEN DEC(diff); diffms := diffms MOD 1000; END;
IF (diff >= overflowdiff-1) THEN
diff := overflowdiff-1;
END;
IF Trace THEN KernelLog.String('GetTimeout.diff '); KernelLog.Int(diff, 4); KernelLog.Ln;END;
IF Trace THEN KernelLog.String('GetTimeout.diffms '); KernelLog.Int(diffms, 4); KernelLog.Ln;END;
timeout := diff*1000+diffms;
IF timeout < 0 THEN RETURN 0; END;
RETURN diff*1000+diffms;
END GetTimeout;
PROCEDURE SetReturner*(s: OSCReturnProc; data: OBJECT);
VAR
i: LONGINT;
BEGIN
SetReturner^(s, data);
FOR i:=0 TO messagescount-1 DO
messages[i].SetReturner(s, data);
END;
END SetReturner;
PROCEDURE dump*(indent: LONGINT);
VAR
i: LONGINT;
BEGIN
indentDump(indent); KernelLog.String('OSCBundle { timetag: '); timetag.dump(indent+1); KernelLog.String(' packets(');
KernelLog.Int(messagescount, 1); KernelLog.String(')'); KernelLog.Ln;
FOR i:=0 TO messagescount-1 DO
messages[i].dump(indent+1);
END;
indentDump(indent); KernelLog.String('}'); KernelLog.Ln;
END dump;
PROCEDURE export(VAR packet: ARRAY OF CHAR; VAR pos: LONGINT);
VAR
i: INTEGER;
BEGIN
exportString(OSCBundleIdent, packet, pos);
timetag.export(packet, pos);
FOR i := 0 TO messagescount-1 DO
Network.PutNet4(packet, pos, messages[i].GetSize()); INC(pos, 4);
messages[i].export(packet, pos);
END;
END export;
PROCEDURE grow;
VAR
newmsgs: OSCPacketArray;
i: LONGINT;
BEGIN
NEW(newmsgs, 2*LEN(messages));
FOR i:=0 TO LEN(messages)-1 DO
newmsgs[i] := messages[i];
END;
messages := newmsgs;
END grow;
END OSCBundle;
PROCEDURE indentDump(i: LONGINT);
VAR
a: LONGINT;
BEGIN
FOR a:=1 TO i DO KernelLog.String(' '); END;
END indentDump;
PROCEDURE TTGetSecondsNow*(): LONGINT;
VAR year, month, day, hour,minute, second: INTEGER;
date, time: LONGINT;
BEGIN
Clock.Get(time, date);
hour := SHORT((time DIV 4096) MOD 32);
minute := SHORT((time DIV 64) MOD 64);
second := SHORT(time MOD 64);
year := 1900+SHORT(date DIV 512);
month := SHORT((date DIV 32) MOD 16);
day := SHORT(date MOD 32);
IF Trace THEN KernelLog.String('TTGetSecondsNow(');KernelLog.Int(year, 4); KernelLog.Int(month, 4); KernelLog.Int(day, 4); KernelLog.Int(hour, 4);
KernelLog.Int(minute, 4); KernelLog.Int(second, 4); KernelLog.String(')'); KernelLog.Ln; END;
RETURN TTGetSecondsLow(year, month, day, hour, minute, second);
END TTGetSecondsNow;
PROCEDURE TTGetSecondsLow*(year , month , day ,
hour , min , sec : INTEGER): LONGINT;
VAR
days, seconds: LONGINT;
i: INTEGER;
BEGIN
days := 0;
FOR i := 1900 TO year-1 DO
IF Dates.LeapYear(i) THEN INC(days); END;
END;
INC(days, (LONG(year)-1900)*365);
INC(days, MonthToDays[month-1]);
IF Dates.LeapYear(year) & (month > 2) THEN INC(days); END;
INC(days, day-1);
seconds := ((days*24 + hour)*60 + min)*60 + sec;
RETURN seconds;
END TTGetSecondsLow;
PROCEDURE TTEqual*(a,b: OSCTimeTag): BOOLEAN;
BEGIN
ASSERT(a # NIL); ASSERT(b # NIL);
IF (a.imm = TRUE) & (b.imm = TRUE) THEN RETURN TRUE; END;
IF (a.imm = TRUE) OR (b.imm = TRUE) THEN RETURN FALSE; END;
RETURN (a.seconds = b.seconds) & (a.miliseconds = b.miliseconds);
END TTEqual;
PROCEDURE TTSmaller*(a,b: OSCTimeTag): BOOLEAN;
BEGIN
ASSERT(a # NIL); ASSERT(b # NIL);
IF (a.imm = TRUE) & (b.imm = FALSE) THEN RETURN TRUE; END;
IF b.imm = TRUE THEN RETURN FALSE; END;
RETURN (a.seconds < b.seconds) OR ((a.seconds = b.seconds) & (a.miliseconds < b.miliseconds));
END TTSmaller;
PROCEDURE TTGreather*(a,b: OSCTimeTag): BOOLEAN;
BEGIN
RETURN TTSmaller(b,a);
END TTGreather;
PROCEDURE ParseOSCPacket*(VAR data: ARRAY OF CHAR; endofs: LONGINT): OSCPacket;
VAR
ofs: LONGINT;
BEGIN
IF Trace THEN
KernelLog.String('ParseOSCPacket started'); KernelLog.Ln;
KernelLog.Buffer(data, 0, endofs); KernelLog.Ln;
END;
ofs := 0;
RETURN parseOSCPacketInt(data, ofs, endofs);
END ParseOSCPacket;
PROCEDURE parseOSCPacketInt(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCPacket;
VAR
p: OSCPacket;
BEGIN
IF Trace THEN KernelLog.String('parseOSCPacketInt: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
IF (endofs-ofs) MOD 4 # 0 THEN RETURN NIL; END;
IF Trace THEN KernelLog.String('size MOD 4 = 0 is ok'); KernelLog.Ln; END;
IF Strings.StartsWith(OSCBundleIdent^, ofs, data) THEN
p := parseOSCBundle(data, ofs, endofs);
ELSE
p := parseOSCMessage(data, ofs, endofs);
END;
IF Trace THEN KernelLog.String('parseOSCPacketInt: '); IF p = NIL THEN KernelLog.String(' parsing message of bundle failed '); END;
KernelLog.String(' ofs is now:'); KernelLog.Int(ofs, 4); KernelLog.Ln; END;
IF ofs # endofs THEN RETURN NIL; END;
RETURN p;
END parseOSCPacketInt;
PROCEDURE parseOSCBundle(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCBundle;
VAR
b: OSCBundle;
p: OSCPacket;
tt: OSCTimeTag;
packetsize: LONGINT;
packetendofs: LONGINT;
i: LONGINT;
BEGIN
IF Trace THEN KernelLog.String('parseOSCBundle: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
IF endofs-ofs < 16 THEN RETURN NIL; END;
IF ~ skipAndCheckOSCString(data, ofs, ofs+8) THEN RETURN NIL END;
tt := parseOSCTT(data, ofs);
NEW(b, tt, NIL, 0);
WHILE (ofs+4) < endofs DO
packetsize := Network.GetNet4(data, ofs); INC(ofs, 4);
packetendofs := ofs+packetsize;
IF packetendofs > endofs THEN RETURN NIL END;
p := parseOSCPacketInt(data, ofs, packetendofs);
IF p = NIL THEN RETURN NIL END;
ASSERT(ofs = packetendofs);
b.AddPacket(p);
END;
IF ofs # endofs THEN RETURN NIL; END;
FOR i:=0 TO b.messagescount-1 DO
p := b.messages[i];
IF p IS OSCBundle THEN
WITH p: OSCBundle DO
IF TTSmaller(p.timetag, b.timetag) THEN
IF Trace THEN KernelLog.String('parseOSCBundle: Timetag in a enclosed bundle is smaller then the enclosing timetag');
KernelLog.Ln; END;
RETURN NIL;
END;
END;
END;
END;
RETURN b;
END parseOSCBundle;
PROCEDURE parseOSCTT(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT): OSCTimeTag;
VAR
tt: OSCTimeTag;
sec, fraction, msec: LONGINT;
BEGIN
IF Trace THEN KernelLog.String('parseOSCTT: '); KernelLog.Int(ofs, 4); KernelLog.Ln; END;
NEW(tt);
sec := Network.GetNet4(data, ofs);
fraction := Network.GetNet4(data, ofs+4);
INC(ofs, 8);
IF (sec = 0) & (fraction = 1) THEN
tt.SetImmediately(); RETURN tt;
END;
msec := 0;
IF fraction < 0 THEN
fraction := - fraction;
msec := 1000 - (fraction DIV OSCTimeTagOneMS);
IF msec = 1000 THEN INC(sec); msec := 0; END;
ELSE
msec := fraction DIV OSCTimeTagOneMS;
END;
tt.Set(sec, msec);
RETURN tt;
END parseOSCTT;
PROCEDURE parseOSCParamInteger(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCParamInteger;
VAR
p: OSCParamInteger;
BEGIN
IF Trace THEN KernelLog.String('parseOSCParamInteger: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
IF (ofs+4) > endofs THEN RETURN NIL END;
NEW(p, Network.GetNet4(data, ofs)); INC(ofs, 4);
RETURN p;
END parseOSCParamInteger;
PROCEDURE parseOSCParamFloat(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCParamFloat;
VAR
p: OSCParamFloat;
i: LONGINT;
BEGIN
IF (ofs+4) > endofs THEN RETURN NIL END;
i := Network.GetNet4(data, ofs); INC(ofs, 4);
NEW(p, Reals.Real(i));
RETURN p;
END parseOSCParamFloat;
PROCEDURE parseOSCParamString(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCParamString;
VAR
p: OSCParamString;
s: String;
BEGIN
IF Trace THEN KernelLog.String('parseOSCParamString: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
s := importString(data, ofs, endofs);
IF s = NIL THEN RETURN NIL END;
NEW(p, s);
RETURN p;
END parseOSCParamString;
PROCEDURE parseOSCParamBlob(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCParamBlob;
VAR
p: OSCParamBlob;
b: Blob;
size, i: LONGINT;
BEGIN
IF Trace THEN KernelLog.String('parseOSCParamBlob: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
IF (ofs+4) > endofs THEN RETURN NIL END;
size := Network.GetNet4(data, ofs); INC(ofs, 4);
IF (ofs+size) > endofs THEN RETURN NIL END;
NEW(b, size);
FOR i:=0 TO size-1 DO b[i] := data[ofs+i]; END; INC(ofs, size);
NEW(p, b, size);
RETURN p;
END parseOSCParamBlob;
PROCEDURE parseOSCParamInteger64(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCParamInteger64;
VAR
p: OSCParamInteger64;
h, l: LONGINT;
bigint: HUGEINT;
BEGIN
IF Trace THEN KernelLog.String('parseOSCParamInteger64: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
IF (ofs+8) > endofs THEN RETURN NIL END;
h := Network.GetNet4(data, ofs); INC(ofs, 4);
l := Network.GetNet4(data, ofs); INC(ofs, 4);
SYSTEM.PUT(SYSTEM.ADR(bigint)+H, h);
SYSTEM.PUT(SYSTEM.ADR(bigint)+L, l);
NEW(p, bigint);
RETURN p;
END parseOSCParamInteger64;
PROCEDURE parseOSCParamTT(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCParamTT;
VAR
tt: OSCTimeTag;
p: OSCParamTT;
BEGIN
IF Trace THEN KernelLog.String('parseOSCParamTT: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
IF (ofs+8) > endofs THEN RETURN NIL END;
tt := parseOSCTT(data, ofs);
IF tt = NIL THEN RETURN NIL; END;
NEW(p, tt);
RETURN p;
END parseOSCParamTT;
PROCEDURE parseOSCParamFloat64(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCParamFloat64;
VAR
p: OSCParamFloat64;
h,l: LONGINT;
f: LONGREAL;
BEGIN
IF Trace THEN KernelLog.String('parseOSCParamFloat64: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
IF (ofs+8) > endofs THEN RETURN NIL END;
h := Network.GetNet4(data, ofs); INC(ofs, 4);
l := Network.GetNet4(data, ofs); INC(ofs, 4);
f := Reals.RealL(h, l);
NEW(p, f);
RETURN p;
END parseOSCParamFloat64;
PROCEDURE parseOSCParamAltString(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCParamString;
VAR
p: OSCParamAltString;
s: String;
BEGIN
IF Trace THEN KernelLog.String('parseOSCParamAltString: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
s := importString(data, ofs, endofs);
IF s = NIL THEN RETURN NIL END;
NEW(p, s);
RETURN p;
END parseOSCParamAltString;
PROCEDURE parseOSCParamChar(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCParamChar;
VAR
p: OSCParamChar;
i: LONGINT;
BEGIN
IF Trace THEN KernelLog.String('parseOSCParamChar: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
IF (ofs+4) > endofs THEN RETURN NIL END;
i := Network.GetNet4(data, ofs); INC(ofs, 4);
NEW(p, CHR(i));
RETURN p;
END parseOSCParamChar;
PROCEDURE parseOSCParamRGBAColor(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCParamRGBAColor;
VAR
p: OSCParamRGBAColor;
BEGIN
IF Trace THEN KernelLog.String('parseOSCParamRGBAColor: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
IF (ofs + 4) > endofs THEN RETURN NIL END;
NEW(p, Network.GetNet4(data, ofs)); INC(ofs, 4);
RETURN p;
END parseOSCParamRGBAColor;
PROCEDURE parseOSCParams(adr: String; VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCMessage;
VAR
argstrofs: LONGINT;
m: OSCMessage;
param: OSCParamObject;
T: OSCParamTrue;
F: OSCParamFalse;
N: OSCParamNil;
I: OSCParamInf;
BEGIN
IF Trace THEN KernelLog.String('parseOSCParams: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
NEW(m, adr);
argstrofs := ofs;
IF ~ skipAndCheckOSCString(data, ofs, endofs) THEN RETURN NIL END;
INC(argstrofs);
IF Trace THEN KernelLog.String('first parametertype at index: '); KernelLog.Int(argstrofs, 4); KernelLog.Ln; END;
WHILE data[argstrofs] # 0X DO
CASE data[argstrofs] OF
'i': param := parseOSCParamInteger(data, ofs, endofs);
| 'f': param := parseOSCParamFloat(data, ofs, endofs);
| 's': param := parseOSCParamString(data, ofs, endofs);
| 'b': param := parseOSCParamBlob(data, ofs, endofs);
| 'h': param := parseOSCParamInteger64(data, ofs, endofs);
| 't': param := parseOSCParamTT(data, ofs, endofs);
| 'd': param := parseOSCParamFloat64(data, ofs, endofs);
| 'S': param := parseOSCParamAltString(data, ofs, endofs);
| 'c': param := parseOSCParamChar(data, ofs, endofs);
| 'r': param := parseOSCParamRGBAColor(data, ofs, endofs);
| 'T': NEW(T); param := T;
| 'F': NEW(F); param := F;
| 'N': NEW(N); param := N;
| 'I': NEW(I); param := I;
ELSE
KernelLog.String('Unknown OSC-Argumenttype: '); KernelLog.Char(data[argstrofs]); KernelLog.Ln;
RETURN NIL;
END;
IF param = NIL THEN RETURN NIL; END;
m.AddArgument(param);
INC(argstrofs);
END;
IF Trace THEN KernelLog.String('parseOSCParams ended with ofs '); KernelLog.Int(ofs, 4); KernelLog.Ln; END;
RETURN m;
END parseOSCParams;
PROCEDURE parseOSCMessage(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): OSCMessage;
VAR
adr: String;
argumentofs: LONGINT;
m: OSCMessage;
i: LONGINT;
BEGIN
IF Trace THEN KernelLog.String('parseOSCMessage: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
adr := importString(data, ofs, endofs);
IF adr = NIL THEN RETURN NIL END;
IF ~ CheckOSCAdrPattern(adr) THEN RETURN NIL END;
IF Trace THEN KernelLog.String('address parsed: '); KernelLog.String(adr^); KernelLog.Ln; END;
IF (data[ofs] = ',') THEN
argumentofs := ofs;
m := parseOSCParams(adr, data, argumentofs, endofs);
IF (m # NIL) & (argumentofs = endofs) THEN
ofs := argumentofs;
RETURN m
END;
IF Trace THEN KernelLog.String('parseOSCParams falied... returned ofs: '); KernelLog.Int(argumentofs, 4); KernelLog.Ln;
IF m = NIL THEN KernelLog.String('but returned message is NIL'); KernelLog.Ln; END; END;
END;
IF Trace THEN KernelLog.String('parsing of typetag failed (or no typetag there)'); KernelLog.Ln; END;
NEW(m, adr);
m.noTypeTagString := TRUE;
NEW(m.argumentData, endofs-ofs);
FOR i:=0 TO (endofs-ofs)-1 DO
m.argumentData[i] := data[ofs+i];
END;
ofs := endofs;
RETURN m;
END parseOSCMessage;
PROCEDURE CheckOSCAdr*(adr: String): BOOLEAN;
VAR
i: LONGINT;
BEGIN
ASSERT(adr # NIL);
i := 0;
WHILE (i < LEN(adr)) & (adr[i] # 0X) DO
IF (ORD(adr[i]) < 32) OR (ORD(adr[i]) > 126) THEN RETURN FALSE; END;
CASE ORD(adr[i]) OF
32, 35, 42, 44, 63, 91, 93, 123, 125:
RETURN FALSE;
ELSE
END;
INC(i);
END;
IF i = LEN(adr) THEN RETURN FALSE; END;
IF adr[0] # '/' THEN RETURN FALSE; END;
RETURN TRUE;
END CheckOSCAdr;
PROCEDURE CheckOSCAdrPattern*(adr: String): BOOLEAN;
VAR
i: LONGINT;
BEGIN
ASSERT(adr # NIL);
i := 0;
WHILE (i < LEN(adr)) & (adr[i] # 0X) DO
IF (ORD(adr[i]) < 32) OR (ORD(adr[i]) > 126) THEN RETURN FALSE; END;
CASE ORD(adr[i]) OF
32, 35:
RETURN FALSE;
ELSE
END;
INC(i);
END;
IF i = LEN(adr) THEN RETURN FALSE; END;
IF adr[0] # '/' THEN RETURN FALSE; END;
RETURN TRUE;
END CheckOSCAdrPattern;
PROCEDURE skipAndCheckOSCString(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): BOOLEAN;
BEGIN
IF Trace THEN KernelLog.String('skipAndCheckOSCString: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
WHILE (ofs < endofs) & (data[ofs] # 0X) DO INC(ofs); END;
IF ofs = endofs THEN IF Trace THEN KernelLog.String('string is too long!'); KernelLog.Ln; END; RETURN FALSE; END;
INC(ofs);
WHILE (ofs MOD 4) # 0 DO
IF data[ofs] # 0X THEN RETURN FALSE; END;
INC(ofs);
END;
IF Trace THEN KernelLog.String('offset after padding: '); KernelLog.Int(ofs,4); KernelLog.Ln; END;
RETURN TRUE;
END skipAndCheckOSCString;
PROCEDURE importString(VAR data: ARRAY OF CHAR; VAR ofs: LONGINT; endofs: LONGINT): String;
VAR
pos: LONGINT;
s: String;
BEGIN
IF Trace THEN KernelLog.String('importString: '); KernelLog.Int(ofs, 4); KernelLog.Int(endofs, 4); KernelLog.Ln; END;
pos := ofs;
WHILE (pos < endofs) & (data[pos] # 0X) DO
INC(pos);
END;
IF data[pos] # 0X THEN RETURN NIL END;
IF Trace THEN KernelLog.String('end of string: '); KernelLog.Int(pos, 4); KernelLog.Ln; END;
NEW(s, pos-ofs+1);
Strings.Copy(data, ofs, pos-ofs+1, s^);
IF Trace THEN KernelLog.String('copied string: '); KernelLog.String(s^); KernelLog.Ln; END;
ofs := pos+1;
WHILE (ofs MOD 4) # 0 DO
IF data[ofs] # 0X THEN RETURN NIL END;
INC(ofs);
END;
IF Trace THEN KernelLog.String('ofset after padding: '); KernelLog.Int(ofs, 4); KernelLog.Ln; END;
RETURN s;
END importString;
PROCEDURE padsize(i: LONGINT): LONGINT;
BEGIN
CASE i MOD 4 OF
0: RETURN i;
| 1: RETURN i+3;
| 2: RETURN i+2;
| 3: RETURN i+1;
END;
END padsize;
PROCEDURE oscStrSize(s: String): LONGINT;
BEGIN
ASSERT(s # NIL );
RETURN padsize(Strings.Length(s^)+1);
END oscStrSize;
PROCEDURE exportString(s: String; VAR packet: ARRAY OF CHAR; VAR pos: LONGINT);
VAR
i, length: LONGINT;
BEGIN
length := oscStrSize(s);
i := 0;
WHILE (i < length) & (s[i] # 0X) DO
packet[pos+i] := s[i];
INC(i);
END;
FOR i := i TO length-1 DO
packet[pos+i] := 0X;
END;
INC(pos, length);
END exportString;
PROCEDURE Test*;
VAR
a: ParamArray;
b: OSCParamInteger;
c: OSCParamString;
BEGIN
NEW(a, 4);
KernelLog.Int(LEN(a), 4); KernelLog.Ln;
NEW(b, 10);
KernelLog.Int(b.integer, 4); KernelLog.Ln;
NEW(c, Strings.NewString('abc'));
KernelLog.Int(c.GetSize(), 4); KernelLog.Ln;
NEW(c, Strings.NewString('abcd'));
KernelLog.Int(c.GetSize(), 4); KernelLog.Ln;
NEW(c, Strings.NewString('abcde'));
KernelLog.Int(c.GetSize(), 4); KernelLog.Ln;
NEW(c, Strings.NewString('abcdef'));
KernelLog.Int(c.GetSize(), 4); KernelLog.Ln;
NEW(c, Strings.NewString('abcdefgh'));
KernelLog.Int(c.GetSize(), 4); KernelLog.Ln;
KernelLog.String('OSC.Test done'); KernelLog.Ln;
END Test;
PROCEDURE TestGetSize*;
VAR
pi: OSCParamInteger;
pf: OSCParamFloat;
ps: OSCParamString;
m: OSCMessage;
BEGIN
NEW(pi, 15);
KernelLog.Int(pi.GetSize(), 4); KernelLog.Ln;
NEW(pf, 1.52);
KernelLog.Int(pf.GetSize(), 4); KernelLog.Ln;
NEW(ps, Strings.NewString('12345'));
KernelLog.Int(ps.GetSize(), 4);
NEW(m, Strings.NewString('/abc/def/ghi'));
m.AddArgument(pi);
m.AddArgument(pf);
m.AddArgument(ps);
KernelLog.Int(m.GetSize(), 4); KernelLog.Ln;
KernelLog.String('OSC.TestGetSize done'); KernelLog.Ln;
END TestGetSize;
PROCEDURE TestAssemble*;
VAR
pi: OSCParamInteger;
pf: OSCParamFloat;
m: OSCMessage;
pli: OSCParamInteger64;
plf: OSCParamFloat64;
b: OSCBundle;
tt: OSCTimeTag;
BEGIN
NEW(m, Strings.NewString('/abc/def/ghi'));
m.assemble();
KernelLog.Buffer(m.bytearray^, 0, LEN(m.bytearray^));KernelLog.Ln;KernelLog.Ln;KernelLog.Ln;
NEW(pi, 12345678H); m.AddArgument(pi);
NEW(pi, 12345679H); m.AddArgument(pi);
NEW(pi, 1234567AH); m.AddArgument(pi);
NEW(pf, 1.25); m.AddArgument(pf);
NEW(plf, 5); m.AddArgument(plf);
NEW(pli, 123456789ABCDEF0H); m.AddArgument(pli);
m.assemble();
KernelLog.Buffer(m.bytearray^, 0, LEN(m.bytearray^));KernelLog.Ln;KernelLog.Ln;KernelLog.Ln;
NEW(tt); tt.SetLow(2005,12,26,12,1,1,123);
NEW(b, tt, NIL, 0);
b.AddPacket(m);
NEW(m, Strings.NewString('/abc/xxx'));
m.AddArgument(pi);
b.AddPacket(m);
b.assemble();
KernelLog.Buffer(b.bytearray^, 0, LEN(b.bytearray^));KernelLog.Ln;KernelLog.Ln;KernelLog.Ln;
tt.SetImmediately();
b.assemble();
KernelLog.Buffer(b.bytearray^, 0, LEN(b.bytearray^));KernelLog.Ln;KernelLog.Ln;KernelLog.Ln;
KernelLog.String('OSC.TestAssemble done');
END TestAssemble;
PROCEDURE TestTT*;
VAR
t: OSCTimeTag;
BEGIN
KernelLog.String('OSC.TestTT'); KernelLog.Ln;
NEW(t);
t.SetLow(2005, 12, 26, 12, 1, 1, 123);
KernelLog.String('2005/12/26/12/01/01.123: '); KernelLog.Hex(t.seconds, 10); KernelLog.Int(t.miliseconds, 4); KernelLog.Ln;
END TestTT;
PROCEDURE TestBundleTimeout*;
VAR
tt: OSCTimeTag;
b: OSCBundle;
BEGIN
KernelLog.String('Bootup: '); KernelLog.Hex(SysStartSeconds, 10); KernelLog.Ln;
KernelLog.String('Ticks: '); KernelLog.Hex(Kernel.GetTicks (), 10); KernelLog.Ln; KernelLog.Boolean(TicksArePositive); KernelLog.Ln;
KernelLog.String('TTGetSecondsNow'); KernelLog.Hex(TTGetSecondsNow(), 10); KernelLog.Ln;
NEW(tt); tt.Set(TTGetSecondsNow()+1000, 0);
NEW(b,tt, NIL, 0);
KernelLog.String('GetTimeout: '); KernelLog.Int(b.GetTimeout(), 10); KernelLog.Ln;
NEW(tt); tt.SetLow(2006,01,25,10, 28,0,0);
NEW(b,tt, NIL, 0);
KernelLog.String('GetTimeout: '); KernelLog.Int(b.GetTimeout(), 10); KernelLog.Ln;
NEW(tt); tt.SetLow(2005,12,31,13, 28,0,0);
NEW(b,tt, NIL, 0);
KernelLog.String('GetTimeout: '); KernelLog.Int(b.GetTimeout(), 10); KernelLog.Ln;
END TestBundleTimeout;
PROCEDURE TestParser*;
VAR
pi: OSCParamInteger;
pf: OSCParamFloat;
m: OSCMessage;
pli: OSCParamInteger64;
plf: OSCParamFloat64;
b: OSCBundle;
tt: OSCTimeTag;
p: OSCPacket;
BEGIN
NEW(m, Strings.NewString('/abc/def/ghi'));
m.assemble();
KernelLog.String('Parsing: ');KernelLog.Ln;
KernelLog.Buffer(m.bytearray^, 0, LEN(m.bytearray^));KernelLog.Ln;KernelLog.Ln;KernelLog.Ln;
p := ParseOSCPacket(m.bytearray^, LEN(m.bytearray^));
IF p # NIL THEN KernelLog.String('parsing ok'); ELSE KernelLog.String('parsing failed'); END; KernelLog.Ln;
NEW(pi, 12345678H); m.AddArgument(pi);
NEW(pi, 12345679H); m.AddArgument(pi);
NEW(pi, 1234567AH); m.AddArgument(pi);
NEW(pf, 1.25); m.AddArgument(pf);
NEW(plf, 5); m.AddArgument(plf);
NEW(pli, 123456789ABCDEF0H); m.AddArgument(pli);
m.assemble();
KernelLog.String('Parsing: ');KernelLog.Ln;
KernelLog.Buffer(m.bytearray^, 0, LEN(m.bytearray^));KernelLog.Ln;KernelLog.Ln;KernelLog.Ln;
p := ParseOSCPacket(m.bytearray^, LEN(m.bytearray^));
IF p # NIL THEN KernelLog.String('parsing ok'); ELSE KernelLog.String('parsing failed'); END; KernelLog.Ln;
NEW(tt); tt.SetLow(2005,12,26,12,1,1,123);
NEW(b, tt, NIL, 0);
b.AddPacket(m);
NEW(m, Strings.NewString('/abc/xxx'));
m.AddArgument(pi);
b.AddPacket(m);
b.assemble();
KernelLog.String('Parsing: ');KernelLog.Ln;
KernelLog.Buffer(b.bytearray^, 0, LEN(b.bytearray^));KernelLog.Ln;KernelLog.Ln;KernelLog.Ln;
p := ParseOSCPacket(b.bytearray^, LEN(b.bytearray^));
IF p # NIL THEN KernelLog.String('parsing ok'); ELSE KernelLog.String('parsing failed'); END; KernelLog.Ln;
tt.SetImmediately();
b.assemble();
KernelLog.String('Parsing: ');KernelLog.Ln;
KernelLog.Buffer(b.bytearray^, 0, LEN(b.bytearray^));KernelLog.Ln;KernelLog.Ln;KernelLog.Ln;
p := ParseOSCPacket(b.bytearray^, LEN(b.bytearray^));
IF p # NIL THEN KernelLog.String('parsing ok'); ELSE KernelLog.String('parsing failed'); END; KernelLog.Ln;
KernelLog.String('OSC.TestAssemble done');
END TestParser;
PROCEDURE calculateBootup;
VAR
nowseconds: LONGINT;
ticks: LONGINT;
BEGIN
ticks := Kernel.GetTicks ();
nowseconds := TTGetSecondsNow();
TicksArePositive := ticks > 0;
SysStartSeconds := nowseconds - (ticks DIV Kernel.Second);
END calculateBootup;
PROCEDURE updateBootup;
VAR
ticks: LONGINT;
BEGIN
ticks := Kernel.GetTicks ();
IF ticks > 0 THEN
TicksArePositive := TRUE;
ELSIF (ticks < 0) & TicksArePositive THEN
IF Trace THEN KernelLog.String('updateBootup: SysStartSeconds now: '); KernelLog.Int(SysStartSeconds, 10);
KernelLog.Hex(SysStartSeconds, 1); KernelLog.Ln; END;
SysStartSeconds := SysStartSeconds + (1073741824 DIV (Kernel.Second DIV 4));
TicksArePositive := FALSE;
IF Trace THEN KernelLog.String('updateBootup: After update SysStartSeconds: '); KernelLog.Int(SysStartSeconds, 10);
KernelLog.Hex(SysStartSeconds, 1); KernelLog.Ln; END;
END;
END updateBootup;
BEGIN
MonthToDays[0] := 0; MonthToDays[1] := 31; MonthToDays[2] := 59; MonthToDays[3] := 90; MonthToDays[4] := 120;
MonthToDays[5] := 151; MonthToDays[6] := 181; MonthToDays[7] := 212; MonthToDays[8] := 243;
MonthToDays[9] := 273; MonthToDays[10] := 304; MonthToDays[11] := 334; MonthToDays[12] := 365;
OSCBundleIdent := Strings.NewString('#bundle');
calculateBootup;
END OSC.
PC.Compile OSCStrings.Mod OSC.Mod OSCRegistry.Mod OSCQueue.Mod OSCService.Mod OSCNet.Mod OSCExample.Mod OSCEval.Mod~
SystemTools.Free OSCEval OSCExample OSCNet OSCService OSCQueue OSCRegistry OSC OSCUtilities ~
OSC.Test ~
OSC.TestGetSize ~
OSC.TestAssemble ~
OSC.TestTT ~
OSC.TestParser ~