12
12
* express or implied. See the License for the specific language governing
13
13
* permissions and limitations under the License.
14
14
*/
15
- using Amazon . Runtime ;
16
- using Amazon . Runtime . Internal ;
17
- using Amazon . Runtime . Internal . Transform ;
18
- using Amazon . Runtime . Internal . Util ;
19
- using Amazon . Util ;
15
+
20
16
using System ;
21
- using System . Collections . Generic ;
22
17
using System . Formats . Cbor ;
23
- using System . IO ;
24
- using System . Text . RegularExpressions ;
18
+ using Amazon . Util ;
25
19
26
20
namespace AWSSDK . Extensions . CborProtocol
27
21
{
@@ -47,57 +41,82 @@ public static void WriteOptimizedNumber(this CborWriter writer, double value)
47
41
{
48
42
if ( double . IsNaN ( value ) || double . IsInfinity ( value ) )
49
43
{
50
- writer . WriteDouble ( value ) ;
44
+ writer . WriteDouble ( value ) ; // Write NaN or Infinity as a double.
51
45
return ;
52
46
}
53
47
48
+ // If the value is an integer (without fractional part), write it as Int64 or UInt64.
54
49
if ( value % 1 == 0 )
55
50
{
56
51
if ( value >= long . MinValue && value <= long . MaxValue )
57
52
{
53
+ // If the value fits within the signed 64-bit integer (long) range,
54
+ // WriteInt64 serializes it into the smallest CBOR type representation
55
+ // that can contain its value without loss of precision.
58
56
writer . WriteInt64 ( ( long ) value ) ;
59
57
return ;
60
58
}
61
59
62
60
if ( value >= 0 && value <= ulong . MaxValue )
63
61
{
62
+ // If the value is non-negative and fits within the unsigned 64-bit range,
63
+ // WriteUInt64 serializes it into the smallest possible CBOR type representation.
64
64
writer . WriteUInt64 ( ( ulong ) value ) ;
65
65
return ;
66
66
}
67
67
}
68
68
69
+ // Check if value can safely be represented as float32
70
+ float floatCandidate = ( float ) value ;
71
+ if ( ( double ) floatCandidate == value )
72
+ {
73
+ WriteOptimizedNumber ( writer , floatCandidate ) ;
74
+ return ;
75
+ }
76
+
77
+ // If none of the above conditions are satisfied, write the value as a double.
69
78
writer . WriteDouble ( value ) ;
70
79
}
71
80
72
81
/// <summary>
73
82
/// Writes a float using the smallest CBOR representation that preserves value and precision.
83
+ /// This method uses manual encoding to avoid writing as a half-precision float.
74
84
/// </summary>
75
85
/// <param name="writer">The CBOR writer to use.</param>
76
86
/// <param name="value">The float value to write.</param>
77
87
public static void WriteOptimizedNumber ( this CborWriter writer , float value )
78
88
{
79
- if ( float . IsNaN ( value ) || float . IsInfinity ( value ) )
80
- {
81
- writer . WriteSingle ( value ) ;
82
- return ;
83
- }
84
-
89
+ // If the value is an integer (without fractional part), write it as Int64 or UInt64.
85
90
if ( value % 1 == 0 )
86
91
{
87
92
if ( value >= long . MinValue && value <= long . MaxValue )
88
93
{
94
+ // If the value fits within the signed 64-bit integer (long) range,
95
+ // WriteInt64 serializes it into the smallest CBOR type representation
96
+ // that can contain its value without loss of precision.
89
97
writer . WriteInt64 ( ( long ) value ) ;
90
98
return ;
91
99
}
92
100
93
101
if ( value >= 0 && value <= ulong . MaxValue )
94
102
{
103
+ // If the value is non-negative and fits within the unsigned 64-bit range,
104
+ // WriteUInt64 serializes it into the smallest possible CBOR type representation.
95
105
writer . WriteUInt64 ( ( ulong ) value ) ;
96
106
return ;
97
107
}
98
108
}
99
109
100
- writer . WriteSingle ( value ) ;
110
+ // Manual encoding to avoid half-precision floats
111
+ var bytes = new byte [ 5 ] ;
112
+ bytes [ 0 ] = 0xFA ; // CBOR float32 marker
113
+ BitConverter . GetBytes ( value ) . CopyTo ( bytes , 1 ) ;
114
+
115
+ // Ensure the bytes are in the correct endian order for CBOR.
116
+ if ( BitConverter . IsLittleEndian )
117
+ Array . Reverse ( bytes , 1 , 4 ) ;
118
+
119
+ writer . WriteEncodedValue ( bytes ) ;
101
120
}
102
121
}
103
122
}
0 commit comments