1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "nel/misc/types_nl.h"
25 #include "nel/misc/smart_ptr.h"
26 #include "nel/misc/time_nl.h"
27 #include "nel/misc/mem_stream.h"
45 class CSerializeContext
;
48 // vistor triggered at traversal of object tree. see CObject::visit
51 virtual ~IObjectVisitor() { }
53 virtual void visit(CObjectRefId
&/* obj */) {}
54 virtual void visit(CObjectString
&/* obj */) {}
55 virtual void visit(CObjectNumber
&/* obj */) {}
56 virtual void visit(CObjectInteger
&/* obj */) {}
57 virtual void visit(CObjectTable
&/* obj */) {}
61 class CObject
: public NLMISC::CRefCount
64 typedef NLMISC::CRefPtr
<CObject
> TRefPtr
;
65 typedef NLMISC::CSmartPtr
<CObject
> TSmartPtr
;
67 // recursively visit hierarchy of objects
68 void visit(IObjectVisitor
&visitor
);
72 virtual CObject
* clone() const;
74 void serialize(std::string
& out
) const;
76 virtual void doSerialize(std::string
& out
, CSerializeContext
& context
) const = 0;
78 virtual const char *getTypeAsString() const = 0;
80 CObject
* findAttr(const std::string
& first
) const;
82 CObject
* findAttr(const std::string
& first
, const std::string
& second
) const;
84 CObject
* findAttr(const std::string
& first
, const std::string
& second
, const std::string
& third
) const;
86 CObject
* findAttr(const std::vector
<std::string
>& attrName
) const;
88 bool isNumber(const std::string
& prop
="") const;
90 bool isInteger(const std::string
& prop
="") const;
92 bool isString(const std::string
& prop
="") const;
94 bool isTable(const std::string
& prop
="") const;
96 bool isRefId(const std::string
& prop
="") const;
98 virtual bool insert(const std::string
& key
, CObject
* value
, sint32 position
= -1);
101 double toNumber(const std::string
& prop
="") const;
103 sint64
toInteger(const std::string
& prop
="") const;
105 std::string
toString(const std::string
& prop
="") const;
107 CObjectTable
* toTable(const std::string
& prop
="") const;
110 virtual sint32
findIndex(const CObject
* child
) const;
112 // find index from a key, or -1 if not found
113 virtual sint32
findIndex(const std::string
&key
) const;
116 virtual CObject
* getAttr(const std::string
& name
) const;
118 virtual std::string
getKey(uint32 pos
) const;
120 virtual CObject
* getValueAtPos(uint32 pos
) const;
122 virtual uint32
getSize() const;
124 virtual CObject
* take(sint32 pos
);
126 virtual bool canTake(sint32 pos
) const;
131 void add(const std::string
& key
, CObject
* value
);
133 void add(CObject
* value
);
135 void add(const std::string
& key
, const std::string
& value
);
137 void add(const std::string
& key
, double value
);
139 void add(const std::string
& key
, sint64 value
);
143 virtual bool set(const std::string
& key
, const std::string
& value
);
145 virtual bool set(const std::string
& key
, double value
);
147 virtual bool set(const std::string
& key
, sint64 value
);
149 virtual bool setObject(const std::string
& key
, CObject
* value
);
151 CObject
* getParent() const;
153 void setParent(CObject
* parent
);
156 virtual void dump(const std::string prefix
= "", uint depth
= 0) const = 0;
158 /** In place copy of object "src" into this object
159 * Type and fields must match, otherwise error msg are printed
161 void inPlaceCopy(const CObject
&src
);
163 virtual bool equal(const CObject
* /* other */) const { return false; }
165 static std::string
uint32ToInstanceId(uint32 id
);
167 static uint32
instanceIdToUint32(const std::string
& instanceId
);
169 // set / get the 'ghost' flag, meaning that this objet only exist for the client
170 bool getGhost() const;
171 virtual void setGhost(bool ghost
);
173 virtual void checkIntegrity() const {}
175 /** Find the shortest name for this object as a (instanceId, attrName, position) triplet
176 * \return false if such a name could not be found
178 bool getShortestName(std::string
&instanceId
, std::string
&attrName
, sint32
&position
) const;
179 bool getNameInParent(std::string
&instanceId
, std::string
&attrName
, sint32
&position
) const;
186 virtual bool doIsNumber() const;
188 virtual bool doIsInteger() const;
190 virtual bool doIsString() const;
192 virtual bool doIsTable() const;
194 virtual bool doIsRefId() const;
196 virtual double doToNumber() const;
198 virtual sint64
doToInteger() const;
200 virtual std::string
doToString() const;
202 virtual CObjectTable
* doToTable() const;
206 virtual void previsit(std::vector
<TRefPtr
> &sons
);
209 virtual void inPlaceCopyTo(CObject
&dest
) const = 0;
210 virtual void inPlaceCopy(const CObjectString
&src
);
211 virtual void inPlaceCopy(const CObjectNumber
&src
);
212 virtual void inPlaceCopy(const CObjectTable
&src
);
214 void copyMismatchMsg(const CObject
&src
);
215 virtual void visitInternal(IObjectVisitor
&visitor
) = 0;
226 /*inline std::ostream& operator<<( std::ostream& os, const CObject& c )
232 class CObjectString
: public CObject
235 explicit CObjectString(const std::string
& value
);
237 virtual const char *getTypeAsString() const;
239 virtual CObject
* clone() const;
241 virtual bool set(const std::string
& key
, const std::string
& value
);
243 virtual bool setObject(const std::string
& key
, CObject
* value
);
245 const std::string
&getValue() const { return _Value
; }
247 virtual void dump(const std::string prefix
= "", uint depth
= 0) const;
249 virtual bool equal(const CObject
* other
) const;
252 virtual void visitInternal(IObjectVisitor
&visitor
);
254 virtual void doSerialize(std::string
& out
, CSerializeContext
& context
) const;
256 virtual std::string
doToString() const;
258 virtual bool doIsString() const;
260 virtual void inPlaceCopyTo(CObject
&dest
) const;
261 virtual void inPlaceCopy(const CObjectString
&src
);
269 // A single string from the server viewpoint
270 // From client viewpoint, derived class 'observes' a target object and tells when it has been deleted
272 class CObjectRefId
: public CObjectString
275 explicit CObjectRefId(const std::string
& value
);
277 virtual const char *getTypeAsString() const;
278 virtual CObject
* clone() const;
279 virtual bool equal(const CObject
* other
) const;
281 virtual void visitInternal(IObjectVisitor
&visitor
);
282 virtual bool doIsRefId() const;
283 virtual void doSerialize(std::string
& out
, CSerializeContext
& context
) const;
287 class CObjectNumber
: public CObject
291 explicit CObjectNumber(double value
);
292 explicit CObjectNumber(sint64 value
);
293 double getNumberValue() const { return m_IsInteger
? m_Value
.Integer
: m_Value
.Number
; }
294 sint64
getIntegerValue() const { return m_IsInteger
? m_Value
.Integer
: m_Value
.Number
; }
296 #if !defined(CLANG_VERSION) && defined(NL_COMP_GCC) && (GCC_VERSION < 40800)
297 virtual const char *getTypeAsString() const;
299 virtual bool set(const std::string
& key
, sint64 value
);
300 virtual bool set(const std::string
& key
, double value
);
301 virtual bool set(const std::string
& key
, const std::string
&value
);
303 virtual bool setObject(const std::string
& key
, CObject
* value
);
305 virtual CObject
* clone() const;
307 virtual void dump(const std::string prefix
= "", uint depth
= 0) const;
309 virtual bool equal(const CObject
* other
) const;
311 virtual const char *getTypeAsString() const NL_OVERRIDE
;
313 virtual bool set(const std::string
& key
, sint64 value
) NL_OVERRIDE
;
314 virtual bool set(const std::string
& key
, double value
) NL_OVERRIDE
;
315 virtual bool set(const std::string
& key
, const std::string
&value
) NL_OVERRIDE
;
317 virtual bool setObject(const std::string
& key
, CObject
* value
) NL_OVERRIDE
;
319 virtual CObject
* clone() const NL_OVERRIDE
;
321 virtual void dump(const std::string prefix
= "", uint depth
= 0) const NL_OVERRIDE
;
323 virtual bool equal(const CObject
* other
) const NL_OVERRIDE
;
327 #if !defined(CLANG_VERSION) && defined(NL_COMP_GCC) && (GCC_VERSION < 40800)
328 virtual void doSerialize(std::string
& out
, CSerializeContext
& context
) const;
330 virtual bool doIsNumber() const;
332 virtual double doToNumber() const;
334 virtual bool doIsInteger() const;
336 virtual sint64
doToInteger() const;
338 virtual std::string
doToString() const;
340 virtual void inPlaceCopyTo(CObject
&dest
) const;
341 virtual void inPlaceCopy(const CObjectNumber
&src
);
343 virtual void visitInternal(IObjectVisitor
&visitor
);
345 virtual void doSerialize(std::string
& out
, CSerializeContext
& context
) const NL_OVERRIDE
;
347 virtual bool doIsNumber() const NL_OVERRIDE
;
349 virtual double doToNumber() const NL_OVERRIDE
;
351 virtual bool doIsInteger() const NL_OVERRIDE
;
353 virtual sint64
doToInteger() const NL_OVERRIDE
;
355 virtual std::string
doToString() const NL_OVERRIDE
;
357 virtual void inPlaceCopyTo(CObject
&dest
) const NL_OVERRIDE
;
358 virtual void inPlaceCopy(const CObjectNumber
&src
) NL_OVERRIDE
;
360 virtual void visitInternal(IObjectVisitor
&visitor
) NL_OVERRIDE
;
373 class CObjectTable
: public CObject
377 typedef NLMISC::CRefPtr
<CObjectTable
> TRefPtr
;
378 typedef NLMISC::CRefPtr
<const CObjectTable
> TRefPtrConst
;
380 explicit CObjectTable();
382 virtual ~CObjectTable();
384 virtual const char *getTypeAsString() const;
386 virtual bool insert(const std::string
& key
, CObject
* value
, sint32 pos
);
388 virtual CObject
* clone() const;
390 virtual void doSerialize(std::string
& out
, CSerializeContext
& context
) const;
392 virtual CObject
* getAttr(const std::string
& name
) const;
395 virtual std::string
getKey(uint32 pos
) const;
397 virtual CObject
* getValueAtPos(uint32 pos
) const;
399 virtual sint32
findIndex(const CObject
* child
) const;
401 // find index from a key, or -1 if not found
402 virtual sint32
findIndex(const std::string
&key
) const;
404 virtual uint32
getSize() const;
406 virtual bool set(const std::string
& key
, const std::string
& value
);
408 virtual bool set(const std::string
& key
, double value
);
410 virtual bool setObject(const std::string
& key
, CObject
* value
);
412 virtual CObject
* take(sint32 pos
);
414 virtual bool canTake(sint32 pos
) const;
420 virtual void dump(const std::string prefix
= "", uint depth
= 0) const;
422 virtual bool equal(const CObject
* other
) const;
424 virtual void setGhost(bool ghost
);
426 virtual void checkIntegrity() const;
429 virtual void visitInternal(IObjectVisitor
&visitor
);
431 virtual bool doIsTable() const;
433 virtual CObjectTable
* doToTable() const;
435 virtual void inPlaceCopyTo(CObject
&dest
) const;
436 virtual void inPlaceCopy(const CObjectTable
&src
);
439 virtual void previsit(std::vector
<CObject::TRefPtr
> &sons
);
441 /** Compute absolute position, return true if index is valid
442 * A negative index indicate an offset from the end of the table (-1 for the last element)
445 typedef std::vector
< std::pair
<std::string
, CObject
*> > TContainer
;
453 class CTypedObject
: public CObjectTable
457 CTypedObject(const std::string
& type
);
458 virtual bool isOk() const;
465 sint32
getNewId(const std::string
& type
="") ;
466 std::string
getNewName(const std::string
& type
="", sint32 id
= -1);
467 void setMaxId(const std::string
& eid
,sint32 id
);
468 sint32
getMaxId(const std::string
& eid
);
471 std::map
< std::string
, sint32
> _Value
;
475 class CObjectGenerator
;
477 // NB nico : added 'virtual' because client derives its own factory
481 CObjectFactory(const std::string
& prefix
);
482 void registerGenerator(CObject
* classObject
);
483 virtual ~CObjectFactory();
484 virtual CObject
* newBasic(const std::string
& type
);
485 CObject
* newAvanced(const std::string
& type
);
486 CObject
* newComponent(const std::string
& type
);
487 CObjectGenerator
* getGenerator(const std::string
& type
);
488 std::string
getNewName(const std::string
& type
="") const;
489 void setMaxId(const std::string
& eid
,sint32 id
);
490 void setPrefix(const std::string
& prefix
);
491 sint32
getMaxId(const std::string
& eid
) const;
494 CNameGiver
* _NameGiver
;
496 std::map
<std::string
, CObjectGenerator
*> _Map
;
500 class CObjectGenerator
503 CObject
* instanciate(CObjectFactory
* factory
) const;
504 CObjectGenerator(CObject
* objectClass
, CObjectFactory
* factory
):
505 _ObjectClass(objectClass
){ createDefaultValues(factory
);}
507 CObject
* getDefaultValue(const std::string
& propName
) const;
508 std::string
getBaseClass() const;
510 void createDefaultValues(CObjectFactory
* factory
);
512 typedef std::map
<std::string
, CObject
* > TDefaultValues
;
514 CObject
* _ObjectClass
;
515 TDefaultValues _DefaultValues
;
518 class CClass
: public CObjectTable
521 CClass(const std::string
& classType
);
522 void addAttribute(const std::string
& name
, const std::string
& type
);
523 void addAttribute(const std::string
& name
, const std::string
& type
, const std::string
& defaultValue
);
526 std::string _ClassType
;
529 class CClassAttribute
: public CObjectTable
533 CClassAttribute(const std::string
& propName
, const std::string
& propType
)
535 add("Name", propName
);
536 add("Type", propType
);
538 CClassAttribute(const std::string
& propName
, const std::string
& propType
, const std::string
& defaultValue
)
540 add("Name", propName
);
541 add("Type", propType
);
542 add("DefaultValue", defaultValue
);
544 //virtual CObject* instanciate() const = 0;
546 virtual bool verify(CObject
* /* prop */) const { return true;}
549 // Don't take ownership
550 class CObjectSerializer
553 // for client : factory to use when reading objects
554 CObjectFactory
*Factory
;
556 // to force static serializer memory cleanup
557 static void releaseInstance();
559 CObjectSerializer(CObjectFactory
*factory
, CObject
* data
= 0);
562 void serial(NLMISC::IStream
& stream
);
563 CObject
* getData() const;
564 // make a copy of data (the caller must handle data)
565 void setData(CObject
* data
);
566 // :XXX: don't delete _Data
567 ~CObjectSerializer();
568 static void serialStringInstanceId( NLMISC::IStream
& stream
, std::string
& data
);
570 bool isCompresed() const { return _Compressed
;}
574 void uncompress() const;
576 void swap(CObjectSerializer
& other
);
577 void setVersion(uint32 version
) { _Version
= version
; }
578 uint32
getVersion() const { return _Version
; }
582 CObjectSerializer(const CObjectSerializer
& lh
);
583 CObjectSerializer
& operator=(const CObjectSerializer
& rh
);
584 void uncompressImpl();
590 bool _MustUncompress
;
591 uint8
* _CompressedBuffer
;
592 uint32 _CompressedLen
;
593 uint32 _UncompressedLen
;
600 class CObjectSerializerClient
: public CObjectSerializer
602 static CObjectFactory
*_ClientObjecFactory
;
604 // constructor for client side serializer, we use the client side factory
605 CObjectSerializerClient(CObject
*data
=0)
606 : CObjectSerializer(_ClientObjecFactory
, data
)
608 nlassert(_ClientObjecFactory
!= NULL
);
611 static void setClientObjectFactory(CObjectFactory
*factory
)
613 _ClientObjecFactory
= factory
;
617 class CObjectSerializerServer
: public CObjectSerializer
620 // constructor for server side serializer, we don't use object factory
621 CObjectSerializerServer(CObject
*data
=0)
622 : CObjectSerializer(NULL
, data
)