00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifdef __GNUG__
00032 # pragma implementation "OutSerializer.h"
00033 #endif
00034
00035 #include "StrMod/OutSerializer.h"
00036 #include "StrMod/BufferChunkFactory.h"
00037 #include "StrMod/DynamicBuffer.h"
00038
00039 namespace strmod {
00040 namespace strmod {
00041
00042 inline OutSerializer::State::State(BufferChunk::Factory *fact)
00043 : fact_(fact), cur_chunk_(0), buf_(0), chnklen_(0), cur_pos_(0)
00044 {
00045 }
00046
00047 inline OutSerializer::State::State(const State &b)
00048 : fact_(b.fact_), cur_chunk_(b.cur_chunk_),
00049 buf_(b.buf_), chnklen_(b.chnklen_), cur_pos_(b.cur_pos_)
00050 {
00051 }
00052
00053 inline const OutSerializer::State &
00054 OutSerializer::State::operator =(const State &b)
00055 {
00056 cur_chunk_ = b.cur_chunk_;
00057 buf_ = b.buf_;
00058 chnklen_ = b.chnklen_;
00059 cur_pos_ = b.cur_pos_;
00060 return(*this);
00061 }
00062
00063 OutSerializer::OutSerializer(size_t suggested_size)
00064 : state_(0), external_state_(0)
00065 {
00066 state_.cur_chunk_ = new DynamicBuffer;
00067 state_.cur_chunk_->resize(suggested_size);
00068 state_.chnklen_ = state_.cur_chunk_->Length();
00069 state_.buf_ = state_.cur_chunk_->getCharP();
00070 }
00071
00072 OutSerializer::OutSerializer(State &savedstate)
00073 : state_(savedstate), external_state_(&savedstate)
00074 {
00075 if (state_.cur_chunk_ == 0)
00076 {
00077 assert(state_.fact_ != 0);
00078 state_.cur_chunk_ = state_.fact_->makeChunk();
00079 state_.chnklen_ = state_.cur_chunk_->Length();
00080 state_.cur_pos_ = 0;
00081 }
00082 else
00083 {
00084 assert(state_.chnklen_ == state_.cur_chunk_->Length());
00085 assert(state_.cur_pos_ <= state_.chnklen_);
00086 }
00087 }
00088
00089 OutSerializer::OutSerializer() : state_(0), external_state_(0)
00090 {
00091 state_.cur_chunk_ = new DynamicBuffer;
00092 state_.cur_chunk_->resize(256);
00093 state_.cur_pos_ = 0;
00094 state_.chnklen_ = state_.cur_chunk_->Length();
00095 state_.buf_ = state_.cur_chunk_->getCharP();
00096 }
00097
00098 OutSerializer::~OutSerializer()
00099 {
00100 if (external_state_)
00101 {
00102 *external_state_ = state_;
00103 }
00104 else if (state_.cur_chunk_)
00105 {
00106 delete state_.cur_chunk_;
00107 state_.cur_chunk_ = 0;
00108 }
00109 }
00110
00111 static void SAddCharStr(OutSerializer &out, const char *data, size_t len)
00112 {
00113 if (len >= 65535)
00114 {
00115 len = 65534;
00116 }
00117
00118 lcore::U2Byte netlen = len;
00119
00120 out.addU2Byte(netlen + 1);
00121 out.addRaw(data, netlen);
00122 out.addU1Byte('\0');
00123 }
00124
00125 void OutSerializer::addString(const ::std::string &str)
00126 {
00127 size_t len = str.length();
00128
00129 SAddCharStr(*this, str.c_str(), len);
00130 }
00131
00132 void OutSerializer::addString(const char *str)
00133 {
00134 SAddCharStr(*this, str, strlen(str));
00135 }
00136
00137 BufferChunk *OutSerializer::takeChunk()
00138 {
00139 assert(state_.cur_chunk_ != 0);
00140
00141 BufferChunk *temp = state_.cur_chunk_;
00142
00143 state_.cur_chunk_ = 0;
00144 state_.buf_ = 0;
00145 state_.chnklen_ = 0;
00146 temp->resize(state_.cur_pos_);
00147 state_.cur_pos_ = 0;
00148 return(temp);
00149 }
00150
00151 void OutSerializer::resizeChunk(size_t newsize)
00152 {
00153 assert(state_.cur_chunk_ != 0);
00154
00155 if ((newsize - state_.chnklen_) < 256)
00156 {
00157 state_.cur_chunk_->resize(newsize + newsize / 16);
00158 }
00159 else
00160 {
00161 state_.cur_chunk_->resize(newsize + newsize / 256);
00162 }
00163 state_.buf_ = state_.cur_chunk_->getCharP();
00164 state_.chnklen_ = state_.cur_chunk_->Length();
00165 assert(state_.chnklen_ >= newsize);
00166 }
00167
00168 };
00169 };