@@ -5,7 +5,10 @@ const supportedEncodings = {
55 utf : "utf-8" ,
66 utf8 : "utf-8" ,
77 utf_8 : "utf-8" ,
8+ latin_1 : "latin1" , // browser spec
89 ascii : "ascii" ,
10+ utf16 : "utf-16" ,
11+ utf_16 : "utf-16" ,
912} ;
1013
1114var space_reg = / \s + / g;
@@ -19,8 +22,8 @@ function normalizeEncoding(encoding) {
1922 return supported ;
2023 }
2124}
22- const Encoder = new TextEncoder ( ) ;
23- const Decoder = new TextDecoder ( ) ;
25+ const UtfEncoder = new TextEncoder ( ) ;
26+ const UtfDecoder = new TextDecoder ( ) ;
2427
2528/**
2629 * @constructor
@@ -77,7 +80,12 @@ Sk.builtin.bytes = Sk.abstr.buildNativeClass("bytes", {
7780 if ( args . length <= 1 && + kwargs . length === 0 ) {
7881 pySource = args [ 0 ] ;
7982 } else {
80- [ pySource , encoding , errors ] = Sk . abstr . copyKeywordsToNamedArgs ( "bytes" , [ null , "pySource" , "errors" ] , args , kwargs ) ;
83+ [ pySource , encoding , errors ] = Sk . abstr . copyKeywordsToNamedArgs (
84+ "bytes" ,
85+ [ null , "encoding" , "errors" ] ,
86+ args ,
87+ kwargs
88+ ) ;
8189 ( { encoding, errors } = checkGetEncodingErrors ( "bytes" , encoding , errors ) ) ;
8290 if ( ! Sk . builtin . checkString ( pySource ) ) {
8391 throw new Sk . builtin . TypeError ( "encoding or errors without a string argument" ) ;
@@ -965,19 +973,25 @@ function checkGetEncodingErrors(funcname, encoding, errors) {
965973 return { encoding : encoding , errors : errors } ;
966974}
967975
976+ function checkErrorsIsValid ( errors ) {
977+ if ( ! ( errors === "strict" || errors === "ignore" || errors === "replace" ) ) {
978+ throw new Sk . builtin . LookupError (
979+ "Unsupported or invalid error type '" + errors + "'"
980+ ) ;
981+ }
982+ }
983+
968984function strEncode ( pyStr , encoding , errors ) {
969985 const source = pyStr . $jsstr ( ) ;
970986 encoding = normalizeEncoding ( encoding ) ;
971- if ( ! ( errors === "strict" || errors === "ignore" || errors === "replace" ) ) {
972- throw new Sk . builtin . NotImplementedError ( "'" + errors + "' error handling not implemented in Skulpt" ) ;
973- }
987+ checkErrorsIsValid ( errors ) ;
974988 let uint8 ;
975989 if ( encoding === "ascii" ) {
976990 uint8 = encodeAscii ( source , errors ) ;
977991 } else if ( encoding === "utf-8" ) {
978- uint8 = Encoder . encode ( source ) ;
992+ uint8 = UtfEncoder . encode ( source ) ;
979993 } else {
980- throw new Sk . builtin . LookupError ( "unknown encoding: " + encoding ) ;
994+ throw new Sk . builtin . LookupError ( "Unsupported or unknown encoding: ' " + encoding + "'" ) ;
981995 }
982996 return new Sk . builtin . bytes ( uint8 ) ;
983997}
@@ -1040,8 +1054,8 @@ function decodeAscii(source, errors) {
10401054 return final ;
10411055}
10421056
1043- function decodeUtf ( source , errors ) {
1044- const string = Decoder . decode ( source ) ;
1057+ function decode ( decoder , source , errors , encoding ) {
1058+ const string = decoder . decode ( source ) ;
10451059 if ( errors === "replace" ) {
10461060 return string ;
10471061 } else if ( errors === "strict" ) {
@@ -1050,7 +1064,7 @@ function decodeUtf(source, errors) {
10501064 return string ;
10511065 }
10521066 throw new Sk . builtin . UnicodeDecodeError (
1053- "'utf-8 ' codec can't decode byte 0x" + source [ i ] . toString ( 16 ) + " in position " + i + " : invalid start byte"
1067+ `' ${ encoding } ' codec can't decode byte 0x ${ source [ i ] . toString ( 16 ) } in position ${ i } : invalid start byte`
10541068 ) ;
10551069 }
10561070 return string . replace ( / � / g, "" ) ;
@@ -1060,17 +1074,21 @@ function bytesDecode(encoding, errors) {
10601074 ( { encoding, errors } = checkGetEncodingErrors ( "decode" , encoding , errors ) ) ;
10611075 encoding = normalizeEncoding ( encoding ) ;
10621076
1063- if ( ! ( errors === "strict" || errors === "ignore" || errors === "replace" ) ) {
1064- throw new Sk . builtin . NotImplementedError ( "'" + errors + "' error handling not implemented in Skulpt" ) ;
1065- }
1077+ checkErrorsIsValid ( errors ) ;
10661078
10671079 let jsstr ;
10681080 if ( encoding === "ascii" ) {
10691081 jsstr = decodeAscii ( this . v , errors ) ;
10701082 } else if ( encoding === "utf-8" ) {
1071- jsstr = decodeUtf ( this . v , errors ) ;
1083+ jsstr = decode ( UtfDecoder , this . v , errors , encoding ) ;
10721084 } else {
1073- throw new Sk . builtin . LookupError ( "unknown encoding: " + encoding ) ;
1085+ let decoder ;
1086+ try {
1087+ decoder = new TextDecoder ( encoding ) ;
1088+ } catch ( e ) {
1089+ throw new Sk . builtin . LookupError ( `Unsupported or unknown encoding: ${ encoding } . ${ e . message } ` ) ;
1090+ }
1091+ jsstr = decode ( decoder , this . v , errors , encoding ) ;
10741092 }
10751093 return new Sk . builtin . str ( jsstr ) ;
10761094}
0 commit comments