diff options
author | Benoit Foucher <benoit@zeroc.com> | 2012-05-21 18:06:22 +0200 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2012-05-21 18:06:22 +0200 |
commit | 6647d73fc31958e7ef8723a15d3b6c185fde4239 (patch) | |
tree | 76933229811eb89926e6af172493abb8d72345e8 /cpp/src/Ice/BasicStream.cpp | |
parent | Changed the 1.1 encoding to write pending objects only if necessary (diff) | |
download | ice-6647d73fc31958e7ef8723a15d3b6c185fde4239.tar.bz2 ice-6647d73fc31958e7ef8723a15d3b6c185fde4239.tar.xz ice-6647d73fc31958e7ef8723a15d3b6c185fde4239.zip |
Added implementation of optional data members encoding (not tested yet)
Diffstat (limited to 'cpp/src/Ice/BasicStream.cpp')
-rwxr-xr-x | cpp/src/Ice/BasicStream.cpp | 103 |
1 files changed, 101 insertions, 2 deletions
diff --git a/cpp/src/Ice/BasicStream.cpp b/cpp/src/Ice/BasicStream.cpp index 5295c73ea35..0d8ea17953d 100755 --- a/cpp/src/Ice/BasicStream.cpp +++ b/cpp/src/Ice/BasicStream.cpp @@ -170,8 +170,7 @@ IceInternal::BasicStream::swap(BasicStream& other) void IceInternal::BasicStream::format(Ice::FormatType format) { - // TODO: XXX: shouldn't this compare format instead of _format? - if(_format != DefaultFormat) + if(format != DefaultFormat) { _format = format; } @@ -1807,6 +1806,16 @@ void IceInternal::BasicStream::EncapsEncoder::endSlice() { // + // Write the optional member end marker if some optional members + // were encoded. Note that the optional members are encoded before + // the indirection table and are included in the slice size. + // + if(_sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) + { + _stream->write(static_cast<Byte>(MemberTypeEndMarker)); + } + + // // Write the slice length if necessary. // if(_sliceFlags & FLAG_HAS_SLICE_SIZE) @@ -1852,6 +1861,23 @@ IceInternal::BasicStream::EncapsEncoder::endSlice() } void +IceInternal::BasicStream::EncapsEncoder::writeOpt(int tag, MemberType type) +{ + assert(_sliceType != NoSlice); + _sliceFlags |= FLAG_HAS_OPTIONAL_MEMBERS; + Byte v = static_cast<Byte>(type); + if(tag < 31) + { + v |= tag << 3; + } + else + { + v |= 0x0F8; // tag = 31 + _stream->writeSize(tag); + } +} + +void IceInternal::BasicStream::EncapsEncoder::writePendingObjects() { // @@ -2313,6 +2339,19 @@ IceInternal::BasicStream::EncapsDecoder::startSlice() void IceInternal::BasicStream::EncapsDecoder::endSlice() { + if(_sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) + { + // + // Read remaining un-read optional members. + // + Byte v; + do + { + _stream->read(v); + } + while(skipOpt(static_cast<MemberType>(v & 0x07))); + } + // // Read the indirection table if one is present and transform the // indirect patch list into patch entries with direct references. @@ -2360,6 +2399,66 @@ IceInternal::BasicStream::EncapsDecoder::endSlice() } } +bool +IceInternal::BasicStream::EncapsDecoder::readOpt(int readTag, MemberType expectedType) +{ + assert(_sliceType != NoSlice); + if(!(_sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS)) + { + return false; // No optional data members + } + + int tag; + MemberType type; + do + { + Byte v; + _stream->read(v); + + type = static_cast<MemberType>(v & 0x07); // Read first 3 bits. + tag = static_cast<int>(v >> 3); + if(tag == 31) + { + _stream->readSize(tag); + } + } + while(tag < readTag && skipOpt(type)); // Skip optional data members with lower tag values. + + if(type == MemberTypeEndMarker) + { + // + // Clear the optional members flag since we've reach the end. We clear + // the flag to prevent endSlice to skip un-read optional members and + // to prevent other optional members from being read. + // + _sliceFlags &= ~FLAG_HAS_OPTIONAL_MEMBERS; + return false; + } + else if(tag > readTag) + { + // + // Rewind the stream so that we correctly read the next + // optional data member tag & type. + // + _stream->i -= tag < 31 ? 1 : (tag < 255 ? 2 : 6); + return false; // No optional data members with the requested tag. + } + + assert(readTag == tag); + if(type != expectedType) + { + ostringstream os; + os << "invalid optional data member `" << tag << "' in `" << _typeId << "': unexpected type"; + throw MarshalException(__FILE__, __LINE__, os.str()); + } + + // + // We have an optional data member with the requested tag and + // type. + // + return true; +} + void IceInternal::BasicStream::EncapsDecoder::readPendingObjects() { |