Safir SDK Core
Loading...
Searching...
No Matches
BlobWriter.h
Go to the documentation of this file.
1/******************************************************************************
2*
3* Copyright Saab AB, 2004-2015 (http://safirsdkcore.com)
4*
5* Created by: Joel Ottosson / joot
6*
7*******************************************************************************
8*
9* This file is part of Safir SDK Core.
10*
11* Safir SDK Core is free software: you can redistribute it and/or modify
12* it under the terms of version 3 of the GNU General Public License as
13* published by the Free Software Foundation.
14*
15* Safir SDK Core is distributed in the hope that it will be useful,
16* but WITHOUT ANY WARRANTY; without even the implied warranty of
17* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18* GNU General Public License for more Internals.
19*
20* You should have received a copy of the GNU General Public License
21* along with Safir SDK Core. If not, see <http://www.gnu.org/licenses/>.
22*
23******************************************************************************/
24#ifndef __DOTS_INTERNAL_BLOB_WRITER_H__
25#define __DOTS_INTERNAL_BLOB_WRITER_H__
26
27#include <assert.h>
30
31namespace Safir
32{
33namespace Dob
34{
35namespace Typesystem
36{
37namespace ToolSupport
38{
61 template <class RepositoryT, class Traits=Safir::Dob::Typesystem::ToolSupport::TypeRepositoryTraits<RepositoryT> >
63 {
64 public:
67 typedef typename Traits::RepositoryType RepositoryType;
68 typedef typename Traits::ClassDescriptionType ClassDescriptionType;
69 typedef typename Traits::MemberDescriptionType MemberDescriptionType;
70 typedef typename Traits::PropertyDescriptionType PropertyDescriptionType;
71 typedef typename Traits::ExceptionDescriptionType ExceptionDescriptionType;
72 typedef typename Traits::ParameterDescriptionType ParameterDescriptionType;
73 typedef typename Traits::EnumDescriptionType EnumDescriptionType;
74 typedef typename Traits::MemberMappingDescriptionType MemberMappingDescriptionType;
75 typedef typename Traits::PropertyMappingDescriptionType PropertyMappingDescriptionType;
76 typedef typename Traits::CreateRoutineDescriptionType CreateRoutineDescriptionType;
77
83 BlobWriter(const RepositoryT* rep, DotsC_TypeId typeId)
84 :m_repository(rep)
85 ,m_classDescription(m_repository->GetClass(typeId))
86 ,m_memberDescription(NULL)
87 ,m_memberIndex(-1)
88 ,m_valueIndex(-1)
89 ,m_blob(typeId, m_classDescription->GetNumberOfMembers())
90 {
91 Init();
92 }
93
95 :m_repository(Internal::BlobUtils::BlobAccess::GetRepository<BlobReader<RepositoryT, Traits> >(reader))
96 ,m_classDescription(m_repository->GetClass(reader.TypeId()))
97 ,m_memberDescription(NULL)
98 ,m_memberIndex(-1)
99 ,m_valueIndex(-1)
100 ,m_blob(Internal::BlobUtils::BlobAccess::GetBlob<BlobReader<RepositoryT, Traits> >(reader))
101 {
102 }
103
104 BlobWriter(const BlobWriter&) = delete;
105 BlobWriter& operator=(const BlobWriter&) = delete;
106
111 DotsC_TypeId TypeId() const {return m_blob.TypeId();}
112
117 DotsC_Int32 CalculateBlobSize() const {return m_blob.CalculateBlobSize();}
118
124 void CopyRawBlob(char* destBlob) const {m_blob.Serialize(destBlob);}
125
132 void SetChangedTopLevel(DotsC_MemberIndex member, bool isChanged)
133 {
134 const MemberDescriptionType* md=m_classDescription->GetMember(member);
135 DotsC_CollectionType collectionType=md->GetCollectionType();
136 if (collectionType==SequenceCollectionType || collectionType==DictionaryCollectionType)
137 {
138 m_blob.SetChangedTopLevel(member, isChanged);
139 }
140 }
141
149 void SetChangedHere(DotsC_MemberIndex member,
150 DotsC_Int32 valueIndex,
151 bool isChanged)
152 {m_blob.SetChangedHere(member, valueIndex, isChanged);}
153
165 template <class Key>
166 void WriteKey(DotsC_MemberIndex member, const Key& key)
167 {
168 MoveToMember(member);
169 if (m_memberDescription->GetCollectionType()==DictionaryCollectionType)
170 {
171 m_valueIndex=m_blob.AddValue(m_memberIndex, false);
172 WriteKey(key);
173 }
174 else
175 {
176 throw std::logic_error("WriteKey was called on member thats not a dictionary.");
177 }
178 }
179
194 template <class Val>
195 void WriteValue(DotsC_MemberIndex member, DotsC_Int32 index, const Val& val, bool isNull, bool isChanged)
196 {
197 MoveToMember(member);
198 switch (m_memberDescription->GetCollectionType())
199 {
200 case SingleValueCollectionType:
201 {
202 m_valueIndex=0;
203 m_blob.SetChangedHere(m_memberIndex, m_valueIndex, isChanged);
204 }
205 break;
206 case ArrayCollectionType:
207 {
208 m_valueIndex=index;
209 m_blob.SetChangedHere(m_memberIndex, m_valueIndex, isChanged);
210 }
211 break;
212 case SequenceCollectionType:
213 {
214 m_valueIndex=m_blob.AddValue(m_memberIndex, isChanged);
215 }
216 break;
217 case DictionaryCollectionType:
218 {
219 m_blob.SetChangedHere(m_memberIndex, m_valueIndex, isChanged);
220 }
221 break;
222 }
223
224 if (!isNull)
225 {
226 WriteValue(val);
227 }
228 }
229
234 void SetChangedRecursive(bool isChanged)
235 {
236 bool dummy=false, isNull=false;
237
238 for (int memIx=0; memIx<m_classDescription->GetNumberOfMembers(); ++memIx)
239 {
240 const MemberDescriptionType* md=m_classDescription->GetMember(memIx);
241
242 switch (md->GetCollectionType())
243 {
244 case SingleValueCollectionType:
245 {
246 m_blob.SetChangedHere(memIx, 0, isChanged);
247 if (md->GetMemberType()==ObjectMemberType)
248 {
249 m_blob.ValueStatus(memIx, 0, isNull, dummy);
250 if (!isNull)
251 {
252 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memIx, 0);
253 BlobWriterType inner(BlobReaderType(m_repository, obj.first));
254 inner.SetChangedRecursive(isChanged);
255 WriteValue(memIx, 0, inner, isNull, isChanged);
256 }
257 }
258 }
259 break;
260 case ArrayCollectionType:
261 {
262 if (md->GetMemberType()==ObjectMemberType)
263 {
264 for (int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
265 {
266 m_blob.ValueStatus(memIx, valIx, isNull, dummy);
267 if (isNull)
268 {
269 m_blob.SetChangedHere(memIx, valIx, isChanged);
270 }
271 else
272 {
273 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memIx, valIx);
274 BlobWriterType inner(BlobReaderType(m_repository, obj.first));
275 inner.SetChangedRecursive(isChanged);
276 WriteValue(memIx, valIx, inner, isNull, isChanged);
277 }
278 }
279 }
280 else
281 {
282 for (int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
283 {
284 m_blob.SetChangedHere(memIx, valIx, isChanged);
285 }
286 }
287 }
288 break;
289 case SequenceCollectionType:
290 {
291 m_blob.SetChangedTopLevel(memIx, isChanged);
292 if (md->GetMemberType()==ObjectMemberType)
293 {
294 MoveToMember(memIx);
295 for (int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
296 {
297 m_blob.ValueStatus(memIx, valIx, isNull, dummy);
298 if (!isNull)
299 {
300 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memIx, valIx);
301 BlobWriterType inner(BlobReaderType(m_repository, obj.first));
302 inner.SetChangedRecursive(isChanged);
303 m_valueIndex=valIx;
304 WriteValue(inner);
305 }
306 }
307 }
308 }
309 break;
310 case DictionaryCollectionType:
311 {
312 m_blob.SetChangedTopLevel(memIx, isChanged);
313 MoveToMember(memIx);
314
315 for (int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
316 {
317 m_blob.SetChangedHere(memIx, valIx, isChanged);
318 if (md->GetMemberType()==ObjectMemberType)
319 {
320 m_blob.ValueStatus(memIx, valIx, isNull, dummy);
321 if (!isNull)
322 {
323 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memIx, valIx);
324 BlobWriterType inner(BlobReaderType(m_repository, obj.first));
325 inner.SetChangedRecursive(isChanged);
326 m_valueIndex=valIx;
327 WriteValue(inner);
328 }
329 }
330 }
331 }
332 break;
333 }
334 }
335 }
336
342 bool MarkChanges(const BlobReaderType& reader)
343 {
344 if (TypeId()!=reader.TypeId())
345 return true;
346 bool diff=false;
347 const Internal::Blob& other=Internal::BlobUtils::BlobAccess::GetBlob(reader);
348
349 for (int memIx=0; memIx<m_classDescription->GetNumberOfMembers(); ++memIx)
350 {
351 const MemberDescriptionType* md=m_classDescription->GetMember(memIx);
352 switch (md->GetCollectionType())
353 {
354 case SingleValueCollectionType:
355 {
356 if (Diff(other, md, memIx, 0, 0))
357 {
358 m_blob.SetChangedHere(memIx, 0, true);
359 diff=true;
360 }
361 }
362 break;
363 case ArrayCollectionType:
364 {
365 for (int valIx=0; valIx<md->GetArraySize(); ++valIx)
366 {
367 if (Diff(other, md, memIx, valIx, valIx))
368 {
369 m_blob.SetChangedHere(memIx, valIx, true);
370 diff=true;
371 }
372 }
373 }
374 break;
375 case SequenceCollectionType:
376 {
377 if (m_blob.NumberOfValues(memIx)!=other.NumberOfValues(memIx))
378 {
379 diff=true;
380 m_blob.SetChangedTopLevel(memIx, true);
381 }
382
383 for (int valIx=0; valIx<m_blob.NumberOfValues(memIx); ++valIx)
384 {
385 if (Diff(other, md, memIx, valIx, valIx))
386 {
387 m_blob.SetChangedTopLevel(memIx, true);
388 if (md->GetMemberType()==ObjectMemberType)
389 {
390 m_blob.SetChangedHere(memIx, valIx, true);
391 }
392 diff=true;
393 }
394 }
395 }
396 break;
397 case DictionaryCollectionType:
398 {
399 //Different count, or something in this that is not in other -> topLevel
400
401 //different size, i.e top level changed
402 if (m_blob.NumberOfValues(memIx)!=other.NumberOfValues(memIx))
403 {
404 m_blob.SetChangedTopLevel(memIx, true);
405 diff=true;
406 }
407
408 typedef std::map<DotsC_Int64, int> Uki;
409 Uki myUki, otherUki;
410 UniversalKeyToIndex(m_blob, md, memIx, myUki);
411 UniversalKeyToIndex(other, md, memIx, otherUki);
412
413 for (Uki::const_iterator myIt=myUki.begin(); myIt!=myUki.end(); ++myIt)
414 {
415 Uki::const_iterator otherIt=otherUki.find(myIt->first);
416 if (otherIt==otherUki.end())
417 {
418 //not found, we have something that is new
419 m_blob.SetChangedTopLevel(memIx, true);
420 m_blob.SetChangedHere(memIx, myIt->second, true);
421 diff=true;
422 }
423 else if (Diff(other, md, memIx, myIt->second, otherIt->second))
424 {
425 m_blob.SetChangedHere(memIx, myIt->second, true);
426 diff=true;
427 }
428 }
429 }
430 break;
431 }
432 }
433
434 return diff;
435 }
436
437 private:
438 const RepositoryType* m_repository;
439 const ClassDescriptionType* m_classDescription;
440 const MemberDescriptionType* m_memberDescription;
441 DotsC_MemberIndex m_memberIndex;
442 DotsC_Int32 m_valueIndex;
443 mutable Safir::Dob::Typesystem::ToolSupport::Internal::Blob m_blob;
444
445 inline void Init()
446 {
447 //Add values to single value members and arrays since they are not allowed to be empty.
448 //Other collections (sequence, dictionary) are allowed to be empty.
449 for (DotsC_MemberIndex memberIndex=0; memberIndex<m_classDescription->GetNumberOfMembers(); ++memberIndex)
450 {
451 const MemberDescriptionType* member=m_classDescription->GetMember(memberIndex);
452 switch (member->GetCollectionType())
453 {
454 case SingleValueCollectionType:
455 {
456 m_blob.AddValue(memberIndex, false);
457 }
458 break;
459
460 case ArrayCollectionType:
461 {
462 for (int arrayIndex=0; arrayIndex<member->GetArraySize(); ++arrayIndex)
463 {
464 m_blob.AddValue(memberIndex, false);
465 }
466 }
467 break;
468
469 default:
470 break;
471 }
472 }
473 }
474
475 inline void MoveToMember(DotsC_MemberIndex member)
476 {
477 if (m_memberIndex!=member)
478 {
479 m_memberDescription=m_classDescription->GetMember(member);
480 m_memberIndex=member;
481 }
482 }
483
484 inline void ThrowWrongMemberType() const
485 {
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());
489 }
490
491 inline void ThrowWrongCollectionType() const
492 {
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());
496 }
497
498 //-----------------------
499 // write keys
500 //-----------------------
501 void WriteKey(DotsC_Int32 key)
502 {
503 m_blob.SetKeyInt32(m_memberIndex, m_valueIndex, key);
504 }
505
506 void WriteKey(DotsC_Int64 key)
507 {
508 m_blob.SetKeyInt64(m_memberIndex, m_valueIndex, key);
509
510 }
511 void WriteKey(const char* key)
512 {
513 m_blob.SetKeyString(m_memberIndex, m_valueIndex, key);
514 }
515
516 void WriteKey(const std::pair<DotsC_Int64, const char *>& key)
517 {
518 m_blob.SetKeyHash(m_memberIndex, m_valueIndex, key.first);
519 if (key.second)
520 {
521 m_blob.SetKeyString(m_memberIndex, m_valueIndex, key.second);
522 }
523 }
524
525 void WriteKey(const std::pair<DotsC_EntityId, const char*>& key)
526 {
527 m_blob.SetKeyInt64(m_memberIndex, m_valueIndex, key.first.typeId);
528 WriteKey(std::pair<DotsC_Int64, const char *>(key.first.instanceId, key.second));
529 }
530
531 //-----------------------
532 // write values
533 //-----------------------
534 void WriteValue(DotsC_Int32 val)
535 {
536 assert(m_memberDescription->GetMemberType()==Int32MemberType || m_memberDescription->GetMemberType()==EnumerationMemberType);
537 m_blob.SetValueInt32(m_memberIndex, m_valueIndex, val);
538 }
539
540 void WriteValue(DotsC_Int64 val)
541 {
542 assert(m_memberDescription->GetMemberType()==Int64MemberType || m_memberDescription->GetMemberType()==TypeIdMemberType);
543 m_blob.SetValueInt64(m_memberIndex, m_valueIndex, val);
544 }
545
546 void WriteValue(DotsC_Float32 val)
547 {
548 //assert(m_memberDescription->GetMemberType()==Float32MemberType);
549 m_blob.SetValueFloat32(m_memberIndex, m_valueIndex, val);
550 }
551
552 void WriteValue(DotsC_Float64 val)
553 {
554 //assert(m_memberDescription->GetMemberType()==Float64MemberType);
555 m_blob.SetValueFloat64(m_memberIndex, m_valueIndex, val);
556 }
557
558 void WriteValue(bool val)
559 {
560 assert(m_memberDescription->GetMemberType()==BooleanMemberType);
561 m_blob.SetValueBool(m_memberIndex, m_valueIndex, val);
562 }
563
564 void WriteValue(const char* val)
565 {
566 assert(m_memberDescription->GetMemberType()==StringMemberType);
567 m_blob.SetValueString(m_memberIndex, m_valueIndex, val);
568 }
569
570 void WriteValue(const std::pair<DotsC_Int64, const char *>& val) //hashed val
571 {
572 assert(m_memberDescription->GetMemberType()==InstanceIdMemberType || m_memberDescription->GetMemberType()==ChannelIdMemberType || m_memberDescription->GetMemberType()==HandlerIdMemberType);
573 m_blob.SetValueHash(m_memberIndex, m_valueIndex, val.first);
574 if (val.second)
575 {
576 m_blob.SetValueString(m_memberIndex, m_valueIndex, val.second);
577 }
578 }
579
580 void WriteValue(const std::pair<DotsC_EntityId, const char*>& val) //entityId with optional instance string
581 {
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);
585 if (val.second)
586 {
587 m_blob.SetValueString(m_memberIndex, m_valueIndex, val.second);
588 }
589 }
590
591 void WriteValue(const std::pair<const char*, DotsC_Int32>& val) //binary data or object
592 {
593 assert(m_memberDescription->GetMemberType()==BinaryMemberType || m_memberDescription->GetMemberType()==ObjectMemberType);
594 m_blob.SetValueBinary(m_memberIndex, m_valueIndex, val.first, val.second);
595 }
596
597 void WriteValue(const std::pair<char*, DotsC_Int32>& val) //binary data or object
598 {
599 assert(m_memberDescription->GetMemberType()==BinaryMemberType || m_memberDescription->GetMemberType()==ObjectMemberType);
600 m_blob.SetValueBinary(m_memberIndex, m_valueIndex, val.first, val.second);
601 }
602
603 void WriteValue(const BlobWriterType& val) //object
604 {
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()));
609 }
610
611 bool Diff(const Internal::Blob& other, const MemberDescriptionType* md, int memberIndex, int myValueIndex, int otherValueIndex)
612 {
613 bool meIsNull=false, meIsChanged=false;
614 bool otherIsNull=false, otherIsChanged=false;
615
616 m_blob.ValueStatus(memberIndex, myValueIndex, meIsNull, meIsChanged);
617 other.ValueStatus(memberIndex, otherValueIndex, otherIsNull, otherIsChanged);
618
619 if (meIsNull!=otherIsNull)
620 {
621 if (!meIsNull && md->GetMemberType()==ObjectMemberType)
622 {
623 std::pair<const char*, DotsC_Int32> obj=m_blob.GetValueBinary(memberIndex, myValueIndex);
624 BlobWriterType inner(BlobReaderType(m_repository, obj.first));
625 inner.SetChangedRecursive(true);
626 MoveToMember(memberIndex);
627 m_valueIndex=myValueIndex;
628 WriteValue(inner);
629 }
630 return true;
631 }
632 else if (!meIsNull)
633 {
634 switch(md->GetMemberType())
635 {
636 case BooleanMemberType:
637 return m_blob.GetValueBool(memberIndex, myValueIndex)!=other.GetValueBool(memberIndex, otherValueIndex);
638
639 case Int32MemberType:
640 case EnumerationMemberType:
641 return m_blob.GetValueInt32(memberIndex, myValueIndex)!=other.GetValueInt32(memberIndex, otherValueIndex);
642
643 case Int64MemberType:
644 case TypeIdMemberType:
645 return m_blob.GetValueInt64(memberIndex, myValueIndex)!=other.GetValueInt64(memberIndex, otherValueIndex);
646
647 case InstanceIdMemberType:
648 case ChannelIdMemberType:
649 case HandlerIdMemberType:
650 return m_blob.GetValueHash(memberIndex, myValueIndex)!=other.GetValueHash(memberIndex, otherValueIndex);
651
652 case EntityIdMemberType:
653 return (m_blob.GetValueInt64(memberIndex, myValueIndex)!=other.GetValueInt64(memberIndex, otherValueIndex)) ||
654 (m_blob.GetValueHash(memberIndex, myValueIndex)!=other.GetValueHash(memberIndex, otherValueIndex));
655
656 case StringMemberType:
657 return strcmp(m_blob.GetValueString(memberIndex, myValueIndex), other.GetValueString(memberIndex, otherValueIndex))!=0;
658
659 case ObjectMemberType:
660 {
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)
664 {
665 //not binary equal, something is probably different
666 BlobWriterType inner(BlobReaderType(m_repository, meInner.first));
667 BlobReaderType otherReader(m_repository, otherInner.first);
668 bool diff=inner.MarkChanges(otherReader);
669 if (diff)
670 {
671 MoveToMember(memberIndex);
672 m_valueIndex=myValueIndex;
673 WriteValue(inner);
674 return true;
675 }
676 }
677 return false;
678 }
679 break;
680
681 case BinaryMemberType:
682 {
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;
686 }
687 break;
688
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);
710
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);
732
733 } //end switch-statement
734 }
735 return false; //both values are null, i.e not changed
736 }
737
738 static void UniversalKeyToIndex(const Internal::Blob& blob,
739 const MemberDescriptionType* md,
740 int memberIndex,
741 std::map<DotsC_Int64, int>& keyToIndex)
742 {
743 //, InstanceId, HandlerId, ChannelId, EntityId.
744 switch (md->GetKeyType())
745 {
746 case Int32MemberType:
747 case EnumerationMemberType:
748 {
749 for (int i=0; i<blob.NumberOfValues(memberIndex); ++i)
750 {
751 keyToIndex.insert(std::make_pair(TypeUtilities::ToUnifiedDictionaryKey(blob.GetKeyInt32(memberIndex, i)), i));
752 }
753 }
754 break;
755
756 case Int64MemberType:
757 case TypeIdMemberType:
758 {
759 for (int i=0; i<blob.NumberOfValues(memberIndex); ++i)
760 {
761 keyToIndex.insert(std::make_pair(TypeUtilities::ToUnifiedDictionaryKey(blob.GetKeyInt64(memberIndex, i)), i));
762 }
763 }
764 break;
765
766 case StringMemberType:
767 {
768 for (int i=0; i<blob.NumberOfValues(memberIndex); ++i)
769 {
770 keyToIndex.insert(std::make_pair(TypeUtilities::ToUnifiedDictionaryKey(blob.GetKeyString(memberIndex, i)), i));
771 }
772 }
773 break;
774
775 case InstanceIdMemberType:
776 case HandlerIdMemberType:
777 case ChannelIdMemberType:
778 {
779 for (int i=0; i<blob.NumberOfValues(memberIndex); ++i)
780 {
781 keyToIndex.insert(std::make_pair(TypeUtilities::ToUnifiedDictionaryKey(blob.GetKeyHash(memberIndex, i)), i));
782 }
783 }
784 break;
785
786 case EntityIdMemberType:
787 {
788 for (int i=0; i<blob.NumberOfValues(memberIndex); ++i)
789 {
790 DotsC_EntityId eid={blob.GetKeyInt64(memberIndex, i), blob.GetKeyHash(memberIndex, i)};
791 keyToIndex.insert(std::make_pair(TypeUtilities::ToUnifiedDictionaryKey(eid), i));
792 }
793 }
794 break;
795
796 default:
797 break;
798 }
799
800 }
801 };
802}
803}
804}
805} //end namespace Safir::Dob::Typesystem::ToolSupport
806
807#endif
This namespace contains all the functionality and definitions of the SAFIR SDK.
Definition Backdoor.h:31
DotsC_TypeId TypeId
A unique type identifier.
Definition Defs.h:218
DotsC_Int64 ToUnifiedDictionaryKey(DotsC_Int64 key)
ToUnifiedDictionaryKey - Convert all keys to an int64 that is the internal key format.
Definition TypeUtilities.h:246
This class is used to unpack and read blobs created by the BlobWriter class.
Definition BlobReader.h:65
DotsC_TypeId TypeId() const
Get the type id of the blob.
Definition BlobReader.h:119
This class is used to create blobs by writing member values and the finally calling the CopyRawBlob-m...
Definition BlobWriter.h:63
bool MarkChanges(const BlobReaderType &reader)
MarkChanges - Set change flag for all members that differs between this blob and the reader blob.
Definition BlobWriter.h:342
void SetChangedRecursive(bool isChanged)
SetChangedRecursive - Recursively set all change flags to specified value.
Definition BlobWriter.h:234
DotsC_TypeId TypeId() const
Get the type id of this BlobWriter.
Definition BlobWriter.h:111
Traits::PropertyDescriptionType PropertyDescriptionType
Definition BlobWriter.h:70
Traits::EnumDescriptionType EnumDescriptionType
Definition BlobWriter.h:73
Traits::RepositoryType RepositoryType
Definition BlobWriter.h:67
void CopyRawBlob(char *destBlob) const
Copy the binarey blob into a destination buffer.
Definition BlobWriter.h:124
BlobWriter(const RepositoryT *rep, DotsC_TypeId typeId)
Constructor - Creates a new writeable blob of specified type.
Definition BlobWriter.h:83
void SetChangedTopLevel(DotsC_MemberIndex member, bool isChanged)
Set the top level isChanged flag.
Definition BlobWriter.h:132
Traits::ClassDescriptionType ClassDescriptionType
Definition BlobWriter.h:68
BlobReader< RepositoryT, Traits > BlobReaderType
Definition BlobWriter.h:66
Traits::ParameterDescriptionType ParameterDescriptionType
Definition BlobWriter.h:72
DotsC_Int32 CalculateBlobSize() const
Calculate the size of the blob in bytes.
Definition BlobWriter.h:117
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:195
Traits::PropertyMappingDescriptionType PropertyMappingDescriptionType
Definition BlobWriter.h:75
BlobWriter & operator=(const BlobWriter &)=delete
Traits::MemberDescriptionType MemberDescriptionType
Definition BlobWriter.h:69
Traits::CreateRoutineDescriptionType CreateRoutineDescriptionType
Definition BlobWriter.h:76
void WriteKey(DotsC_MemberIndex member, const Key &key)
Write member key to the a blob.
Definition BlobWriter.h:166
Traits::ExceptionDescriptionType ExceptionDescriptionType
Definition BlobWriter.h:71
void SetChangedHere(DotsC_MemberIndex member, DotsC_Int32 valueIndex, bool isChanged)
Set the change flag for a member value.
Definition BlobWriter.h:149
BlobWriter(const BlobReaderType &reader)
Definition BlobWriter.h:94
Traits::MemberMappingDescriptionType MemberMappingDescriptionType
Definition BlobWriter.h:74
BlobWriter< RepositoryT, Traits > BlobWriterType
Definition BlobWriter.h:65