Issue 3537: Sequence mapping & custom marshalling (cxx_revision) Source: Cisco Systems (Mr. Paul Kyzivat, pkyzivat(at)cisco.com) Nature: Uncategorized Issue Severity: Summary: Section 1.17.11 of ptc/2000-01-02 says that DataInputStream & DataOutputStream are mapped according to the normal valuetype mappings. This mapping results in operations that are at best cumbersome to use in marshalling sequences of primitive types: Operations read_xxx_array and write_xxx_array are defined, taking argments of type CORBA::xxxSeq. These are obviously intended to be sufficient for marshalling all defined sequences of the corresponding primitive type xxx. However, the c++ mapping for sequences requires that each distinctly declared sequence type be unique and separately overloadable. This guarantees that a marshaller attempting to marshal an sequence of primitive other than CORBA::xxxSeq will not be able to pass that sequence to the corresponding read_xxx_array and write_xxx_array operations. Instead, code must be written to bypass strict typing. To fix this, either the mappings for DataInputStream and DataOutputStream need to be non-standard, the mapping of sequences needs to change, or the mapping of CORBA::xxxSeq needs to change to something special. Resolution: Revised Text: Actions taken: April 10, 2000: received issue Discussion: deferred in June 2011 to the next RTF End of Annotations:===== From: Paul Kyzivat To: "'cxx_revision@omg.org'" , "'issues@omg.org'" Subject: Sequence mapping & custom marshalling Date: Mon, 10 Apr 2000 13:00:44 -0400 MIME-Version: 1.0 X-Mailer: Internet Mail Service (5.5.2448.0) Content-Type: text/plain; charset="iso-8859-1" X-UIDL: H*a!!+]Y!!l0,!!bSX!! Section 1.17.11 of ptc/2000-01-02 says that DataInputStream & DataOutputStream are mapped according to the normal valuetype mappings. This mapping results in operations that are at best cumbersome to use in marshalling sequences of primitive types: Operations read_xxx_array and write_xxx_array are defined, taking argments of type CORBA::xxxSeq. These are obviously intended to be sufficient for marshalling all defined sequences of the corresponding primitive type xxx. However, the c++ mapping for sequences requires that each distinctly declared sequence type be unique and separately overloadable. This guarantees that a marshaller attempting to marshal an sequence of primitive other than CORBA::xxxSeq will not be able to pass that sequence to the corresponding read_xxx_array and write_xxx_array operations. Instead, code must be written to bypass strict typing. To fix this, either the mappings for DataInputStream and DataOutputStream need to be non-standard, the mapping of sequences needs to change, or the mapping of CORBA::xxxSeq needs to change to something special. ____________________ Paul Kyzivat Rogue Wave Software paulk@roguewave.com X-Sender: vinoski@mail.boston.amer.iona.com X-Mailer: QUALCOMM Windows Eudora Version 4.3 Date: Mon, 10 Apr 2000 13:46:49 -0500 To: Paul Kyzivat From: Steve Vinoski Subject: Re: Sequence mapping & custom marshalling Cc: "'cxx_revision@omg.org'" In-Reply-To: <9B164B713EE9D211B6DC0090273CEEA926BDB8@bos1.noblenet.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; format=flowed X-UIDL: 8B]!!e To: "'cxx_revision@omg.org'" Subject: RE: Sequence mapping & custom marshalling Date: Mon, 10 Apr 2000 15:16:32 -0400 MIME-Version: 1.0 X-Mailer: Internet Mail Service (5.5.2448.0) Content-Type: text/plain; charset="iso-8859-1" X-UIDL: Wo)e9+ From: Steve Vinoski [mailto:vinoski@iona.com] > Using the buffer manipulation operations that sequences > provide allows you > to easily exchange sequence buffers between sequence > instances. I don't > think it's too much to ask applications to use these > operations to portably > work around this problem. It only takes two or three extra > lines of code. So you are saying that in an implementation of marshal(...), if my custom valuetype happens to contain an instance afoo of type Foo that is a sequence, I should do something like: CORBA::OctetSeq temp( afoo.maximum(),afoo.length(),afoo.get_buffer(),false); stream->write_octet_array(temp); And for unmarshal, I need to do something like: CORBA::OctetSeq temp; stream->read_octet_array(temp); afoo.replace( temp.maximum(),temp.length(),temp.get_buffer(true),true); But this requires an extra buffer. Instead, I could do: CORBA::OctetSeq temp( afoo.maximum(),afoo.length(),afoo.get_buffer(true),true); stream->read_octet_array(temp); afoo.replace( temp.maximum(),temp.length(),temp.get_buffer(true),true); But this doesn't work if afoo doesn't own its buffer. So, to work in that case, without requiring an unnecessary buffer in other cases, I need something like: CORBA::OctetSeq temp; if (afoo.release()) temp.replace( afoo.maximum(),afoo.length(),afoo.get_buffer(true),true); stream->read_octet_array(temp); afoo.replace( temp.maximum(),temp.length(),temp.get_buffer(true),true); but this could leave an unexpected result if read_octet_array throws an exception. So, if I want the result to reflect the content of the sequence at the time the exception is thrown, I should write: CORBA::OctetSeq temp; if (afoo.release()) temp.replace( afoo.maximum(),afoo.length(),afoo.get_buffer(true),true); try { stream->read_octet_array(temp); } catch(CORBA::SystemException& e) { afoo.replace( temp.maximum(),temp.length(), temp.get_buffer(true),true); throw; }; afoo.replace( temp.maximum(),temp.length(),temp.get_buffer(true),true); And, if I am trying to marshal bounded sequences, the above are somewhat different and more complex. The main problem I have with this is that anybody that wants to marshal sequences is going to have to work this out. If I was a user that ran into this I would definitely be annoyed. Paul Sender: jbiggar@corvette.floorboard.com Message-ID: <38F22A74.520BABBC@floorboard.com> Date: Mon, 10 Apr 2000 12:24:36 -0700 From: Jonathan Biggar X-Mailer: Mozilla 4.7 [en] (X11; U; SunOS 5.6 sun4u) X-Accept-Language: en MIME-Version: 1.0 To: Steve Vinoski CC: Paul Kyzivat , "'cxx_revision@omg.org'" Subject: Re: Sequence mapping & custom marshalling References: <4.3.2.20000410134350.03bda1e0@mail.boston.amer.iona.com> Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=us-ascii X-UIDL: c1od9Y)!e9CNZd9CN5!! Steve Vinoski wrote: > > At 01:00 PM 4/10/00 -0400, Paul Kyzivat wrote: > >Section 1.17.11 of ptc/2000-01-02 says that DataInputStream & > >DataOutputStream are mapped according to the normal valuetype > mappings. > >This mapping results in operations that are at best cumbersome to > use in > >marshalling sequences of primitive types: > > > >Operations read_xxx_array and write_xxx_array are defined, taking > argments > >of type CORBA::xxxSeq. These are obviously intended to be > sufficient for > >marshalling all defined sequences of the corresponding primitive > type xxx. > > > >However, the c++ mapping for sequences requires that each > distinctly > >declared sequence type be unique and separately overloadable. This > >guarantees that a marshaller attempting to marshal an sequence of > primitive > >other than CORBA::xxxSeq will not be able to pass that sequence to > the > >corresponding read_xxx_array and write_xxx_array > operations. Instead, code > >must be written to bypass strict typing. > > Using the buffer manipulation operations that sequences provide > allows you > to easily exchange sequence buffers between sequence instances. I > don't > think it's too much to ask applications to use these operations to > portably > work around this problem. It only takes two or three extra lines of > code. Try something like this: template void move_buffer_unbounded(S1 &to, S2 &from) { to.replace(from.maximum(), from.length(), from.get_buffer(from.release()), from.release()); } template void move_buffer_bounded(S1 &to, S2 &from) { to.replace(from.length(), from.get_buffer(from.release()), from.release()); } This is off the top of my head, so I don't make an compilation guarantees. :-) -- Jon Biggar Floorboard Software jon@floorboard.com jon@biggar.org