@@ -172,6 +172,82 @@ pub mod utf8 {
172
172
}
173
173
}
174
174
175
+ pub mod latin_1 {
176
+ use super :: * ;
177
+
178
+ pub const ENCODING_NAME : & str = "latin-1" ;
179
+
180
+ const ERR_REASON : & str = "ordinal not in range(256)" ;
181
+
182
+ #[ inline]
183
+ pub fn encode < E : ErrorHandler > ( s : & str , errors : & E ) -> Result < Vec < u8 > , E :: Error > {
184
+ let full_data = s;
185
+ let mut data = s;
186
+ let mut char_data_index = 0 ;
187
+ let mut out = Vec :: < u8 > :: new ( ) ;
188
+ loop {
189
+ match data
190
+ . char_indices ( )
191
+ . enumerate ( )
192
+ . find ( |( _, ( _, c) ) | ( * c as u32 ) > 255 )
193
+ {
194
+ None => {
195
+ out. extend_from_slice ( data. as_bytes ( ) ) ;
196
+ break ;
197
+ }
198
+ Some ( ( char_i, ( byte_i, _) ) ) => {
199
+ out. extend_from_slice ( & data. as_bytes ( ) [ ..byte_i] ) ;
200
+ let char_start = char_data_index + char_i;
201
+ // number of non-latin_1 chars between the first non-latin_1 char and the next latin_1 char
202
+ let non_latin_1_run_length = data[ byte_i..]
203
+ . chars ( )
204
+ . take_while ( |c| ( * c as u32 ) > 255 )
205
+ . count ( ) ;
206
+ let char_range = char_start..char_start + non_latin_1_run_length;
207
+ let ( replace, char_restart) =
208
+ errors. handle_encode_error ( full_data, char_range. clone ( ) , ERR_REASON ) ?;
209
+ match replace {
210
+ EncodeReplace :: Str ( s) => {
211
+ if s. as_ref ( ) . chars ( ) . any ( |c| ( c as u32 ) > 255 ) {
212
+ return Err (
213
+ errors. error_encoding ( full_data, char_range, ERR_REASON )
214
+ ) ;
215
+ }
216
+ out. extend_from_slice ( s. as_ref ( ) . as_bytes ( ) ) ;
217
+ }
218
+ EncodeReplace :: Bytes ( b) => {
219
+ out. extend_from_slice ( b. as_ref ( ) ) ;
220
+ }
221
+ }
222
+ data = crate :: str:: try_get_chars ( full_data, char_restart..)
223
+ . ok_or_else ( || errors. error_oob_restart ( char_restart) ) ?;
224
+ char_data_index = char_restart;
225
+ continue ;
226
+ }
227
+ }
228
+ }
229
+ Ok ( out)
230
+ }
231
+
232
+ pub fn decode < E : ErrorHandler > ( data : & [ u8 ] , errors : & E ) -> Result < ( String , usize ) , E :: Error > {
233
+ decode_utf8_compatible (
234
+ data,
235
+ errors,
236
+ |v| {
237
+ std:: str:: from_utf8 ( v) . map_err ( |e| {
238
+ // SAFETY: as specified in valid_up_to's documentation, input[..e.valid_up_to()]
239
+ // is valid ascii & therefore valid utf8
240
+ unsafe { make_decode_err ( v, e. valid_up_to ( ) , e. error_len ( ) ) }
241
+ } )
242
+ } ,
243
+ |_rest, err_len| HandleResult :: Error {
244
+ err_len,
245
+ reason : ERR_REASON ,
246
+ } ,
247
+ )
248
+ }
249
+ }
250
+
175
251
pub mod ascii {
176
252
use super :: * ;
177
253
use :: ascii:: AsciiStr ;
0 commit comments