cauterize 0.0.1.pre1 → 0.0.1.pre5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. data/.gitignore +5 -0
  2. data/.rspec +1 -1
  3. data/Gemfile +1 -1
  4. data/README.md +0 -2
  5. data/Rakefile +19 -3
  6. data/bin/cauterize +14 -6
  7. data/example/Cauterize +22 -10
  8. data/example/build.sh +15 -2
  9. data/lib/cauterize/base_type.rb +2 -5
  10. data/lib/cauterize/builders.rb +1 -3
  11. data/lib/cauterize/builders/c/buildable.rb +3 -2
  12. data/lib/cauterize/builders/c/builtin.rb +46 -0
  13. data/lib/cauterize/builders/c/enumeration.rb +23 -2
  14. data/lib/cauterize/builders/c/fixed_array.rb +16 -7
  15. data/lib/cauterize/builders/c/group.rb +32 -3
  16. data/lib/cauterize/builders/c/scalar.rb +5 -0
  17. data/lib/cauterize/builders/c/variable_array.rb +1 -1
  18. data/lib/cauterize/builders/cs/buildable.rb +59 -0
  19. data/lib/cauterize/builders/cs/builtin.rb +23 -0
  20. data/lib/cauterize/builders/cs/composite.rb +21 -0
  21. data/lib/cauterize/builders/cs/csarray.rb +32 -0
  22. data/lib/cauterize/builders/cs/enumeration.rb +21 -0
  23. data/lib/cauterize/builders/cs/fixed_array.rb +25 -0
  24. data/lib/cauterize/builders/cs/group.rb +33 -0
  25. data/lib/cauterize/builders/cs/scalar.rb +10 -0
  26. data/lib/cauterize/builders/cs/variable_array.rb +34 -0
  27. data/lib/cauterize/builtin.rb +52 -0
  28. data/lib/cauterize/c_builder.rb +15 -1
  29. data/lib/cauterize/cauterize.rb +44 -13
  30. data/lib/cauterize/composite.rb +3 -3
  31. data/lib/cauterize/cs_builder.rb +53 -0
  32. data/lib/cauterize/enumeration.rb +20 -3
  33. data/lib/cauterize/fixed_array.rb +3 -3
  34. data/lib/cauterize/formatter.rb +7 -3
  35. data/lib/cauterize/group.rb +5 -8
  36. data/lib/cauterize/scalar.rb +16 -7
  37. data/lib/cauterize/variable_array.rb +6 -6
  38. data/lib/cauterize/version.rb +1 -1
  39. data/spec/base_type_spec.rb +133 -125
  40. data/spec/builders/c/buildable_spec.rb +18 -18
  41. data/spec/builders/c/builtin_spec.rb +22 -0
  42. data/spec/builders/c/composite_spec.rb +37 -33
  43. data/spec/builders/c/enumeration_spec.rb +84 -21
  44. data/spec/builders/c/fixed_array_spec.rb +6 -6
  45. data/spec/builders/c/group_spec.rb +97 -90
  46. data/spec/builders/c/scalar_spec.rb +24 -6
  47. data/spec/builders/c/variable_array_spec.rb +37 -37
  48. data/spec/builders/cs/buildable_spec.rb +8 -0
  49. data/spec/builders/cs/composite_spec.rb +32 -0
  50. data/spec/builders/cs/enumeration_spec.rb +33 -0
  51. data/spec/builders/cs/fixed_array_spec.rb +40 -0
  52. data/spec/builders/cs/group_spec.rb +56 -0
  53. data/spec/builders/cs/scalar_spec.rb +7 -0
  54. data/spec/builders/cs/variable_array_spec.rb +46 -0
  55. data/spec/builders_spec.rb +38 -38
  56. data/spec/builtin_spec.rb +46 -0
  57. data/spec/c_builder_spec.rb +116 -102
  58. data/spec/cauterize_spec.rb +8 -1
  59. data/spec/composite_spec.rb +52 -48
  60. data/spec/cs_builder_spec.rb +113 -0
  61. data/spec/enumeration_spec.rb +55 -16
  62. data/spec/fixed_array_spec.rb +7 -9
  63. data/spec/group_spec.rb +81 -76
  64. data/spec/scalar_spec.rb +20 -10
  65. data/spec/spec_helper.rb +103 -94
  66. data/spec/support/shared_examples_for_c_buildables.rb +68 -64
  67. data/spec/variable_array_spec.rb +12 -17
  68. data/{c → support/c}/src/cauterize.c +8 -7
  69. data/support/c/src/cauterize.h +59 -0
  70. data/{c → support/c}/src/cauterize_debug.h +0 -0
  71. data/support/c/src/cauterize_util.h +49 -0
  72. data/{c → support/c}/test/greatest.h +0 -0
  73. data/{c → support/c}/test/test.c +0 -0
  74. data/support/cs/src/CauterizeCompositeFormatter.cs +34 -0
  75. data/support/cs/src/CauterizeContainerFormatter.cs +18 -0
  76. data/support/cs/src/CauterizeEnumFormatter.cs +67 -0
  77. data/support/cs/src/CauterizeException.cs +15 -0
  78. data/support/cs/src/CauterizeFixedArrayFormatter.cs +39 -0
  79. data/support/cs/src/CauterizeFormatter.cs +40 -0
  80. data/support/cs/src/CauterizeGroupFormatter.cs +46 -0
  81. data/support/cs/src/CauterizePrimitiveFormatter.cs +33 -0
  82. data/support/cs/src/CauterizeTypeFormatterFactory.cs +39 -0
  83. data/support/cs/src/CauterizeTypes.cs +107 -0
  84. data/support/cs/src/CauterizeVariableArrayFormatter.cs +49 -0
  85. data/support/cs/src/ICauterizeTypeFormatter.cs +12 -0
  86. data/support/cs/src/OrderAttribute.cs +50 -0
  87. data/support/cs/src/PrimitiveSupport.cs +134 -0
  88. data/support/cs/src/SerializedRepresentationAttribute.cs +24 -0
  89. data/support/cs/test/CauterizeCompositeFormatterTest.cs +59 -0
  90. data/support/cs/test/CauterizeEnumFormatterTest.cs +110 -0
  91. data/support/cs/test/CauterizeFixedArrayFormatterTest.cs +91 -0
  92. data/support/cs/test/CauterizeFormatterTest.cs +40 -0
  93. data/support/cs/test/CauterizeGroupFormatterTest.cs +147 -0
  94. data/support/cs/test/CauterizeIntegrationTest.cs +129 -0
  95. data/support/cs/test/CauterizePrimitiveFormatterTest.cs +98 -0
  96. data/support/cs/test/CauterizeTypeFormatterFactoryTest.cs +73 -0
  97. data/support/cs/test/CauterizeVariableArrayFormatterTest.cs +130 -0
  98. data/support/cs/test/OrderAttributeTest.cs +39 -0
  99. data/support/cs/test/SerializedRepresentationAttributeTest.cs +39 -0
  100. metadata +68 -10
  101. data/c/src/cauterize.h +0 -46
  102. data/c/src/cauterize_util.h +0 -7
