Symbian OS Communications (779884), страница 62
Текст из файла (страница 62)
There has also been a binary (but not source) compatibilitybreak between the pre-v9.1 releases and v9.1, to accommodate a new compiler andplatform security. From v9.1 onwards, source and binary compatibility will be maintainedfor future releases.302OBEX• Old-style API: use one of the various overloads of CObexBufObject::SetDataBufL() that take combinations of CBufFlat anddescriptors containing filenames.• New-style API: use the overload of CObexBufObject::SetDataBufL() that takes a reference to a TObexBufferingDetails.The new-style API and the TObexBufferingDetails class wereintroduced to stop the CObexBufObject API growing every time a newvariation of its usage was devised. This is the recommended means to setup the CObexBufObject ready for use.The TObexBufferingDetails class only contains the basic information required for setting up CObexBufObject with a buffer, but hasa number of derived classes, which provide additional information forsetting up the CObexBufObject for use with a combination of bufferand file.There is a further (important) subtlety to be aware of when using aCBufFlat for receiving data; when initially created, a CBufFlat is ofzero size.
This is fine for use in conjunction with CObexBufObjectin a ‘buffer only’ setup, because the buffer is automatically expandedto accept new data. However, when a CBufFlat of zero size is usedin conjunction with CObexBufObject in a ‘buffer and file’ setup, thebuffer is not automatically expanded. For this reason, it is importantto use CBufFlat::ResizeL() to adjust the size of the buffer beforebeginning a transfer in this case.This, and the use of SetDataBufL(), is illustrated by the followingsequence of code fragments from the example OBEX File Transfer Profileapplication.// Create a buffer to be used when receiving data//iReceiveBuf = CBufFlat::NewL(KExpandSize);// Important to remember that when a buffer is being// used as a temporary store for received data before the// data is ultimately committed to file, OBEX will not// expand the buffer as data arrives.
Therefore, the// application must size the buffer as well as create it// before use.//iReceiveBuf->ResizeL(KBufSize);// TObexFilenameBackedBuffer allows the application writer// to specify the buffer size, filename and buffering// strategy to be used during reception.//TObexFilenameBackedBuffer bufDetails(*iReceiveBuf,iTempFileName, CObexBufObject::ESingleBuffering);//////For the moment, we provide CObexBufObject with a NULLbuffer pointer.OBEX IN SYMBIAN OS303iReceiveObject = CObexBufObject::NewL(NULL);// Call SetDataBufL to prepare iReceiveObject for transfer.//iReceiveObject->SetDataBufL(bufDetails);Example 10.6Creating a CObexBufObject for receptionTObexBufferingDetails buffering strategy TObexBufferingDetails contains the details of a CBufFlat, and is used for sendingand receiving from a RAM-based buffer.
This makes it ideal for sendingsmall objects that can be constructed in RAM buffers, or receiving objectsthat can be extracted easily from RAM buffers. As mentioned above,when being used for data reception, the CBufFlat will be expanded toaccommodate the incoming body data.TObexPureFileBufferbufferingstrategy TObexPureFileBuffer is derived from TObexBufferingDetails, and adds a filename to the information used to set up the CObexBufObject. The filename is the name of the file that body data should be sent from orreceived to when the CObexBufObject is used in an OBEX transfer.Immediately on being provided with TObexPureFileBuffer, OBEXwill attempt to open the named file for read/write access, or, failing that,read only access. If the file does not exist, OBEX will attempt to createa file with the specified name.
If none of these steps succeed, an errorwill result. When receiving to the file, any pre-existing file contents areerased before reception commences.This class provides a special case where no buffering occurs whenreceiving body data. For performance purposes, it is generally advisable touse one of TObexFilenameBackedBuffer or TObexRFileBackedBuffer in preference to this class.TObexFilenameBackedBuffer buffering strategy TObexFilenameBackedBuffer is derived from TObexBufferingDetails, andagain adds a file name to the information used to set up the CObexBufObject.The behaviour of this class is identical to that of TObexPureFileBuffer in all but one important aspect. Unlike TObexPureFileBuffer, this class provides buffering when receiving data, and is theclass most commonly used by OBEX applications.CObexBufObject’s receive buffering works by accumulating bodydata from successive OBEX packets into a RAM buffer, and only writingthe accumulated data to file when the buffer is full, or the transfer iscomplete.
This improves transfer performance because making a fewlarge file writes is much more efficient than making a large number ofsmall file writes.When choosing the size of the buffer, the application writer should takeinto consideration the likely amount of body data being received within a304OBEXparticular transfer, the amount of body data that might be transferred in anOBEX packet (see the section ‘Maximum OBEX packet sizes’ on varyingOBEX packet sizes), and the likely availability of heap space. Ideally,the application should create a buffer that is big enough to contain anentire transfer’s worth of body data, but the penalty for adopting thisapproach is increased RAM usage. If the amount of body data is too largeto make that practical or desirable, to make the buffer worthwhile it mustat least be large enough to accommodate multiple OBEX packets’ worthof body data to see any performance gain.
However, these are roughheuristics, and some experimentation might be necessary to find the idealRAM/performance trade off for a given application.TObexRFileBackedBufferbufferingstrategy TObexRFileBackedBuffer is derived from TObexBufferingDetails, and isalmost identical in TObexFilenameBackedBuffer. The difference isthat rather than adding a filename to the base class, it adds a file handle inthe form of an RFile object. This, in conjunction with the handle-sharingscheme in Symbian OS, can allow access to a file in another (cooperating)application’s private directory.The RFile should have already been opened when it is passed intothe TObexRFileBackedBuffer constructor. OBEX will use the filereferenced by this handle in the same way that it would a file named in aTObexFilenameBackedBuffer structure.CObexFileObjectThe CObexFileObject provides a means to send body data from,and receive body data to, a file.
For sending, it performs the same taskas a CObexBufObject configured with a file (that is, with a TObexPureFileBuffer, TObexFilenameBackedBuffer, or TObexRFileBackedBuffer object). For receiving, it performs the same taskas a CObexBufObject configured with a filename only (that is, witha TObexPureFileBuffer). For the best performance when receivingbody data to a file, it is advisable to use CObexBufObject configuredwith a file and buffer in preference to CObexFileObject.CObexNullObjectThe CObexNullObject is used where there is no body data to send,or where the receiving code is only concerned with non-body headers.Although used internally in the OBEX implementation, this class is oflimited use in general applications.10.2.5 OBEX Client APIThe OBEX client API in Symbian OS is defined by the class CObexClient.
An object of this class must be instantiated by any applicationOBEX IN SYMBIAN OS305wishing to issue OBEX commands to remote devices.7 The part of theAPI used for initiating OBEX commands is asynchronous, and uses thestandard mechanism built around using a TRequestStatus to signalcompletion of an OBEX command.
This allows OBEX commands to berun (effectively) in parallel with other application activities using theactive object framework.Important note: the OBEX implementation is built of various activeobjects, and so to process OBEX commands, it relies upon the activescheduler not being blocked. This means that OBEX applicationsthat make asynchronous requests to CObexClient must not useUser::WaitForRequest() or any other mechanism that will blockthe thread to wait for completion of the request.