summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/Stream.cpp
diff options
context:
space:
mode:
authorMarc Laukien <marc@zeroc.com>2001-09-06 13:57:04 +0000
committerMarc Laukien <marc@zeroc.com>2001-09-06 13:57:04 +0000
commit4f294feef76a816128689edda6c17510a06744ca (patch)
tree7fc5334c91437fafcadf200748f8dd125eb54c46 /cpp/src/Ice/Stream.cpp
parentbatch-mode (diff)
downloadice-4f294feef76a816128689edda6c17510a06744ca.tar.bz2
ice-4f294feef76a816128689edda6c17510a06744ca.tar.xz
ice-4f294feef76a816128689edda6c17510a06744ca.zip
encapsulation/stream redirection fixes
Diffstat (limited to 'cpp/src/Ice/Stream.cpp')
-rw-r--r--cpp/src/Ice/Stream.cpp269
1 files changed, 111 insertions, 158 deletions
diff --git a/cpp/src/Ice/Stream.cpp b/cpp/src/Ice/Stream.cpp
index 7fa0802c9e6..089c30607bb 100644
--- a/cpp/src/Ice/Stream.cpp
+++ b/cpp/src/Ice/Stream.cpp
@@ -21,13 +21,22 @@ using namespace std;
using namespace Ice;
using namespace IceInternal;
-static const Byte stringEncodingNormal = 0;
-static const Byte stringEncodingRedirect = 1;
-
IceInternal::Stream::Stream(const InstancePtr& instance) :
_instance(instance),
- _stringSet(CmpPosPos(b))
+ _encapsStack(1)
+{
+ _encapsStack.resize(1);
+ _encapsStack.back().start = 0;
+ _encapsStack.back().encoding = 0;
+}
+
+IceInternal::Stream::~Stream()
{
+ //
+ // No check for exactly one, because an error might have aborted
+ // marshalling/unmarshalling
+ //
+ assert(_encapsStack.size() > 0);
}
InstancePtr
@@ -43,8 +52,7 @@ IceInternal::Stream::swap(Stream& other)
b.swap(other.b);
std::swap(i, other.i);
- _encapsStartStack.swap(other._encapsStartStack);
- _stringSet.swap(other._stringSet);
+ _encapsStack.swap(other._encapsStack);
}
void
@@ -52,7 +60,7 @@ IceInternal::Stream::resize(int total)
{
if (total > 1024 * 1024) // TODO: configurable
{
- throw ::Ice::MemoryLimitException(__FILE__, __LINE__);
+ throw MemoryLimitException(__FILE__, __LINE__);
}
b.resize(total);
}
@@ -62,7 +70,7 @@ IceInternal::Stream::reserve(int total)
{
if (total > 1024 * 1024) // TODO: configurable
{
- throw ::Ice::MemoryLimitException(__FILE__, __LINE__);
+ throw MemoryLimitException(__FILE__, __LINE__);
}
b.reserve(total);
}
@@ -70,16 +78,18 @@ IceInternal::Stream::reserve(int total)
void
IceInternal::Stream::startWriteEncaps()
{
- write(Byte(0)); // Encoding version
write(Int(0)); // Placeholder for the encapsulation length
- _encapsStartStack.push_back(b.size());
+ _encapsStack.resize(_encapsStack.size() + 1);
+ _encapsStack.back().start = b.size();
+ _encapsStack.back().encoding = 0;
+ write(_encapsStack.back().encoding);
}
void
IceInternal::Stream::endWriteEncaps()
{
- int start = _encapsStartStack.back();
- _encapsStartStack.pop_back();
+ int start = _encapsStack.back().start;
+ _encapsStack.pop_back();
Int sz = b.size() - start;
const Byte* p = reinterpret_cast<const Byte*>(&sz);
#ifdef ICE_BIGENDIAN
@@ -92,26 +102,22 @@ IceInternal::Stream::endWriteEncaps()
void
IceInternal::Stream::startReadEncaps()
{
- //
- // If in the future several encoding versions are supported, we
- // need a pushEncoding() and popEncoding() operation.
- //
- Byte encVer;
- read(encVer);
- if (encVer != 0)
+ Int sz;
+ read(sz);
+ _encapsStack.resize(_encapsStack.size() + 1);
+ _encapsStack.back().start = i - b.begin();
+ read(_encapsStack.back().encoding);
+ if (_encapsStack.back().encoding != 0)
{
throw UnsupportedEncodingException(__FILE__, __LINE__);
}
- Int sz;
- read(sz);
- _encapsStartStack.push_back(i - b.begin());
}
void
IceInternal::Stream::endReadEncaps()
{
- int start = _encapsStartStack.back();
- _encapsStartStack.pop_back();
+ int start = _encapsStack.back().start;
+ _encapsStack.pop_back();
Container::iterator save = i;
i = b.begin() + start - sizeof(Int);
Int sz;
@@ -126,8 +132,6 @@ IceInternal::Stream::endReadEncaps()
void
IceInternal::Stream::skipEncaps()
{
- Byte encVer;
- read(encVer);
Int sz;
read(sz);
i += sz;
@@ -600,40 +604,33 @@ IceInternal::Stream::read(vector<Double>& v)
void
IceInternal::Stream::write(const string& v)
{
- pair<multiset<int, CmpPosPos>::const_iterator, multiset<int, CmpPosPos>::const_iterator> p =
- equal_range(_stringSet.begin(), _stringSet.end(), v, CmpPosString(b));
- if (p.first != p.second)
+ map<string, Int>::const_iterator p = _encapsStack.back().stringsWritten.find(v);
+ if (p != _encapsStack.back().stringsWritten.end())
{
- write(stringEncodingRedirect);
- Int diff = b.size() - *p.first;
- write(diff);
+ write(p->second);
}
else
{
- write(stringEncodingNormal);
+ write(Int(-1));
int pos = b.size();
resize(pos + v.size() + 1);
copy(v.begin(), v.end(), b.begin() + pos);
b.back() = 0;
- _stringSet.insert(pos);
+ Int sz = _encapsStack.back().stringsWritten.size();
+ _encapsStack.back().stringsWritten[v] = sz;
}
}
void
IceInternal::Stream::write(const char* v)
{
- write(stringEncodingNormal);
- int pos = b.size();
- int len = strlen(v);
- resize(pos + len + 1);
- copy(v, v + len + 1, b.begin() + pos);
- _stringSet.insert(pos);
+ write(string(v));
}
void
IceInternal::Stream::write(const vector<string>& v)
{
- write(Ice::Int(v.size()));
+ write(Int(v.size()));
vector<string>::const_iterator p;
for (p = v.begin(); p != v.end(); ++p)
{
@@ -644,61 +641,41 @@ IceInternal::Stream::write(const vector<string>& v)
void
IceInternal::Stream::read(string& v)
{
- Byte stringEnc;
- read(stringEnc);
-
- switch (stringEnc)
+ Int idx;
+ read(idx);
+
+ if (idx >= 0)
{
- case stringEncodingNormal:
+ if (static_cast<vector<string>::size_type>(idx) >= _encapsStack.back().stringsRead.size())
{
- Container::iterator begin = i;
- do
- {
- if (i >= b.end())
- {
- throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
- }
- }
- while (*i++);
- v = begin;
- _stringSet.insert(begin - b.begin());
- break;
+ throw StringEncodingException(__FILE__, __LINE__);
}
-
- case stringEncodingRedirect:
+ v = _encapsStack.back().stringsRead[idx];
+ }
+ else if(idx == -1)
+ {
+ Container::iterator begin = i;
+ do
{
- Int diff;
- read(diff);
- Container::iterator j = i - 4 - diff;
- Container::iterator begin = j;
- if (j < b.begin())
+ if (i >= b.end())
{
throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
}
-
- do
- {
- if (j >= b.end())
- {
- throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
- }
- }
- while (*j++);
- v = begin;
- break;
- }
-
- default:
- {
- throw StringEncodingException(__FILE__, __LINE__);
}
+ while (*i++);
+ v = begin;
+ _encapsStack.back().stringsRead.push_back(v);
+ }
+ else
+ {
+ throw StringEncodingException(__FILE__, __LINE__);
}
}
void
IceInternal::Stream::read(vector<string>& v)
{
- Ice::Int sz;
+ Int sz;
read(sz);
// Don't use v.resize(sz) or v.reserve(sz) here, as it cannot be
// checked whether sz is a reasonable value
@@ -716,19 +693,29 @@ IceInternal::Stream::read(vector<string>& v)
void
IceInternal::Stream::write(const wstring& v)
{
- write(stringEncodingNormal);
- wstring::const_iterator p;
- for (p = v.begin(); p != v.end(); ++p)
+ map<wstring, Int>::const_iterator p = _encapsStack.back().wstringsWritten.find(v);
+ if (p != _encapsStack.back().wstringsWritten.end())
{
- write(static_cast<Short>(*p));
+ write(p->second);
+ }
+ else
+ {
+ write(Int(-1));
+ wstring::const_iterator p;
+ for (p = v.begin(); p != v.end(); ++p)
+ {
+ write(static_cast<Short>(*p));
+ }
+ write(Short(0));
+ Int sz = _encapsStack.back().wstringsWritten.size();
+ _encapsStack.back().wstringsWritten[v] = sz;
}
- write(Short(0));
}
void
IceInternal::Stream::write(const vector<wstring>& v)
{
- write(Ice::Int(v.size()));
+ write(Int(v.size()));
vector<wstring>::const_iterator p;
for (p = v.begin(); p != v.end(); ++p)
{
@@ -739,27 +726,48 @@ IceInternal::Stream::write(const vector<wstring>& v)
void
IceInternal::Stream::read(wstring& v)
{
- Byte stringEnc;
- read(stringEnc);
- if (stringEnc != stringEncodingNormal)
+ Int idx;
+ read(idx);
+
+ if (idx >= 0)
{
- throw StringEncodingException(__FILE__, __LINE__);
+ if (static_cast<vector<string>::size_type>(idx) >= _encapsStack.back().wstringsRead.size())
+ {
+ throw StringEncodingException(__FILE__, __LINE__);
+ }
+ v = _encapsStack.back().wstringsRead[idx];
}
- // TODO: This can be optimized
- while (true)
+ else if(idx == -1)
+ {
+ v.erase();
+ while (true)
+ {
+ Short s;
+ read(s);
+ if (!s)
+ {
+ break;
+ }
+ v += static_cast<wchar_t>(s);
+ }
+ _encapsStack.back().wstringsRead.push_back(v);
+ }
+ else
{
- Short s;
- read(s);
- if (!s)
- break;
- v += static_cast<wchar_t>(s);
+ throw StringEncodingException(__FILE__, __LINE__);
}
}
void
+IceInternal::Stream::write(const wchar_t* v)
+{
+ write(wstring(v));
+}
+
+void
IceInternal::Stream::read(vector<wstring>& v)
{
- Ice::Int sz;
+ Int sz;
read(sz);
// Don't use v.resize(sz) or v.reserve(sz) here, as it cannot be
// checked whether sz is a reasonable value
@@ -775,13 +783,13 @@ IceInternal::Stream::read(vector<wstring>& v)
}
void
-IceInternal::Stream::write(const ::Ice::ObjectPrx& v)
+IceInternal::Stream::write(const ObjectPrx& v)
{
_instance->proxyFactory()->proxyToStream(v, this);
}
void
-IceInternal::Stream::read(::Ice::ObjectPrx& v)
+IceInternal::Stream::read(ObjectPrx& v)
{
v = _instance->proxyFactory()->streamToProxy(this);
}
@@ -790,7 +798,7 @@ void
IceInternal::Stream::write(const ObjectPtr& v)
{
const string* classIds = v->_classIds();
- Ice::Int sz = 0;
+ Int sz = 0;
while (classIds[sz] != "::Ice::Object")
{
++sz;
@@ -840,58 +848,3 @@ IceInternal::Stream::read(ObjectPtr& v, const string& signatureType)
throw ValueUnmarshalException(__FILE__, __LINE__);
}
-
-IceInternal::Stream::CmpPosPos::CmpPosPos(const Container& cont) :
- _cont(cont)
-{
-}
-
-IceInternal::Stream::CmpPosPos::CmpPosPos(const CmpPosPos& cmp) :
- _cont(cmp._cont)
-{
-}
-
-IceInternal::Stream::CmpPosPos&
-IceInternal::Stream::CmpPosPos::operator=(const CmpPosPos&)
-{
- // Do *not* assign anything! I want CmpPosPos to ignore std::swap().
- return *this;
-}
-
-bool
-IceInternal::Stream::CmpPosPos::operator()(int p, int q) const
-{
- assert(!_cont.empty());
- return strcmp(_cont.begin() + p, _cont.begin() + q) < 0;
-}
-
-IceInternal::Stream::CmpPosString::CmpPosString(const Container& cont) :
- _cont(cont)
-{
-}
-
-IceInternal::Stream::CmpPosString::CmpPosString(const CmpPosString& cmp) :
- _cont(cmp._cont)
-{
-}
-
-IceInternal::Stream::CmpPosString&
-IceInternal::Stream::CmpPosString::operator=(const CmpPosString&)
-{
- // Do *not* assign anything! I want CmpPosString to ignore std::swap().
- return *this;
-}
-
-bool
-IceInternal::Stream::CmpPosString::operator()(int i, const string& s) const
-{
- assert(!_cont.empty());
- return _cont.begin() + i < s;
-}
-
-bool
-IceInternal::Stream::CmpPosString::operator()(const string& s, int i) const
-{
- assert(!_cont.empty());
- return s < _cont.begin() + i;
-}