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 #ifndef _BASE_SERIALIZER_
00026 #define _BASE_SERIALIZER_
00027
00028 #include <base/base>
00029 #include <base/Serializable>
00030 #include <base/Referenced>
00031 #include <base/array>
00032 #include <base/ref>
00033 #include <base/reflist>
00034 #include <base/serialization_error>
00035 #include <base/VFile>
00036
00037 #include <base/Time>
00038 #include <base/Vector3>
00039 #include <base/Quat4>
00040 #include <base/Orient>
00041 #include <base/Matrix3>
00042 #include <base/Matrix4>
00043 #include <base/Vector>
00044 #include <base/Matrix>
00045
00046
00047 #include <iostream>
00048 #include <list>
00049
00050
00051 namespace base {
00052
00053 class Serializable;
00054
00055
00056 class Serializer : public Object
00057 {
00058 public:
00059 enum SerializerType { Input=0, Output=1 };
00060 Serializer(SerializerType type);
00061 Serializer(SerializerType type, ref<VFile> archive);
00062 Serializer(SerializerType type, std::ios& stream);
00063 virtual ~Serializer();
00064
00065 virtual bool isOutput() const { return output; }
00066 virtual bool isInput() const { return !isOutput(); }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 virtual bool followReferences(bool follow);
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 Serializer& comment(const String& comment) { serializeComment(comment); return *this; }
00108
00109 enum Hint { Indent=0, Unindent=1 };
00110
00111 virtual Serializer& hint(Int h) { return *this; }
00112
00113
00114
00115 Serializer& operator()(char& c, const String& memberName = "") { return serialize(c, memberName); }
00116 Serializer& operator()(const char& c, const String& memberName = "")
00117 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return serialize(const_cast<char&>(c), memberName); }
00118
00119 Serializer& operator()(Byte& b, const String& memberName = "") { return serialize(b, memberName); }
00120 Serializer& operator()(const Byte& b, const String& memberName = "")
00121 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return serialize(const_cast<Byte&>(b), memberName); }
00122
00123 Serializer& operator()(bool& b, const String& memberName = "") { return serialize(b, memberName); }
00124 Serializer& operator()(const bool& b, const String& memberName = "")
00125 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return serialize(const_cast<bool&>(b), memberName); }
00126
00127 Serializer& operator()(SInt& i, const String& memberName = "") { return serialize(i, memberName); }
00128 Serializer& operator()(const SInt& i, const String& memberName = "")
00129 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return serialize(const_cast<SInt&>(i), memberName); }
00130
00131 Serializer& operator()(Int& i, const String& memberName = "") { return serialize(i, memberName); }
00132 Serializer& operator()(const Int& i, const String& memberName = "")
00133 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return serialize(const_cast<Int&>(i), memberName); }
00134
00135 Serializer& operator()(LInt& i, const String& memberName = "") { return serialize(i, memberName); }
00136 Serializer& operator()(const LInt& i, const String& memberName = "")
00137 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return serialize(const_cast<LInt&>(i), memberName); }
00138
00139 Serializer& operator()(Real& r, const String& memberName = "") { return serialize(r, memberName); }
00140 Serializer& operator()(const Real& r, const String& memberName = "")
00141 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return serialize(const_cast<Real&>(r), memberName); }
00142
00143
00144
00145 Serializer& operator()(String& s, const String& memberName = "") { return serialize(s, memberName); }
00146 Serializer& operator()(const String& s, const String& memberName = "")
00147 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return serialize(const_cast<String&>(s), memberName); }
00148
00149 Serializer& operator()(Time& t, const String& memberName = "")
00150 { t.serialize(*this); return *this; }
00151 Serializer& operator()(const Time& t, const String& memberName = "")
00152 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return operator()(const_cast<Time&>(t), memberName); }
00153
00154 Serializer& operator()(Vector3& v, const String& memberName = "")
00155 { v.serialize(*this); return *this; }
00156 Serializer& operator()(const Vector3& v, const String& memberName = "")
00157 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return operator()(const_cast<Vector3&>(v), memberName); }
00158
00159 Serializer& operator()(Quat4& q, const String& memberName = "")
00160 { q.serialize(*this); return *this; }
00161 Serializer& operator()(const Quat4& q, const String& memberName = "")
00162 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return operator()(const_cast<Quat4&>(q), memberName); }
00163
00164 Serializer& operator()(Orient& o, const String& memberName = "")
00165 { o.serialize(*this); return *this; }
00166 Serializer& operator()(const Orient& o, const String& memberName = "")
00167 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return operator()(const_cast<Orient&>(o), memberName); }
00168
00169 Serializer& operator()(Matrix3& m, const String& memberName = "")
00170 { m.serialize(*this); return *this; }
00171 Serializer& operator()(const Matrix3& m, const String& memberName = "")
00172 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return operator()(const_cast<Matrix3&>(m), memberName); }
00173
00174 Serializer& operator()(Matrix4& m, const String& memberName = "")
00175 { m.serialize(*this); return *this; }
00176 Serializer& operator()(const Matrix4& m, const String& memberName = "")
00177 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return operator()(const_cast<Matrix4&>(m), memberName); }
00178
00179 Serializer& operator()(Vector& v, const String& memberName = "");
00180 Serializer& operator()(const Vector& v, const String& memberName = "")
00181 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return operator()(const_cast<Vector&>(v), memberName); }
00182
00183 Serializer& operator()(Matrix& m, const String& memberName = "");
00184 Serializer& operator()(const Matrix& m, const String& memberName = "")
00185 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return operator()(const_cast<Matrix&>(m), memberName); }
00186
00187
00188
00189
00190
00191
00192
00193 Serializer& operator()(Serializable& r, const String& memberName = "") { return serialize(r, memberName); }
00194 Serializer& operator()(const Serializable& r, const String& memberName = "")
00195 { if (!output) throw serialization_error(Exception(inputToConstErrorString)); else return serialize(const_cast<Serializable&>(r), memberName); }
00196
00197
00198
00199 template<class T>
00200 Serializer& operator()(ref<T>& r, const String& memberName = "")
00201 {
00202 T* p = GetImplRef(r);
00203
00204 Serializable* sp = 0;
00205 if (p!=0) {
00206 if (!instanceof(*p,Serializable))
00207 throw serialization_error(Exception("can only archive references to Serializable derived classes (ref<Serializable>)"));
00208 sp = dynamic_cast<Serializable*>(p);
00209 }
00210
00211 if (!output) {
00212 Serializable::SerializableDerivedInstantiator<T> i;
00213 serializePointer(sp,(sp==0)?&i:0, memberName);
00214 Assert(sp);
00215 p = dynamic_cast<T*>(sp);
00216 Reset(r,p);
00217 }
00218 else
00219 serializePointer(sp,0, memberName);
00220
00221 return *this;
00222 }
00223
00224
00225 template<class T>
00226 Serializer& baseRef(ref<T>& r, const String& memberName = "")
00227 {
00228 T* p = GetImplRef(r);
00229
00230 Serializable* sp = 0;
00231 if (p!=0) {
00232 if (!instanceof(*p,Serializable))
00233 throw serialization_error(Exception("can only archive references to Serializable derived classes (ref<Serializable>)"));
00234 sp = dynamic_cast<Serializable*>(p);
00235 }
00236
00237 if (!output) {
00238
00239 r = ref<T>();
00240 sp = 0;
00241 serializePointer(sp,0, memberName,true);
00242 Assert(sp);
00243 p = dynamic_cast<T*>(sp);
00244 Reset(r,p);
00245 }
00246 else
00247 serializePointer(sp,0, memberName, true);
00248
00249 return *this;
00250 }
00251
00252
00253 template<class T>
00254 Serializer& operator()(const ref<T>& r, const String& memberName = "")
00255 {
00256 if (!output)
00257 throw serialization_error(Exception("can't input to a const ref<>"));
00258
00259 T* p = GetImplRef(r);
00260
00261 Serializable* sp = 0;
00262 if (p != 0) {
00263 if (!instanceof(*p,Serializable))
00264 throw serialization_error(Exception("can only archive references to Serializable derived classes (ref<Serializable>)"));
00265 sp = dynamic_cast<Serializable*>(p);
00266 }
00267 serializePointer(sp,0, memberName);
00268 return *this;
00269 }
00270
00271
00272
00273 template<class T>
00274 Serializer& operator()(array<T>& a, const String& memberName = "")
00275 {
00276 serializeComment(String("begin array ")+memberName);
00277 Int size = a.size();
00278 operator()(size, "size");
00279 for(Int i=0; i<size; i++)
00280 operator()(a.at(i));
00281 serializeComment(String("end array ")+memberName);
00282 return *this;
00283 }
00284
00285 template<class T>
00286 Serializer& operator()(const array<T>& a, const String& memberName = "")
00287 {
00288 if (!output)
00289 throw serialization_error(Exception(inputToConstErrorString));
00290
00291 serializeComment(String("begin array ")+memberName);
00292 Int size = a.size();
00293 operator()(size, "size");
00294 for(Int i=0; i<a.size(); i++)
00295 operator()(a[i]);
00296 serializeComment(String("end array ")+memberName);
00297 return *this;
00298 }
00299
00300
00301 template<class T>
00302 Serializer& operator()(std::list<T>& l, const String& memberName = "")
00303 {
00304 if (output) {
00305 serializeComment(String("begin list ")+memberName);
00306 Int size = l.size();
00307 operator()(size, "size");
00308 typename std::list<T>::iterator i = l.begin();
00309 typename std::list<T>::iterator end = l.end();
00310 while (i != end) {
00311 operator()(*i);
00312 ++i;
00313 }
00314 serializeComment(String("end list ")+memberName);
00315 }
00316 else {
00317 l.clear();
00318 Int size;
00319 operator()(size, "size");
00320 if (size > 0) {
00321 T e;
00322 for(Int i=0; i<size; i++) {
00323 operator()(e);
00324 l.push_back( e );
00325 }
00326 }
00327 }
00328
00329 return *this;
00330 }
00331
00332 template<class T>
00333 Serializer& operator()(const std::list<T>& a, const String& memberName = "")
00334 {
00335 if (!output)
00336 throw serialization_error(Exception(inputToConstErrorString));
00337 return operator()(const_cast<std::list<T>&>(a), memberName);
00338 }
00339
00340
00341
00342 template<class T>
00343 Serializer& operator()(reflist<T>& l, const String& memberName = "")
00344 {
00345 if (output) {
00346 serializeComment(String("begin reflist ")+memberName);
00347 Int size = l.size();
00348 operator()(size, "size");
00349 typename reflist<T>::iterator i = l.begin();
00350 typename reflist<T>::iterator end = l.end();
00351 while (i != end) {
00352 operator()(*i);
00353 ++i;
00354 }
00355 serializeComment(String("end reflist ")+memberName);
00356 }
00357 else {
00358 l.clear();
00359 Int size;
00360 operator()(size, "size");
00361 if (size > 0) {
00362 for(Int i=0; i<size; i++) {
00363 ref<T> e(0);
00364 operator()(e);
00365 l.push_back( e );
00366 }
00367 }
00368 }
00369
00370 return *this;
00371 }
00372
00373 template<class T>
00374 Serializer& operator()(const reflist<T>& l, const String& memberName = "")
00375 {
00376 if (!output)
00377 throw serialization_error(Exception(inputToConstErrorString));
00378 return operator()(const_cast<reflist<T>&>(l), memberName);
00379 }
00380
00381
00382 virtual void flush() = 0;
00383
00384 protected:
00385 Serializer(const Serializer& s) : output(s.output), follow(s.follow), aborted(s.aborted) {}
00386
00387 const static String inputToConstErrorString;
00388
00389
00390 virtual void serializeReferenceIndex(Int& index)
00391 { operator()(index,"refindex"); }
00392 virtual void serializePointer(Serializable*& p, Serializable::SerializableInstantiator* i, const String& memberName, bool forceTypeSerialization = false);
00393
00394 void abort(const String& exceptionString);
00395
00396
00397
00398
00399
00400
00401
00402 virtual Serializer& serialize(char& c, const String& memberName) = 0;
00403 virtual Serializer& serialize(Byte& b, const String& memberName) = 0;
00404 virtual Serializer& serialize(bool& b, const String& memberName) = 0;
00405 virtual Serializer& serialize(SInt& i, const String& memberName) = 0;
00406 virtual Serializer& serialize(Int& i, const String& memberName) = 0;
00407 virtual Serializer& serialize(LInt& i, const String& memberName) = 0;
00408 virtual Serializer& serialize(String& s, const String& memberName) = 0;
00409 virtual Serializer& serialize(Real& r, const String& memberName) = 0;
00410
00411
00412 enum TypeModifier { UnknownType = 0,
00413 ObjectType = 1,
00414 ReferencedObjectType = 2,
00415 ObjectReferenceType = 3,
00416 InvalidType = 4 };
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 virtual TypeModifier preSerializeObject(String& typeName, TypeModifier typeModifier, const String& memberName, bool forceTypeSerialization = false) = 0;
00457
00458
00459
00460 virtual void postSerializeObject(const String& memberName) = 0;
00461
00462
00463
00464 virtual Serializer& serialize(Serializable& r, const String& memberName);
00465
00466
00467 virtual void serializeComment(const String& comment) {}
00468
00469
00470
00471
00472 bool output;
00473 bool follow;
00474 bool aborted;
00475
00476 Int ptrIndex(Serializable* p);
00477
00478 array<Serializable*> ptrs;
00479 array<bool> serialized;
00480 Int serializePointerRecursionDepth;
00481 Int depthAtFollowDisable;
00482 };
00483
00484
00485 }
00486
00487 #endif