TypeID = $Type;
$this->CreatorID = $Creator;
$this->Name = $Name;
$this->CreationTime = time();
$this->ModificationTime = time();
}
/*
* Data manipulation functions
*
* These convert various numbers and strings into the hexadecimal
* format that is used internally to construct the file. We use hex
* encoded strings since that is a lot easier to work with than binary
* data in strings, and we can easily tell how big the true value is.
* B64 encoding does some odd stuff, so we just make the memory
* consumption grow tremendously and the complexity level drops
* considerably.
*/
// Converts a byte and returns the value
function Int8($value) {
$value &= 0xFF;
return sprintf("%02x", $value);
}
// Loads a single byte as a number from the file
// Use if you want to make your own ReadFile function
function LoadInt8($file) {
if (is_resource($file))
$string = fread($file, 1);
else
$string = $file;
return ord($string[0]);
}
// Converts an integer (two bytes) and returns the value
function Int16($value) {
$value &= 0xFFFF;
return sprintf("%02x%02x", $value / 256, $value % 256);
}
// Loads two bytes as a number from the file
// Use if you want to make your own ReadFile function
function LoadInt16($file) {
if (is_resource($file))
$string = fread($file, 2);
else
$string = $file;
return ord($string[0]) * 256 + ord($string[1]);
}
// Converts an integer (three bytes) and returns the value
function Int24($value) {
$value &= 0xFFFFFF;
return sprintf("%02x%02x%02x", $value / 65536,
($value / 256) % 256, $value % 256);
}
// Loads three bytes as a number from the file
// Use if you want to make your own ReadFile function
function LoadInt24($file) {
if (is_resource($file))
$string = fread($file, 3);
else
$string = $file;
return ord($string[0]) * 65536 + ord($string[1]) * 256 +
ord($string[2]);
}
// Converts an integer (four bytes) and returns the value
// 32-bit integers have problems with PHP when they are bigger than
// 0x80000000 (about 2 billion) and that's why I don't use pack() here
function Int32($value) {
$negative = false;
if ($value < 0) {
$negative = true;
$value = - $value;
}
$big = $value / 65536;
settype($big, 'integer');
$little = $value - ($big * 65536);
if ($negative) {
// Little must contain a value
$little = - $little;
// Big might be zero, and should be 0xFFFF if that is the case.
$big = 0xFFFF - $big;
}
$value = PalmDB::Int16($big) . PalmDB::Int16($little);
return $value;
}
// Loads a four-byte string from a file into a number
// Use if you want to make your own ReadFile function
function LoadInt32($file) {
if (is_resource($file))
$string = fread($file, 4);
else
$string = $file;
$value = 0;
$i = 0;
while ($i < 4) {
$value *= 256;
$value += ord($string[$i]);
$i ++;
}
return $value;
}
// Converts the number into a double and returns the encoded value
// Not sure if this will work on all platforms.
// Double(10.53) should return "40250f5c28f5c28f"
function Double($value) {
if ($this->DoubleMethod == PDB_DOUBLEMETHOD_UNTESTED) {
$val = bin2hex(pack('d', 10.53));
$val = strtolower($val);
if (substr($val, 0, 4) == '8fc2')
$this->DoubleMethod = PDB_DOUBLEMETHOD_REVERSE;
if (substr($val, 0, 4) == '4025')
$this->DoubleMethod = PDB_DOUBLEMETHOD_NORMAL;
if ($this->DoubleMethod == PDB_DOUBLEMETHOD_UNTESTED)
$this->DoubleMethod = PDB_DOUBLEMETHOD_BROKEN;
}
if ($this->DoubleMethod == PDB_DOUBLEMETHOD_BROKEN)
return '0000000000000000';
$value = bin2hex(pack('d', $value));
if ($this->DoubleMethod == PDB_DOUBLEMETHOD_REVERSE)
$value = substr($value, 14, 2) . substr($value, 12, 2) .
substr($value, 10, 2) . substr($value, 8, 2) .
substr($value, 6, 2) . substr($value, 4, 2) .
substr($value, 2, 2) . substr($value, 0, 2);
return $value;
}
// The reverse? Not coded yet.
// Use if you want to make your own ReadFile function
function LoadDouble($file) {
if (is_resource($file))
$string = fread($file, 8);
else
$string = $file;
return 0;
}
// Converts a string into hexadecimal.
// If $maxLen is specified and is greater than zero, the string is
// trimmed and will contain up to $maxLen characters.
// String("abcd", 2) will return "ab" hex encoded (a total of 4
// resulting bytes, but 2 encoded characters).
// Returned string is *not* NULL-terminated.
function String($value, $maxLen = false) {
$value = bin2hex($value);
if ($maxLen !== false && $maxLen > 0)
$value = substr($value, 0, $maxLen * 2);
return $value;
}
// Pads a hex-encoded value (typically a string) to a fixed size.
// May grow too long if $value starts too long
// $value = hex encoded value
// $minLen = Append nulls to $value until it reaches $minLen
// $minLen is the desired size of the string, unencoded.
// PadString('6162', 3) results in '616200' (remember the hex encoding)
function PadString($value, $minLen) {
$PadBytes = '00000000000000000000000000000000';
$PadMe = $minLen - (strlen($value) / 2);
while ($PadMe > 0) {
if ($PadMe > 16)
$value .= $PadBytes;
else
return $value . substr($PadBytes, 0, $PadMe * 2);
$PadMe = $minLen - (strlen($value) / 2);
}
return $value;
}
/*
* Record manipulation functions
*/
// Sets the current record pointer to the new record number if an
// argument is passed in.
// Returns the old record number (just in case you want to jump back)
// Does not do basic record initialization if we are going to a new
// record.
function GoToRecord($num = false) {
if ($num === false)
return $this->CurrentRecord;
if (gettype($num) == 'string' && ($num[0] == '+' || $num[0] == '-'))
$num = $this->CurrentRecord + $num;
$oldRecord = $this->CurrentRecord;
$this->CurrentRecord = $num;
return $oldRecord;
}
// Returns the size of the current record if no arguments.
// Returns the size of the specified record if arguments.
function GetRecordSize($num = false) {
if ($num === false)
$num = $this->CurrentRecord;
if (! isset($this->Records[$num]))
return 0;
return strlen($this->Records[$num]) / 2;
}
// Adds to the current record. The input data must be already
// hex encoded. Initializes the record if it doesn't exist.
function AppendCurrent($value) {
if (! isset($this->Records[$this->CurrentRecord]))
$this->Records[$this->CurrentRecord] = '';
$this->Records[$this->CurrentRecord] .= $value;
}
// Adds a byte to the current record
function AppendInt8($value) {
$this->AppendCurrent($this->Int8($value));
}
// Adds an integer (2 bytes) to the current record
function AppendInt16($value) {
$this->AppendCurrent($this->Int16($value));
}
// Adds an integer (4 bytes) to the current record
function AppendInt32($value) {
$this->AppendCurrent($this->Int32($value));
}
// Adds a double to the current record
function AppendDouble($value) {
$this->AppendCurrent($this->Double($value));
}
// Adds a string (not NULL-terminated)
function AppendString($value, $maxLen = false) {
$this->AppendCurrent($this->String($value, $maxLen));
}
// Returns true if the specified/current record exists and is set
function RecordExists($Rec = false) {
if ($Rec === false)
$Rec = $this->CurrentRecord;
if (isset($this->Records[$Rec]))
return true;
return false;
}
// Returns the hex-encoded data for the specified record or the current
// record if not specified
// This is nearly identical to GetRecordRaw except that this function
// may be overridden by classes (see modules/doc.inc) and that there
// should always be a function that will return the raw data of the
// Records array.
function GetRecordAttr($Rec = false) {
if ($Rec === false)
$Rec = $this->CurrentRecord;
if (isset($this->RecordAttrs[$Rec])) {
return $this->RecordAttrs[$Rec];
}
return '';
}
function CleanRecord($Rec = false) {
if ($Rec === false)
$Rec = $this->CurrentRecord;
if (isset($this->RecordAttrs[$Rec])) {
$this->RecordAttrs[$Rec] = $this->RecordAttrs[$Rec] & !PDB_RECORD_ATTRIB_DIRTY;
}
return '';
}
function GetRecord($Rec = false) {
if ($Rec === false)
$Rec = $this->CurrentRecord;
if (isset($this->Records[$Rec]))
return $this->Records[$Rec];
return '';
}
// Returns the raw data inside the current/specified record. Use this
// for odd record types (like a Datebook record). Also, use this
// instead of just using $PDB->Records[] directly.
// Please do not override this function.
function GetRecordRaw($Rec = false) {
if ($Rec === false)
$Rec = $this->CurrentRecord;
if (isset($this->Records[$Rec]))
return $this->Records[$Rec];
return false;
}
// Sets the hex-encoded data (or whatever) for the current record
// Use this instead of the Append* functions if you have an odd
// type of record (like a Datebook record).
// Also, use this instead of just setting $PDB->Records[]
// directly.
// SetRecordRaw('data');
// SetRecordRaw(24, 'data'); (specifying the record num)
function SetRecordRaw($A, $B = false, $C = 0) {
if ($B === false) {
$B = $A;
$A = $this->CurrentRecord;
}
$this->Records[$A] = $B;
$this->RecordAttrs[$A] = $C;
}
// Deletes the current record
// You are urged to use GoToRecord() and jump to an existing record
// after this function call so that the deleted record doesn't
// get accidentally recreated/used -- all append functions will
// create a new, empty record if the current record doesn't exist.
function DeleteCurrentRecord() {
if (isset($this->Records[$this->CurrentRecord]))
unset($this->Records[$this->CurrentRecord]);
if (isset($this->RecordAttrs[$this->CurrentRecord]))
unset($this->RecordAttrs[$this->CurrentRecord]);
}
// Deletes the record
// And sets current record to 0
// You are urged to use GoToRecord() and jump to an existing record
// after this function call so that the deleted record doesn't
// get accidentally recreated/used -- all append functions will
// create a new, empty record if the current record doesn't exist.
function DeleteRecord($Rec = false) {
if ($Rec === false)
$Rec = $this->CurrentRecord;
if (isset($this->Records[$Rec]))
unset($this->Records[$Rec]);
if (isset($this->RecordAttrs[$Rec]))
unset($this->RecordAttrs[$Rec]);
$this->GoToRecord(0);
}
// Returns an array of available record IDs in the order they should
// be written.
// Probably should only be called within the class.
function GetRecordIDs() {
$keys = array_keys($this->Records);
if (! is_array($keys) || count($keys) < 1)
return array();
sort($keys, SORT_NUMERIC);
return $keys;
}
// Returns the number of records. This should match the number of
// keys returned by GetRecordIDs().
function GetRecordCount() {
return count($this->Records);
}
// Returns the size of the AppInfo block.
// Used only for writing
function GetAppInfoSize() {
if (! isset($this->AppInfo))
return 0;
return strlen($this->AppInfo) / 2;
}
// Returns the AppInfo block (hex encoded)
// Used only for writing
function GetAppInfo() {
if (! isset($this->AppInfo))
return 0;
return $this->AppInfo;
}
// Returns the size of the SortInfo block
// Used only for writing
function GetSortInfoSize() {
if (! isset($this->SortInfo))
return 0;
return strlen($this->SortInfo) / 2;
}
// Returns the SortInfo block (hex encoded)
// Used only for writing
function GetSortInfo() {
if (! isset($this->SortInfo))
return 0;
return $this->SortInfo;
}
/*
* Category Support
*/
// Creates the hex-encoded data to be stuck in the AppInfo
// block if the database supports categories.
//
// Data format:
// $categoryArray[id#] = name
// Or:
// $categoryArray[id#]['name'] = name
// $categoryArray[id#]['renamed'] = true / false
//
// Tips:
// * I'd suggest numbering your categories sequentially
// * Do not have a category 0. It must always be 'Unfiled'. This
// function will overwrite any category with the ID of 0.
// * There is a maximum of 16 categories, including 'Unfiled'.
//
// Category 0 is reserved for 'Unfiled'
// Categories 1-127 are used for handheld ID numbers
// Categories 128-255 are used for desktop ID numbers
// Do not let category numbers be created larger than 255
function CreateCategoryData($CategoryArray) {
$CategoryArray[0] = array('Name' => 'Unfiled', 'Renamed' => false);
$CatsWritten = 0;
$LastIdWritten = 0;
$RenamedFlags = 0;
$CategoryStr = '';
$IdStr = '';
$keys = array_keys($CategoryArray);
sort($keys);
foreach ($keys as $id) {
if ($CatsWritten < PDB_CATEGORY_NUM) {
$CatsWritten ++;
$LastIdWritten = $id;
$RenamedFlags *= 2;
if (is_array($CategoryArray[$id]) &&
isset($CategoryArray[$id]['Renamed']) &&
$CategoryArray[$id]['Renamed'])
$RenamedFlags += 1;
$name = '';
if (is_array($CategoryArray[$id])) {
if (isset($CategoryArray[$id]['Name']))
$name = $CategoryArray[$id]['Name'];
} else
$name = $CategoryArray[$id];
$name = $this->String($name, PDB_CATEGORY_NAME_LENGTH);
$CategoryStr .= $this->PadString($name,
PDB_CATEGORY_NAME_LENGTH);
$IdStr .= $this->Int8($id);
}
}
while ($CatsWritten < PDB_CATEGORY_NUM) {
$CatsWritten ++;
$LastIdWritten ++;
$RenamedFlags *= 2;
$CategoryStr .= $this->PadString('', PDB_CATEGORY_NAME_LENGTH);
$IdStr .= $this->Int8($LastIdWritten);
}
$TrailingBytes = $this->Int8($LastIdWritten);
$TrailingBytes .= $this->Int8(0);
// Error checking
if ($LastIdWritten >= 256)
return $this->PadString('', PDB_CATEGORY_SIZE);
return $this->Int16($RenamedFlags) . $CategoryStr . $IdStr .
$TrailingBytes;
}
// This should be called by other subclasses that use category support
// It returns a category array. Each element in the array is another
// array with the key 'name' set to the name of the category and
// the key 'renamed' set to the renamed flag for that category.
function LoadCategoryData($fileData) {
$RenamedFlags = $this->LoadInt16(substr($fileData, 0, 2));
$Offset = 2;
$StartingFlag = 65536;
$Categories = array();
while ($StartingFlag > 1) {
$StartingFlag /= 2;
$Name = substr($fileData, $Offset, PDB_CATEGORY_NAME_LENGTH);
$i = 0;
while ($i < PDB_CATEGORY_NAME_LENGTH && $Name[$i] != "\0")
$i ++;
if ($i == 0)
$Name = '';
elseif ($i < PDB_CATEGORY_NAME_LENGTH)
$Name = substr($Name, 0, $i);
if ($RenamedFlags & $StartingFlag)
$RenamedFlag = true;
else
$RenamedFlag = false;
$Categories[] = array('Name' => $Name, 'Renamed' => $RenamedFlag);
$Offset += PDB_CATEGORY_NAME_LENGTH;
}
$CategoriesParsed = array();
foreach ($Categories as $CategoryData) {
$UID = $this->LoadInt8(substr($fileData, $Offset, 1));
$Offset ++;
if ($CategoryData['Name'] != '')
$CategoriesParsed[$UID] = $CategoryData;
}
// Ignore the last ID
return $CategoriesParsed;
}
/*
* Database Writing Functions
*/
// *NEW*
// Takes a hex-encoded string and makes sure that when decoded, the data
// lies on a four-byte boundary. If it doesn't, it pads the string with
// NULLs
/*
* Commented out because we don't use this function currently.
* It is part of a test to see what is needed to get files to sync
* properly with Desktop 4.0
*
function PadTo4ByteBoundary($string) {
while ((strlen($string)/2) % 4) {
$string .= '00';
}
return $string;
}
*
*/
// Returns the hex encoded header of the pdb file
// Header = name, attributes, version, creation/modification/backup
// dates, modification number, some offsets, record offsets,
// record attributes, appinfo block, sortinfo block
// Shouldn't be called from outside the class
function MakeHeader() {
// 32 bytes = name, but only 31 available (one for null)
$header = $this->String($this->Name, 31);
$header = $this->PadString($header, 32);
// Attributes & version fields
$header .= $this->Int16($this->Attributes);
$header .= $this->Int16($this->Version);
// Creation, modification, and backup date
if ($this->CreationTime != 0)
$header .= $this->Int32($this->CreationTime + PDB_EPOCH_1904);
else
$header .= $this->Int32(time() + PDB_EPOCH_1904);
if ($this->ModificationTime != 0)
$header .= $this->Int32($this->ModificationTime + PDB_EPOCH_1904);
else
$header .= $this->Int32(time() + PDB_EPOCH_1904);
if ($this->BackupTime != 0)
$header .= $this->Int32($this->BackupTime + PDB_EPOCH_1904);
else
$header .= $this->Int32(0);
// Calculate the initial offset
$Offset = PDB_HEADER_SIZE + PDB_INDEX_HEADER_SIZE;
$Offset += PDB_RECORD_HEADER_SIZE * count($this->GetRecordIDs());
// Modification number, app information id, sort information id
$header .= $this->Int32($this->ModNumber);
$AppInfo_Size = $this->GetAppInfoSize();
if ($AppInfo_Size > 0) {
$header .= $this->Int32($Offset);
$Offset += $AppInfo_Size;
} else
$header .= $this->Int32(0);
$SortInfo_Size = $this->GetSortInfoSize();
if ($SortInfo_Size > 0) {
$header .= $this->Int32($Offset);
$Offset += $SortInfo_Size;
} else
$header .= $this->Int32(0);
// Type, creator
$header .= $this->String($this->TypeID, 4);
$header .= $this->String($this->CreatorID, 4);
// Unique ID seed
$header .= $this->Int32(0);
// next record list
$header .= $this->Int32(0);
// Number of records
$header .= $this->Int16($this->GetRecordCount());
// Compensate for the extra 2 NULL characters in the $Offset
$Offset += 2;
// Dump each record
if ($this->GetRecordCount() != 0) {
$keys = $this->GetRecordIDs();
sort($keys, SORT_NUMERIC);
foreach ($keys as $index) {
$header .= $this->Int32($Offset);
if (isset($this->RecordAttrs[$index]))
$header .= $this->Int8($this->RecordAttrs[$index]);
else
$header .= $this->Int8(0);
// The unique id is just going to be the record number
$header .= $this->Int24($index);
$Offset += $this->GetRecordSize($index);
// *new* method 3
//$Mod4 = $Offset % 4;
//if ($Mod4)
// $Offset += 4 - $Mod4;
}
}
// AppInfo and SortInfo blocks go here
if ($AppInfo_Size > 0)
// *new* method 1
$header .= $this->GetAppInfo();
//$header .= $this->PadTo4ByteBoundary($this->GetAppInfo());
if ($SortInfo_Size > 0)
// *new* method 2
$header .= $this->GetSortInfo();
//$header .= $this->PadTo4ByteBoundary($this->GetSortInfo());
// These are the mysterious two NULL characters that we need
$header .= $this->Int16(0);
return $header;
}
// Writes the database to the file handle specified.
// Use this function like this:
// $file = fopen("output.pdb", "wb");
// // "wb" = write binary for non-Unix systems
// if (! $file) {
// echo "big problem -- can't open file";
// exit;
// }
// $pdb->WriteToFile($file);
// fclose($file);
function WriteToFile($file) {
$header = $this->MakeHeader();
fwrite($file, pack('H*', $header), strlen($header) / 2);
$keys = $this->GetRecordIDs();
sort($keys, SORT_NUMERIC);
foreach ($keys as $index) {
// *new* method 3
//$data = $this->PadTo4ByteBoundary($this->GetRecord($index));
$data = $this->GetRecordRaw($index);
//echo $data . '
';
fwrite($file, pack('H*', $data), strlen($data) / 2);
}
fflush($file);
}
// Writes the database to the standard output (like echo).
// Can be trapped with output buffering
function WriteToStdout() {
// You'd think these three lines would work.
// If someone can figure out why they don't, please tell me.
//
// $fp = fopen('php://stdout', 'wb');
// $this->WriteToFile($fp);
// fclose($fp);
$header = $this->MakeHeader();
echo pack("H*", $header);
$keys = $this->GetRecordIDs();
sort($keys, SORT_NUMERIC);
foreach ($keys as $index) {
// *new* method 3
$data = $this->GetRecord($index);
//$data = $this->PadTo4ByteBoundary($this->GetRecord($index));
echo pack("H*", $data);
}
}
// Writes the database to the standard output (like echo) but also
// writes some headers so that the browser should prompt to save the
// file properly.
//
// Use this only if you didn't send any content and you only want the
// PHP script to output the PDB file and nothing else. An example
// would be if you wanted to have 'download' link so the user can
// stick the information they are currently viewing and transfer
// it easily into their handheld.
//
// $filename is the desired filename to download the database as.
// For example, DownloadPDB('memos.pdb');
function DownloadPDB($filename) {
global $HTTP_USER_AGENT;
// Alter the filename to only allow certain characters.
// Some platforms and some browsers don't respond well if
// there are illegal characters (such as spaces) in the name of
// the file being downloaded.
$filename = preg_replace('/[^-a-zA-Z0-9\\.]/', '_', $filename);
if (strstr($HTTP_USER_AGENT, 'compatible; MSIE ') !== false &&
strstr($HTTP_USER_AGENT, 'Opera') === false) {
// IE doesn't properly download attachments. This should work
// pretty well for IE 5.5 SP 1
header("Content-Disposition: inline; filename=$filename");
header("Content-Type: application/download; name=\"$filename\"");
} else {
// Use standard headers for Netscape, Opera, etc.
header("Content-Disposition: attachment; filename=\"$filename\"");
header("Content-Type: application/x-pilot; name=\"$filename\"");
}
$this->WriteToStdout();
}
/*
* Loading in a database
*/
// Reads data from the file and tries to load it properly
// $file is the already-opened file handle.
// Returns false if no error
function ReadFile($file, $headeronly=0) {
// 32 bytes = name, but only 31 available
$this->Name = fread($file, 32);
$i = 0;
while ($i < 32 && $this->Name[$i] != "\0")
$i ++;
$this->Name = substr($this->Name, 0, $i);
$this->Attributes = $this->LoadInt16($file);
$this->Version = $this->LoadInt16($file);
$this->CreationTime = $this->LoadInt32($file);
if ($this->CreationTime != 0)
$this->CreationTime -= PDB_EPOCH_1904;
if ($this->CreationTime < 0)
$this->CreationTime = 0;
$this->ModificationTime = $this->LoadInt32($file);
if ($this->ModificationTime != 0)
$this->ModificationTime -= PDB_EPOCH_1904;
if ($this->ModificationTime < 0)
$this->ModificationTime = 0;
$this->BackupTime = $this->LoadInt32($file);
if ($this->BackupTime != 0)
$this->BackupTime -= PDB_EPOCH_1904;
if ($this->BackupTime < 0)
$this->BackupTime = 0;
// Modification number
$this->ModNumber = $this->LoadInt32($file);
// AppInfo and SortInfo size
$AppInfoOffset = $this->LoadInt32($file);
$SortInfoOffset = $this->LoadInt32($file);
// Type, creator
$this->TypeID = fread($file, 4);
$this->CreatorID = fread($file, 4);
// Skip unique ID seed
fread($file, 4);
// skip next record list (hope that's ok)
fread($file, 4);
$RecCount = $this->LoadInt16($file);
$RecordData = array();
while ($RecCount > 0) {
$RecCount --;
$Offset = $this->LoadInt32($file);
$Attrs = $this->LoadInt8($file);
$UID = $this->LoadInt24($file);
if($headeronly!=0) { // laduje tylko artybuty, nic wiêcej
$this->Records[$UID] = '';
$this->RecordAttrs[$UID] = $Attrs;
} else {
$RecordData[] = array('Offset' => $Offset, 'Attrs' => $Attrs,
'UID' => $UID);
}
}
if($headeronly!=0)
return false;
// Create the offset list
if ($AppInfoOffset != 0)
$OffsetList[$AppInfoOffset] = 'AppInfo';
if ($SortInfoOffset != 0)
$OffsetList[$SortInfoOffset] = 'SortInfo';
foreach ($RecordData as $data) {
$OffsetList[$data['Offset']] = array('Record', $data);
// echo $OffsetList[$data['Offset']][0] . ' ' .$OffsetList[$data['Offset']][1] . '
';
}
fseek($file, 0, SEEK_END);
$OffsetList[ftell($file)] = 'EOF';
// Parse each chunk
ksort($OffsetList);
$Offsets = array_keys($OffsetList);
while (count($Offsets) > 1) {
// Don't use the EOF (which should be the last offset)
$ThisOffset = $Offsets[0];
$NextOffset = $Offsets[1];
if ($OffsetList[$ThisOffset] == 'EOF')
// Messed up file. Stop here.
return true;
$FuncName = 'Load';
if (is_array($OffsetList[$ThisOffset])) {
$FuncName .= $OffsetList[$ThisOffset][0];
$extraData = $OffsetList[$ThisOffset][1];
// echo $FuncName . ' ' . $extraData . '
' ;
} else {
$FuncName .= $OffsetList[$ThisOffset];
$extraData = false;
}
fseek($file, $ThisOffset);
$fileData = fread($file, $NextOffset - $ThisOffset);
if ($this->$FuncName($fileData, $extraData))
return -2;
array_shift($Offsets);
}
return false;
}
// Generic function to load the AppInfo block into $this->AppInfo
// Should only be called within this class
// Return false to signal no error
function LoadAppInfo($fileData) {
$this->AppInfo = bin2hex($fileData);
return false;
}
// Generic function to load the SortInfo block into $this->SortInfo
// Should only be called within this class
// Return false to signal no error
function LoadSortInfo($fileData) {
$this->SortInfo = bin2hex($fileData);
return false;
}
// Generic function to load a record
// Should only be called within this class
// Return false to signal no error
function LoadRecord($fileData, $recordInfo) {
$this->Records[$recordInfo['UID']] = bin2hex($fileData);
$this->RecordAttrs[$recordInfo['UID']] = $recordInfo['Attrs'];
//echo $recordInfo['UID'] . ' ' . $this->Records[$recordInfo['UID']] . ' ' . $this->RecordAttrs[$recordInfo['UID']] . '
';
return false;
}
}
?>