24 #ifndef __DOTS_INTERNAL_BLOB_WRITER_H__
25 #define __DOTS_INTERNAL_BLOB_WRITER_H__
61 template <
class RepositoryT,
class Traits=Safir::Dob::Typesystem::ToolSupport::TypeRepositoryTraits<RepositoryT> >
85 ,m_classDescription(m_repository->GetClass(typeId))
86 ,m_memberDescription(NULL)
95 :m_repository(Internal::BlobUtils::BlobAccess::GetRepository<
BlobReader<RepositoryT, Traits> >(reader))
96 ,m_classDescription(m_repository->GetClass(reader.
TypeId()))
97 ,m_memberDescription(NULL)
100 ,m_blob(Internal::BlobUtils::BlobAccess::GetBlob<
BlobReader<RepositoryT, Traits> >(reader))
108 DotsC_TypeId
TypeId()
const {
return m_blob.TypeId();}
121 void CopyRawBlob(
char* destBlob)
const {m_blob.Serialize(destBlob);}
131 const MemberDescriptionType* md=m_classDescription->GetMember(member);
132 DotsC_CollectionType collectionType=md->GetCollectionType();
133 if (collectionType==SequenceCollectionType || collectionType==DictionaryCollectionType)
135 m_blob.SetChangedTopLevel(member, isChanged);
146 void SetChanged(DotsC_MemberIndex member, DotsC_Int32 valueIndex,
bool isChanged) {m_blob.SetChanged(member, valueIndex, isChanged);}
160 void WriteKey(DotsC_MemberIndex member,
const Key& key)
162 MoveToMember(member);
163 if (m_memberDescription->GetCollectionType()==DictionaryCollectionType)
165 m_valueIndex=m_blob.AddValue(m_memberIndex,
false);
170 throw std::logic_error(
"WriteKey was called on member thats not a dictionary.");
189 void WriteValue(DotsC_MemberIndex member, DotsC_Int32 index,
const Val& val,
bool isNull,
bool isChanged)
191 MoveToMember(member);
192 switch (m_memberDescription->GetCollectionType())
194 case SingleValueCollectionType:
197 m_blob.SetChanged(m_memberIndex, m_valueIndex, isChanged);
200 case ArrayCollectionType:
203 m_blob.SetChanged(m_memberIndex, m_valueIndex, isChanged);
206 case SequenceCollectionType:
208 m_valueIndex=m_blob.AddValue(m_memberIndex, isChanged);
211 case DictionaryCollectionType:
213 m_blob.SetChanged(m_memberIndex, m_valueIndex, isChanged);
230 bool dummy=
false, isNull=
false;
232 for (
int memIx=0; memIx<m_classDescription->GetNumberOfMembers(); ++memIx)
234 const MemberDescriptionType* md=m_classDescription->GetMember(memIx);
236 switch (md->GetCollectionType())
238 case SingleValueCollectionType:
240 m_blob.SetChanged(memIx, 0, isChanged);
241 if (md->GetMemberType()==ObjectMemberType)
243 m_blob.ValueStatus(memIx, 0, isNull, dummy);
246 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memIx, 0);
249 WriteValue(memIx, 0, inner, isNull, isChanged);
254 case ArrayCollectionType:
256 if (md->GetMemberType()==ObjectMemberType)
258 for (
int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
260 m_blob.ValueStatus(memIx, valIx, isNull, dummy);
263 m_blob.SetChanged(memIx, valIx, isChanged);
267 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memIx, valIx);
270 WriteValue(memIx, valIx, inner, isNull, isChanged);
276 for (
int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
278 m_blob.SetChanged(memIx, valIx, isChanged);
283 case SequenceCollectionType:
285 m_blob.SetChangedTopLevel(memIx, isChanged);
286 if (md->GetMemberType()==ObjectMemberType)
289 for (
int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
291 m_blob.ValueStatus(memIx, valIx, isNull, dummy);
294 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memIx, valIx);
304 case DictionaryCollectionType:
306 m_blob.SetChangedTopLevel(memIx, isChanged);
309 for (
int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
311 m_blob.SetChanged(memIx, valIx, isChanged);
312 if (md->GetMemberType()==ObjectMemberType)
314 m_blob.ValueStatus(memIx, valIx, isNull, dummy);
317 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memIx, valIx);
341 const Internal::Blob& other=Internal::BlobUtils::BlobAccess::GetBlob(reader);
343 for (
int memIx=0; memIx<m_classDescription->GetNumberOfMembers(); ++memIx)
345 const MemberDescriptionType* md=m_classDescription->GetMember(memIx);
346 switch (md->GetCollectionType())
348 case SingleValueCollectionType:
350 if (Diff(other, md, memIx, 0, 0))
352 m_blob.SetChanged(memIx, 0,
true);
357 case ArrayCollectionType:
359 for (
int valIx=0; valIx<md->GetArraySize(); ++valIx)
361 if (Diff(other, md, memIx, valIx, valIx))
363 m_blob.SetChanged(memIx, valIx,
true);
369 case SequenceCollectionType:
371 if (m_blob.NumberOfValues(memIx)!=other.NumberOfValues(memIx))
374 m_blob.SetChangedTopLevel(memIx,
true);
378 for (
int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
380 if (Diff(other, md, memIx, valIx, valIx))
382 m_blob.SetChangedTopLevel(memIx,
true);
390 case DictionaryCollectionType:
395 if (m_blob.NumberOfValues(memIx)!=other.NumberOfValues(memIx))
397 m_blob.SetChangedTopLevel(memIx,
true);
401 typedef std::map<DotsC_Int64, int> Uki;
403 UniversalKeyToIndex(m_blob, md, memIx, myUki);
404 UniversalKeyToIndex(other, md, memIx, otherUki);
406 for (Uki::const_iterator myIt=myUki.begin(); myIt!=myUki.end(); ++myIt)
408 Uki::const_iterator otherIt=otherUki.find(myIt->first);
409 if (otherIt==otherUki.end())
412 m_blob.SetChangedTopLevel(memIx,
true);
413 m_blob.SetChanged(memIx, myIt->second,
true);
416 else if (Diff(other, md, memIx, myIt->second, otherIt->second))
418 m_blob.SetChanged(memIx, myIt->second,
true);
431 const RepositoryType* m_repository;
432 const ClassDescriptionType* m_classDescription;
433 const MemberDescriptionType* m_memberDescription;
434 DotsC_MemberIndex m_memberIndex;
435 DotsC_Int32 m_valueIndex;
436 mutable Safir::Dob::Typesystem::ToolSupport::Internal::Blob m_blob;
442 for (DotsC_MemberIndex memberIndex=0; memberIndex<m_classDescription->GetNumberOfMembers(); ++memberIndex)
444 const MemberDescriptionType* member=m_classDescription->GetMember(memberIndex);
445 switch (member->GetCollectionType())
447 case SingleValueCollectionType:
449 m_blob.AddValue(memberIndex,
false);
453 case ArrayCollectionType:
455 for (
int arrayIndex=0; arrayIndex<member->GetArraySize(); ++arrayIndex)
457 m_blob.AddValue(memberIndex,
false);
468 inline void MoveToMember(DotsC_MemberIndex member)
470 if (m_memberIndex!=member)
472 m_memberDescription=m_classDescription->GetMember(member);
473 m_memberIndex=member;
477 inline void ThrowWrongMemberType()
const
479 std::ostringstream os;
480 os<<
"Trying to write data of wrong memberType to a blob for member '"<<m_memberDescription->GetName()<<
"' in class '"<<m_classDescription->GetName()<<
"'";
481 throw std::logic_error(os.str());
484 inline void ThrowWrongCollectionType()
const
486 std::ostringstream os;
487 os<<
"Trying to write data of wrong collectionType to a blob for member '"<<m_memberDescription->GetName()<<
"' in class '"<<m_classDescription->GetName()<<
"'";
488 throw std::logic_error(os.str());
496 m_blob.SetKeyInt32(m_memberIndex, m_valueIndex, key);
501 m_blob.SetKeyInt64(m_memberIndex, m_valueIndex, key);
506 m_blob.SetKeyString(m_memberIndex, m_valueIndex, key);
509 void WriteKey(
const std::pair<DotsC_Int64, const char *>& key)
511 m_blob.SetKeyHash(m_memberIndex, m_valueIndex, key.first);
514 m_blob.SetKeyString(m_memberIndex, m_valueIndex, key.second);
518 void WriteKey(
const std::pair<DotsC_EntityId, const char*>& key)
520 m_blob.SetKeyInt64(m_memberIndex, m_valueIndex, key.first.typeId);
521 WriteKey(std::pair<DotsC_Int64, const char *>(key.first.instanceId, key.second));
529 assert(m_memberDescription->GetMemberType()==Int32MemberType || m_memberDescription->GetMemberType()==EnumerationMemberType);
530 m_blob.SetValueInt32(m_memberIndex, m_valueIndex, val);
535 assert(m_memberDescription->GetMemberType()==Int64MemberType || m_memberDescription->GetMemberType()==TypeIdMemberType);
536 m_blob.SetValueInt64(m_memberIndex, m_valueIndex, val);
542 m_blob.SetValueFloat32(m_memberIndex, m_valueIndex, val);
548 m_blob.SetValueFloat64(m_memberIndex, m_valueIndex, val);
553 assert(m_memberDescription->GetMemberType()==BooleanMemberType);
554 m_blob.SetValueBool(m_memberIndex, m_valueIndex, val);
559 assert(m_memberDescription->GetMemberType()==StringMemberType);
560 m_blob.SetValueString(m_memberIndex, m_valueIndex, val);
563 void WriteValue(
const std::pair<DotsC_Int64, const char *>& val)
565 assert(m_memberDescription->GetMemberType()==InstanceIdMemberType || m_memberDescription->GetMemberType()==ChannelIdMemberType || m_memberDescription->GetMemberType()==HandlerIdMemberType);
566 m_blob.SetValueHash(m_memberIndex, m_valueIndex, val.first);
569 m_blob.SetValueString(m_memberIndex, m_valueIndex, val.second);
573 void WriteValue(
const std::pair<DotsC_EntityId, const char*>& val)
575 assert(m_memberDescription->GetMemberType()==EntityIdMemberType);
576 m_blob.SetValueInt64(m_memberIndex, m_valueIndex, val.first.typeId);
577 m_blob.SetValueHash(m_memberIndex, m_valueIndex, val.first.instanceId);
580 m_blob.SetValueString(m_memberIndex, m_valueIndex, val.second);
584 void WriteValue(
const std::pair<const char*, DotsC_Int32>& val)
586 assert(m_memberDescription->GetMemberType()==BinaryMemberType || m_memberDescription->GetMemberType()==ObjectMemberType);
587 m_blob.SetValueBinary(m_memberIndex, m_valueIndex, val.first, val.second);
590 void WriteValue(
const std::pair<char*, DotsC_Int32>& val)
592 assert(m_memberDescription->GetMemberType()==BinaryMemberType || m_memberDescription->GetMemberType()==ObjectMemberType);
593 m_blob.SetValueBinary(m_memberIndex, m_valueIndex, val.first, val.second);
598 assert(m_memberDescription->GetMemberType()==ObjectMemberType);
599 std::vector<char> bin(static_cast<size_t>(val.CalculateBlobSize()));
600 val.CopyRawBlob(&bin[0]);
601 m_blob.SetValueBinary(m_memberIndex, m_valueIndex, &bin[0], static_cast<boost::int32_t>(bin.size()));
604 bool Diff(
const Internal::Blob& other,
const MemberDescriptionType* md,
int memberIndex,
int myValueIndex,
int otherValueIndex)
606 bool meIsNull=
false, meIsChanged=
false;
607 bool otherIsNull=
false, otherIsChanged=
false;
609 m_blob.ValueStatus(memberIndex, myValueIndex, meIsNull, meIsChanged);
610 other.ValueStatus(memberIndex, otherValueIndex, otherIsNull, otherIsChanged);
612 if (meIsNull!=otherIsNull)
614 if (!meIsNull && md->GetMemberType()==ObjectMemberType)
616 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memberIndex, myValueIndex);
618 inner.SetAllChangeFlags(
true);
619 MoveToMember(memberIndex);
620 m_valueIndex=myValueIndex;
627 switch(md->GetMemberType())
629 case BooleanMemberType:
630 return m_blob.GetValueBool(memberIndex, myValueIndex)!=other.GetValueBool(memberIndex, otherValueIndex);
632 case Int32MemberType:
633 case EnumerationMemberType:
634 return m_blob.GetValueInt32(memberIndex, myValueIndex)!=other.GetValueInt32(memberIndex, otherValueIndex);
636 case Int64MemberType:
637 case TypeIdMemberType:
638 return m_blob.GetValueInt64(memberIndex, myValueIndex)!=other.GetValueInt64(memberIndex, otherValueIndex);
640 case InstanceIdMemberType:
641 case ChannelIdMemberType:
642 case HandlerIdMemberType:
643 return m_blob.GetValueHash(memberIndex, myValueIndex)!=other.GetValueHash(memberIndex, otherValueIndex);
645 case EntityIdMemberType:
646 return (m_blob.GetValueInt64(memberIndex, myValueIndex)!=other.GetValueInt64(memberIndex, otherValueIndex)) ||
647 (m_blob.GetValueHash(memberIndex, myValueIndex)!=other.GetValueHash(memberIndex, otherValueIndex));
649 case StringMemberType:
650 return strcmp(m_blob.GetValueString(memberIndex, myValueIndex), other.GetValueString(memberIndex, otherValueIndex))!=0;
652 case ObjectMemberType:
654 std::pair<const char*, boost::int32_t> meInner=m_blob.GetValueBinary(memberIndex, myValueIndex);
655 std::pair<const char*, boost::int32_t> otherInner=other.GetValueBinary(memberIndex, otherValueIndex);
656 if (meInner.second!=otherInner.second || memcmp(meInner.first, otherInner.first, static_cast<size_t>(meInner.second))!=0)
659 BlobWriterType inner(
BlobReaderType(m_repository, meInner.first));
660 BlobReaderType otherReader(m_repository, otherInner.first);
661 bool diff=inner.MarkChanges(otherReader);
664 MoveToMember(memberIndex);
665 m_valueIndex=myValueIndex;
674 case BinaryMemberType:
676 std::pair<const char*, boost::int32_t> a=m_blob.GetValueBinary(memberIndex, myValueIndex);
677 std::pair<const char*, boost::int32_t> b=other.GetValueBinary(memberIndex, otherValueIndex);
678 return a.second!=b.second || memcmp(a.first, b.first, static_cast<size_t>(a.second))!=0;
682 case Float32MemberType:
683 case Ampere32MemberType:
684 case CubicMeter32MemberType:
685 case Hertz32MemberType:
686 case Joule32MemberType:
687 case Kelvin32MemberType:
688 case Kilogram32MemberType:
689 case Meter32MemberType:
690 case MeterPerSecond32MemberType:
691 case MeterPerSecondSquared32MemberType:
692 case Newton32MemberType:
693 case Pascal32MemberType:
694 case Radian32MemberType:
695 case RadianPerSecond32MemberType:
696 case RadianPerSecondSquared32MemberType:
697 case Second32MemberType:
698 case SquareMeter32MemberType:
699 case Steradian32MemberType:
700 case Volt32MemberType:
701 case Watt32MemberType:
702 return m_blob.GetValueFloat32(memberIndex, myValueIndex)!=other.GetValueFloat32(memberIndex, otherValueIndex);
704 case Float64MemberType:
705 case Ampere64MemberType:
706 case CubicMeter64MemberType:
707 case Hertz64MemberType:
708 case Joule64MemberType:
709 case Kelvin64MemberType:
710 case Kilogram64MemberType:
711 case Meter64MemberType:
712 case MeterPerSecond64MemberType:
713 case MeterPerSecondSquared64MemberType:
714 case Newton64MemberType:
715 case Pascal64MemberType:
716 case Radian64MemberType:
717 case RadianPerSecond64MemberType:
718 case RadianPerSecondSquared64MemberType:
719 case Second64MemberType:
720 case SquareMeter64MemberType:
721 case Steradian64MemberType:
722 case Volt64MemberType:
723 case Watt64MemberType:
724 return m_blob.GetValueFloat64(memberIndex, myValueIndex)!=other.GetValueFloat64(memberIndex, otherValueIndex);
731 static void UniversalKeyToIndex(
const Internal::Blob& blob,
732 const MemberDescriptionType* md,
734 std::map<DotsC_Int64, int>& keyToIndex)
737 switch (md->GetKeyType())
739 case Int32MemberType:
740 case EnumerationMemberType:
742 for (
int i=0; i<blob.NumberOfValues(memberIndex); ++i)
749 case Int64MemberType:
750 case TypeIdMemberType:
752 for (
int i=0; i<blob.NumberOfValues(memberIndex); ++i)
759 case StringMemberType:
761 for (
int i=0; i<blob.NumberOfValues(memberIndex); ++i)
768 case InstanceIdMemberType:
769 case HandlerIdMemberType:
770 case ChannelIdMemberType:
772 for (
int i=0; i<blob.NumberOfValues(memberIndex); ++i)
779 case EntityIdMemberType:
781 for (
int i=0; i<blob.NumberOfValues(memberIndex); ++i)
783 DotsC_EntityId eid={blob.GetKeyInt64(memberIndex, i), blob.GetKeyHash(memberIndex, i)};
void SetChanged(DotsC_MemberIndex member, DotsC_Int32 valueIndex, bool isChanged)
Set the change flag for a member value.
Definition: BlobWriter.h:146
Traits::PropertyMappingDescriptionType PropertyMappingDescriptionType
Definition: BlobWriter.h:75
DotsC_Int64 ToUnifiedDictionaryKey(DotsC_Int64 key)
ToUnifiedDictionaryKey - Convert all keys to an int64 that is the internal key format.
Definition: TypeUtilities.h:246
BlobWriter< RepositoryT, Traits > BlobWriterType
Definition: BlobWriter.h:65
DotsC_TypeId TypeId
A unique type identifier.
Definition: Defs.h:218
This class is used to unpack and read blobs created by the BlobWriter class.
Definition: BlobReader.h:64
This namespace contains all the functionality and definitions of the SAFIR SDK.
Definition: Backdoor.h:30
BlobReader< RepositoryT, Traits > BlobReaderType
Definition: BlobWriter.h:66
BlobWriter(const RepositoryT *rep, DotsC_TypeId typeId)
Constructor - Creates a new writeable blob of specified type.
Definition: BlobWriter.h:83
Traits::MemberMappingDescriptionType MemberMappingDescriptionType
Definition: BlobWriter.h:74
Traits::MemberDescriptionType MemberDescriptionType
Definition: BlobWriter.h:69
Traits::ClassDescriptionType ClassDescriptionType
Definition: BlobWriter.h:68
This class is used to create blobs by writing member values and the finally calling the CopyRawBlob-m...
Definition: BlobWriter.h:62
Traits::PropertyDescriptionType PropertyDescriptionType
Definition: BlobWriter.h:70
Traits::CreateRoutineDescriptionType CreateRoutineDescriptionType
Definition: BlobWriter.h:76
void SetChangedTopLevel(DotsC_MemberIndex member, bool isChanged)
Set the top level isChanged flag.
Definition: BlobWriter.h:129
Traits::ParameterDescriptionType ParameterDescriptionType
Definition: BlobWriter.h:72
void WriteValue(DotsC_MemberIndex member, DotsC_Int32 index, const Val &val, bool isNull, bool isChanged)
Write member value to the a blob.
Definition: BlobWriter.h:189
DotsC_Int32 CalculateBlobSize() const
Calculate the size of the blob in bytes.
Definition: BlobWriter.h:114
DotsC_TypeId TypeId() const
Get the type id of this BlobWriter.
Definition: BlobWriter.h:108
BlobWriter(const BlobReaderType &reader)
Definition: BlobWriter.h:94
Traits::ExceptionDescriptionType ExceptionDescriptionType
Definition: BlobWriter.h:71
Traits::RepositoryType RepositoryType
Definition: BlobWriter.h:67
bool MarkChanges(const BlobReaderType &reader)
MarkChanges - Set change flag for all members that differs between this blob and the reader blob...
Definition: BlobWriter.h:336
DOTS_CPP_API Dob::Typesystem::Int32 GetNumberOfMembers(const Dob::Typesystem::TypeId typeId)
Get the number of members for a class or property.
void SetAllChangeFlags(bool isChanged)
SetAllChangeFlags - Recursively set all change flags to specified value.
Definition: BlobWriter.h:228
void WriteKey(DotsC_MemberIndex member, const Key &key)
Write member key to the a blob.
Definition: BlobWriter.h:160
Traits::EnumDescriptionType EnumDescriptionType
Definition: BlobWriter.h:73
void CopyRawBlob(char *destBlob) const
Copy the binarey blob into a destination buffer.
Definition: BlobWriter.h:121
DotsC_TypeId TypeId() const
Get the type id of the blob.
Definition: BlobReader.h:116