═══ 1. Introduction ═══ RxCRC32 V1.00 A REXX interface DLL for CRC-32 Copyright (C) Mads Orbesen Troest & SIRIUS Cybernetics ═══ 1.1. Abstract ═══ Abstract Introduction So what on earth is this stuff all about?! RxCRC32 is a small OS/2 Dynamic Link Library (DLL) that interfaces quite fast routines for the calculation of CRC-32 checksums with REXX. CRC-32 is used many places; it is widely considered a de-facto checking method of most modern communication systems, and is also frequently used as a unique identifier for a given file. However, it is a rather computionally intensive task to calculate a CRC-32; REXX is way too slow for this, unless you are a very, very patient person. With this easy-to-use and very versatile DLL, you can efficiently calculate CRC-32 from your standard REXX programs, without even bothering about the implementation of the algorithm. You won't ever need looking for other alternatives of getting a CRC-32 of a file or buffer from REXX! ═══ 1.2. Conditions of Use ═══ Conditions of Use This version is to be considered internal SIRIUS Cybernetics software; it must not be spread to other parties without the author's explicit accept! If you are not a member of SIRIUS Cybernetics, you may only use this package if you have got the consent of Mads Orbesen Troest. Click here to see how to contact the author... ═══ 1.3. Contacting Author ═══ Contacting Author If you wish to contact me for any questions, feedback, suggestions or just plain talk, you can reach me in the following ways: SnailMail Mads Orbesen Troest Dyrskuevej 53, 1.MF DK-9200 Aalborg SV Denmark Phone (+45) 3073 5352 (Voice) (+45) 9818 5383 (Fax/Data) InterNet motr96@sprog.auc.dk http://www.sprog.auc.dk/~motr96 Eek @ #Eek & #OS/2 (IRC Net) FTN 2:238/202@FidoNet 81:445/202@OS2Net Never you hesitate to write; I always enjoy response to my work! ═══ 2. Using RxCRC32 ═══ Using RxCRC32 This section describes how you make RxCRC32 accessible to your own REXX code, and how you go about utilising the available functions. ═══ 2.1. Making RxCRC32 Accessible ═══ Making RxCRC32 Accessible The first thing you must do to be able to use RxCRC32 from your own REXX programs is to tell the REXX interpreter which external functions to load from which DLL. This is achieved through the RxFuncAdd command: /* Sample REXX Code for making all functions of RxCRC32 available */ CALL RxFuncAdd "RxCRC32Ver", "RXCRC32", "RXCRC32VER" CALL RxFuncAdd "RxCRC32Init", "RXCRC32", "RXCRC32INIT" CALL RxFuncAdd "RxCRC32Update", "RXCRC32", "RXCRC32UPDATE" CALL RxFuncAdd "RxCRC32Done", "RXCRC32", "RXCRC32DONE" I know... I might have made it easier for you by providing a "RxCRC32LoadFuncs", but I was too lazy to do that; you'll have to accept this, or bug me to implement it in a newer version, if any such is to come. A comment on unloading the DLL (and other REXX DLLs): It is, in fact, very nasty behaviour if you try to manually enforce OS/2 to drop the external functions it has loaded. OS/2 will automatically discard these DLLs when the session from which it was loaded is ended; if you force it to drop the functions before that, all other running programs that may use it will also loose the funcs! Please remember that this is a multi-tasking system! After having added the functions with the REXX RxFuncAdd call, you should be able to call them. The next section describes how you use the set of routines to calculate CRC-32 from your own REXX application... ═══ 2.2. RxCRC32 Usage ═══ RxCRC32 Usage To calculate the CRC-32 of something, you need to take the following steps: First, you must call RxCRC32Init; this call returns an initialised CRC-32 variable (which consists of an 8-byte, uppercased hexadecimal numeric string). You might think of this returned value as a sort of handle from an open function (only, this value is not fixed, but continously updated as the CRC calculation progresses); you must supply it to both RxCRC32Update and RxCRC32Done when calling them. After having initialised a CRC variable, you keep calling RxCRC32Update until you are through your data. The reason RxCRC32 works this way is that it becomes very flexible that way. The update-function takes the current CRC variable and a buffer-string to process. It returns the new, updated CRC variable that you must pass the next time. When you have processed all your data this way, you must call RxCRC32Done to complete the calculation. This call also takes the current CRC variable as argument, and returns the final CRC-32 value of the calculation. After having called this function, you may no longer call the update- or done-functions, until a new CRC-session is initialised with the init-function. For further details, I suggest you take a look at the examples to see how to use RxCRC32 in practice. ═══ 3. RxCRC32 Function Reference ═══ RxCRC32 Function Reference This section provides a reference of the functions that RxCRC32 provide. These functions are:  RxCRC32Ver - Return Version Information  RxCRC32Init - Initialise CRC-32 Calculation  RxCRC32Update - Update CRC-32 Calculation with Buffer  RxCRC32Done - Complete CRC-32 Calculation ═══ 3.1. RxCRC32Ver - Return Version Information ═══ RxCRC32Ver ───RxCRC32Ver()───── RxCRC32Ver returns a version and copyright string with the following format: ID VER - COPYRIGHT NOTICE ─────── ───── ─ ──────────────────────────────────────────── RxCRC32 V1.00 - (C) Mads Orbesen Troest & SIRIUS Cybernetics Examples ═══ 3.2. RxCRC32Init - Initialise CRC-32 Calculation ═══ RxCRC32Init ───RxCRC32Init()───── RxCRC32Init returns an initialised CRC-32 variable (an 8-digit hexadecimal string) for further use during the runnning calculation of the CRC. This call must always be made during the initialisation phase of the CRC calculation, before calling RxCRC32Update or RxCRC32Done. Examples ═══ 3.3. RxCRC32Update - Update CRC-32 Calculation with Buffer ═══ RxCRC32Update ───RxCRC32Update( CRC, Buffer )───── RxCRC32Update returns an updated running (must be initialised through RxCRC32Init) CRC-32 variable (an 8-digit hexadecimal string) for continued use during the calculation of the CRC. This function takes the running CRC-32 variable as argument, followed by a string holding the buffer with which to update the running CRC value. Examples ═══ 3.4. RxCRC32Done - Complete CRC-32 Calculation ═══ RxCRC32Done ───RxCRC32Done( CRC )───── RxCRC32Done completes the running CRC calculation; after calling this function no more calls to RxCRC32Update may be made, until it is reinitialised by RxCRC32Init. This function takes the running CRC-32 variable (an 8-digit hexadecimal string) as argument, and returns the final, completed result of the CRC calculation. Examples ═══ 4. Examples of Usage ═══ Examples of Usage This section provides a couple of examples on how to use RxCRC32 in practice:  CRC-32 of Entered String  CRC-32 of File ═══ 4.1. CRC-32 of Entered String ═══ CRC-32 of Entered String Here is the REXX source for a small script that reads a line of text from stdin (keyboard by default), and calculates its corresponding CRC-32 value: Source Code: /* RxCRC32-Test: Calculate CRC-32 of Entered String * * * * (C) Mads Orbesen Troest & SIRIUS Cybernetics */ /* Load External RxCRC32 Routines: */ CALL RxFuncAdd "RxCRC32Ver", "RXCRC32", "RXCRC32VER" CALL RxFuncAdd "RxCRC32Init", "RXCRC32", "RXCRC32INIT" CALL RxFuncAdd "RxCRC32Done", "RXCRC32", "RXCRC32DONE" CALL RxFuncAdd "RxCRC32Update", "RXCRC32", "RXCRC32UPDATE" /* Do some initial chitchat: */ SAY "" SAY "RxCRC32-Test: Calculate CRC-32 of Entered String, utilising:" SAY RxCRC32Ver() /* Report Version Information */ SAY "" /* Initialize the variable CRC for running CRC-32 calculation: */ CRC = RxCRC32Init() /* Get the buffer to calculate: */ SAY "Whack in some line that you want me to calculate the CRC-32 of:" PARSE PULL Buffer /* Calculate CRC-32 of Buffer: */ CRC = RxCRC32Update( CRC, Buffer ) /* Complete Calculation: */ CRC = RxCRC32Done( CRC ) /* Report the result: */ SAY "" SAY "Well, then... CRC-32 : "CRC" (HEX) - Thanks for using RxCRC32 :-)" Screen Dump: RxCRC32-Test: Calculate CRC-32 of Entered String, utilising: RxCRC32 V1.00 - (C) Mads Orbesen Troest & SIRIUS Cybernetics Whack in some line that you want me to calculate the CRC-32 of: Dear Mads Orbesen Troest; thank you SO much for a neat REXX DLL!!! ;-) Well, then... CRC-32 : 08511B7C (HEX) - Thanks for using RxCRC32 :-) ═══ 4.2. CRC-32 of File ═══ CRC-32 of File Here is the REXX source for a small script that reads a file from disk, and calculates its corresponding CRC-32 value: Source Code: /* RxCRC32-Test: Calculate CRC-32 of Stored File * * * * (C) Mads Orbesen Troest & SIRIUS Cybernetics */ ARG FileName /* Get FileName on CommandLine */ IF FileName = "" THEN EXIT /* Exit if no FileName Specified */ /* Define a BufferSize for the blocks read from the File */ /* Do not set too low as this gives unnecessary calling-overhead! */ /* Set it after how much memory you are willing to spend on it... :-) */ BufferSize = 4096 /* Can't be that bad a size; could be bigger though .-) */ /* Load External RxCRC32 Routines: */ CALL RxFuncAdd "RxCRC32Ver", "RXCRC32", "RXCRC32VER" CALL RxFuncAdd "RxCRC32Init", "RXCRC32", "RXCRC32INIT" CALL RxFuncAdd "RxCRC32Done", "RXCRC32", "RXCRC32DONE" CALL RxFuncAdd "RxCRC32Update", "RXCRC32", "RXCRC32UPDATE" /* Do some initial chitchat: */ SAY "" SAY "RxCRC32-Test: Calculate CRC-32 of Stored File, utilising:" SAY RxCRC32Ver() /* Report Version Information */ SAY "" /* Initialize the variable CRC for as in CRC-calculation: */ CRC = RxCRC32Init() /* Calculate CRC-32 of File: */ DO UNTIL LENGTH( Buffer ) \= BufferSize /* Traverse File */ Buffer = CHARIN( FileName,, BufferSize ) /* Fill Buffer (there may be a faster way :-) */ CRC = RxCRC32Update( CRC, Buffer ) /* Update CRC with Buffer */ END /* Complete Calculation: */ CRC = RxCRC32Done( CRC ) /* Report the result: */ SAY "Well, then... CRC-32 : "CRC" (HEX) - Thanks for using RxCRC32 :-)" Screen Dump: WarpTek [d:\work\programming\cpp\rxcrc32.dll] FileCRC32.CMD FileCRC32.CMD RxCRC32-Test: Calculate CRC-32 of Stored File, utilising: RxCRC32 V1.00 - (C) Mads Orbesen Troest & SIRIUS Cybernetics Well, then... CRC-32 : 89BF3738 (HEX) - Thanks for using RxCRC32 :-)