@@ -1798,8 +1798,8 @@ Encoding setFallback(Encoding enc, DecoderFallback fb) {
17981798 case "strict" : e = setFallback ( e , new ExceptionFallback ( e is UTF8Encoding ) ) ; break ;
17991799 case "replace" : e = setFallback ( e , ReplacementFallback ) ; break ;
18001800 case "ignore" : e = setFallback ( e , new PythonDecoderFallback ( encoding , buffer , start ) ) ; break ;
1801- case "surrogateescape" : e = new PythonSurrogateEscapeEncoding ( e ) ; break ;
1802- case "surrogatepass" : e = new PythonSurrogatePassEncoding ( e ) ; break ;
1801+ case "surrogateescape" : e = new PythonSurrogateEscapeEncoding ( e , encoding ) ; break ;
1802+ case "surrogatepass" : e = new PythonSurrogatePassEncoding ( e , encoding ) ; break ;
18031803 default :
18041804 e = setFallback ( e , new PythonDecoderFallback ( encoding ,
18051805 buffer , start ,
@@ -1879,13 +1879,10 @@ static Encoding setFallback(Encoding enc, EncoderFallback fb) {
18791879 case "replace" : e = setFallback ( e , EncoderFallback . ReplacementFallback ) ; break ;
18801880 case "backslashreplace" : e = setFallback ( e , new BackslashEncoderReplaceFallback ( ) ) ; break ;
18811881 case "xmlcharrefreplace" : e = setFallback ( e , new XmlCharRefEncoderReplaceFallback ( ) ) ; break ;
1882- case "ignore" : e = setFallback ( e , new PythonEncoderFallback ( encoding , s ) ) ; break ;
1883- case "surrogateescape" : e = new PythonSurrogateEscapeEncoding ( e ) ; break ;
1884- case "surrogatepass" : e = new PythonSurrogatePassEncoding ( e ) ; break ;
1885- default :
1886- e = setFallback ( e , new PythonEncoderFallback ( encoding , s ,
1887- ( ) => LightExceptions . CheckAndThrow ( PythonOps . LookupEncodingError ( context , errors ) ) ) ) ;
1888- break ;
1882+ case "ignore" : e = setFallback ( e , new EncoderReplacementFallback ( string . Empty ) ) ; break ;
1883+ case "surrogateescape" : e = new PythonSurrogateEscapeEncoding ( e , encoding ) ; break ;
1884+ case "surrogatepass" : e = new PythonSurrogatePassEncoding ( e , encoding ) ; break ;
1885+ default : e = new PythonErrorHandlerEncoding ( context , e , encoding , errors ) ; break ;
18891886 }
18901887
18911888 byte [ ] ? preamble = includePreamble ? e . GetPreamble ( ) : null ;
@@ -1898,8 +1895,8 @@ static Encoding setFallback(Encoding enc, EncoderFallback fb) {
18981895 }
18991896 e . GetBytes ( s , 0 , s . Length , bytes , preambleLen ) ;
19001897 } catch ( EncoderFallbackException ex ) {
1901- ex . Data [ "encoding" ] = encoding ;
1902- ex . Data [ "object" ] = s ;
1898+ if ( ! ex . Data . Contains ( "encoding" ) ) ex . Data [ "encoding" ] = encoding ;
1899+ if ( ! ex . Data . Contains ( "object" ) ) ex . Data [ "object" ] = s ;
19031900 throw ;
19041901 }
19051902
@@ -2030,8 +2027,8 @@ static CodecsInfo() {
20302027 return d ;
20312028 }
20322029
2033- internal static Dictionary < string , object > MakeErrorHandlersDict ( ) {
2034- var d = new Dictionary < string , object > ( ) ;
2030+ internal static ConcurrentDictionary < string , object > MakeErrorHandlersDict ( ) {
2031+ var d = new ConcurrentDictionary < string , object > ( ) ;
20352032
20362033 d [ "strict" ] = BuiltinFunction . MakeFunction (
20372034 "strict_errors" ,
@@ -2324,98 +2321,6 @@ public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[]
23242321 /// and int is an index where encoding/decoding should continue.
23252322 /// TODO: returned int is currently ignored, assumed to be equal to end (i.e. the index is not adjusted).
23262323
2327- private class PythonEncoderFallbackBuffer : EncoderFallbackBuffer {
2328- private readonly string _encoding ;
2329- private readonly string _strData ;
2330- private readonly object ? _function ;
2331- private string ? _buffer ;
2332- private int _bufferIndex ;
2333-
2334- public PythonEncoderFallbackBuffer ( string encoding , string str , object ? function ) {
2335- _encoding = encoding ;
2336- _strData = str ;
2337- _function = function ;
2338- }
2339-
2340- public override bool Fallback ( char charUnknown , int index ) {
2341- return DoPythonFallback ( index , 1 ) ;
2342- }
2343-
2344- public override bool Fallback ( char charUnknownHigh , char charUnknownLow , int index ) {
2345- return DoPythonFallback ( index , 2 ) ;
2346- }
2347-
2348- public override char GetNextChar ( ) {
2349- if ( _buffer == null || _bufferIndex >= _buffer . Length ) return Char . MinValue ;
2350-
2351- return _buffer [ _bufferIndex ++ ] ;
2352- }
2353-
2354- public override bool MovePrevious ( ) {
2355- if ( _bufferIndex > 0 ) {
2356- _bufferIndex -- ;
2357- return true ;
2358- }
2359- return false ;
2360- }
2361-
2362- public override int Remaining {
2363- get {
2364- if ( _buffer == null ) return 0 ;
2365- return _buffer . Length - _bufferIndex ;
2366- }
2367- }
2368-
2369- public override void Reset ( ) {
2370- _buffer = null ;
2371- _bufferIndex = 0 ;
2372- base . Reset ( ) ;
2373- }
2374-
2375- private bool DoPythonFallback ( int index , int length ) {
2376- if ( _function != null ) {
2377- // create the exception object to hand to the user-function...
2378- var exObj = PythonExceptions . CreatePythonThrowable ( PythonExceptions . UnicodeEncodeError , _encoding , _strData , index , index + length , "unexpected code byte" ) ;
2379-
2380- // call the user function...
2381- object ? res = PythonCalls . Call ( _function , exObj ) ;
2382-
2383- string replacement = CheckReplacementTuple ( res , "encoding" , index + length ) ;
2384-
2385- // finally process the user's request.
2386- _buffer = replacement ;
2387- _bufferIndex = 0 ;
2388- return true ;
2389- }
2390-
2391- return false ;
2392- }
2393- }
2394-
2395- private class PythonEncoderFallback : EncoderFallback {
2396- private readonly string encoding ;
2397- private readonly string data ;
2398- private readonly Func < object > ? lookup ;
2399- private object ? function ;
2400-
2401- public PythonEncoderFallback ( string encoding , string data , Func < object > ? lookup = null ) {
2402- this . encoding = encoding ;
2403- this . data = data ;
2404- this . lookup = lookup ;
2405- }
2406-
2407- public override EncoderFallbackBuffer CreateFallbackBuffer ( ) {
2408- if ( function == null && lookup != null ) {
2409- function = lookup . Invoke ( ) ;
2410- }
2411- return new PythonEncoderFallbackBuffer ( encoding , data , function ) ;
2412- }
2413-
2414- public override int MaxCharCount {
2415- get { return Int32 . MaxValue ; }
2416- }
2417- }
2418-
24192324 private class PythonDecoderFallbackBuffer : DecoderFallbackBuffer {
24202325 private readonly object ? _function ;
24212326 private readonly string _encoding ;
0 commit comments