Skip to content

Commit 83689ee

Browse files
committed
Backport more changes
1 parent 2e347b5 commit 83689ee

File tree

7 files changed

+235
-77
lines changed

7 files changed

+235
-77
lines changed

Src/IronPython.Modules/_codecs.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,20 @@ public static PythonTuple mbcs_encode(CodeContext/*!*/ context, [NotNone] string
227227

228228
#endregion
229229

230+
#region OEM Functions
231+
232+
[SupportedOSPlatform("windows"), PythonHidden(PlatformsAttribute.PlatformFamily.Unix)]
233+
public static PythonTuple oem_decode(CodeContext/*!*/ context, [NotNone] IBufferProtocol input, string? errors = null, bool final = false) {
234+
using IPythonBuffer buffer = input.GetBuffer();
235+
return DoDecode(context, "oem", StringOps.CodecsInfo.OemEncoding, buffer, errors).ToPythonTuple();
236+
}
237+
238+
[SupportedOSPlatform("windows"), PythonHidden(PlatformsAttribute.PlatformFamily.Unix)]
239+
public static PythonTuple oem_encode(CodeContext/*!*/ context, [NotNone] string input, string? errors = null)
240+
=> DoEncode(context, "oem", StringOps.CodecsInfo.OemEncoding, input, errors).ToPythonTuple();
241+
242+
#endregion
243+
230244
#region Code Page Functions
231245

232246
[SupportedOSPlatform("windows"), PythonHidden(PlatformsAttribute.PlatformFamily.Unix)]

Src/IronPython.Modules/_struct.cs

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,22 @@ public void __init__(CodeContext/*!*/ context, object fmt) {
192192
break;
193193
case FormatType.Float:
194194
for (int j = 0; j < curFormat.Count; j++) {
195-
WriteFloat(res, _isLittleEndian, (float)GetDoubleValue(context, curObj++, values));
195+
var d = GetDoubleValue(context, curObj++, values);
196+
var val = (float)d;
197+
if (float.IsInfinity(val) && !double.IsInfinity(d)) throw PythonOps.OverflowError("float too large to pack with f format");
198+
WriteFloat(res, _isLittleEndian, val);
196199
}
197200
break;
201+
#if NET6_0_OR_GREATER
202+
case FormatType.Half:
203+
for (int j = 0; j < curFormat.Count; j++) {
204+
var d = GetDoubleValue(context, curObj++, values);
205+
var val = (Half)d;
206+
if (Half.IsInfinity(val) && !double.IsInfinity(d)) throw PythonOps.OverflowError("float too large to pack with e format");
207+
WriteHalf(res, _isLittleEndian, val);
208+
}
209+
break;
210+
#endif
198211
case FormatType.CString:
199212
WriteString(res, curFormat.Count, GetStringValue(context, curObj++, values));
200213
break;
@@ -273,7 +286,7 @@ public void pack_into(CodeContext/*!*/ context, [NotNone] IBufferProtocol/*!*/ b
273286
break;
274287
case FormatType.SignedChar:
275288
for (int j = 0; j < curFormat.Count; j++) {
276-
res[res_idx++] = (int)(sbyte)CreateCharValue(context, ref curIndex, data);
289+
res[res_idx++] = (int)unchecked((sbyte)CreateCharValue(context, ref curIndex, data));
277290
}
278291
break;
279292
case FormatType.UnsignedChar:
@@ -336,7 +349,7 @@ public void pack_into(CodeContext/*!*/ context, [NotNone] IBufferProtocol/*!*/ b
336349
break;
337350
case FormatType.SizeT:
338351
for (int j = 0; j < curFormat.Count; j++) {
339-
res[res_idx++] = CreateUIntValue(context, ref curIndex, _isLittleEndian, data);
352+
res[res_idx++] = BigIntegerOps.__int__(CreateUIntValue(context, ref curIndex, _isLittleEndian, data));
340353
}
341354
break;
342355
case FormatType.LongLong:
@@ -349,9 +362,16 @@ public void pack_into(CodeContext/*!*/ context, [NotNone] IBufferProtocol/*!*/ b
349362
res[res_idx++] = BigIntegerOps.__int__(CreateULongValue(context, ref curIndex, _isLittleEndian, data));
350363
}
351364
break;
365+
#if NET6_0_OR_GREATER
366+
case FormatType.Half:
367+
for (int j = 0; j < curFormat.Count; j++) {
368+
res[res_idx++] = (double)CreateHalfValue(context, ref curIndex, _isLittleEndian, data);
369+
}
370+
break;
371+
#endif
352372
case FormatType.Float:
353373
for (int j = 0; j < curFormat.Count; j++) {
354-
res[res_idx++] = CreateFloatValue(context, ref curIndex, _isLittleEndian, data);
374+
res[res_idx++] = (double)CreateFloatValue(context, ref curIndex, _isLittleEndian, data);
355375
}
356376
break;
357377
case FormatType.Double:
@@ -472,6 +492,12 @@ private static Struct CompileAndCache(CodeContext/*!*/ context, string/*!*/ fmt)
472492
res.Add(new Format(FormatType.UnsignedLongLong, count));
473493
count = 1;
474494
break;
495+
#if NET6_0_OR_GREATER
496+
case 'e': // half
497+
res.Add(new Format(FormatType.Half, count));
498+
count = 1;
499+
break;
500+
#endif
475501
case 'f': // float
476502
res.Add(new Format(FormatType.Float, count));
477503
count = 1;
@@ -697,6 +723,9 @@ private enum FormatType {
697723

698724
Short,
699725
UnsignedShort,
726+
#if NET6_0_OR_GREATER
727+
Half,
728+
#endif
700729

701730
Int,
702731
UnsignedInt,
@@ -730,6 +759,9 @@ private static int GetNativeSize(FormatType c) {
730759
return 1;
731760
case FormatType.Short:
732761
case FormatType.UnsignedShort:
762+
#if NET6_0_OR_GREATER
763+
case FormatType.Half:
764+
#endif
733765
return 2;
734766
case FormatType.Int:
735767
case FormatType.UnsignedInt:
@@ -911,6 +943,18 @@ private static void WriteSignedNetPointer(this MemoryStream res, bool fLittleEnd
911943
res.WritePointer(fLittleEndian, unchecked((ulong)val.ToInt64()));
912944
}
913945

946+
#if NET6_0_OR_GREATER
947+
private static void WriteHalf(this MemoryStream res, bool fLittleEndian, Half val) {
948+
byte[] bytes = BitConverter.GetBytes(val);
949+
if (BitConverter.IsLittleEndian == fLittleEndian) {
950+
res.Write(bytes, 0, bytes.Length);
951+
} else {
952+
res.WriteByte(bytes[1]);
953+
res.WriteByte(bytes[0]);
954+
}
955+
}
956+
#endif
957+
914958
private static void WriteFloat(this MemoryStream res, bool fLittleEndian, float val) {
915959
byte[] bytes = BitConverter.GetBytes(val);
916960
if (BitConverter.IsLittleEndian == fLittleEndian) {
@@ -1134,7 +1178,7 @@ internal static ulong GetULongLongValue(CodeContext/*!*/ context, int index, obj
11341178
internal static double GetDoubleValue(CodeContext/*!*/ context, int index, object[] args) {
11351179
object val = GetValue(context, index, args);
11361180
if (Converter.TryConvertToDouble(val, out double res)) return res;
1137-
throw Error(context, "expected double value");
1181+
throw Error(context, "required argument is not a float");
11381182
}
11391183

11401184
internal static IList<byte> GetStringValue(CodeContext/*!*/ context, int index, object[] args) {
@@ -1194,6 +1238,28 @@ internal static ushort CreateUShortValue(CodeContext/*!*/ context, ref int index
11941238
}
11951239
}
11961240

1241+
#if NET6_0_OR_GREATER
1242+
internal static Half CreateHalfValue(CodeContext/*!*/ context, ref int index, bool fLittleEndian, IList<byte> data) {
1243+
byte[] bytes = new byte[2];
1244+
if (fLittleEndian == BitConverter.IsLittleEndian) {
1245+
bytes[0] = data[index++];
1246+
bytes[1] = data[index++];
1247+
} else {
1248+
bytes[1] = data[index++];
1249+
bytes[0] = data[index++];
1250+
}
1251+
Half res = BitConverter.ToHalf(bytes, 0);
1252+
1253+
if (context.LanguageContext.FloatFormat == FloatFormat.Unknown) {
1254+
if (Half.IsNaN(res) || Half.IsInfinity(res)) {
1255+
throw PythonOps.ValueError("can't unpack IEEE 754 special value on non-IEEE platform");
1256+
}
1257+
}
1258+
1259+
return res;
1260+
}
1261+
#endif
1262+
11971263
internal static float CreateFloatValue(CodeContext/*!*/ context, ref int index, bool fLittleEndian, IList<byte> data) {
11981264
byte[] bytes = new byte[4];
11991265
if (fLittleEndian == BitConverter.IsLittleEndian) {

0 commit comments

Comments
 (0)