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 #include <base/BinarySerializer>
00026
00027 #include <base/Serializable>
00028
00029 using base::BinarySerializer;
00030 using base::Serializer;
00031 using base::Serializable;
00032 using base::Referenced;
00033 using base::VFile;
00034 using base::ref;
00035
00036 using std::iostream;
00037 using std::istream;
00038 using std::ostream;
00039 using std::ios;
00040 using std::streambuf;
00041
00042
00043 #ifdef DEBUG
00044
00045
00046
00047
00048 #endif
00049
00050
00051 BinarySerializer::BinarySerializer(SerializerType type, ref<VFile> archive)
00052 : Serializer(type,archive),
00053 stream(output?archive->iostream(iostream::binary|iostream::out)
00054 :archive->iostream(iostream::binary|iostream::in)),
00055 buf(*stream.rdbuf())
00056 {
00057 #ifdef SDEBUG
00058 Debugln(Ser,"Constructed:" << (isOutput()?String("Output"):String("Input")) );
00059 #endif
00060 }
00061
00062 BinarySerializer::BinarySerializer(SerializerType type, std::ios& stream)
00063 : Serializer(type,stream),
00064 stream(stream),
00065 buf(*stream.rdbuf())
00066 {
00067 Assert(output?instanceof(stream, ostream)
00068 :instanceof(stream, istream));
00069 #ifdef SDEBUG
00070 Debugln(Ser,"Constructed:" << (isOutput()?String("Output"):String("Input")) );
00071 #endif
00072 }
00073
00074 BinarySerializer::~BinarySerializer()
00075 {
00076 }
00077
00078
00079 bool BinarySerializer::followReferences(bool follow)
00080 {
00081 #ifdef SDEBUG
00082 Debugln(Ser,"Reference following " << (follow?String("enabled"):String("disabled")));
00083 #endif
00084 return Serializer::followReferences(follow);
00085 }
00086
00087
00088 Serializer& BinarySerializer::serialize(char& c, const String& memberName)
00089 {
00090 if (output)
00091 buf.sputc(c);
00092 else
00093 c = char(buf.sbumpc());
00094 #ifdef SDEBUG
00095
00096 #endif
00097 return *this;
00098 }
00099
00100 Serializer& BinarySerializer::serialize(Byte& b, const String& memberName)
00101 {
00102 if (output)
00103 buf.sputc(char(b));
00104 else
00105 b = Byte(buf.sbumpc());
00106 #ifdef SDEBUG
00107 Debugln(Ser,"serialized Byte:" << b);
00108 #endif
00109 return *this;
00110 }
00111
00112 Serializer& BinarySerializer::serialize(bool& b, const String& memberName)
00113 {
00114 if (output)
00115 buf.sputc(char(b));
00116 else
00117 b = Byte(buf.sbumpc());
00118 #ifdef SDEBUG
00119 Debugln(Ser,"serialized bool:" << b);
00120 #endif
00121 return *this;
00122 }
00123
00124 Serializer& BinarySerializer::serialize(SInt& i, const String& memberName)
00125 {
00126 if (output)
00127 buf.sputn((const char*)(&i),sizeof(SInt));
00128 else
00129 buf.sgetn((char*)(&i),sizeof(SInt));
00130 #ifdef SDEBUG
00131 Debugln(Ser,"serialized SInt:" << i);
00132 #endif
00133 return *this;
00134 }
00135
00136 Serializer& BinarySerializer::serialize(Int& i, const String& memberName)
00137 {
00138 if (output)
00139 buf.sputn((const char*)(&i),sizeof(Int));
00140 else
00141 buf.sgetn((char*)(&i),sizeof(Int));
00142 #ifdef SDEBUG
00143 Debugln(Ser,"serialized Int:" << i);
00144 #endif
00145 return *this;
00146 }
00147
00148 Serializer& BinarySerializer::serialize(LInt& i, const String& memberName)
00149 {
00150 if (output)
00151 buf.sputn((const char*)(&i),sizeof(LInt));
00152 else
00153 buf.sgetn((char*)(&i),sizeof(LInt));
00154 #ifdef SDEBUG
00155 Debugln(Ser,"serialized LInt:" << i);
00156 #endif
00157 return *this;
00158 }
00159
00160 Serializer& BinarySerializer::serialize(String& s, const String& memberName)
00161 {
00162 if (output) {
00163 Int len = s.length();
00164 operator()(len);
00165 if (len>0)
00166 buf.sputn((const char*)(s.c_str()),len);
00167 }
00168 else {
00169 Int len;
00170 operator()(len);
00171 if (len>0) {
00172 char* sbuf = new char[len+1];
00173 buf.sgetn(sbuf,len);
00174 sbuf[len]=char(0);
00175 s = String(sbuf);
00176 delete[] sbuf;
00177 }
00178 }
00179 #ifdef SDEBUG
00180 Debugln(Ser,"serialized String:" << s);
00181 #endif
00182 return *this;
00183 }
00184
00185 Serializer& BinarySerializer::serialize(Real& r, const String& memberName)
00186 {
00187 if (output)
00188 buf.sputn((const char*)(&r),sizeof(Real));
00189 else
00190 buf.sgetn((char*)(&r),sizeof(Real));
00191 #ifdef SDEBUG
00192 Debugln(Ser,"serialized Real:" << r);
00193 #endif
00194 return *this;
00195 }
00196
00197 void BinarySerializer::flush()
00198 {
00199 if (output) {
00200 if (instanceof(stream,std::ostream)) {
00201 std::ostream* out = dynamic_cast<std::ostream*>(&stream);
00202 (*out) << std::flush;
00203 }
00204 }
00205 }
00206
00207
00208
00209 Serializer::TypeModifier BinarySerializer::preSerializeObject(String& typeName, TypeModifier typeModifier, const String& memberName, bool forceTypeSerialization)
00210 {
00211 if (output) {
00212 switch (typeModifier) {
00213 case ObjectType: break;
00214 case ReferencedObjectType:
00215 operator()(char(ReferencedObjectType)); break;
00216 case ObjectReferenceType:
00217 operator()(char(ObjectReferenceType)); break;
00218 default:
00219 abort(String("unknown/invalid typeModifier passed for output. Member:")+memberName);
00220 }
00221 operator()(forceTypeSerialization);
00222
00223 if (forceTypeSerialization) {
00224 String typeString;
00225 try {
00226 typeString = base::demangleTypeidName(typeName);
00227 } catch (std::exception& e) {
00228 abort(String("error demangling typeName:")+typeName+" for member "+memberName+" - "+e.what());
00229 }
00230
00231 operator()(typeString);
00232 }
00233 return typeModifier;
00234 }
00235 else {
00236
00237 TypeModifier readTypeModifier = ObjectType;
00238 if (typeModifier != ObjectType) {
00239
00240
00241
00242 char c;
00243 operator()(c);
00244 readTypeModifier = TypeModifier(Int(c));
00245
00246 if ((readTypeModifier == UnknownType) || (readTypeModifier >= InvalidType))
00247 abort("unknown serialized object type read");
00248
00249
00250 if (typeModifier != UnknownType) {
00251 if (readTypeModifier != typeModifier)
00252 abort("unexpected serialized referenced object type read");
00253 }
00254 }
00255
00256 bool typeSerialized(false);
00257 operator()(typeSerialized);
00258 if (typeSerialized) {
00259 String readTypeName;
00260 operator()(readTypeName);
00261 if (typeName.empty())
00262 typeName = readTypeName;
00263 else
00264 if (typeName != readTypeName)
00265 abort(String("read type "+readTypeName+" but expected "+typeName));
00266 }
00267 else
00268 typeName.clear();
00269
00270 return readTypeModifier;
00271 }
00272 }