@@ -1,91 +1,95 @@
1
1
  # shared examples for c buildables
2
2
 
3
- include Cauterize::Builders::C
3
+ module Cauterize
4
+ include Cauterize::Builders::C
4
5
 
5
- shared_examples "a buildable" do
6
- let(:desc_instance) { type_constructor.call(:some_type_name) }
7
- let(:formatter) { default_formatter }
8
- let(:builder) { Cauterize::Builders.get(:c, desc_instance) }
9
- subject { described_class.new(desc_instance) }
6
+ shared_examples "a buildable" do
7
+ let(:desc_instance) { type_constructor.call(:some_type_name) }
8
+ let(:formatter) { default_formatter }
9
+ let(:builder) { Cauterize::Builders.get(:c, desc_instance) }
10
+ subject { described_class.new(desc_instance) }
10
11
 
11
- it "should be registered" do
12
- builder.class.should be described_class
13
- end
12
+ it "should be registered" do
13
+ builder.class.should be described_class
14
+ end
14
15
 
15
- it "errors on duplicate type names" do
16
- BaseType.class_variable_set(:@@used_names, Set.new([:a_common_name]))
17
- lambda {
18
- type_constructor.call(:a_common_name)
19
- }.should raise_error /already exists/
20
- end
16
+ it "errors on duplicate type names" do
17
+ instances = BaseType.class_variable_get(:@@instances)
18
+ instances[:a_common_name] = nil
19
+ BaseType.class_variable_set(:@@instances, instances)
20
+ lambda {
21
+ type_constructor.call(:a_common_name)
22
+ }.should raise_error /already exists/
23
+ end
21
24
 
