A GCF for BREW: Working with File I/O & Network Resources, Page 2
... and Filing
A file system is a luxury offered by BREW since its inception. Usually mobile systems offer Database/Records contraptions as storage facilities and not files. Anyway, using the File family of interfaces is quite straightforward and there are various examples illustrating the generic aspects.
GCF has a FileStream resource adapter to deal with files. As file and network resources access might be easily abstracted in terms of streams for example we expect some similarity between FileStream and HTTPpipe. The answer is yes and no.
initConnection(){ IFILEMGR_OpenFile Relinquish_contol_to_AEEShell(read/write)}write(){ check_connection_status IFILE_Write Case Writing: Relinquish_contol_to_AEEShell(write) Case Done: clean_resources}read(){ check_connection_status IFILE_Read Case Reading: read_data. Relinquish_contol_to_AEEShell(read) Case Done: Clean_Resources}
Another significant difference is that write and read are omnipotent — a write is a transaction by itself. This makes obviously makes some difference in the implementation.FileStream offers support for operations on large data sets. Actually, the same mechanism can be easily reused by HTTPpipe. In read() operations every data chunk (of size bufSize) can be processed immediately, with no delay, making consumer-producer scenarios easy to implement.
Implementation Details
the Data Structure (FDS) has no particular differences other than support for large data sets operations — a psCBK and a bool isInterrupted member.
psCBK is a command structure working with static functions. It can be used in two ways; as a simple callback wrapper or as a BREW asynchronous callback adapter.
struct psCBK{ typedef void (*F)(void*); psCBK() : y_(0), f_(0), shell_(0) {} bool isActive() { return y_!=0; } void setCallback(void* y, F fx, IShell* shell = 0) { y_ = y; f_ = fx; shell_ = shell; } void operator()() { if (!shell_) { f_(y_); return; } cb_.pfnNotify = (PFNNOTIFY)f_; cb_.pNotifyData = y_; cb_.pfnCancel = NULL; ISHELL_Resume(shell_,&cb_); } private: void* y_; F f_; IShell* shell_; AEECallback cb_;}; Usage :
----.. psCBK p; //passing IShell BREW async cbk p.setCallback(this,onReadChunk,m_pIShell); //ordinary cbk example //p.setCallback(this,onReadChunk); //passing data to FNS ds->fnc = p; ----- //using psCBK if (ds_->fnc.isActive()) ds_->fnc(); //isInterrupted set in onReadChunk if (!ds_->isInterrupted) IFILE_Readable(f_, (PFNNOTIFY)P::callbackHandler, &p_);
Final Notes
Calls involving different resource types can be freely mixed. For example:
initIO<FileStream, FDS>(onWriteCbk,"bubumic", String("123"));initIO<HTTPpipe<HDS1>, HDS1>(onReadCbk<HDS1>, "192.168.10.100", String("/discrepancies.htm"));and in onWriteCbk:
---..if (ds->error == SUCCESS){ initIO<FileStream, FDS>(onReadCbk<FDS>, ds->address, String("")); initIO<HTTPpipe<HDS>, HDS>(onReadCbk<HDS>, "192.168.10.100", String("/a.htm"));}This produces an "avalanche" of I/O and networking activity — namely a parallel HTTP transaction and a file write/read. ConnectionPolicy can be embedded in the data structures as a type based policy. The advantage is finer granularity (for example it might make sense to reuse network connections but not to reuse file connections).
Source Code
There are 3 versions of the code due to various compiler portability issues. The 3 packages are not in sync — VC7.1 is the final version and contains all the features presented in this article. As there are no important structural changes migrating to another compiler should be almost automatic.
- Download for Visual C++ 6 - 271 kb
- Download for Visual C++ 7.1 - 310 kb
- Download for ADS1.0.1 - 283 kb
End Notes
[1] A Generic Connection Framework for BREW-
http://www.developer.com/ws/brew/article.php/2242101
About the Author
Radu Braniste is Director of Technology at Epicad. He can be contacted at rbraniste@epicad.com
# # #
