comparison orange/serialization/Serializer.d @ 29:c422ff6477dd experimental

Better handling of serializing pointers.
author Jacob Carlborg <doob@me.com>
date Sun, 21 Nov 2010 16:53:46 +0100
parents bffcbc8c392b
children 9d1a8023bb89
comparison
equal deleted inserted replaced
28:bffcbc8c392b 29:c422ff6477dd
63 void*[Id] deserializedReferences; 63 void*[Id] deserializedReferences;
64 64
65 Array[Id] serializedArrays; 65 Array[Id] serializedArrays;
66 void[][Id] deserializedSlices; 66 void[][Id] deserializedSlices;
67 67
68 Id[void*] serializedPointers;
69 Id[void*] serializedValues;
70
68 bool hasBegunSerializing; 71 bool hasBegunSerializing;
69 bool hasBegunDeserializing; 72 bool hasBegunDeserializing;
70 73
71 void delegate (ArchiveException exception, string[] data) throwOnErrorCallback; 74 void delegate (ArchiveException exception, string[] data) throwOnErrorCallback;
72 void delegate (ArchiveException exception, string[] data) doNothingOnErrorCallback; 75 void delegate (ArchiveException exception, string[] data) doNothingOnErrorCallback;
112 serializedReferences = null; 115 serializedReferences = null;
113 deserializedReferences = null; 116 deserializedReferences = null;
114 117
115 serializedArrays = null; 118 serializedArrays = null;
116 deserializedSlices = null; 119 deserializedSlices = null;
120
121 serializedValues = null;
122 serializedPointers = null;
117 123
118 hasBegunSerializing = false; 124 hasBegunSerializing = false;
119 hasBegunDeserializing = false; 125 hasBegunDeserializing = false;
120 126
121 archive.reset; 127 archive.reset;
296 private void serializePointer (T) (T value, string key) 302 private void serializePointer (T) (T value, string key)
297 { 303 {
298 if (!value) 304 if (!value)
299 return archive.archiveNull(T.stringof, key); 305 return archive.archiveNull(T.stringof, key);
300 306
301 auto reference = getSerializedReference(value);
302
303 if (reference != Id.max)
304 return archive.archiveReference(key, reference);
305
306 Id id = nextId; 307 Id id = nextId;
307
308 addSerializedReference(value, id);
309 308
310 archive.archivePointer(key, id, { 309 archive.archivePointer(key, id, {
311 if (key in serializers) 310 if (key in serializers)
312 { 311 {
313 auto wrapper = getSerializerWrapper!(T)(key); 312 auto wrapper = getSerializerWrapper!(T)(key);
324 323
325 else 324 else
326 serializeInternal(*value, nextKey); 325 serializeInternal(*value, nextKey);
327 } 326 }
328 }); 327 });
328
329 addSerializedPointer(value, id);
329 } 330 }
330 331
331 private void serializeEnum (T) (T value, string key) 332 private void serializeEnum (T) (T value, string key)
332 { 333 {
333 alias BaseTypeOfEnum!(T) EnumBaseType; 334 alias BaseTypeOfEnum!(T) EnumBaseType;
663 664
664 static if (!internalFields.ctfeContains(field) && !nonSerializedFields.ctfeContains(field)) 665 static if (!internalFields.ctfeContains(field) && !nonSerializedFields.ctfeContains(field))
665 { 666 {
666 alias typeof(T.tupleof[i]) Type; 667 alias typeof(T.tupleof[i]) Type;
667 Type v = value.tupleof[i]; 668 Type v = value.tupleof[i];
669
670 addSerializedValue(value.tupleof[i], nextId);
668 serializeInternal(v, toData(field)); 671 serializeInternal(v, toData(field));
669 } 672 }
670 } 673 }
671 674
672 static if (isObject!(T) && !is(T == Object)) 675 static if (isObject!(T) && !is(T == Object))
737 static assert(isArray!(T) || isString!(T), format!(`The given type "`, T, `" is not a slice type, i.e. array or string.`)); 740 static assert(isArray!(T) || isString!(T), format!(`The given type "`, T, `" is not a slice type, i.e. array or string.`));
738 741
739 deserializedSlices[id] = value; 742 deserializedSlices[id] = value;
740 } 743 }
741 744
745 private void addSerializedValue (T) (ref T value, Id id)
746 {
747 serializedValues[&value] = id;
748 }
749
750 private void addSerializedPointer (T) (T value, Id id)
751 {
752 serializedPointers[value] = id;
753 }
754
742 private Id getSerializedReference (T) (T value) 755 private Id getSerializedReference (T) (T value)
743 { 756 {
744 if (auto tmp = cast(void*) value in serializedReferences) 757 if (auto tmp = cast(void*) value in serializedReferences)
745 return *tmp; 758 return *tmp;
746 759
767 { 780 {
768 if (auto array = id in deserializedSlices) 781 if (auto array = id in deserializedSlices)
769 return cast(T*) array; 782 return cast(T*) array;
770 } 783 }
771 784
785 private Id getSerializedPointer (T) (T value)
786 {
787 if (auto tmp = cast(void*) value in serializedPointers)
788 return *tmp;
789
790 return Id.max;
791 }
792
772 private T[] toSlice (T) (T[] array, Slice slice) 793 private T[] toSlice (T) (T[] array, Slice slice)
773 { 794 {
774 return array[slice.offset .. slice.offset + slice.length]; 795 return array[slice.offset .. slice.offset + slice.length];
775 } 796 }
776 797
815 } 836 }
816 837
817 private void addSerializedArray (Array array, Id id) 838 private void addSerializedArray (Array array, Id id)
818 { 839 {
819 serializedArrays[id] = array; 840 serializedArrays[id] = array;
841 }
842
843 private void postProcess ()
844 {
845 postProcessArrays();
846 postProcessPointers();
820 } 847 }
821 848
822 private void postProcessArrays () 849 private void postProcessArrays ()
823 { 850 {
824 bool foundSlice = true; 851 bool foundSlice = true;
842 if (!foundSlice) 869 if (!foundSlice)
843 archive.postProcessArray(sliceKey); 870 archive.postProcessArray(sliceKey);
844 } 871 }
845 } 872 }
846 873
847 private void postProcess () 874 private void postProcessPointers ()
848 { 875 {
849 postProcessArrays(); 876 foreach (key, pointerId ; serializedPointers)
877 {
878 if (auto pointeeId = key in serializedValues)
879 archive.archivePointer(pointerId, *pointeeId);
880
881 else
882 archive.postProcessPointer(pointerId);
883 }
850 } 884 }
851 885
852 private template arrayToString (T) 886 private template arrayToString (T)
853 { 887 {
854 const arrayToString = ElementTypeOfArray!(T).stringof; 888 const arrayToString = ElementTypeOfArray!(T).stringof;