Mercurial > projects > orange
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; |