20 #ifndef INCLUDE_SF_SERIALIZER_HPP 21 #define INCLUDE_SF_SERIALIZER_HPP 23 #include <RCF/Exception.hpp> 24 #include <RCF/Export.hpp> 25 #include <RCF/MemStream.hpp> 26 #include <RCF/TypeTraits.hpp> 28 #include <SF/Archive.hpp> 29 #include <SF/I_Stream.hpp> 30 #include <SF/SerializeFundamental.hpp> 31 #include <SF/SfNew.hpp> 32 #include <RCF/Tools.hpp> 38 class RCF_EXPORT SerializerBase : Noncopyable
41 void invokeRead(Archive &ar);
42 void invokeWrite(Archive &ar);
45 virtual std::string getTypeName() = 0;
46 virtual void newObject(Archive &ar) = 0;
47 virtual bool isDerived() = 0;
48 virtual std::string getDerivedTypeName() = 0;
49 virtual void getSerializerPolymorphic(
const std::string &derivedTypeName) = 0;
50 virtual void invokeSerializerPolymorphic(
SF::Archive &) = 0;
51 virtual void serializeContents(Archive &ar) = 0;
52 virtual void addToInputContext(IStream *,
const UInt32 &) = 0;
53 virtual bool queryInputContext(IStream *,
const UInt32 &) = 0;
54 virtual void addToOutputContext(OStream *, UInt32 &) = 0;
55 virtual bool queryOutputContext(OStream *, UInt32 &) = 0;
56 virtual void setFromId() = 0;
57 virtual void setToNull() = 0;
58 virtual bool isNull() = 0;
59 virtual bool isNonAtomic() = 0;
63 virtual ~SerializerBase();
64 void invoke(Archive &ar);
72 #pragma warning( push ) 73 #pragma warning( disable : 4675 ) // warning C4675: resolved overload was found by argument-dependent lookup 74 #pragma warning( disable : 4702 ) // warning C4702: unreachable code 77 class I_SerializerPolymorphic;
80 class Serializer :
public SerializerBase
88 I_SerializerPolymorphic * pf;
91 std::string getTypeName();
92 void newObject(Archive &ar);
94 std::string getDerivedTypeName();
95 void getSerializerPolymorphic(
const std::string &derivedTypeName);
97 void serializeContents(Archive &ar);
98 void addToInputContext(
SF::IStream *stream,
const UInt32 &nid);
99 bool queryInputContext(
SF::IStream *stream,
const UInt32 &nid);
100 void addToOutputContext(
SF::OStream *stream, UInt32 &nid);
101 bool queryOutputContext(
SF::OStream *stream, UInt32 &nid);
109 #pragma warning( pop ) 112 template<
typename PPT>
113 struct GetIndirection
115 typedef typename RCF::RemovePointer<PPT>::type PT;
116 typedef typename RCF::IsPointer<PPT>::type is_single;
117 typedef typename RCF::IsPointer<PT>::type is_double;
131 typename RCF::RemoveCv<
132 typename RCF::RemovePointer<
133 typename RCF::RemoveCv<
134 typename RCF::RemovePointer<
135 typename RCF::RemoveCv<PPT>::type
143 inline void invokeCustomSerializer(
148 static_assert(!RCF::IsPointer<T>::value,
"Incorrect serialization code.");
149 Serializer<T>(ppt).invoke(ar);
152 template<
typename U,
typename T>
153 inline void invokeSerializer(
160 static_assert(!RCF::IsPointer<T>::value,
"Incorrect serialization code.");
161 T *pt =
const_cast<T *
>(&u);
162 invokeCustomSerializer( (T **) (&pt), ar, 0);
165 template<
typename U,
typename T>
166 inline void invokeSerializer(
173 static_assert(!RCF::IsPointer<T>::value,
"Incorrect serialization code.");
174 invokeCustomSerializer( (T **) (&u), ar, 0);
177 template<
typename U,
typename T>
178 inline void invokeSerializer(
185 static_assert(!RCF::IsPointer<T>::value,
"Incorrect serialization code.");
186 invokeCustomSerializer( (T**) (u), ar, 0);
190 inline void invokeSerializer(U u, Archive &ar)
192 typedef typename GetIndirection<U>::Level Level;
193 typedef typename GetIndirection<U>::Base T;
194 static_assert(!RCF::IsPointer<T>::value,
"Incorrect serialization code.");
195 invokeSerializer( (U *) 0, (T *) 0, (Level *) 0, u, ar);
199 inline void invokePtrSerializer(U u, Archive &ar)
201 typedef typename GetIndirection<U>::Level Level;
202 const int levelOfIndirection = Level::value;
203 static_assert( levelOfIndirection == 1 || levelOfIndirection == 2,
"Incorrect value from GetIndirection<>.");
204 const bool isPointer = (levelOfIndirection == 2);
211 ar.setFlag( SF::Archive::POINTER, isPointer );
217 invokeSerializer(u, ar);
230 if (runtimeVersion >= 2)
232 ar & SF::Archive::Flag(SF::Archive::NO_BEGIN_END);
249 inline void serializeInternal(Archive &archive, T &t)
266 t.serialize(archive);
270 inline void serializeFundamentalOrNot(
275 serializeFundamental(archive, t);
279 inline void serializeFundamentalOrNot(
284 serializeInternal(archive, t);
288 inline void serializeEnumOrNot(
293 serializeEnum(archive, t);
297 inline void serializeEnumOrNot(
302 typedef typename RCF::IsFundamental<T>::type type;
303 serializeFundamentalOrNot(archive, t, (type *) NULL);
307 inline void serialize(
311 typedef typename std::is_enum<T>::type type;
312 serializeEnumOrNot(archive, t, (type *) NULL);
316 inline void serialize_vc6(
321 serialize(archive, t);
325 inline void preserialize(
330 static_assert(!RCF::IsPointer<T>::value,
"Incorrect serialization code.");
331 typedef typename RCF::RemoveCv<T>::type U;
332 serialize_vc6(archive, (U &) *pt, static_cast<const unsigned int>(0) );
340 invokePtrSerializer(&t, archive);
344 template<
typename T,
typename U>
345 inline void serializeAs(Archive & ar, T &t)
349 U u =
static_cast<U
>(t);
356 t =
static_cast<T
>(u);
361 #define SF_SERIALIZE_ENUM_CLASS(EnumType, BaseType) \ 362 void serialize(SF::Archive & ar, EnumType & e) \ 364 SF::serializeAs<EnumType, BaseType>(ar, e); \ 370 #include <SF/SerializePolymorphic.hpp> 371 #include <SF/Stream.hpp> 376 Serializer<T>::Serializer(T **ppt) :
383 std::string Serializer<T>::getTypeName()
385 return SF::Registry::getSingleton().getTypeName( (T *) 0);
389 #pragma warning( push ) 390 #pragma warning( disable: 4702 ) 394 void Serializer<T>::newObject(Archive &ar)
396 *ppt = sfNew((T *) NULL, (T **) NULL, ar);
400 #pragma warning( pop ) 404 bool Serializer<T>::isDerived()
406 static const bool isFundamental = RCF::IsFundamental<T>::value;
407 if RCF_CONSTEXPR(!isFundamental)
409 if ( *ppt &&
typeid(T) !=
typeid(**ppt) )
411 if ( !SF::Registry::getSingleton().isTypeRegistered(
typeid(**ppt)) )
413 RCF::Exception e(RCF::RcfError_SfTypeRegistration,
typeid(**ppt).name());
423 std::string Serializer<T>::getDerivedTypeName()
425 return SF::Registry::getSingleton().getTypeName(
typeid(**ppt) );
429 void Serializer<T>::getSerializerPolymorphic(
430 const std::string &derivedTypeName)
432 pf = & SF::Registry::getSingleton().getSerializerPolymorphic(
438 void Serializer<T>::invokeSerializerPolymorphic(
SF::Archive &ar)
441 void **ppvb = (
void **) (ppt);
442 pf->invoke(ppvb, ar);
446 void Serializer<T>::serializeContents(Archive &ar)
448 preserialize(ar, *ppt, 0);
452 void Serializer<T>::addToInputContext(
SF::IStream *stream,
const UInt32 &nid)
454 ContextRead &ctx = stream->getTrackingContext();
455 ctx.add(nid, IdT( (
void *) (*ppt), &
typeid(T)));
459 bool Serializer<T>::queryInputContext(
SF::IStream *stream,
const UInt32 &nid)
461 ContextRead &ctx = stream->getTrackingContext();
462 return ctx.query(nid,
id);
466 void Serializer<T>::addToOutputContext(
SF::OStream *stream, UInt32 &nid)
468 ContextWrite &ctx = stream->getTrackingContext();
469 ctx.add( IdT( (
void *) *ppt, &
typeid(T)), nid);
473 bool Serializer<T>::queryOutputContext(
SF::OStream *stream, UInt32 &nid)
475 ContextWrite &ctx = stream->getTrackingContext();
476 return ctx.query( IdT( (
void *) *ppt, &
typeid(T)), nid);
480 void Serializer<T>::setFromId()
482 *ppt =
reinterpret_cast<T *
>(
id.first);
486 void Serializer<T>::setToNull()
492 bool Serializer<T>::isNull()
498 bool Serializer<T>::isNonAtomic()
500 bool isFundamental = RCF::IsFundamental<T>::value;
501 return !isFundamental;
506 #endif // ! INCLUDE_SF_SERIALIZER_HPP Represents an archive, in which serialized objects are stored.
Definition: Archive.hpp:31
int getRuntimeVersion()
Gets the RCF runtime version associated with this archive.
Base class for all RCF exceptions.
Definition: Exception.hpp:67
Definition: ByteBuffer.hpp:188
Base class for output streams using SF serialization. Use operator <<() to serialize objects into the...
Definition: Stream.hpp:235
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:137