| # ITK Programmer's Guide
Table of contents | Intro | General | TCP Low Level | TCP High Level | UDP | DNS | PPP Encoding/Decoding | Internet Config | Goodies | Cryptography & SSL | Appendix
Chapter 10 : Goodies
Chapter contents: | Timer routines: ITK_TimerStart ITK_TimerLap ITK_TimerStop Inter Process Communication: ITK_NbIPCMsg ITK_SendIPCMsg ITK_RcvIPCMsg ITK_ResetIPCMsg ITK_CountIPC ITK_GetIndIPC Picture routines: ITK_PictSize ITK_PictSave ITK_PictRead Miscelaneous routines: ITK_ICMPEcho ITK_OpenFile ITK_SetPriority ITK_GetPriority Blob related routines: ITK_Pict2Blob ITK_Blob2Pict ITK_BlobSave ITK_BlobRead ITK_Record2Blob ITK_Blob2Record ITK_BlobSearch ITK_BlobReplace ITK_Blobgzip ITK_Blobgunzip
About this chapter... | This chapter describes some "goodies" routines provided with ITK. These routines are useful to measure time accurately (needed for example for optimizing a portion of code), communicate between processes (useful in many server implementations), etc.

About ITK Timer Routine

These routines can be used to accurately measure elapsed time in some critical code portions.
Under MacOS, these routines use the Time Manager to get a high level of accuracy (up to the millisecond).

ITK_TimerStart
Syntax: | timerRef := ITK_TimerStart
Description: | Start a timer and returns a reference to it. These reference will be used when calling ITK_TimerLap and ITK_TimerStop .
Params: |
In/Out | Parameter | Type |  | Example or note
<- | timerRef | Longint | Timer reference number |
Example: |
    $timer := ITK_TimerStart
    ...
    $elapsedTime := ITK_TimerStop($timer)

Back to top

ITK_TimerLap
Syntax: | lapTime := ITK_TimerLap (timerRef)
Description: | Returns the number of milliseconds since ITK_TimerStart was called without stopping the timer.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | timerRef | Longint | Timer reference number | As returned by ITK_TimerStart
<- | lapTime | Longint | Elapsed time in milliseconds |
Example: |
    $timer := ITK_TimerStart
    ...
    $lapTime1 := ITK_TimerLap($timer)
    ...
    $lapTime2 := ITK_TimerLap($timer)
    ...
    $totalTime := ITK_TimerStop($timer)

Back to top

ITK_TimerStop
Syntax: | totalTime := ITK_TimerStop (timerRef)
Description: | Returns the number of milliseconds since ITK_TimerStart was called and then stops the timer.
Note: | After calling ITK_TimerStop, the Timer Reference number returned by ITK_TimerStart is not valid anymore.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | timerRef | Longint | Timer reference number | As returned by ITK_TimerStart
<- | totalTime | Longint | Elapsed time in milliseconds |
Example: |
    $timer := ITK_TimerStart
    ...
    $totalTime := ITK_TimerStop($timer)

Back to top

About ITK Inter Process Communication (IPC) routines

ITK's IPC routines are useful to exchange data between processes through communications channels. These channels are memory based to provide speed efficient communications.

The number of channels and the number of messages queued in a channel is limited to 2 billions and by the available memory.

It is not recommended to keep a large number of messages in IPC channels as they can use a lot of memory and fragment 4D's memory.