22
- describe :packer_sym do
23
- it "contains the word Pack" do
24
- subject.packer_sym.should match /Pack_/
25
+ describe :packer_sym do
26
+ it "contains the word Pack" do
27
+ subject.packer_sym.should match /Pack_/
28
+ end
25
29
  end
26
- end
27
30
 
28
- describe :packer_sig do
29
- it "looks like this" do
30
- r = /CAUTERIZE_STATUS_T (?<sym>[^\(]+)\(struct Cauterize \* dst, (?<rend>(?:(?:struct|enum) )?[^ ]+) \* src\)/
31
- subject.packer_sig.should match r
32
- m = subject.packer_sig.match(r)
33
- m[:sym].should == subject.packer_sym
34
- m[:rend].should == subject.render
31
+ describe :packer_sig do
32
+ it "looks like this" do
33
+ r = /CALLCONV CAUTERIZE_STATUS_T DLLDECL (?<sym>[^\(]+)\(struct Cauterize \* dst, (?<rend>(?:(?:struct|enum) )?[^ ]+) \* src\)/
34
+ subject.packer_sig.should match r
35
+ m = subject.packer_sig.match(r)
36
+ m[:sym].should == subject.packer_sym
37
+ m[:rend].should == subject.render
38
+ end
35
39
  end
36
- end
37
40
 
38
- describe :packer_proto do
39
- it "should format the sig + ;" do
40
- subject.packer_proto(formatter)
41
- formatter.to_s.should == subject.packer_sig + ";"
41
+ describe :packer_proto do
42
+ it "should format the sig + ;" do
43
+ subject.packer_proto(formatter)
44
+ formatter.to_s.should == subject.packer_sig + ";"
45
+ end
42
46
  end
43
- end
44
47
 
45
- describe :packer_defn do
46
- before { subject.packer_defn(formatter) }
48
+ describe :packer_defn do
49
+ before { subject.packer_defn(formatter) }
47
50
 
48
- it "contains the signature" do
49
- formatter.to_s.should match Regexp.escape(subject.packer_sig)
50
- end
51
+ it "contains the signature" do
52
+ formatter.to_s.should match Regexp.escape(subject.packer_sig)
53
+ end
51
54
 
52
- it "contains a return statement" do
53
- formatter.to_s.should match /return.*;/
55
+ it "contains a return statement" do
56
+ formatter.to_s.should match /return.*;/
57
+ end
54
58
  end
55
- end
56
59
 
57
- describe :unpacker_sym do
58
- it "contains the word Unpack" do
59
- subject.unpacker_sym.should match /Unpack_/
60
+ describe :unpacker_sym do
61
+ it "contains the word Unpack" do
62
+ subject.unpacker_sym.should match /Unpack_/
63
+ end
60
64
  end
61
- end
62
65
 
63
- describe :unpacker_sig do
64
- it "looks like this" do
65
- r = /CAUTERIZE_STATUS_T (?<sym>[^\(]+)\(struct Cauterize \* src, (?<rend>(?:(?:struct|enum) )?[^ ]+) \* dst\)/
66
- subject.unpacker_sig.should match r
67
- m = subject.unpacker_sig.match(r)
68
- m[:sym].should == subject.unpacker_sym
69
- m[:rend].should == subject.render
66
+ describe :unpacker_sig do
67
+ it "looks like this" do
68
+ r = /CALLCONV CAUTERIZE_STATUS_T DLLDECL (?<sym>[^\(]+)\(struct Cauterize \* src, (?<rend>(?:(?:struct|enum) )?[^ ]+) \* dst\)/
69
+ subject.unpacker_sig.should match r
70
+ m = subject.unpacker_sig.match(r)
71
+ m[:sym].should == subject.unpacker_sym
72
+ m[:rend].should == subject.render
73
+ end
70
74
  end
71
- end
72
75
 
73
- describe :unpacker_proto do
74
- it "should format the sig + ;" do
75
- subject.unpacker_proto(formatter)
76
- formatter.to_s.should == subject.unpacker_sig + ";"
76
+ describe :unpacker_proto do
77
+ it "should format the sig + ;" do
78
+ subject.unpacker_proto(formatter)
79
+ formatter.to_s.should == subject.unpacker_sig + ";"
80
+ end
77
81
  end
78
- end
79
82
 
80
- describe :unpacker_defn do
81
- before { subject.unpacker_defn(formatter) }
83
+ describe :unpacker_defn do
84
+ before { subject.unpacker_defn(formatter) }
82
85
 
83
- it "contains the signature" do
84
- formatter.to_s.should match Regexp.escape(subject.unpacker_sig)
85
- end
86
+ it "contains the signature" do
87
+ formatter.to_s.should match Regexp.escape(subject.unpacker_sig)
88
+ end
86
89
 
87
- it "contains a return statement" do
88
- formatter.to_s.should match /return.*;/
90
+ it "contains a return statement" do
91
+ formatter.to_s.should match /return.*;/
92
+ end
89
93
  end
90
94
  end
91
95
  end
@@ -1,26 +1,20 @@
1
- describe Cauterize do
2
- before { reset_for_test }
3
-
1
+ module Cauterize
4
2
  describe :variable_array do
5
3
  it { creates_a_named_object(:variable_array, VariableArray) }
6
4
  it { retrieves_obj_with_identical_name(:variable_array) }
7
5
  it { yields_the_object(:variable_array) }
8
- it { adds_object_to_hash(:variable_array, :variable_arrays) }
6
+ it { adds_object_to_hash(:variable_array, Cauterize.variable_arrays) }
9
7
  end
10
8
 
11
9
  describe :variable_array! do
12
10
  it { creates_a_named_object(:variable_array!, VariableArray) }
13
11
  it { raises_exception_with_identical_name(:variable_array!) }
14
12
  it { yields_the_object(:variable_array!) }
15
- it { adds_object_to_hash(:variable_array!, :variable_arrays) }
13
+ it { adds_object_to_hash(:variable_array!, Cauterize.variable_arrays) }
16
14
  end
17
15
 
18
16
  describe :variable_arrays do
19
- it "is all the variable arrays" do
20
- variable_array(:a)
21
- variable_array(:b)
22
- variable_arrays.values.map(&:name).should == [:a, :b]
23
- end
17
+ it { is_hash_of_created_objs(:variable_array, Cauterize.variable_arrays) }
24
18
  end
25
19
 
26
20
  describe VariableArray do
@@ -34,21 +28,21 @@ describe Cauterize do
34
28
 
35
29
  describe :array_type do
36
30
  it "defines the type of the VariableArray" do
37
- scalar(:uint32_t)
31
+ Cauterize.scalar(:uint32_t)
38
32
  @a.array_type :uint32_t
39
33
  @a.instance_variable_get(:@array_type).name.should == :uint32_t
40
34
  end
41
35
 
42
36
  it "raises an error if type doesn't exist" do
43
37
  lambda {
44
- fixed_array(:fa) do |f|
38
+ Cauterize.fixed_array(:fa) do |f|
45
39
  f.array_type :lol
46
40
  end
47
41
  }.should raise_error /lol does not correspond/
48
42
  end
49
43
 
50
44
  it "is the defined type if no argument is passed" do
51
- s = scalar(:uint32_t)
45
+ s = Cauterize.scalar(:uint32_t)
52
46
  @a.array_type :uint32_t
53
47
  @a.array_type.should be s
54
48
  end
@@ -68,7 +62,7 @@ describe Cauterize do
68
62
 
69
63
  describe :size_type do
70
64
  it "defines the type to use to encode the array size" do
71
- scalar(:uint16_t)
65
+ Cauterize.scalar(:uint16_t)
72
66
  @a.size_type :uint16_t
73
67
  @a.instance_variable_get(:@size_type).name.should == :uint16_t
74
68
  end
@@ -78,12 +72,13 @@ describe Cauterize do
78
72
  end
79
73
 
80
74
  it "raises an error if the type isn't an scalar" do
81
- enumeration(:lol)
82
- lambda { @a.size_type :lol }.should raise_error /is not an scalar/
75
+ Cauterize.scalar(:uint32_t) { |t| t.type_name(:uint32) }
76
+ Cauterize.enumeration(:lol)
77
+ lambda { @a.size_type :lol }.should raise_error /is not a built-in or scalar/
83
78
  end
84
79
 
85
80
  it "is the defined type if no argument is passed" do
86
- s = scalar(:uint32_t)
81
+ s = Cauterize.scalar(:uint32_t)
87
82
  @a.size_type :uint32_t
88
83
  @a.size_type.should be s
89
84
  end
@@ -1,14 +1,15 @@
1
1
  #define CAUTERIZE_C
2
2
 
3
3
  #include "cauterize.h"
4
+ #include "cauterize_util.h"
4
5
  #include "cauterize_debug.h"
5
6
 
6
7
  #include <string.h>
7
8
 
8
- #define S CAUTERIZE_STATUS_T
9
+ #define S CALLCONV CAUTERIZE_STATUS_T DLLDECL
9
10
  #define T struct Cauterize
10
11
 
11
- S CauterizeInitAppend( struct Cauterize * m, uint8_t * buffer, size_t length)
12
+ S CauterizeInitAppend(T * m, uint8_t * buffer, uint32_t length)
12
13
  {
13
14
  CA_ASSERT(NULL != m);
14
15
  CA_ASSERT(NULL != buffer);
@@ -21,7 +22,7 @@ S CauterizeInitAppend( struct Cauterize * m, uint8_t * buffer, size_t length)
21
22
  return CA_OK;
22
23
  }
23
24
 
24
- S CauterizeInitRead( struct Cauterize * m, uint8_t * buffer, size_t used)
25
+ S CauterizeInitRead(T * m, uint8_t * buffer, uint32_t used)
25
26
  {
26
27
  CA_ASSERT(NULL != m);
27
28
  CA_ASSERT(NULL != buffer);
@@ -34,12 +35,12 @@ S CauterizeInitRead( struct Cauterize * m, uint8_t * buffer, size_t used)
34
35
  return CA_OK;
35
36
  }
36
37
 
37
- S CauterizeAppend(T * m, uint8_t * src, size_t length)
38
+ S CauterizeAppend(T * m, uint8_t * src, uint32_t length)
38
39
  {
39
40
  CA_ASSERT(NULL != m);
40
41
  CA_ASSERT(NULL != src);
41
42
 
42
- size_t needed = m->used + length;
43
+ uint32_t needed = m->used + length;
43
44
 
44
45
  if (needed > m->size)
45
46
  return CA_ERR_NOT_ENOUGH_SPACE;
@@ -51,13 +52,13 @@ S CauterizeAppend(T * m, uint8_t * src, size_t length)
51
52
  return CA_OK;
52
53
  }
53
54
 
54
- S CauterizeRead(T * m, uint8_t * dst, size_t length)
55
+ S CauterizeRead(T * m, uint8_t * dst, uint32_t length)
55
56
  {
56
57
  CA_ASSERT(NULL != m);
57
58
  CA_ASSERT(NULL != dst);
58
59
  CA_ASSERT(m->used >= m->pos);
59
60
 
60
- size_t available = m->used - m->pos;
61
+ uint32_t available = m->used - m->pos;
61
62
 
62
63
  if (length > available)
63
64
  return CA_ERR_NOT_ENOUGH_DATA;
@@ -0,0 +1,59 @@
1
+ #ifndef CAUTERIZE_H
2
+ #define CAUTERIZE_H
3
+
4
+ #ifndef CUSTOM_TYPES
5
+ #include <stdint.h>
6
+ #include <stddef.h>
7
+ #else
8
+ #include "cauterize_custom_types.h"
9
+ #endif
10
+
11
+ #include "cauterize_util.h"
12
+
13
+ typedef enum cauterize_status {
14
+ CA_OK = 0,
15
+ CA_ERR_ASSERT = 1,
16
+ CA_ERR_NOT_ENOUGH_SPACE = 2,
17
+ CA_ERR_NOT_ENOUGH_DATA = 3,
18
+ CA_ERR_INVALID_LENGTH = 4,
19
+ CA_ERR_INVALUD_TYPE_TAG = 5,
20
+ CA_ERR_INVALID_ENUM_VAL = 6,
21
+ CA_ERR_GENERAL = UINT32_MAX,
22
+ } CAUTERIZE_STATUS_T;
23
+
24
+ struct Cauterize {
25
+ uint32_t size; // Size of the buffer in bytes
26
+ uint32_t used; // Number of used bytes in the buffer
27
+ uint32_t pos; // The next byte to be read
28
+ uint8_t * buffer; // Buffer to hold data
29
+ };
30
+
31
+ #ifdef __cplusplus
32
+ extern "C" {
33
+ #endif
34
+
35
+ CALLCONV CAUTERIZE_STATUS_T DLLDECL CauterizeInitAppend(
36
+ struct Cauterize * m,
37
+ uint8_t * buffer,
38
+ uint32_t length);
39
+
40
+ CALLCONV CAUTERIZE_STATUS_T DLLDECL CauterizeInitRead(
41
+ struct Cauterize * m,
42
+ uint8_t * buffer,
43
+ uint32_t used);
44
+
45
+ CALLCONV CAUTERIZE_STATUS_T DLLDECL CauterizeAppend(
46
+ struct Cauterize * m,
47
+ uint8_t * src,
48
+ uint32_t length);
49
+
50
+ CALLCONV CAUTERIZE_STATUS_T DLLDECL CauterizeRead(
51
+ struct Cauterize * m,
52
+ uint8_t * dst,
53
+ uint32_t length);
54
+
55
+ #ifdef __cplusplus
56
+ }
57
+ #endif
58
+
59
+ #endif /* CAUTERIZE_H */
File without changes
@@ -0,0 +1,49 @@
1
+ #ifndef CAUTERIZE_UTIL_H
2
+ #define CAUTERIZE_UTIL_H
3
+
4
+ #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
5
+ #define CA_MIN(a, b) (((a) < (b)) ? (a) : (b))
6
+ #define CA_MAX(a,b) ((a) > (b) ? (a) : (b))
7
+
8
+ /* Buidling Cauterize files as a DLL. */
9
+
10
+ #if defined(BUILDING_DLL) || defined(USING_DLL)
11
+ #if !defined(_WIN32)
12
+ #error "Can only build DLL in Windows."
13
+ #endif
14
+
15
+ #define CALLCONV __stdcall
16
+ #endif
17
+
18
+ #if defined(BUILDING_DLL)
19
+ #define DLLDECL __declspec(dllexport)
20
+ #elif defined(USING_DLL)
21
+ #define DLLDECL __declspec(dllimport)
22
+ #endif
23
+
24
+ #ifndef DLLDECL
25
+ #define DLLDECL
26
+ #endif
27
+
28
+ #ifndef CALLCONV
29
+ #define CALLCONV
30
+ #endif
31
+
32
+ /* Buidling Cauterize files as a DLL. */
33
+
34
+ #if defined(BUILDING_DLL)
35
+ #define DLLDECL __declspec(dllexport)
36
+ #elif defined(USING_DLL)
37
+ #define DLLDECL __declspec(dllimport)
38
+ #else
39
+ #define DLLDECL
40
+ #endif
41
+
42
+ #if defined(_WIN32)
43
+ #warn "building on win32"
44
+ #define CALLCONV __stdcal
45
+ #else
46
+ #define CALLCONV
47
+ #endif
48
+
49
+ #endif /* CAUTERIZE_UTIL_H */
File without changes
File without changes
@@ -0,0 +1,34 @@
1
+ using System;
2
+ using System.IO;
3
+
4
+ namespace Cauterize
5
+ {
6
+ public class CauterizeCompositeFormatter : CauterizeContainerFormatter
7
+ {
8
+ public CauterizeCompositeFormatter(CauterizeTypeFormatterFactory factory) : base(factory)
9
+ {
10
+ }
11
+ public override object Deserialize(Stream serializationStream, Type t)
12
+ {
13
+ var ret = t.GetConstructor(new Type[] {}).Invoke(new object[] {});
14
+ foreach (var prop in OrderAttribute.GetSortedProperties(t))
15
+ {
16
+ var subType = prop.PropertyType;
17
+ var subFormatter = _typeFormatterFactory.GetFormatter(subType);
18
+ var subObj = subFormatter.Deserialize(serializationStream, subType);
19
+ prop.SetValue(ret, subObj, null);
20
+ }
21
+ return ret;
22
+ }
23
+
24
+ public override void Serialize(Stream serializationStream, object obj)
25
+ {
26
+ foreach (var prop in OrderAttribute.GetSortedProperties(obj.GetType()))
27
+ {
28
+ var subType = prop.PropertyType;
29
+ var subFormatter = _typeFormatterFactory.GetFormatter(subType);
30
+ subFormatter.Serialize(serializationStream, prop.GetValue(obj, null));
31
+ }
32
+ }
33
+ }
34
+ }