21 #ifndef INCLUDE_SF_SERIALIZER_HPP 22 #define INCLUDE_SF_SERIALIZER_HPP 24 #include <RCF/Exception.hpp> 25 #include <RCF/Export.hpp> 26 #include <RCF/MemStream.hpp> 27 #include <RCF/TypeTraits.hpp> 29 #include <SF/Archive.hpp> 30 #include <SF/I_Stream.hpp> 31 #include <SF/SerializeFundamental.hpp> 32 #include <SF/SfNew.hpp> 33 #include <RCF/Tools.hpp> 39 class RCF_EXPORT SerializerBase : Noncopyable
42 void invokeRead(Archive &ar);
43 void invokeWrite(Archive &ar);
46 virtual std::string getTypeName() = 0;
47 virtual void newObject(Archive &ar) = 0;
48 virtual bool isDerived() = 0;
49 virtual std::string getDerivedTypeName() = 0;
50 virtual void getSerializerPolymorphic(
const std::string &derivedTypeName) = 0;
51 virtual void invokeSerializerPolymorphic(
SF::Archive &) = 0;
52 virtual void serializeContents(Archive &ar) = 0;
53 virtual void addToInputContext(IStream *,
const UInt32 &) = 0;
54 virtual bool queryInputContext(IStream *,
const UInt32 &) = 0;
55 virtual void addToOutputContext(OStream *, UInt32 &) = 0;
56 virtual bool queryOutputContext(OStream *, UInt32 &) = 0;
57 virtual void setFromId() = 0;
58 virtual void setToNull() = 0;
59 virtual bool isNull() = 0;
60 virtual bool isNonAtomic() = 0;
64 virtual ~SerializerBase();
65 void invoke(Archive &ar);
73 #pragma warning( push ) 74 #pragma warning( disable : 4675 ) // warning C4675: resolved overload was found by argument-dependent lookup 75 #pragma warning( disable : 4702 ) // warning C4702: unreachable code 78 class I_SerializerPolymorphic;
81 class Serializer :
public SerializerBase
89 I_SerializerPolymorphic * pf;
92 std::string getTypeName();
93 void newObject(Archive &ar);
95 std::string getDerivedTypeName();
96 void getSerializerPolymorphic(
const std::string &derivedTypeName);
98 void serializeContents(Archive &ar);
99 void addToInputContext(
SF::IStream *stream,
const UInt32 &nid);
100 bool queryInputContext(
SF::IStream *stream,
const UInt32 &nid);
101 void addToOutputContext(
SF::OStream *stream, UInt32 &nid);
102 bool queryOutputContext(
SF::OStream *stream, UInt32 &nid);
110 #pragma warning( pop ) 113 template<
typename PPT>
114 struct GetIndirection
116 typedef typename RCF::RemovePointer<PPT>::type PT;
117 typedef typename RCF::IsPointer<PPT>::type is_single;
118 typedef typename RCF::IsPointer<PT>::type is_double;
132 typename RCF::RemoveCv<
133 typename RCF::RemovePointer<
134 typename RCF::RemoveCv<
135 typename RCF::RemovePointer<
136 typename RCF::RemoveCv<PPT>::type
144 inline void invokeCustomSerializer(
149 static_assert(!RCF::IsPointer<T>::value,
"Incorrect serialization code.");
150 Serializer<T>(ppt).invoke(ar);
153 template<
typename U,
typename T>
154 inline void invokeSerializer(
161 static_assert(!RCF::IsPointer<T>::value,
"Incorrect serialization code.");
162 T *pt =
const_cast<T *
>(&u);
163 invokeCustomSerializer( (T **) (&pt), ar, 0);
166 template<
typename U,
typename T>
167 inline void invokeSerializer(
174 static_assert(!RCF::IsPointer<T>::value,
"Incorrect serialization code.");
175 invokeCustomSerializer( (T **) (&u), ar, 0);
178 template<
typename U,
typename T>
179 inline void invokeSerializer(
186 static_assert(!RCF::IsPointer<T>::value,
"Incorrect serialization code.");
187 invokeCustomSerializer( (T**) (u), ar, 0);
191 inline void invokeSerializer(U u, Archive &ar)
193 typedef typename GetIndirection<U>::Level Level;
194 typedef typename GetIndirection<U>::Base T;
195 static_assert(!RCF::IsPointer<T>::value,
"Incorrect serialization code.");
196 invokeSerializer( (U *) 0, (T *) 0, (Level *) 0, u, ar);
200 inline void invokePtrSerializer(U u, Archive &ar)
202 typedef typename GetIndirection<U>::Level Level;
203 const int levelOfIndirection = Level::value;
204 static_assert( levelOfIndirection == 1 || levelOfIndirection == 2,
"Incorrect value from GetIndirection<>.");
205 const bool isPointer = (levelOfIndirection == 2);
212 ar.setFlag( SF::Archive::POINTER, isPointer );
218 invokeSerializer(u, ar);
231 if (runtimeVersion >= 2)
233 ar & SF::Archive::Flag(SF::Archive::NO_BEGIN_END);
250 inline void serializeInternal(Archive &archive, T &t)
267 t.serialize(archive);
271 inline void serializeFundamentalOrNot(
276 serializeFundamental(archive, t);
280 inline void serializeFundamentalOrNot(
285 serializeInternal(archive, t);
289 inline void serializeEnumOrNot(
294 serializeEnum(archive, t);
298 inline void serializeEnumOrNot(
303 typedef typename RCF::IsFundamental<T>::type type;
304 serializeFundamentalOrNot(archive, t, (type *) NULL);
308 inline void serialize(
312 typedef typename std::is_enum<T>::type type;
313 serializeEnumOrNot(archive, t, (type *) NULL);
317 inline void serialize_vc6(
322 serialize(archive, t);
326 inline void preserialize(
331 static_assert(!RCF::IsPointer<T>::value,
"Incorrect serialization code.");
332 typedef typename RCF::RemoveCv<T>::type U;
333 serialize_vc6(archive, (U &) *pt, static_cast<const unsigned int>(0) );
341 invokePtrSerializer(&t, archive);
345 template<
typename T,
typename U>
346 inline void serializeAs(Archive & ar, T &t)
350 U u =
static_cast<U
>(t);
357 t =
static_cast<T
>(u);
362 #define SF_SERIALIZE_ENUM_CLASS(EnumType, BaseType) \ 363 void serialize(SF::Archive & ar, EnumType & e) \ 365 SF::serializeAs<EnumType, BaseType>(ar, e); \ 371 #include <SF/SerializePolymorphic.hpp> 372 #include <SF/Stream.hpp> 377 Serializer<T>::Serializer(T **ppt) :
384 std::string Serializer<T>::getTypeName()
386 return SF::Registry::getSingleton().getTypeName( (T *) 0);
390 #pragma warning( push ) 391 #pragma warning( disable: 4702 ) 395 void Serializer<T>::newObject(Archive &ar)
397 *ppt = sfNew((T *) NULL, (T **) NULL, ar);
401 #pragma warning( pop ) 405 bool Serializer<T>::isDerived()
407 static const bool isFundamental = RCF::IsFundamental<T>::value;
408 if RCF_CONSTEXPR(!isFundamental)
410 if ( *ppt &&
typeid(T) !=
typeid(**ppt) )
412 if ( !SF::Registry::getSingleton().isTypeRegistered(
typeid(**ppt)) )
414 RCF::Exception e(RCF::RcfError_SfTypeRegistration,
typeid(**ppt).name());
424 std::string Serializer<T>::getDerivedTypeName()
426 return SF::Registry::getSingleton().getTypeName(
typeid(**ppt) );
430 void Serializer<T>::getSerializerPolymorphic(
431 const std::string &derivedTypeName)
433 pf = & SF::Registry::getSingleton().getSerializerPolymorphic(
439 void Serializer<T>::invokeSerializerPolymorphic(
SF::Archive &ar)
442 void **ppvb = (
void **) (ppt);
443 pf->invoke(ppvb, ar);
447 void Serializer<T>::serializeContents(Archive &ar)
449 preserialize(ar, *ppt, 0);
453 void Serializer<T>::addToInputContext(
SF::IStream *stream,
const UInt32 &nid)
455 ContextRead &ctx = stream->getTrackingContext();
456 ctx.add(nid, IdT( (
void *) (*ppt), &
typeid(T)));
460 bool Serializer<T>::queryInputContext(
SF::IStream *stream,
const UInt32 &nid)
462 ContextRead &ctx = stream->getTrackingContext();
463 return ctx.query(nid,
id);
467 void Serializer<T>::addToOutputContext(
SF::OStream *stream, UInt32 &nid)
469 ContextWrite &ctx = stream->getTrackingContext();
470 ctx.add( IdT( (
void *) *ppt, &
typeid(T)), nid);
474 bool Serializer<T>::queryOutputContext(
SF::OStream *stream, UInt32 &nid)
476 ContextWrite &ctx = stream->getTrackingContext();
477 return ctx.query( IdT( (
void *) *ppt, &
typeid(T)), nid);
481 void Serializer<T>::setFromId()
483 *ppt =
reinterpret_cast<T *
>(
id.first);
487 void Serializer<T>::setToNull()
493 bool Serializer<T>::isNull()
499 bool Serializer<T>::isNonAtomic()
501 bool isFundamental = RCF::IsFundamental<T>::value;
502 return !isFundamental;
507 #endif // ! INCLUDE_SF_SERIALIZER_HPP Represents an archive, in which serialized objects are stored.
Definition: Archive.hpp:32
int getRuntimeVersion()
Gets the RCF runtime version associated with this archive.
Base class for all RCF exceptions.
Definition: Exception.hpp:64
Definition: ByteBuffer.hpp:189
Base class for output streams using SF serialization. Use operator <<() to serialize objects into the...
Definition: Stream.hpp:236
bool isRead() const
Returns true if this archive is being read from.
Base class for input streams using SF serialization. Use operator >>() to deserialize objects from th...
Definition: Stream.hpp:138