=Unwritten, @=Currently Coding, !=Needs Testing, .=Done (Tested), r=Rewrite, ?=Review Public Interface . Append - Appends a new record to the end of the database. . Data - Sets or retrieves a record's data. . Debug_GetAll - Returns a string that contains the entire contents of the CDP. . Debug_SayAll - Displays the entire contents of the CDP on STDOUT . Debug_SayString - Used to display details about each character in a string. . Delete - Deletes a specified record from the database. . DeleteAll - Deletes all records in the database. . DeleteRecord - Deletes a specified record from the database. . Deserialize - Converts a BLOB containing a serialized database into a usable database. . FindData - Used to get the record number of a record containing specified data. . FindKey - Used to get the record number of a record containing a specified key. . RecordData - Sets or retrieves the data for a specified record (specified by record number). . RecordKey - Sets or retrieves the key for a specified record (specified by record number). . Serialize - Returns the entire database as a string (binary large object - BLOB). . SerializeSize - Used to determine the exact byte-size of the entire database when serialized. Private Services . _appendRecord - Used to append a new record to the database. . _asInteger_String_ASCII - Used to convert a string to a integer. . _deleteRecordByIndex - Deletes a specified record from the database. . _editRecordByIndex - Used to edit the key and data of a specified record. . _indexOfData - Used to determine the index of the first record containing specified data. . _indexOfKey - Used to determine the index of the first record containing a specified key. . _isDatabaseFull - Used to determine if the database contains the maximum number of records allowed. . _isValidIndex - Used to determine if a specified index is valid. . _trimData - Returns specified data trimmed to the maximum allowed length. . _trimKey - Returns a specified key trimmed to the maximum allowed length. Version History --------------- 1.0 6/30/2004 Tested by Russ Tanner *//////////////////////////////////////////////////////////////////////////////////////// // This is the class provided by this file class clsrtCDPJr { /////////////////////// // Private Variables // /////////////////////// //Purpose // Stores the maximum number of records allowed in the database. //Valid Values (Number) // 0 through 1,000,000,000. var $_cstMaxCount = 1000000000; //Purpose // This is the maximum length of any record's name. //Valid Values (Number) // 0 through 1,000. var $_cstMaxLength_Key = 1000; //Purpose // This is the maximum length of any record's data. //Valid Values (Number) // 0 through 1,000,000,000. var $_cstMaxLength_Data = 1000000000; //Purpose // This is the maximum allowed length of the database when serialized. //Valid Values (Number) // 20 through 1,000,000,000. var $_cstMaxSize = 1000000000; //Purpose // This is the main data table (DT). It's used to store records of the database. // Each element of the array contains a two-element array. // The first element of this array (0) is the name of the record. // The second element of this array (1) is the data the record contains. var $_DT = array(); /////////////////////////// // Property Declarations // /////////////////////////// //Purpose // Stores the number of records currently in the database. //Valid Values (Number) // 0 through 1,000,000,000. //var $_Count = 0; /////////////////////////// // Function Declarations // /////////////////////////// //Purpose // Constructor //Version History // 1.0 //--- function clsrtCDPJr() { } //Purpose // Used to append a new record to the database. //Parameters // Key (String) = The key assigned to the new record. // This value is trimmed to the maximum allowed length for a key. // If this value contains a zero-length string, a new record will be appended with a zero-length string as its key. // Data (String) = The new record's value. // This value is trimmed to the maximum allowed length for data. // If this value is zero-length, a new record containing no elements will be appended to the database. // NOTE: This behavior is different than the "Data" (let) property. //Return (Boolean) // Returns True if a record was successfully appended to the database. // Returns False if a record was not appended to the database. //Notes // If a record with the specified Key already exists, the new record will still be appended to the database. // The result is that 2 records will share the same Key name. // If the database is full (contains the maximum number of allowed records), no new record is appended. //Version History // 1.0 6/11/2004 Tested by Russ Tanner on PHP 4.3.2 function Append($Key, $Data) { // Trap: The database is full, cannot add another record, return False and exit now if ($this->_isDatabaseFull()) { return False; } // Append a new record to the database $this->_appendRecord($this->_trimKey($Key), $Data); // Success! Return True return True; } //Purpose // Used to append a new record to the database. //Parameters // Key (String) = The key to assign to the new record. // Data (Byte()) = The data to assign to the new record. //Notes // This function does not check to see if the database is full. // A new record will be appended even if the database currently contains the maximum number of allowed records. // This function trims the specified Key and Data to the maximum allowed length. //Version History // 1.0 6/10/2004 Tested by Russ Tanner on PHP 4.3.2 function _appendRecord($Key, $Data) { // Append a new blank record to the database $this->_DT[] = array(); // Update the record key and data $this->_DT[count($this->_DT) - 1][0] = $this->_trimKey($Key); $this->_DT[count($this->_DT) - 1][1] = $this->_trimData($Data); } //Purpose // Used to convert an ASCII String to an Integer. //Parameters // MyString (String) = The string to convert. // Default (Optional Integer) = The value to return if // the specified ASCII string is not convertable to an Integer. // This type is cast to an Integer using the (integer) command, so, if it enters as any type // other than an Integer, it is converted using standard PHP rules for (integer) casting. // Default value: 0 (zero) //Return (Integer) // Returns the specified string as an Integer. // If the specified string contains a decimal value, it is disregarded (no rounding takes place). // Function returns zero if: // - the specified string is zero-length, or // - the first character of the specified string is a decimal point (".123"), or // - the first two characters of the specified string are a minus sign and a decimal point ("-.123"), or // - the first two characters of the specified string are a plus sign and a decimal point ("+.123"), or // - all characters between a leading minus sign and a decimal point are zeros (-000.123), or // - all characters between a leading plus sign and a decimal point are zeros (+000.123). // Function returns the specified default value if: // - the value contains any characters other than "0123456789.+-" (whether before or after the decimal), or // - the value is less than -2,147,483,648, or // - the value is greater than 2,147,483,647, or // - the value contains more than one decimal point, or // - the value contains a minus sign (-) in any position other than the beginning, or // - the value contains a plus sign (+) in any position other than the beginning. // Additional considerations // There can be any number of leading zeros. // They are all ignored and will not affect the returned value. // Examples: 0000000000000123 = 123 // -00000000000000000000000123.456 = -123 // There can be any number of digits after the decimal. // They are all ignored and will not affect the returned value. // Example: 123.983983897438778432764328723487 = 123 // -123.000000000000000000000000000000000000005 = 123 //Notes // The specified string stores a string of ASCII characters representing an Integer. // This is an example of an "ASCII" Integer with a value of 12: // (0) 48 "0" (1) 48 "0" (2) 49 "1" (3) 50 "2" // Note that the LSB is the one with the highest index. //Version History // 1.0 6/30/2004 Tested by Russ Tanner on PHP 4.3.6 function _asInteger_String_ASCII($MyString, $Default = 0) { //Initiate variables $X = ''; // String buffer for returned Integer (before being converted to an Integer) // Set the default return value $RetDefault = (integer) $Default; // Get the length of the specified string $eCount = strlen($MyString); // Trap: The specified string is zero-length, this is a valid zero value, return zero and exit now if ($eCount == 0) { return (integer) 0; } // Main loop: Build a numeric string from the ASCII characters of the specified string for ($C = 0; $C < $eCount; $C++) { // Error Trap: The current character is invalid, return the default value and exit now if (strpos('0123456789.-+', substr($MyString, $C, 1)) === False) { return $RetDefault; } // Error Trap: The specified value contains more than one decimal point, return the default value and exit now if (substr($MyString, $C, 1) == '.' && strpos($X, '.') !== False) { return $RetDefault; } // Error Trap: The specified value contains a minus sign (-) within (not before) it, return the default value and exit now if (substr($MyString, $C, 1) == '-' && $C > 0) { return $RetDefault; } // Error Trap: The specified value contains a plus sign (+) within (not before) it, return the default value and exit now if (substr($MyString, $C, 1) == '+' && $C > 0) { return $RetDefault; } //The current character is valid, append it to the string accumulator $X = $X . substr($MyString, $C, 1); } // The specified value has a decimal, trim it off (no rounding takes place) if (strpos($X, '.') !== False) { $X = substr($X, 0, strpos($X, '.')); } // At this point, we know we have a series of (only) digits. // The series may or may not have a "+" or "-" prefix. // Remove all leading zeros from the string (excluding leading minus signs and plus signs)... // Get the sign of the sequence, if one exists $Y = ''; // String buffer for $X $FoundNZ = False; // Flag used to determine if a non-zero character has been found yet $eCount = strlen($X); // Get the length of the string now for ($C = 0; $C < $eCount; $C++) { // Get the current character we're looking at $cChar = substr($X, $C, 1); // The FoundNZ flag is set, always append the current character to the output buffer if ($FoundNZ == True) { $Y .= $cChar; } // The FoundNZ flag is not set else { // Current character is a non-zero digit or a sign (+/-) if (strpos('123456789+-', $cChar) !== False) { $Y .= $cChar; // Append it to the output buffer // Current character is a non-zero digit, set the FoundNZ flag if (strpos('123456789', $cChar) !== False) { $FoundNZ = True; } } } } $X = $Y; // Restore the data to the original buffer // Trap: The resulting string is either a zero-length string or only a minus sign or only a plus sign, // these all represent a valid zero value, return zero and exit now if (strlen($X) == 0 || $X == '-' || $X == '+') { return (integer) 0; } // Error Trap: The specified value is out of range, return the default value and exit now if (strlen($X) > 12) { return $RetDefault; } // Too many characters, value must be out of range (-N,NNN,NNN,NNN.) if ((float) $X < -2147483648 || (float) $X > 2147483647) { return $RetDefault; } // Value is out of range // Cast the specified number to an Integer and return the result return (integer) $X; } //Purpose // Used to determine the number of records currently in the database. //Returns (Integer) // Returns the number of records currently in the database. // Returns 0 (zero) if no records currently exist in the database. //Version History // 1.0 6/9/2004 Tested by Russ Tanner on PHP 4.3.2 //--- function Count() { return count($this->_DT); } //Purpose // Used to set or retrieve a record's data from the database. //Parameters // Key (String) = The key of the record we want to work with. // This value is trimmed to the maximum allowed length for a key. // Data (Optional String) = The data to assign to the record we're working with. // This value is trimmed to the maximum allowed length for Data. // If this value is omitted, this function returns the data of the specified record. // If this value is provided, this function sets the data of the specified record. // If this value is a zero-length string, this function deletes the record we're working with (if it exists). //Return (String (Get mode) Boolean (Set mode)) // If Data is omitted or passed as NULL, function operates in Get mode: // - Function returns the value associated with the record specified by Key. // - If the specified record (Key) is not found, function returns a zero-length string. // If Data is specified and not passed as NULL, function operates in Set mode: // - Function returns True if the specified record already exists. // - Function returns False if the specified record does not exist. //Notes // If multiple records exist with the specified key, this function works only with the first occuring one. //Version History // 1.0 6/13/2004 Tested by Russ Tanner on PHP 4.3.2 function Data($Key, $Data = NULL) { // Trim the specified key $Key = $this->_trimKey($Key); // Get the index of the record to work with $Index = $this->_indexOfKey($Key); // Vector to the correct code (Get/Set)... // Get mode if ($Data === NULL) { // Trap: The specified record was not found, return a zero-length string and exit now if ($Index == -1) { return ''; } // The specified record exists, return it's value return $this->_DT[$Index][1]; } // Set mode // Trim the specified data $Data = $this->_trimData($Data); // The specified record does not exist, we have to append a new record if ($Index == -1) { // Trap: The specified data is empty, don't append a new record, return False and exit now if ($Data == '') { return False; } // Trap: The database is full, cannot add another record, return False and exit now if ($this->_isDatabaseFull()) { return False; } // Append a new record to the data table $this->_appendRecord($Key, $Data); // All done, exit now. Return False because the record didn't already exist. return False; } // At this point we know that the specified record does exist // The specified data is empty, delete the specified record, return True (because the record exists) and exit now If ($Data == '') { $this->_deleteRecordByIndex($Index); return True; } // Edit the existing record in the database $this->_editRecordByIndex($Index, $Key, $Data); // Return True because the specified record exists return True; } //Purpose // Returns a string that contains the entire contents of the CDP. //Version History // 1.0 6/10/2004 Tested by Russ Tanner on PHP 4.3.2 function Debug_GetAll() { // Initiate variables $Msg = ''; // The message we're going to return // Get the record count to improve speed in the loop $RecCnt = $this->Count(); // Loop through all the records and assemble the message for ($C = 0; $C < $RecCnt; $C++){ // Append a newline if necessary if (strlen($Msg) > 0) $Msg .= "\n"; // Append the current record number $Msg .= sprintf('%0' . strlen($RecCnt -1) . 's ', $C); // Append the record's name and data $Msg .= $this->_DT[$C][0] . ':' . $this->_DT[$C][1]; } // Return the result return $Msg; } //Purpose // Displays the entire contents of the CDP on STDOUT. //Version History // 1.0 6/10/2004 Tested by Russ Tanner on PHP 4.3.2 function Debug_SayAll() { // Initiate variables $R = ''; // Return buffer // Append the record count $R .= 'Record Count: ' . $this->Count(); // Append the column header and divider $R .= "\n\n" . str_pad('', strlen($this->Count() - 1), '#') . " Key:Value\n---------------------------------------"; // Append all the record data $R .= "\n" . $this->Debug_GetAll(); // Display the data print $R; } //Purpose // Used to display details about each character in a string. //Parameters // MyString (String) = The string we're displaying information about. //Version History // 1.0 6/15/2004 Tested by Russ Tanner on PHP 4.3.2 function Debug_SayString($MyString) { // Get the length of the string $sLen = strlen($MyString); // Loop, displaying each character of the string on STDOUT for ($C = 0; $C < $sLen; $C++) { $X = substr($MyString, $C, 1); print sprintf('%0' . strlen($sLen - 1) . 's ', $C); // The display of the character is modifying, alter it's display to a space only if (9 == ord($X) || 10 == ord($X) || 13 == ord($X)) { print ' '; } // The display of the character is not modifying, just print it as is else { print substr($MyString, $C, 1); } // Now, print the ASCII value of the character print ' (' . ord(substr($MyString, $C, 1)) . ")\n"; } } //Purpose // Deletes a specified record from the database. //Parameters // Key (String) = The record to delete. // This value is trimmed to the maximum allowed length for a key. //Return (Boolean) // Returns True if the specified record was deleted. // Returns False of no matching records were found (or deleted). //Notes // If the specified record is not found, nothing changes. // If multiple records have the same key, only the first occuring one is deleted. //Version History // 1.0 6/14/2004 Tested by Russ Tanner on PHP 4.3.2 function Delete($Key) { // Trim the specified Key $Key = $this->_trimKey($Key); // Get the index number of the specified element $Index = $this->_indexOfKey($Key); // Trap: The specified record was not found, nothing changes, return False and exit now if (Index == -1) { return False; } // The specified data element does exist, delete it now $this->_deleteRecordByIndex($Index); // Success! Return True return True; } //Purpose // Removes all records from the database. //Version History // 1.0 6/14/2004 Tested by Russ Tanner on PHP 4.3.2 function DeleteAll() { $this->_DT = array(); //Make the Data Table an empty array } //Purpose // Deletes a specified record from the database using it's record number. //Parameters // Index (Long) = The record number of the record to delete. //Notes // If the specified record does not exist, nothing changes. //Version History // 1.0 6/14/2004 Tested by Russ Tanner on PHP 4.3.2 function DeleteRecord($Index) { // Trap: The specified record does not exist, nothing changes, exit now if (! $this->_isValidIndex($Index)) { return False; } // The specified record does exist, delete it now $this->_deleteRecordByIndex($Index); // Success! Return true. return True; } //Purpose // Deletes a specified record from the database. //Parameters // Index (Integer) = This is the index number of the record to delete. //Entry Conditions // The specified data element must exist or results are undefined. //Version History // 1.0 6/10/2004 Tested by Russ Tanner on PHP 4.3.2 function _deleteRecordByIndex($Index) { // Mark the element for deletion unset($this->_DT[$Index]); // Reindex the array $this->_DT = array_values($this->_DT); } //Purpose // Used to load a serialized database(a BLOB) into this object and prepare it for use. // If the function fails (returns any error code), no changes are made to the current database. //Parameters // BLOB (String) = The raw data to convert into this object's database. //Return (Integer) // Returns a status code indicating the success or failure of a conversion. // // Following are range values for codes: // ------------------------------------- // 1000 to 1999 // Indicates physical problems with the BLOB. // This includes: // - physical size problems, and // - data corruption. // 2000 to 2999 // Indicates errors related to the Package Size field. // 3000 to 3999 // Indicates errors related to the Record Count field. // 5000 to 5999 // Indicates errors related to the Data Table area. // // Code: "Official Message" and Explaination: // ---------- ------------------------------------ // 0 "OK" // The BLOB was successfully parsed and converted into a working database. // ---------- // 1000 "BLOB too small" // The BLOB is < 20 bytes long. // Every BLOB must be >= 20 bytes long to qualify as a valid database. // 1510 "Key Length field truncated (actual)" // The physical package is too small for a Key Length field to be parsed. // 1520 "Data Length field truncated (actual)" // The physical package is too small for a Data Length field to be parsed. // 1530 "Key field truncated (actual)" // The physical package is too small for a Key field to be parsed. // 1540 "Data field truncated (actual)" // The physical package is too small for a Data field to be parsed. // ---------- // 2000 "Package Size field corrupt" // The Package Size field cannot be converted to a numeric value. // 2010 "Package Size field too low" // The Package Size field contains a value that is lower than allowed. // This indicates that the value is < 20. // Every valid package contains a minimum of 20 bytes. // 2020 "Package Size field too high" // The Package Size field contains a value that is higher than allowed. // 2100 "Package Size field mismatch" // The Package Size field contains a value higher than the actual // physical size of the package. // NOTE: There is no test performed to see if the actual physical size of the // package is larger than this field indicates. This is by design and allows the // other data appended to the package to not interfere with the correct parsing // of the database. // 2510 "Key Length field truncated (stated)" // The stated package size is too small for a Key Length field to be parsed. // 2520 "Data Length field truncated (stated)" // The stated package size is too small for a Data Length field to be parsed. // 2530 "Key field truncated (stated)" // The stated package size is too small for a Key field to be parsed. // 2540 "Data field truncated (stated)" // The stated package size is too small for a Data field to be parsed. // ---------- // 3000 "Record Count field corrupt" // The Record Count field cannot be converted to a numeric value. // 3010 "Record Count field too low" // The Record Size field contains a value that is lower than allowed. // This indicates that the value is negative. // Zero is an acceptable value in this field. // 3020 "Record Count field too high" // The Record Count field contains a value that is higher than allowed. // ---------- // 5100 "Key Length field corrupt" // This field is not convertable to a number. // 5110 "Key Length field too low" // This field contains a negative value. Zero values are allowed. // 5120 "Key Length field too high" // This field contains a value that is higher than allowed. // 5200 "Data Length field corrupt" // This field is not convertable to a number. // 5210 "Data Length field too low" // This field contains a negative value. Zero values are allowed. // 5220 "Data Length field too high" // This field contains a value that is higher than allowed. //Notes // This function has been altered from the rtCDP object in that it allows a BLOB to be passed that contains // additional data following the BLOB that is to be parsed into a database. This allows the easy handling // of files that have a BLOB prepended to the beginning and other unrelated data following. //Version History // 1.0 6/30/2004 Tested by Russ Tanner on PHP 4.3.6 function Deserialize($BLOB) { // Initiate variables $tmpDT = array(); // Temporary data table $ErrFlag = -2147483648; // Value returned by _asInteger_String_ASCII() to flag an error // $Pointer - Points to the current position we are working with in pBLOB // $cKeyLength - The current Data Name field length // $cDataLength - The current Data Data field length // $pakSize - The stated (by the BLOB) byte-size of the package // $pakCount - The stated (by the BLOB) record count of the package // $C - Loop counter // Get the byte-size of the entire BLOB $ActualSize = strlen($BLOB); // Error Trap: "BLOB too small" if ($ActualSize < 20) { return (integer) 1000; } // Parse the Package Size field $Pointer = 0; $pakSize = $this->_asInteger_String_ASCII(substr($BLOB, $Pointer, 10), $ErrFlag); // Error Trap: "Package Size field corrupt" if ($pakSize == $ErrFlag) { return (integer) 2000; } // Error Trap: "Package Size field too low" if ($pakSize < 20) { return (integer) 2010; } // Error Trap: "Package Size field too high" if ($pakSize > $this->_cstMaxSize) { return (integer) 2020; } // Error Trap: "Package Size field mismatch" if ($pakSize > $ActualSize) { return (integer) 2100; } // Parse the Record Count field $Pointer = 10; $pakCount = $this->_asInteger_String_ASCII(substr($BLOB, $Pointer, 10), $ErrFlag); // Error Trap: "Record Count field corrupt" if ($pakCount == $ErrFlag) { return (integer) 3000; } // Error Trap: "Record Count field too low" if ($pakCount < 0) { return (integer) 3010; } // Error Trap: "Record Count field too high" if ($pakCount > $this->_cstMaxCount) { return (integer) 3020; } // Now, parse the Data Table... // Adjust the pointer to the start of the Data Table $Pointer = 20; // Loop for each data element for ($C = 0; $C < $pakCount; $C++) { // Append a blank record to the temporary data table $tmpDT[] = array(); // Get the Key Length field value for this record... // Error Trap: "Key Length field truncated (actual)" if ($ActualSize < $Pointer + 4) { return (integer) 1510; } // Error Trap: "Key Length field truncated (stated)" If ($pakSize < $Pointer + 4) { return (integer) 2510; } // Parse the Key Length field $cKeyLength = $this->_asInteger_String_ASCII(substr($BLOB, $Pointer, 4), $ErrFlag); // Error Trap: "Key Length field corrupt" If ($cKeyLength == $ErrFlag) { return (integer) 5100; } // Error Trap: "Key Length field too low" if ($cKeyLength < 0) { return (integer) 5110; } // Error Trap: "Key Length field too high" if ($cKeyLength > $this->_cstMaxLength_Key) { return (integer) 5120; } // Adjust the pointer to the beginning of the next field $Pointer += 4; // Get the Data Length field value for this record... // Error Trap: "Data Length field truncated (actual)" if ($ActualSize < $Pointer + 10) { return (integer) 1520; } // Error Trap: "Data Length field truncated (stated)" If ($pakSize < $Pointer + 10) { return (integer) 2520; } // Parse the Data Length field $cDataLength = $this->_asInteger_String_ASCII(substr($BLOB, $Pointer, 10), $ErrFlag); // Error Trap: "Data Length field corrupt" If ($cDataLength == $ErrFlag) { return (integer) 5200; } // Error Trap: "Data Length field too low" if ($cDataLength < 0) { return (integer) 5210; } // Error Trap: "Data Length field too high" if ($cDataLength > $this->_cstMaxLength_Data) { return (integer) 5220; } // Adjust the pointer to the beginning of the next field $Pointer += 10; // Get the Key field value for this record... // Error Trap: "Key field truncated (actual)" if ($ActualSize < $Pointer + $cKeyLength) { return (integer) 1530; } // Error Trap: "Key field truncated (stated)" If ($pakSize < $Pointer + $cKeyLength) { return (integer) 2530; } // Parse the Key field value and append it into the temporary data table $tmpDT[$C][0] = substr($BLOB, $Pointer, $cKeyLength); // Adjust the pointer to the beginning of the next field $Pointer += $cKeyLength; // Get the Data field value for this record... // Error Trap: "Data field truncated (actual)" if ($ActualSize < $Pointer + $cDataLength) { return (integer) 1540; } // Error Trap: "Data field truncated (stated)" if ($pakSize < $Pointer + $cDataLength) { return (integer) 2540; } // Parse the field value $tmpDT[$C][1] = substr($BLOB, $Pointer, $cDataLength); // Adjust the pointer to the beginning of the next field $Pointer += $cDataLength; } // Now all data has been parsed successfully, // complete the transaction by committing data to the module's data table $this->_DT = $tmpDT; // Function executed successfully, return OK code return (integer) 0; } //Purpose // Used to edit an existing record of the database. //Parameters // Index (Long) = The index of the record to edit. // This must be a valid index or this function will crash. // Key (Optional String) = The key to assign to the new record. // If omitted or NULL, the key of the specified record is unchanged. // Data (Optional String) = The data to assign to the record. // If omitted or NULL, the data of the specified record is unchanged. //Entry Conditions // The specified Index must be valid or nothing changes. //Notes // Key and Data lengths are not checked or trimmed. // They must be trimmed before calling this function. //Version History // 1.0 6/13/2004 Tested by Russ Tanner on PHP 4.3.2 function _editRecordByIndex($Index, $Key = NULL, $Data = NULL) { // Trap: Index is invalid, nothing changes, exit now // This has to be here because without it, PHP creates a new element in _DT // when the specified index is higher than the highest index in _DT. if (! $this->_isValidIndex($Index)) { return; } // The specified index is valid, edit the specified record if ($Key !== NULL) {$this->_DT[$Index][0] = $Key; } if ($Data !== NULL) {$this->_DT[$Index][1] = $Data; } } //Purpose // Used to get the record number of a specified record by it's data. //Parameters // Data (String) = The data of the record to search for. // This value is trimmed to the maximum allowed length for data. //Return (Long) // Returns the record number of the record containing the specified data. // If more than one record contains the specified data, // function returns the record number of the first occuring record containing the specified data. // If a matching record is not found, function returns -1. //Version History // 1.0 6/14/2004 Tested by Russ Tanner on PHP 4.3.2 function FindData($Data) { // Return the record number of the record containing the specified data return $this->_indexOfData($this->_trimData($Data)); } //Purpose // Used to get the record number of a specified record by it's key. //Parameters // Key (String) = The Key of the record to search for. // This value is trimmed to the maximum allowed length for a key. //Return (Long) // Returns the record number of the record containing the specified data. // If more than one record contains the specified key, // function returns the record number of the first occuring record containing the specified key. // If a matching record is not found, function returns -1. //Version History // 1.0 6/14/2004 Tested by Russ Tanner on PHP 4.3.2 function FindKey($Key) { // Return the record number of the record containing the specified key return $this->_indexOfKey($this->_trimData($Key)); } //Purpose // Used to determine the index of the first record containing specified data. //Return (Integer) // Returns the index number of the first record containing the specified data. // If a matching record is not found, returns -1. //Parameters // Data (String) = The data of the record to search for. // This data is not trimmed. It must be preprocessed before entering this function. //Version History // 1.0 6/14/2004 Tested by Russ Tanner on PHP 4.3.2 function _indexOfData($Data) { // Get the record count to speed up the loop $RecCnt = $this->Count(); // Main loop For ($C = 0; $C < $RecCnt; $C++) { // Match found, return the index and exit now If ($Data == $this->_DT[$C][1]) { return $C; } } // No matching record was found, return -1 return -1; } //Purpose // Used to determine the index of the first record containing a specified key. //Return (Integer) // Returns the index number of the first record containing the specified key. // If a matching record is not found, returns -1. //Parameters // Key (String) = The key of the record to search for. // This key is not trimmed. It must be preprocessed before entering this function. //Version History // 1.0 6/11/2004 Tested by Russ Tanner on PHP 4.3.2 function _indexOfKey($Key) { // Get the record count to speed up the loop $RecCnt = $this->Count(); // Main loop For ($C = 0; $C < $RecCnt; $C++) { // Match found, return the index and exit now If ($Key == $this->_DT[$C][0]) { return $C; } } // No matching record was found, return -1 return -1; } //Purpose // Used to determine if the database currently contains the maximum number of records allowed. //Return (Boolean) // Returns True if the database currently contains the maximum number of records allowed. // Returns False otherwise. //Version History // 1.0 6/11/2004 Tested by Russ Tanner on PHP 4.3.2 Function _isDatabaseFull() { return count($this->_DT) == $this->_cstMaxCount ? True : False; } //Purpose // Used to determine if a specified index is valid. // A valid index is one which currently exists in the data table. //Parameters // Index (Long) = The index we're testing. //Return (Boolean) // Returns True if the specified index is valid (currently exists in the data table). // Returns False if the specified index is not valid. //Version History // 1.0 6/14/2004 Tested by Russ Tanner on PHP 4.3.2 function _isValidIndex($Index) { return $Index < 0 || $Index > $this->Count() - 1 ? False : True; } //Purpose // Used to get or retrieve the data of a specified record. //Parameters // Index (Long) = The index of the record we're working with. // Data (Optional String) = The data to assign to the record we're working with. // This value is trimmed to the maximum allowed length for Data. // If this value is omitted, this function returns the data of the specified record. // If this value is provided, this function sets the data of the specified record. // If this value is a zero-length string, this function sets the data of the specified record // to a zero-length string (if it exists). //Return (String (Get mode) Boolean (Set mode)) // If Data is omitted or passed as NULL, function operates in Get mode: // - Function returns the value associated with the record specified by Index. // - If the specified record (Index) is not found, function returns a zero-length string. // If Data is specified and not passed as NULL, function operates in Set mode: // - Function returns True if the specified index is valid. // - Function returns False if the specified index is not valid. //Version History // 1.0 6/14/2004 Tested by Russ Tanner on PHP 4.3.2 function RecordData($Index, $Data = NULL) { // Vector to the correct code (Get/Set)... // Get mode if ($Data === NULL) { // Trap: The specified index is not valid, return a zero-length string and exit now If (! $this->_isValidIndex($Index)) { return ''; } // The specified record exists, return it's data return $this->_DT[$Index][1]; } // Set mode // Trap: The specified index is not valid, return False and exit now If (! $this->_isValidIndex($Index)) { return False; } // Edit the existing record in the database $this->_editRecordByIndex($Index, NULL, $this->_trimData($Data)); // Return True because the specified record exists return True; } //Purpose // Used to get or retrieve the key of a specified record. //Parameters // Index (Long) = The index of the record we're working with. // Key (Optional String) = The key to assign to the record we're working with. // This value is trimmed to the maximum allowed length for Key. // If this value is omitted, this function returns the key of the specified record. // If this value is provided, this function sets the key of the specified record. // If this value is a zero-length string, this function sets the key of the specified record // to a zero-length string (if it exists). //Return (String (Get mode) Boolean (Set mode)) // If Key is omitted or passed as NULL, function operates in Get mode: // - Function returns the key associated with the record specified by Index. // - If the specified record (Index) is not found, function returns a zero-length string. // If Key is specified and not passed as NULL, function operates in Set mode: // - Function returns True if the specified index is valid. // - Function returns False if the specified index is not valid. //Version History // 1.0 6/14/2004 Tested by Russ Tanner on PHP 4.3.2 function RecordKey($Index, $Key = NULL) { // Vector to the correct code (Get/Set)... // Get mode if ($Key === NULL) { // Trap: The specified index is not valid, return a zero-length string and exit now If (! $this->_isValidIndex($Index)) { return ''; } // The specified record exists, return it's key return $this->_DT[$Index][0]; } // Set mode // Trap: The specified index is not valid, return False and exit now If (! $this->_isValidIndex($Index)) { return False; } // Edit the existing record in the database $this->_editRecordByIndex($Index, $this->_trimKey($Key), NULL); // Return True because the specified record exists return True; } //Purpose // Returns the entire database as a byte array. //Return (String) // Returns the entire database in a form that can be recreated by the Deserialize function. //Version History // 1.0 6/30/2004 Tested by Russ Tanner on PHP 4.3.6 function Serialize() { // Get the number of records in the database $RecCnt = $this->Count(); // Assemble the PackageLength field $R = sprintf('%010s', $this->SerializeSize()); // Assemble the DataElementCount field $R .= sprintf('%010s', $RecCnt); // Now, assemble the Data Table... // Loop through all elements in the Data Table for ($C = 0; $C < $RecCnt; $C++) { // Assemble the Data Element Name Length $R .= sprintf('%04s', strlen($this->_DT[$C][0])); // Assemble the Data Element Data Length $R .= sprintf('%010s', strlen($this->_DT[$C][1])); // Assemble the Data Element Name $R .= $this->_DT[$C][0]; // Assemble the Data $R .= $this->_DT[$C][1]; } // Return the entire package return $R; } //Purpose // Used to determine the exact byte-size of the entire database when serialized. //Return (Long) // Returns the exact byte-size of the entire database when serialized. //Version History // 1.0 6/14/2004 Tested by Russ Tanner on PHP 4.3.2 function SerializeSize() { // Initiate variables $RecCnt = $this->Count(); // Number of recored in the database; Used to speed up the For loop $R = 20; // Return buffer; Every package has 20 bytes at the beginning: Byte Length (10) and Record Count (10) // Loop through all the Data Table elements for ($C = 0; $C < $RecCnt; $C++) { // Add 14 bytes for the Name Length field (4) and the Data Length field (10) $R += 14; // Add the length of the Name and Data fields $R += strlen($this->_DT[$C][0]); $R += strlen($this->_DT[$C][1]); } // Return the calculated amount return $R; } //Purpose // Used to trim a key to the maximum allowed length. //Parameters // Key (String) = The key we're working with. //Return (String) // Returns the specified key trimmed to the maximum allowed length. // If the specified key is already shorter than the maximum allowed length, then Key is returned unchanged. //Version History // 1.0 6/11/2004 Tested by Russ Tanner on PHP 4.3.2 function _trimKey($Key) { return substr($Key, 0, $this->_cstMaxLength_Key); } //Purpose // Used to trim data to the maximum allowed length. //Parameters // Data (String) = The data we're working with. //Return (String) // Returns the specified data trimmed to the maximum allowed length. // If the specified data is already shorter than the maximum allowed length, then Data is returned unchanged. //Version History // 1.0 6/11/2004 Tested by Russ Tanner on PHP 4.3.2 function _trimData($Data) { return substr($Data, 0, $this->_cstMaxLength_Data); } } // End of class definition ?>