1212 * express or implied. See the License for the specific language governing
1313 * permissions and limitations under the License.
1414 */
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+
2016using System ;
21- using System . Collections . Generic ;
2217using System . Formats . Cbor ;
23- using System . IO ;
24- using System . Text . RegularExpressions ;
18+ using Amazon . Util ;
2519
2620namespace AWSSDK . Extensions . CborProtocol
2721{
@@ -47,57 +41,82 @@ public static void WriteOptimizedNumber(this CborWriter writer, double value)
4741 {
4842 if ( double . IsNaN ( value ) || double . IsInfinity ( value ) )
4943 {
50- writer . WriteDouble ( value ) ;
44+ writer . WriteDouble ( value ) ; // Write NaN or Infinity as a double.
5145 return ;
5246 }
5347
48+ // If the value is an integer (without fractional part), write it as Int64 or UInt64.
5449 if ( value % 1 == 0 )
5550 {
5651 if ( value >= long . MinValue && value <= long . MaxValue )
5752 {
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.
5856 writer . WriteInt64 ( ( long ) value ) ;
5957 return ;
6058 }
6159
6260 if ( value >= 0 && value <= ulong . MaxValue )
6361 {
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.
6464 writer . WriteUInt64 ( ( ulong ) value ) ;
6565 return ;
6666 }
6767 }
6868
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.
6978 writer . WriteDouble ( value ) ;
7079 }
7180
7281 /// <summary>
7382 /// 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.
7484 /// </summary>
7585 /// <param name="writer">The CBOR writer to use.</param>
7686 /// <param name="value">The float value to write.</param>
7787 public static void WriteOptimizedNumber ( this CborWriter writer , float value )
7888 {
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.
8590 if ( value % 1 == 0 )
8691 {
8792 if ( value >= long . MinValue && value <= long . MaxValue )
8893 {
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.
8997 writer . WriteInt64 ( ( long ) value ) ;
9098 return ;
9199 }
92100
93101 if ( value >= 0 && value <= ulong . MaxValue )
94102 {
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.
95105 writer . WriteUInt64 ( ( ulong ) value ) ;
96106 return ;
97107 }
98108 }
99109
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 ) ;
101120 }
102121 }
103122}
0 commit comments