[omniORB] bulk data transfer of files
Steven W. Brenneis
brennes1@rjrt.com
Tue, 13 Jul 1999 08:00:50 -0400
Smith, Norman wrote:
>
> Have a question about sending bulk data transfer via omniORB. I want to send
> large chunks of data between processes, using omniORB as the IPC mechanism.
> I've successfully implemented a test case using the array datatype, but read
> the postings in this forum regarding arrays being marshalled item-by-item,
> and the efficiency of using sequences instead. However, the sequence data
> type doesn't seem to have any interface for pushing data into it except on
> an item-by-item basis, and it seems rather inefficient to transfer the
> contents of a 64K buffer (i.e. an array) item-by-item into a sequence, then
> pass the sequence to the ORB.
>
> I've thought about creating a "sequence of array" datatype (i.e.
> sequence<char[65535]>), but I would think the ORB would be smart enough to
> marshall each member of the sequence according to its declared type (in this
> case an array of char's) and I'm back where I started with the array being
> marshalled character-by-character.
>
> Question is this: what is the best way to perform this bulk transfer? Will
> the above sequence declaration marshall the entire array at once? Should I
> just stick to arrays, or is there some alternative that I'm not seeing?
>
Norman,
There is a non-portable method of transferring bulk quantities of scalar
data using sequences that is very fast and very efficient. I have been
using it for a quite a while and it works well. I'm not sure if this
will be the answer you are looking for, but here goes:
In your IDL:
typedef sequence<octet> buffer;
interface My_Class {
attribute buffer Buf;
};
The implementation goes something like this:
class My_Class_I : public _sk_My_Class {
public:
My_Class_I();
~My_Class_I();
void Buf(const buffer&);
buffer* Buf();
private:
buffer mybuffer;
};
The mutator is implemented thus:
void My_Class_I::Buf(const buffer& inbuffer) {
mybuffer.length(inbuffer.length());
::memcpy(mybuffer.NP_Data(),inbuffer.NP_data(),inbuffer.length());
}
The accessor can be implemented as either:
buffer* My_Class_I::Buf() {
return new buffer(mybuffer);
}
or:
buffer* My_Class_I::Buf() {
buffer* out = new buffer;
out->length(mybuffer.length());
::memcpy(out->NP_data(),mybuffer.NP_data(),mybuffer.length());
return out;
}
I think on most platforms the performance difference of either method is
nominal. Since the marshalling operation on this sequence is performed
into a memory buffered stream, the code is very efficient and quick.
Hope this helps.
Steve Brenneis