|
|
| Symbian OS Explained - errata |
| home/ SOSE-Errata/ |
|
Many thanks to Peter van Sebille, Mark Bowler, Richard Jackson, Martin Hardman, Scott Meyers, Kari Salo, David Caabeiro, Jarmo Petäjäaho, Michael Baker, Julian Hope and Magnus Bjørnsen Løberg for pointing out these errors. We will continue to update this page as others are reported. |
|
(1) The copyright date is given as 2004 on pg. ii and 2005 on pg. iv. It should read 2004 throughout.
(2) At the top of P22, in MyNonLeavingFunction(), the line which reads: TRAP(PotentialLeaverL()); Should be: TRAP(result, PotentialLeaverL());
TInt MyNonLeavingFunction() rather than simply MyNonLeavingFunction()
(3) At the bottom of P23 and top of P24, both calls to OpenFileObjectL() should be passed CFileObject*& as follows: TInt errorCode = OpenFileObject(fileObject); // page 23 and TRAPD(r, errorCode=OpenFileObjectL(fileObject)); // page 24
(4) Page 25, first code example: The call to User::Leave(err) should be User::Leave(r) third code example, line 7: CThing::NewL() should be CFileObject::NewL()
(5) First code example on P35: CExample* pExample = TRAPD(r, CExample::NewLC()); should read: CExample* pExample; TRAPD(r, pExample = CExample::NewLC()); // This will panic
(6) Bottom of page 35, and page 36 There’s no forward declaration of TChilliPepper, while there is one for CChilli, which is rather inconsistent. Since there are other definitions missing (eg for class CExample, which is also used here) I would suggest that the forward declaration of CChilli is removed and anything that is not present is assumed defined elsewhere but “omitted for clarity”.
(7) Page 36, 13th line of code, dragon-> should be dragon. (dragon is a stack based object, not a pointer).
(8) On page 40, in LeavingFunctionL(). The line of code that reads CleanupStack::PushL() should be CleanupStack::PushL(safeExample)
(9) On the bottom of page 44 and top of page 45, the code should be as follows: class CSpreadSheet : public CBase { public: // Guarantees an atomic update void UpdateSpreadSheetL(const CData& aData); ... // Other methods omitted private: // Recalculates the contents of iSpreadSheet void RecalculateL(const CData& aData); void UpdateL(); // Updates iSpreadSheetView void RollBack(); // Reverts to the previous state private: CExampleSpreadSheet* iSpreadSheet; // Defined elsewhere CExampleSpreadSheetView* iSpreadSheetView;// Defined elsewhere ... }; void CSpreadSheet::UpdateSpreadSheetL(const CData& aData) { TRAPD(result, RecalculateL(aData)); // Performs the recalculation if (KErrNone==result) // if no error, update the view { TRAP(result, UpdateL()); } if (KErrNone!=result) // RecalculateL() or UpdateL() failed {// Undo the changes RollBack(); User::Leave(result); } } The code at the bottom of page 45 should be as follows: class CSpreadSheet : public CBase { public: // Guarantees an atomic update void UpdateSpreadSheetL(const CData& aData); ... // Other methods omitted private: // Recalculates the contents of iSpreadSheet void RecalculateL(const CData& aData); void UpdateL(); // Updates iSpreadSheetView // Reverts to the previous state static void RollBack(TAny* aSpreadSheet); void DoRollBack(); private: CExampleSpreadSheet* iSpreadSheet; CExampleSpreadSheetView* iSpreadSheetView; ... }; void CSpreadSheet::UpdateSpreadSheetL(const CData& aData) { // Initialize the TCleanupItem TCleanupItem cleanup(CSpreadSheet::RollBack, this); CleanupStack::PushL(cleanup); // Put it on the cleanup stack RecalculateL(aData); UpdateL(); CleanupStack::Pop(&cleanup); // TCleanupItem is no longer required }
(10) On P 61, the first paragraph of text states “If you want to indicate that the data your TPtrC points at should not be changed, you can declare the TPtrC to be const, which typically generates a compiler warning if an attempt is made to call Set() upon it. It will not fail, however, since the rules of const-ness in C++ are such that both const and non-const functions may be called on a const object” This is not the case; you cannot call Set() on a const TPtrC
(11) On page 63, section 5.4 Stack-Based Buffer Descriptors, figure 5.2 Buffer Descriptors: Both parts of the diagram are labelled as TBufC. The second, lower example should be labelled as TBuf and not TBufC
(12) The second line of the second paragraph of the footnote on page 78 mentionsNextLineL() and DoGetNextLineL() but CPoem only has GetLineL() and DoGetLineL() functions. It should read “GetLineL() will leave because CPoem::DoGetLineL() leaves to indicate the end of the poem…” The second code example of page 78 is thus also incorrect (because it calls NextLineL()) and instead it should be as follows: HBufC8* CPoem::GetLineL(TInt aLineNumber) { return (DoGetLineL(aLineNumber)); // As shown above } void PrintPoemLinesL(CPoem& aPoem) { HBufC* line; FOREVER // See footnote 2 { line = poem.GetLineL(); ... // Do something with line (make it leave-safe if necessary) delete line; } }
(13) On page 98, the box on upper left in Figure 7.3 should be labeled RArrayBase, not RArray
(14) On page 99, the implementation of ComparePriorities(), which is used as a comparator function to order the array, is back-to-front, for its use by TLinearOrder. It should return a negative value if aTask1 < aTask2 (ie the first object is less than the second) and a positive value if aTask1 > aTask2
(15) Page 175, line 6: RThread::Complete() should read RThread::RequestComplete()
(16) In Section 12.5 Server Classes, there is no implementation of the CHerculeanServer::NewSessionL() method, which is crucial to show the linkage between the CSharableSession derived class and the CSession derived class (it's hard to see the connection between CServer & CSharableSession without it). The following code should ideally be added to the code box on p206 (as inline code) or page 207. CSharableSession* CHerculeanServer::NewSessionL(const TVersion&) const {// This example performs no version checking return new(ELeave) CHerculeanSession(); }
(17) In the source code for CHerculeanSession, the cancellation methods for the asynchronous requests,CancelCleanAugeanStablesL() and CancelSlayStymphalianBirdsL() do not show the code required to cancel the outstanding asynchronous requestion on CAsyncHandler (as described in page 212). The text makes it clear that the the outstanding async request must be completed, and the original client-server request also completed, with KErrCancel, by calling RMessagePtr::Complete(). What is not shown, is that the client-server cancellation request must also be completed, with KErrNone, otherwise the server will hang and process no further requests. Thus, the two cancellation methods on CHerculeanSession, should takeRMessage& parameters and call Complete() upon them, once the async request and original client-server call are cancelled. I have updated the source code, available for download, to take this into account. Many thanks are due to David Caabeiro for pointing out this glaring omission.
(18) On page 221, the code for CTaskManager::TaskManagerL() should not be assigning iTaskManager = iTaskManager. The correct code should read iTaskManager = taskManager;
(19) On page 243, right at the top of the page, the .RSS file is misnamed. The first line of the code example should be: // 10009EE1.RSS A few lines lower, the 7th written line of the code example, should be: dll_uid = 0x10009EE1; // interfaces info This is so the UID matches that given for the resource file and for UID3 on page 240 (in the code for the mmp file for ECryptoExample).
(20) Page 262 In the code example, when passing iFs to file.Open(), it should be passed as *iFs because it appears to be a pointer (the line above calls __ASSERT_DEBUG to check that it is non-zero). In fact, since it is rarely necessary to create RFs objects on the heap, particularly as C class members, it seems more likely that the __ASSERT_DEBUG line should in fact be checking that iFs.Handle() is non-zero. If this line is corrected, passing iFs as it is to RFile::Open() is OK. |
|