ITK_NbIPCMsg
Syntax: | nbMsg := ITK_NbIPCMsg (ipcChannel)
Description: | Returns the number of messages currently stored on the specified IPC channel.
Note: | IPC channel number are used to create as many IPC channels as you need. For example, you can use the Current Process instruction in 4D language to allocate one IPC channel for each 4D process or use any other channel numbering.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | ipcChannel | Longint | IPC Channel Number | see note above.
<- | nbMsg | Longint | Number of messages stored in this IPC channel. |
Example: |
    While (ITK_NbIPCMsg(1)>0)
    ` process IPC messages
    ...
    End While

Back to top

ITK_SendIPCMsg
Syntax: | ITK_SendIPCMsg (ipcChannel;message)
Description: | Sends a message on the specified IPC channel. The message will be stored in the channel message queue.
Note: | IPC channel number are used to create as many IPC channels as you need. For example, you can use the Current Process instruction in 4D language to allocate one IPC channel for each 4D process or use any other channel numbering.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | ipcChannel | Longint | IPC Channel Number | see note above.
-> | message | Text | Message to send in the above channel |
Example: |
    ITK_SendIPCMsg(1;"quit")

Back to top

ITK_RcvIPCMsg
Syntax: | message := ITK_RcvIPCMsg (ipcChannel;option)
Description: | Reads a message from the specified IPC channel. If no message is available, returns an empty string. The option parameter can be used to keep the message in the IPC channel queue. In that case, the same message will be returned on the next call to ITK_RcvIPCMsg.
Note: | IPC channel number are used to create as many IPC channels as you need. For example, you can use the Current Process instruction in 4D language to allocate one IPC channel for each 4D process or use any other channel numbering.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | ipcChannel | Longint | IPC Channel Number | see note above.
-> | option | Longint |  | 0 = default behaviour 1 = keep message in channel queue
<- | message | Text | Receive message | will be empty if no message available on the requested IPC channel.
Example: |
    $msg := ITK_RcvIPCMsg(1;0)
    If ($msg = "quit")
      QUIT 4D
    End If

Back to top

ITK_ResetIPCMsg
Syntax: | ITK_ResetIPCMsg (ipcChannel)
Description: | Removes all the messages stored on the specified IPC channel.
Note: | IPC channel number are used to create as many IPC channels as you need. For example, you can use the Current Process instruction in 4D language to allocate one IPC channel for each 4D process or use any other channel numbering.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | ipcChannel | Longint | IPC Channel Number | see note above.
Example: |
    ITK_ResetIPCMsg(1)

Back to top

ITK_CountIPC
Syntax: | ipcCount := ITK_CountIPC
Description: | Returns the current number of existing IPC channels.
Note: | This routine has been introduced in version 2.0.3 of Internet ToolKit.
Params: |
In/Out | Parameter | Type |  | Example or note
<- | ipcCount | Longint | Number of IPC Channels |
Example: |
    ` Total number of messages in IPC channels
    $nbMsg := 0
    For ($i;1;ITK_CountIPC)
      $nbMsg := $nbMsg + ITK_NbIPCMsg(ITK_GetIndIPC($i))
    End For

Back to top

