REM Declarations for working with structs in PeopleCode; Declare Function GlobalAlloc Library "kernel32" (ulong Value As number, ulong Value As number) Returns ulong As number; Declare Function GlobalFree Library "kernel32" (ulong Value As number) Returns ulong As number; Declare Function CopyPtrToInt Library "kernel32" Alias "RtlMoveMemory" (integer As number, ulong Value As number, ulong Value As number); Declare Function GetLocalTime Library "kernel32" (ulong Value As number); Function GetSizeForType(&sType As string) Returns integer Evaluate &sType When = "integer" Return 2; When = "uinteger" Return 2; When = "word" Return 2; When = "dword" Return 4; When = "long" Return 4; When = "ulong" Return 4; When = "lpszchar" REM Pointer to a string; Return 4; When-Other If Left(&sType, 4) = "char" Then Local integer &iSize = Value(Substring(&sType, 5, Len(&sType) - 4)); Return &iSize; Else Error ("Unknown type for GetSizeForType: " | &sType); End-If; End-Evaluate; End-Function; Function IsValidStructDefn(&structDefn As array of array of string) If &structDefn.Len <> 2 Then Error ("Invalid struct definition. Definition should have one array of field names, and one of field types"); End-If; If &structDefn [1].Len <> &structDefn [2].Len Then Error ("Invalid struct definition. The number of fields does not match the number of field types"); End-If; End-Function; Function GetStructSize(&structDefn As array of array of string) Returns integer IsValidStructDefn(&structDefn); Local integer &iCtr, &iStructSize; For &iCtr = 1 To &structDefn [2].Len &iStructSize = &iStructSize + GetSizeForType(&structDefn [2][&iCtr]); End-For; Return &iStructSize; End-Function; Function AllocStruct(&structDefn As array of array of string) Returns number IsValidStructDefn(&structDefn); REM GlobalAlloc the memory after calculating the size; Local integer &iStructSize = GetStructSize(&structDefn); Local number &nFixedZeroInit = 64; Local number &nPtrToStruct = GlobalAlloc(&nFixedZeroInit, &iStructSize); If &nPtrToStruct = 0 Then Error ("Could not allocate memory for struct"); End-If; Return &nPtrToStruct; End-Function; Function FreeStruct(&nPtrToStruct As number) If &nPtrToStruct = 0 Then Error ("Can't call FreeStruct on a struct that has not been initialized"); End-If; Local number &nResult = GlobalFree(&nPtrToStruct); End-Function; Function GetFieldOffsetFromStructDefn(&sFieldName As string, &structDefn As array of array of string, &iOffset As integer, &iSize As integer) &iOffset = 0; Local integer &iCtr, &iFieldPos; For &iCtr = 1 To &structDefn [1].Len If &structDefn [1][&iCtr] = &sFieldName Then &iFieldPos = &iCtr; &iSize = GetSizeForType(&structDefn [2][&iCtr]); Break; Else REM Keep track of how far "into" the struct we need to go; &iOffset = &iOffset + GetSizeForType(&structDefn [2][&iCtr]); End-If; End-For; If Not &iFieldPos > 0 Then Local string &CR = Char(13) | Char(10); Error ("Could not find field name " | &sFieldName | " in struct definition. " | &CR | &structDefn [1].Join(&CR, "", "")); End-If; End-Function; Function GetIntegerFromStruct(&sFieldName As string, &nStructPtr As number, &structDefn As array of array of string) Returns integer If &nStructPtr = 0 Then Error ("nStructPtr has not been initialized!"); End-If; REM Check which field we're looking for; Local integer &iOffset, &iSize; GetFieldOffsetFromStructDefn(&sFieldName, &structDefn, &iOffset, &iSize); REM Sanity check on our size; If &iSize <> 2 Then Error ("Attempting to get integer from struct field " | &sFieldName | " which is not defined as an integer in the struct defn"); End-If; Local integer &iReturnValue = 0; CopyPtrToInt(&iReturnValue, &nStructPtr + &iOffset, &iSize); Return &iReturnValue; End-Function; Function GetLocalTimeFromSystem() Local array of string &arrFields = CreateArray("year", "month", "dayofweek", "day", "hour", "minute", "second", "millisecond"); Local array of string &arrTypes = CreateArray("word", "word", "word", "word", "word", "word", "word", "word"); Local array of array of string &arrStructDefn = CreateArray(&arrFields, &arrTypes); Local number &nPtrSystime = AllocStruct(&arrStructDefn); REM Do the actual API call; GetLocalTime(&nPtrSystime); Warning (GetIntegerFromStruct("year", &nPtrSystime, &arrStructDefn) | "-" | GetIntegerFromStruct("month", &nPtrSystime, &arrStructDefn) | "-" | GetIntegerFromStruct("day", &nPtrSystime, &arrStructDefn) | " " | GetIntegerFromStruct("hour", &nPtrSystime, &arrStructDefn) | ":" | GetIntegerFromStruct("minute", &nPtrSystime, &arrStructDefn) | ":" | GetIntegerFromStruct("second", &nPtrSystime, &arrStructDefn)); FreeStruct(&nPtrSystime); End-Function; GetLocalTimeFromSystem();