85 ,m_classDescription(m_repository->GetClass(typeId))
86 ,m_memberDescription(NULL)
89 ,m_blob(typeId, m_classDescription->GetNumberOfMembers())
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))
111 DotsC_TypeId
TypeId()
const {
return m_blob.TypeId();}
124 void CopyRawBlob(
char* destBlob)
const {m_blob.Serialize(destBlob);}
135 DotsC_CollectionType collectionType=md->GetCollectionType();
136 if (collectionType==SequenceCollectionType || collectionType==DictionaryCollectionType)
138 m_blob.SetChangedTopLevel(member, isChanged);
150 DotsC_Int32 valueIndex,
152 {m_blob.SetChangedHere(member, valueIndex, isChanged);}
166 void WriteKey(DotsC_MemberIndex member,
const Key& key)
168 MoveToMember(member);
169 if (m_memberDescription->GetCollectionType()==DictionaryCollectionType)
171 m_valueIndex=m_blob.AddValue(m_memberIndex,
false);
176 throw std::logic_error(
"WriteKey was called on member thats not a dictionary.");
195 void WriteValue(DotsC_MemberIndex member, DotsC_Int32 index,
const Val& val,
bool isNull,
bool isChanged)
197 MoveToMember(member);
198 switch (m_memberDescription->GetCollectionType())
200 case SingleValueCollectionType:
203 m_blob.SetChangedHere(m_memberIndex, m_valueIndex, isChanged);
206 case ArrayCollectionType:
209 m_blob.SetChangedHere(m_memberIndex, m_valueIndex, isChanged);
212 case SequenceCollectionType:
214 m_valueIndex=m_blob.AddValue(m_memberIndex, isChanged);
217 case DictionaryCollectionType:
219 m_blob.SetChangedHere(m_memberIndex, m_valueIndex, isChanged);
236 bool dummy=
false, isNull=
false;
238 for (
int memIx=0; memIx<m_classDescription->GetNumberOfMembers(); ++memIx)
242 switch (md->GetCollectionType())
244 case SingleValueCollectionType:
246 m_blob.SetChangedHere(memIx, 0, isChanged);
247 if (md->GetMemberType()==ObjectMemberType)
249 m_blob.ValueStatus(memIx, 0, isNull, dummy);
252 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memIx, 0);
255 WriteValue(memIx, 0, inner, isNull, isChanged);
260 case ArrayCollectionType:
262 if (md->GetMemberType()==ObjectMemberType)
264 for (
int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
266 m_blob.ValueStatus(memIx, valIx, isNull, dummy);
269 m_blob.SetChangedHere(memIx, valIx, isChanged);
273 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memIx, valIx);
276 WriteValue(memIx, valIx, inner, isNull, isChanged);
282 for (
int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
284 m_blob.SetChangedHere(memIx, valIx, isChanged);
289 case SequenceCollectionType:
291 m_blob.SetChangedTopLevel(memIx, isChanged);
292 if (md->GetMemberType()==ObjectMemberType)
295 for (
int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
297 m_blob.ValueStatus(memIx, valIx, isNull, dummy);
300 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memIx, valIx);
310 case DictionaryCollectionType:
312 m_blob.SetChangedTopLevel(memIx, isChanged);
315 for (
int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
317 m_blob.SetChangedHere(memIx, valIx, isChanged);
318 if (md->GetMemberType()==ObjectMemberType)
320 m_blob.ValueStatus(memIx, valIx, isNull, dummy);
323 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memIx, valIx);
347 const Internal::Blob& other=Internal::BlobUtils::BlobAccess::GetBlob(reader);
349 for (
int memIx=0; memIx<m_classDescription->GetNumberOfMembers(); ++memIx)
352 switch (md->GetCollectionType())
354 case SingleValueCollectionType:
356 if (Diff(other, md, memIx, 0, 0))
358 m_blob.SetChangedHere(memIx, 0,
true);
363 case ArrayCollectionType:
365 for (
int valIx=0; valIx<md->GetArraySize(); ++valIx)
367 if (Diff(other, md, memIx, valIx, valIx))
369 m_blob.SetChangedHere(memIx, valIx,
true);
375 case SequenceCollectionType:
377 if (m_blob.NumberOfValues(memIx)!=other.NumberOfValues(memIx))
380 m_blob.SetChangedTopLevel(memIx,
true);
383 for (
int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
385 if (Diff(other, md, memIx, valIx, valIx))
387 m_blob.SetChangedTopLevel(memIx,
true);
388 if (md->GetMemberType()==ObjectMemberType)
390 m_blob.SetChangedHere(memIx, valIx,
true);
397 case DictionaryCollectionType:
402 if (m_blob.NumberOfValues(memIx)!=other.NumberOfValues(memIx))
404 m_blob.SetChangedTopLevel(memIx,
true);
408 typedef std::map<DotsC_Int64, int> Uki;
410 UniversalKeyToIndex(m_blob, md, memIx, myUki);
411 UniversalKeyToIndex(other, md, memIx, otherUki);
413 for (Uki::const_iterator myIt=myUki.begin(); myIt!=myUki.end(); ++myIt)
415 Uki::const_iterator otherIt=otherUki.find(myIt->first);
416 if (otherIt==otherUki.end())
419 m_blob.SetChangedTopLevel(memIx,
true);
420 m_blob.SetChangedHere(memIx, myIt->second,
true);
423 else if (Diff(other, md, memIx, myIt->second, otherIt->second))
425 m_blob.SetChangedHere(memIx, myIt->second,
true);
441 DotsC_MemberIndex m_memberIndex;
442 DotsC_Int32 m_valueIndex;
443 mutable Safir::Dob::Typesystem::ToolSupport::Internal::Blob m_blob;
449 for (DotsC_MemberIndex memberIndex=0; memberIndex<m_classDescription->GetNumberOfMembers(); ++memberIndex)
452 switch (member->GetCollectionType())
454 case SingleValueCollectionType:
456 m_blob.AddValue(memberIndex,
false);
460 case ArrayCollectionType:
462 for (
int arrayIndex=0; arrayIndex<member->GetArraySize(); ++arrayIndex)
464 m_blob.AddValue(memberIndex,
false);
475 inline void MoveToMember(DotsC_MemberIndex member)
477 if (m_memberIndex!=member)
479 m_memberDescription=m_classDescription->GetMember(member);
480 m_memberIndex=member;
484 inline void ThrowWrongMemberType()
const
486 std::ostringstream os;
487 os<<
"Trying to write data of wrong memberType to a blob for member '"<<m_memberDescription->GetName()<<
"' in class '"<<m_classDescription->GetName()<<
"'";
488 throw std::logic_error(os.str());
491 inline void ThrowWrongCollectionType()
const
493 std::ostringstream os;
494 os<<
"Trying to write data of wrong collectionType to a blob for member '"<<m_memberDescription->GetName()<<
"' in class '"<<m_classDescription->GetName()<<
"'";
495 throw std::logic_error(os.str());
503 m_blob.SetKeyInt32(m_memberIndex, m_valueIndex, key);
508 m_blob.SetKeyInt64(m_memberIndex, m_valueIndex, key);
513 m_blob.SetKeyString(m_memberIndex, m_valueIndex, key);
516 void WriteKey(
const std::pair<DotsC_Int64, const char *>& key)
518 m_blob.SetKeyHash(m_memberIndex, m_valueIndex, key.first);
521 m_blob.SetKeyString(m_memberIndex, m_valueIndex, key.second);
525 void WriteKey(
const std::pair<DotsC_EntityId, const char*>& key)
527 m_blob.SetKeyInt64(m_memberIndex, m_valueIndex, key.first.typeId);
528 WriteKey(std::pair<DotsC_Int64, const char *>(key.first.instanceId, key.second));
536 assert(m_memberDescription->GetMemberType()==Int32MemberType || m_memberDescription->GetMemberType()==EnumerationMemberType);
537 m_blob.SetValueInt32(m_memberIndex, m_valueIndex, val);
542 assert(m_memberDescription->GetMemberType()==Int64MemberType || m_memberDescription->GetMemberType()==TypeIdMemberType);
543 m_blob.SetValueInt64(m_memberIndex, m_valueIndex, val);
549 m_blob.SetValueFloat32(m_memberIndex, m_valueIndex, val);
555 m_blob.SetValueFloat64(m_memberIndex, m_valueIndex, val);
560 assert(m_memberDescription->GetMemberType()==BooleanMemberType);
561 m_blob.SetValueBool(m_memberIndex, m_valueIndex, val);
566 assert(m_memberDescription->GetMemberType()==StringMemberType);
567 m_blob.SetValueString(m_memberIndex, m_valueIndex, val);
570 void WriteValue(
const std::pair<DotsC_Int64, const char *>& val)
572 assert(m_memberDescription->GetMemberType()==InstanceIdMemberType || m_memberDescription->GetMemberType()==ChannelIdMemberType || m_memberDescription->GetMemberType()==HandlerIdMemberType);
573 m_blob.SetValueHash(m_memberIndex, m_valueIndex, val.first);
576 m_blob.SetValueString(m_memberIndex, m_valueIndex, val.second);
580 void WriteValue(
const std::pair<DotsC_EntityId, const char*>& val)
582 assert(m_memberDescription->GetMemberType()==EntityIdMemberType);
583 m_blob.SetValueInt64(m_memberIndex, m_valueIndex, val.first.typeId);
584 m_blob.SetValueHash(m_memberIndex, m_valueIndex, val.first.instanceId);
587 m_blob.SetValueString(m_memberIndex, m_valueIndex, val.second);
591 void WriteValue(
const std::pair<const char*, DotsC_Int32>& val)
593 assert(m_memberDescription->GetMemberType()==BinaryMemberType || m_memberDescription->GetMemberType()==ObjectMemberType);
594 m_blob.SetValueBinary(m_memberIndex, m_valueIndex, val.first, val.second);
597 void WriteValue(
const std::pair<char*, DotsC_Int32>& val)
599 assert(m_memberDescription->GetMemberType()==BinaryMemberType || m_memberDescription->GetMemberType()==ObjectMemberType);
600 m_blob.SetValueBinary(m_memberIndex, m_valueIndex, val.first, val.second);
605 assert(m_memberDescription->GetMemberType()==ObjectMemberType);
606 std::vector<char> bin(
static_cast<size_t>(val.CalculateBlobSize()));
607 val.CopyRawBlob(&bin[0]);
608 m_blob.SetValueBinary(m_memberIndex, m_valueIndex, &bin[0],
static_cast<std::int32_t
>(bin.size()));
611 bool Diff(
const Internal::Blob& other,
const MemberDescriptionType* md,
int memberIndex,
int myValueIndex,
int otherValueIndex)
613 bool meIsNull=
false, meIsChanged=
false;
614 bool otherIsNull=
false, otherIsChanged=
false;
616 m_blob.ValueStatus(memberIndex, myValueIndex, meIsNull, meIsChanged);
617 other.ValueStatus(memberIndex, otherValueIndex, otherIsNull, otherIsChanged);
619 if (meIsNull!=otherIsNull)
621 if (!meIsNull && md->GetMemberType()==ObjectMemberType)
623 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memberIndex, myValueIndex);
625 inner.SetChangedRecursive(
true);
626 MoveToMember(memberIndex);
627 m_valueIndex=myValueIndex;
634 switch(md->GetMemberType())
636 case BooleanMemberType:
637 return m_blob.GetValueBool(memberIndex, myValueIndex)!=other.GetValueBool(memberIndex, otherValueIndex);
639 case Int32MemberType:
640 case EnumerationMemberType:
641 return m_blob.GetValueInt32(memberIndex, myValueIndex)!=other.GetValueInt32(memberIndex, otherValueIndex);
643 case Int64MemberType:
644 case TypeIdMemberType:
645 return m_blob.GetValueInt64(memberIndex, myValueIndex)!=other.GetValueInt64(memberIndex, otherValueIndex);
647 case InstanceIdMemberType:
648 case ChannelIdMemberType:
649 case HandlerIdMemberType:
650 return m_blob.GetValueHash(memberIndex, myValueIndex)!=other.GetValueHash(memberIndex, otherValueIndex);
652 case EntityIdMemberType:
653 return (m_blob.GetValueInt64(memberIndex, myValueIndex)!=other.GetValueInt64(memberIndex, otherValueIndex)) ||
654 (m_blob.GetValueHash(memberIndex, myValueIndex)!=other.GetValueHash(memberIndex, otherValueIndex));
656 case StringMemberType:
657 return strcmp(m_blob.GetValueString(memberIndex, myValueIndex), other.GetValueString(memberIndex, otherValueIndex))!=0;
659 case ObjectMemberType:
661 std::pair<const char*, std::int32_t> meInner=m_blob.GetValueBinary(memberIndex, myValueIndex);
662 std::pair<const char*, std::int32_t> otherInner=other.GetValueBinary(memberIndex, otherValueIndex);
663 if (meInner.second!=otherInner.second || memcmp(meInner.first, otherInner.first,
static_cast<size_t>(meInner.second))!=0)
668 bool diff=inner.MarkChanges(otherReader);
671 MoveToMember(memberIndex);
672 m_valueIndex=myValueIndex;
681 case BinaryMemberType:
683 std::pair<const char*, std::int32_t> a=m_blob.GetValueBinary(memberIndex, myValueIndex);
684 std::pair<const char*, std::int32_t> b=other.GetValueBinary(memberIndex, otherValueIndex);
685 return a.second!=b.second || memcmp(a.first, b.first,
static_cast<size_t>(a.second))!=0;
689 case Float32MemberType:
690 case Ampere32MemberType:
691 case CubicMeter32MemberType:
692 case Hertz32MemberType:
693 case Joule32MemberType:
694 case Kelvin32MemberType:
695 case Kilogram32MemberType:
696 case Meter32MemberType:
697 case MeterPerSecond32MemberType:
698 case MeterPerSecondSquared32MemberType:
699 case Newton32MemberType:
700 case Pascal32MemberType:
701 case Radian32MemberType:
702 case RadianPerSecond32MemberType:
703 case RadianPerSecondSquared32MemberType:
704 case Second32MemberType:
705 case SquareMeter32MemberType:
706 case Steradian32MemberType:
707 case Volt32MemberType:
708 case Watt32MemberType:
709 return m_blob.GetValueFloat32(memberIndex, myValueIndex)!=other.GetValueFloat32(memberIndex, otherValueIndex);
711 case Float64MemberType:
712 case Ampere64MemberType:
713 case CubicMeter64MemberType:
714 case Hertz64MemberType:
715 case Joule64MemberType:
716 case Kelvin64MemberType:
717 case Kilogram64MemberType:
718 case Meter64MemberType:
719 case MeterPerSecond64MemberType:
720 case MeterPerSecondSquared64MemberType:
721 case Newton64MemberType:
722 case Pascal64MemberType:
723 case Radian64MemberType:
724 case RadianPerSecond64MemberType:
725 case RadianPerSecondSquared64MemberType:
726 case Second64MemberType:
727 case SquareMeter64MemberType:
728 case Steradian64MemberType:
729 case Volt64MemberType:
730 case Watt64MemberType:
731 return m_blob.GetValueFloat64(memberIndex, myValueIndex)!=other.GetValueFloat64(memberIndex, otherValueIndex);
738 static void UniversalKeyToIndex(
const Internal::Blob& blob,
741 std::map<DotsC_Int64, int>& keyToIndex)
744 switch (md->GetKeyType())
746 case Int32MemberType:
747 case EnumerationMemberType:
749 for (
int i=0; i<blob.NumberOfValues(memberIndex); ++i)
756 case Int64MemberType:
757 case TypeIdMemberType:
759 for (
int i=0; i<blob.NumberOfValues(memberIndex); ++i)
766 case StringMemberType:
768 for (
int i=0; i<blob.NumberOfValues(memberIndex); ++i)
775 case InstanceIdMemberType:
776 case HandlerIdMemberType:
777 case ChannelIdMemberType:
779 for (
int i=0; i<blob.NumberOfValues(memberIndex); ++i)
786 case EntityIdMemberType:
788 for (
int i=0; i<blob.NumberOfValues(memberIndex); ++i)
790 DotsC_EntityId eid={blob.GetKeyInt64(memberIndex, i), blob.GetKeyHash(memberIndex, i)};