ITK_GetIndIPC
Syntax: | ipcChannel := ITK_GetIndIPC (index)
Description: | Returns the nth IPC channel.
Note: | This routine has been introduced in version 2.0.3 of Internet ToolKit. It is not available in previous versions.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | index | Longint | IPC Channel index | Must be between 1 and ITK_CountIPC
<- | ipcChannel | Longint | IPC Channel number |
Example: |
    ` Total number of messages in IPC channels
    $nbMsg := 0
    For ($i;1;ITK_CountIPC)
      $nbMsg := $nbMsg + ITK_NbIPCMsg(ITK_GetIndIPC($i))
    End For

Back to top

ITK_PictSize
Syntax: | pictSize := ITK_PictSize (pict; top; left; bottom; right; type)
Description: | This routines extracts size informations from a given picture.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | pict | Picture |  |
-> | top | Longint | Top coordinates of the picture |
-> | left | Longint | Left coordinate of the picture |
-> | bottom | Longint | Bottom coordinate of the picture |
-> | right | Longint | Right coordinate of the picture |
-> | type | Longint | type of picture | 0 = Mac style PICT 1 = GIF image 2 = JPEG/JFIF image 3 = Mac PICT containing JPEG data (since ITK v2.0.3)
<- | pictSize | Longint | Size (in bytes) of the picture | For Mac PICT containing JPEG data, this size correspond to the JPEG data size, not the full PICT size.
Example: |
    $size := ITK_PictSize($pict;$top;$left;$bottom;$right;$type)
    $height := $bottom-$top
    $width := $right-$left

Back to top

ITK_PictSave
Syntax: | error := ITK_PictSave (pict; filePath; startOffset; endOffset; options)
Description: | Saves the content of a picture field or variable into a file. If the picture is encoded in the GIF format, a standard GIF file will be saved. If the picture contains a JPEG portion, this portion will be save as a JPEG/JFIF file. Otherwise, the picture will be saved as a standard Picture (PICT). If startOffset and/or endOffset and not zero, only the corresponding portion of the picture filed will be saved. Options can be used to require ITK_PictSave to add the 512 bytes header required by the standard PICT file format.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | pict | Picture | Picture field or variable to save |
-> | filePath | String | File pathname |
-> | startOffset | Longint | Starting offset of data to save | 0 = save from the beginning of the pict
-> | endOffset | Longint | End offset of data to save | 0 = save up to the end of the pict
-> | options | Longint |  | 0 = default behaviour 1 = add 512 bytes header. (introduced in v2.0.4)
<- | error | Longint | OS Error code |
Example: |
    $err := ITK_PictSave($pict;"MyHD:MyFolder:MyPict")

Back to top

ITK_PictRead
Syntax: | pict := ITK_PictRead (filePath; startOffset; endOffset; options)
Description: | Reads a picture file (PICT, GIF or JFIF/JPEG) and returns it as a 4D pict.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | filePath | String | Filepath of the Picture file to read |
-> | startOffset | Longint | Starting offset | Leave 0 to start reading at the beginning of the file.
-> | endOffset | Longint | End offset | Leave 0 to read up to the end of the file.
-> | options | Longint |  | 0 = default behaviour 1 = remove the 512 header bytes in PICT files. (introduced in v2.0.4)
<- | pict | Picture | Picture read from file. | If an error occured, this picture will have its size set to 0.
Example: |
    $pict := ITK_PictRead("MyHD:MyFolder:MyPict")
    $err := ITK_TCPSendPict($stream; $pict)

Back to top

ITK_ICMPEcho
Syntax: | time := ITK_ICMPEcho (IPaddr; timeout; size)
Description: | This routines sends an "ICMP Echo" packet to the remote IP address and measures the time needed for the echo to come back. It is an equivallent to the famous "ping" function.
Note: | Under Windows, this routine can only be used if 4D is running with administrative rights (this is due to a Winsock limitation).
Params: |
In/Out | Parameter | Type |  | Example or note
-> | IPaddr | Longint | Remote host IP address | As returned by ITK_Name2Addr.
-> | timeout | Longint | Timeout in seconds |
-> | size | Longint | Size of the ICMP Echo packet to send. | 0 will use a default size of 64 bytes.
<- | result | Longint | Measured time in milliseconds | Negative values indicate that an error occured.
Example: |
    $pingtime := ITK_ICMPEcho(ITK_Name2Addr("www.internet-toolkit.com");2000;64)

Back to top

ITK_OpenFile
Syntax: | fileRef := ITK_OpenFile (pathname)
Description: | Opens a file in read-only mode.
Note: | The variable used to store the fileRef value must be types as C_TIME when compiled.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | pathName | String | Pathname of the file to open. | Under Windows, the full pathname must be passed, ex: "C:\MYSTUFF\MYFILE.TXT".
<- | fileRef | Longint | File reference of the opened file. | Will return 0 if the file could not be opened. The returned value can be used in other 4D file related routines like RECEIVE PACKET , CLOSE DOCUMENT , etc. This value is equivallent to the one returned by Open Document .
Example: |
    $file := ITK_OpenFile("C:\MyFile.TXT")
    If ($file#0)
      RECEIVE PACKET($file;$data;32000)
      ...
      CLOSE DOCUMENT($file)
    End If

Back to top

ITK_SetPriority
Syntax: | error := ITK_SetPriority (newPriority)
Description: | Changes 4D's priority level in Windows multitasking.
Note: | This routines currently does nothing under MacOS.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | newPriority | Longint | Priority level value | 32 = Normal 64 = Idle 128 = High 256 = Realtime
<- | error | Longint | Windows error code (0= no error) |
Example: |
    $err := ITK_SetPriority(64) ` go in Idle mode

Back to top

