Game Development Reference
There will obviously be no data needed for the NoChange and Delete difference
A new function will be added to loop through the difference list and extract the
modified bytes, storing them in each PatchDifference object. This function is described
in the following code:
public static PatchDifferenceData BuildDifferenceData(PatchOperation operation)
The source code for this method is available on the Companion Web site.
The preceding function loops through the difference list, and for insertion and
substitution types, specifies the data associated with the change. We are left with
an array of PatchDifference objects containing the data related to the change. At
this point, the array can be easily serialized into an XML document for an exter-
nal system to use, or we can go one step further and build a complete patching
engine. The example provided with this chapter shows how to do both methods.
In order to successfully transform the old file using the difference data, a particu-
lar sequence of changes must be used. You must remember that the slightest error
when transforming the old data will corrupt the file and make it generally unus-
able. The first change to do is substitution because it does not require any bytes to
be added or removed from the source data, only a direct byte swap.
You want to loop through the difference list once for each difference type. First,
loop and process all the substitution types. Remember that the PatchDifference
object contains the target index in the resultant data, and the data to copy.
After substitution, the next difference type to process is deletion of data. Because
the algorithm does not take other deletion changes into consideration, the data
offsets are incorrect after the first deletion. To solve this, we must define a simple
offset counter that is incremented by the number of bytes removed each time a
deletion occurs. This offset is subtracted from the offset specified in the difference
list so that the correct data is deleted and no buffer overflow occurs.
Lastly, the insertion type is processed to allocate memory for new data being
copied into the resultant buffer. The first step is to allocate a block of memory at
the correct index, with the size specified by the PatchDifference object. Once the
memory exists, the insertion data can be safely copied over.