Quantum | 443333333333222222222211111111110000000000 Offset | 109876543210987654321098765432109876543210 +- After we do the move, the result looks like Figure itemref5. The data is in the right place now, but the pointers are wrong. Specifically, the m_Offset fields of the items that have higher item numbers than the one we have deleted are off by the length of the deleted field. That's why we have to call AdjustOffset to reduce the m_Offset field of every item after the deleted one by ItemLength, which is the length of the deleted item. Then we set the data type of the deleted item in the item index to UNUSED_ITEM. Sample IRA, etc., during deletion (Figure itemref5) +- | Quantum Item | Index Number Number | + + Item | 0 | 3 2 + + Reference | 1 | 3 4 + +-+ Array | 2 | 3 5 + +-+-+ (IRA) | 3 | 3 3 + + | | | | 4 | 3 1 + + | | | | | + + | | | | | +- | | | | | | | | | | +- | | | | | | Item # Offset Type Index | | | | | | + + | | | | | Item | 1 | 5 -+ VARSTRING 4 |± + | | | | Index | 2 | 17 +| VARSTRING 0 |± + + | | for | 3 | +-19 || VARSTRING 3 |± + | | Quantum | 4 | ++-34 || VARSTRING 1 |± + | 3 | 5 |+++-41 || VARSTRING 2 |± + | 6 |||| 41 || UNUSED 0 | | ++++ ++ + +- ||| |+ + ||| + + | ||+ + | | +- |+ + | | | | + + + +-+ + + Quantum | | Baldwin123 Main StreetSteve Heller11510| Data | + + +- +- Quantum | 443333333333222222222211111111110000000000 Offset | 109876543210987654321098765432109876543210 +- After correcting the index, our quantum looks like Figure itemref6. We can now access the data in the quantum correctly, as long as we use the "official" route through the IRA and the item index. 43 Sample IRA, etc., after deletion (Figure itemref6) +- | Quantum Item | Index Number Number | + + Item | 0 | 3 2 + + Reference | 1 | 3 4 + +-+ Array | 2 | 3 5 + +-+-+ (IRA) | 3 | 3 3 + + | | | | 4 | 3 1 + + | | | | | + + | | | | | +- | | | | | | | | | | +- | | | | | | Item # Offset Type Index | | | | | | + + | | | | | Item | 1 | 5 -+ VARSTRING 4 |± + | | | | Index | 2 | 17 +| VARSTRING 0 |± + + | | for | 3 | 17 || UNUSED 0 |± + | | Quantum | 4 | + 32 || VARSTRING 1 |± + | 3 | 5 |++ 39 || VARSTRING 2 |± + | 6 ||| 39 || UNUSED 0 | | +++ ++ + +- || |+ + || + + | |+ + | | +- +-+ | | | | + + + + + + Quantum | | Baldwin123 Main StreetSteve Heller11510| Data | + + +- +- Quantum | 443333333333222222222211111111110000000000 Offset | 109876543210987654321098765432109876543210 +- The QuantumBlock::CalculateFreeSpace function Another interesting function in this class is CalculateFreeSpace. You might think that this would be a very simple function, but it has a few twists, as you will see by looking at its code, shown in Figure block.24. The QuantumBlock::CalculateFreeSpace function (from quantum\block.cpp) (Figure block.24) codelist/block.24 As we frequently do, we begin with an assert that tests the validity of the key data used by the function; in this case, that takes the form of checking that the number of items in this quantum is within the legal limit, i.e., that it is less than the NoItem constant used to indicate an invalid item number. Assuming that it passes that test, we then check whether we have already stored the maximum possible number of items in this quantum. If so, we "lie" to the caller by returning the value 0, indicating that there is no space available in this quantum. Of course, this is a white lie, because without an available entry in the item index, we cannot in fact add any new items to this quantum, so the caller needs to look elsewhere. Assuming that we pass that test, we can calculate the free space in the quantum by a series of steps. First, we subtract the size of the quantum block header (plus a margin of safety) from the size of a block. If the number of items in the block is equal to 0, we have the answer: the quantum should be marked as having the maximum possible free space, so we compute the free space code that indicates this situation and return it to the caller. 44 On the other hand, if there are some items in the quantum then we calculate the offset of the last item in the quantum and subtract it from the free space. Then we calculate the size of the item index as the number of entries in the item index multiplied by the size of one entry, and subtract it from the free space. If the result comes out to be less than 0, we return 0; otherwise, we return the calculated free space. The QuantumBlock::UpdateFreeSpace Function As long as we're discussing the intriguing topic of free space, we might as well take a look at UpdateFreeSpace, whose code is shown in Figure block.25. The QuantumBlock::UpdateFreeSpace function (from quantum\block.cpp) (Figure block.25) codelist/block.25 Why do we need this function, when we already have a function to calculate the amount of free space in a quantum? This is not just another version of the CalculateFreeSpace function, because it actually updates the information in the free space list. As you may recall, the free space list stores more than just the amount of free space in a quantum; it also stores the object number of the main object that quantum belongs to. This is so that we can avoid scanning a lot of quanta to find one that has enough free space in it and also belongs to the main object that we need the additional space for. Now that we know what this function does, it shouldn't be too hard to determine how it does it. First, it sets the object number of a newly created free space object to the object number of the block for which the free space is being updated. Then it converts the free space calculated by the CalculateFreeSpace function to a free space code, which occupies only one byte. Finally, it uses the SetFreeSpace function of the quantum file class to update the free space list with the new information for this quantum. The rest of the functions in the quantum block class aren't particularly interesting or instructive, so we won't bother to go over them. You shouldn't have much trouble understanding how they work by simply looking at the code, which is all on the CD ROM in the back of the book, along with the DJGPP compiler. The next class we will examine is the big pointer block class, which is derived from the quantum block class. The BigPointerBlock class The interface for BigPointerBlock is shown in Figure blocki.09. The interface for the BigPointerBlock class (from quantum\blocki.h) (Figure blocki.09) codelist/blocki.09 Most of the functions in this class aren't very interesting, so we won't bother to go over them. However, there are a couple that we should take a quick look at, because they contain a few tricks that you should understand if you're going to have to modify the behavior of any of these classes. We'll start with SetBigArrayHeader, whose code is shown in Figure block.26. The BigPointerBlock::SetBigArrayHeader Function The BigPointerBlock::SetBigArrayHeader function (from quantum\block.cpp) (Figure block.26) codelist/block.26 The purpose of this function is to allow us to access data that is stored in the big pointer block quantum. To be precise, the data that we are going to access is the "big array header", which includes information about the number of elements in the array, the maximum number of elements in the array, and the last quantum where we added data for this array. 45 As you can see by looking at the code, the member variable m_BigArrayHeader is a pointer to the data in the quantum. This is not hazardous, because the header consists of several fields, each of which is fixed length; therefore, we don't have to worry about running off the end of the data in the header. Once we have executed the SetBigArrayHeader function, we can call the various access functions that get and set these values in the array header, where it resides in the big pointer array quantum buffer in memory. 46 The BigPointerBlock::SetBigPointerArray Function The next function we'll look at is SetBigPointerArray, whose code is shown in Figure block.27. The BigPointerBlock::SetBigPointerArray function (from quantum\block.cpp) (Figure block.27) codelist/block.27 This function is superficially similar to the one that we just discussed; its purpose is to allow us to access data that is in the big pointer array quantum. However, there is a major difference between these two functions: while the previous function could safely provide us with a simple pointer to the big array header data structure in the big pointer array quantum, that would be extremely unsafe in the . information for this quantum. The rest of the functions in the quantum block class aren't particularly interesting or instructive, so we won't bother to go over them. You shouldn't