ITK_GetPriority
Syntax: | priority := ITK_GetPriority
Description: | Retrieves 4D's priority level in Windows multitasking.
Note: | This routines currently does nothing under MacOS.
Params: |
In/Out | Parameter | Type |  | Example or note
<- | priority | Longint | Current Windows priority level | 32 = Normal 64 = Idle 128 = High 256 = Realtime
Example: |
    ` Set 4D's at least in "normal" priority
    If (ITK_GetPriority=64)
      $err := ITK_SetPriority(32)
    End If

Back to top

About ITK Blob Routines

All ITK blob related routines are also available in "pre-v6" version of 4D. In that case, blobs are in fact picture fields or variables which will act the same as blobs.

ITK_Pict2Blob
Syntax: | blob := ITK_Pict2Blob (pict; option)
Description: | Converts a picture value (variable or field) into a blob.
Note: | The content in not changed by this routine which simply does some typecasting.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | pict | Picture | picture to convert |
-> | option | Longint | option to indicate if a copy of the blob is requested | 0 = a copy of the original pict is returned 1= the original picture is returned and emptied This parameter has been introduced in version 2.0.2 of Internet ToolKit.
<- | blob | Blob | typecasted blob |
Example: |
    $myBlob := ITK_Pict2Blob($myPict) ` return a copy (uses more memory)
    $myBlob := ITK_Pict2Blob($myPict;1) ` "transfers" the pict into a blob, the original pict is emptied

Back to top

ITK_Blob2Pict
Syntax: | pict := ITK_Blob2Pict (blob; option)
Description: | Converts a blob value (variable or field) into a picture.
Note: | The content in not changed by this routine which simply does some typecasting.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | blob | Blob | blob to convert |
-> | option | Longint | Option to indicate if a copy of the blob is requested | 0 = a copy of the original blob is returned 1 = the original blob is returned and emptied This parameter has been introduced in version 2.0.2 of Internet ToolKit.
<- | pict | Picture | typecasted picture |
Example: |
    $myPict := ITK_Blob2Pict($myBlob) ` return a copy (uses more memory)
    $myPict := ITK_Blob2Pict ($myBlob;1) ` "transfers" the blob into a pict, the original blob is emptied

Back to top

ITK_BlobSave
Syntax: | error := ITK_BlobSave (blob; filePath; startOffset; endOffset; fileStart)
Description: | Saves the content of a blob into a file. If startOffset and/or endOffset and not zero, only the corresponding portion of the blob will be saved. FileStart allows to save the blob at a given position in an existing file instead of storing the blob at the beginning of the file.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | blob | Blob | Blob field or variable to save |
-> | filePath | String | File pathname |
-> | startOffset | Longint | Starting offset of data to save | 0 = save from the beginning of the pict
-> | endOffset | Longint | End offset of data to save | 0 = save up to the end of the pict
-> | fileStart | Longint | File offset where to start storing the blob | 0 = store at the beginning of the file 1..n = store at file start + 1..n bytes.
<- | error | Longint | OS Error code |
Example: |
    $err := ITK_BlobSave($blob;"MyHD:MyFolder:MyPict") ` same as BLOB TO DOCUMENT
    $err := ITK_BlobSave($blob;"MyHD:MyFolder:MyPict";1;10) ` saves a portion of the blob

Back to top

ITK_BlobRead
Syntax: | blob := ITK_BlobRead (filePath; startOffset; endOffset)
Description: | Reads a file or a part of it and returns it a blob.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | filePath | String | Filepath of the file to read |
-> | startOffset | Longint | Starting offset | Leave 0 to start reading at the beginning of the file.
-> | endOffset | Longint | End offset | Leave 0 to read up to the end of the file.
<- | blob | Blob | Blob read from the file | If an error occured while accessing, the blob will have its size set to 0.
Example: |
    $pict := ITK_BlobRead("MyHD:MyFolder:MyPict") ` same as DOCUMENT TO BLOB
    $pict := ITK_BlobRead("MyHD:MyFolder:MyPict";1;10) ` read only a portion of the file

Back to top

ITK_Record2Blob
Syntax: | error := ITK_Record2Blob (tableNum; blob)
Description: | Convert the current record of the table specified into a blob.
Note: | It is not guaranteed that the same format is used to encode records by all version of 4D (past, current and futures).
Params: |
In/Out | Parameter | Type |  | Example or note
-> | tableNum | Longint | Table logical number | As returned by 4D "Table" function (see example)
<- | blob | Blob | Blob containing the converted record |
<- | error | Longint | Error code | 4D error code
Example: |
    GOTO SELECTED RECORD([File1];1)
    $err:=ITK_Blob2Record($blob;Table(->[File1])
    ...

Back to top

ITK_Blob2Record
Syntax: | err := ITK_Blob2Record (blob; tableNumber)
Description: | Converts a blob containing a record obtained by ITK_Record2Blob back into a 4D record (in the current selected record).
Note: | It is not guaranteed that the same format is used to encode records by all version of 4D (past, current and futures).
Params: |
In/Out | Parameter | Type |  | Example or note
-> | blob | Blob | blob to convert |
-> | tableNum | Longint | Table logical number | As returned by 4D "Table" command
<- | err | Longint | Error code | 4D error code
Example: |
    CREATE RECORD([File1])
    $err:=ITK_Blob2Record($blob;Table(->[File1])
    SAVE RECORD([File1])

Back to top

ITK_BlobSearch
Syntax: | pos := ITK_BlobSearch (blob;offset;text;nbOcc)
Description: | Search some text in a blob from a given position, and returns the position of the nth occurence of that text. ITK_BlobSearch can also be used to count the number of occurence of a given text into a blob (see example).
Note: | Text matching is byte based. This means that "E" and "e" and "é" are different.
Params: |
In/Out | Parameter | Type |  | Example or note
-> | blob | Blob | Blob to search in |
-> | offset | Longint | Start search position in the blob | 0 = start of the blob (1st byte in blob) 1 = 2nd byte in blob, etc...
-> | text | Text | Text to search in the blob |
<-> | nbOcc | Longint | Number of occurence to search | 0 or 1 = first occurence 2 = 2nd occurence, etc... Will also return the number of occurence found.
<- | pos | Longint | Last position found | -1 = text not found in blob otherwise return the last position found (starting at 0)
Example: |
    TEXT TO BLOB("Test text";$b;3)
    $p := ITK_BlobSearch($b;0;"text") ` returns 5

    ` count occurences
    $nb := BLOB size($b) ` max number of occurences to count (up to size of blob)
    $p := ITK_blobSearch($b;0;"e";$nb) ` $p returns 6, $nb returns 2 (2 "e" found" in blob)

Back to top

ITK_BlobReplace
Syntax: | err := ITK_BlobReplace (blob; offset; oldText; newText; nbOcc)
Description: | Search some text in a blob from a given position (offsett), and replace it with the new text specified. nbOcc can be used to repeat this search/replace several times.
Note: | It is not guaranteed that the same format is used to encode records by all version of 4D (past, current and futures).
Params: |
In/Out | Parameter | Type |  | Example or note
-> | blob | Blob | Blob to search in |
-> | offset | Longint | Start search position in the blob | 0 = start of the blob (1st byte in blob) 1 = 2nd byte in blob, etc...
-> | oldText | Text | Text to search in the blob |
-> | newText | Text | Text that will replace oldText |
-> | nbOcc | Longint | Number of occurence to search/replace | -1 = all occurences 0 or 1 = first occurence 2 = 2nd occurence, etc... Will also return the number of occurence actually replaced.
<- | pos | Longint | Last position of search/replace | -1 = text not found in blob otherwise return the last position found (starting at 0)
Example: |
    TEXT TO BLOB("Test text";$b;3)
    $p := ITK_BlobReplace($b;0;"te";"Te") ` $p returns 5, blob now contains "Test Text"

