|
57 | 57 | import java.nio.charset.CoderResult;
|
58 | 58 | import java.nio.charset.CodingErrorAction;
|
59 | 59 | import java.nio.charset.StandardCharsets;
|
| 60 | +import java.nio.charset.UnsupportedCharsetException; |
60 | 61 | import java.text.DecimalFormat;
|
61 | 62 | import java.text.ParseException;
|
62 | 63 | import java.text.ParsePosition;
|
@@ -945,6 +946,22 @@ protected static String getUTF32Name(int byteorder) {
|
945 | 946 | }
|
946 | 947 | return csName;
|
947 | 948 | }
|
| 949 | + |
| 950 | + @TruffleBoundary |
| 951 | + protected static CharBuffer allocateCharBuffer(int cap) { |
| 952 | + return CharBuffer.allocate(cap); |
| 953 | + } |
| 954 | + |
| 955 | + @TruffleBoundary |
| 956 | + protected static String toString(CharBuffer cb) { |
| 957 | + return cb.toString(); |
| 958 | + } |
| 959 | + |
| 960 | + @TruffleBoundary |
| 961 | + protected static int remaining(ByteBuffer cb) { |
| 962 | + return cb.remaining(); |
| 963 | + } |
| 964 | + |
948 | 965 | }
|
949 | 966 |
|
950 | 967 | @Builtin(name = "TrufflePInt_AsPrimitive", minNumOfPositionalArgs = 3)
|
@@ -2555,21 +2572,6 @@ Object doUtf8Decode(VirtualFrame frame, Object module, Object cByteArray, String
|
2555 | 2572 | }
|
2556 | 2573 | }
|
2557 | 2574 |
|
2558 |
| - @TruffleBoundary |
2559 |
| - private static CharBuffer allocateCharBuffer(int cap) { |
2560 |
| - return CharBuffer.allocate(cap); |
2561 |
| - } |
2562 |
| - |
2563 |
| - @TruffleBoundary |
2564 |
| - private static String toString(CharBuffer cb) { |
2565 |
| - return cb.toString(); |
2566 |
| - } |
2567 |
| - |
2568 |
| - @TruffleBoundary |
2569 |
| - private static int remaining(ByteBuffer cb) { |
2570 |
| - return cb.remaining(); |
2571 |
| - } |
2572 |
| - |
2573 | 2575 | @TruffleBoundary
|
2574 | 2576 | private CoderResult decodeUTF8(CharBuffer resultBuffer, ByteBuffer inputBuffer, String errors) {
|
2575 | 2577 | CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
|
@@ -2626,4 +2628,35 @@ private Number parse(String source) throws ParseException {
|
2626 | 2628 | return DecimalFormat.getInstance().parse(source);
|
2627 | 2629 | }
|
2628 | 2630 | }
|
| 2631 | + |
| 2632 | + @Builtin(name = "PyUnicode_Decode", minNumOfPositionalArgs = 5, declaresExplicitSelf = true) |
| 2633 | + @GenerateNodeFactory |
| 2634 | + abstract static class PyUnicode_Decode extends NativeUnicodeBuiltin { |
| 2635 | + |
| 2636 | + @Specialization |
| 2637 | + Object doDecode(VirtualFrame frame, Object module, Object cByteArray, long size, String encoding, String errors, |
| 2638 | + @Cached CExtNodes.ToSulongNode toSulongNode, |
| 2639 | + @Cached GetByteArrayNode getByteArrayNode, |
| 2640 | + @Cached GetNativeNullNode getNativeNullNode) { |
| 2641 | + |
| 2642 | + try { |
| 2643 | + ByteBuffer inputBuffer = wrap(getByteArrayNode.execute(frame, cByteArray, size)); |
| 2644 | + int n = remaining(inputBuffer); |
| 2645 | + CharBuffer resultBuffer = allocateCharBuffer(n * 4); |
| 2646 | + decode(resultBuffer, inputBuffer, encoding, errors); |
| 2647 | + return toSulongNode.execute(factory().createTuple(new Object[]{toString(resultBuffer), n - remaining(inputBuffer)})); |
| 2648 | + } catch (IllegalArgumentException e) { |
| 2649 | + return raiseNative(frame, getNativeNullNode.execute(module), PythonErrorType.LookupError, "unknown encoding: " + encoding); |
| 2650 | + } catch (InteropException e) { |
| 2651 | + return raiseNative(frame, getNativeNullNode.execute(module), PythonErrorType.TypeError, "%m", e); |
| 2652 | + } |
| 2653 | + } |
| 2654 | + |
| 2655 | + @TruffleBoundary |
| 2656 | + private CoderResult decode(CharBuffer resultBuffer, ByteBuffer inputBuffer, String encoding, String errors) { |
| 2657 | + CharsetDecoder decoder = Charset.forName(encoding).newDecoder(); |
| 2658 | + CodingErrorAction action = BytesBuiltins.toCodingErrorAction(errors, this); |
| 2659 | + return decoder.onMalformedInput(CodingErrorAction.REPORT).onUnmappableCharacter(action).decode(inputBuffer, resultBuffer, true); |
| 2660 | + } |
| 2661 | + } |
2629 | 2662 | }
|
0 commit comments