Back to top

ITK_Blobgzip
Syntax: | err := ITK_Blobgzip (blob;compLevel)
Description: | Compresses a blob using the gzip compression algorithm.
Note: | The blob content has the same format as a gzip compressed file. The compression algorithm is not compatible with 4D's builtin COMPRESS BLOB command. To decompress the resulting blob, you must use ITK_Blobgunzi or ITK_gzip2Mac (if the blob has been stored in a file).
Params: |
In/Out | Parameter | Type |  | Example or note
<-> | blob | Blob | Blob to compress |
-> | compLevel | Longint | Compression level | 0 = default compression level 1 = faster but less efficient compression ... 9 = best but slower compression
<- | err | Longint | Error code | 0 = no error negative values indicate that some error occured (memory related errors)
Example: |
    $err := ITK_Blobgzip(myBlob;9) ` use best compression

Back to top

ITK_Blobgunzip
Syntax: | err := ITK_Blobgunzip (blob; originalSize)
Description: | Decompresses a blob compressed using ITK_Blobgzip . originalSize can help ITK determine how large the decompressed blob will be.
Note: | The compression algorithm is not compatible with 4D's builtin COMPRESS BLOB command.
Params: |
In/Out | Parameter | Type |  | Example or note
<-> | blob | Blob | Blob to decompress |
-> | originalSize | Longint | Initial output blob used by ITK to decompress the blob. | 0 = let ITK determine the size (slower)
<- | err | Longint | Error code | 0 = no error occured -1 = file error -2 = stream error -3 = invalid data in compressed blob -4 = insufficient memory -5 = buffer error -6 = incompatible version of gzip format other negative values indicates that some memory error occured
Example: |
    $err := ITK_Blobgunzip(myBlob) ` decompress the blob

Back to top

CQ/1-Mar-2002