From da3e1e94fa33e739e19a90e966dfbccefae42205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Antinori?= Date: Sat, 8 Feb 2025 14:05:37 -0300 Subject: [PATCH] added get_char_encoded_length function --- src/header/wchar/lookaheadreader.rs | 18 ++++++------------ src/header/wchar/mod.rs | 12 +++--------- src/header/wchar/utf8.rs | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/header/wchar/lookaheadreader.rs b/src/header/wchar/lookaheadreader.rs index b1e1cfea49..516749084b 100644 --- a/src/header/wchar/lookaheadreader.rs +++ b/src/header/wchar/lookaheadreader.rs @@ -2,7 +2,7 @@ use super::{fseek_locked, ftell_locked, FILE, SEEK_SET}; use crate::{ header::{ errno::EILSEQ, - wchar::{fgetwc, mbrtowc, MB_CUR_MAX}, + wchar::{fgetwc, get_char_encoded_length, mbrtowc, MB_CUR_MAX}, wctype::WEOF, }, io::Read, @@ -22,7 +22,6 @@ struct LookAheadBuffer { impl LookAheadBuffer { fn look_ahead(&mut self) -> Result, i32> { let wchar = unsafe { *self.buf.offset(self.look_ahead) }; - println!("-> {}", wchar as wint_t); if wchar == 0 { Ok(None) } else { @@ -72,17 +71,11 @@ impl<'a> LookAheadFile<'a> { bytes_read += 1; if bytes_read == 1 { - encoded_length = if buf[0] >> 7 == 0 { - 1 - } else if buf[0] >> 5 == 6 { - 2 - } else if buf[0] >> 4 == 0xe { - 3 - } else if buf[0] >> 3 == 0x1e { - 4 + encoded_length = if let Some(el) = get_char_encoded_length(buf[0]) { + el } else { ERRNO.set(EILSEQ); - return Ok(Some(WEOF)); + return Ok(WEOF); }; } @@ -99,9 +92,10 @@ impl<'a> LookAheadFile<'a> { encoded_length, ptr::null_mut(), ); + + fseek_locked(self.f, seek, SEEK_SET); } - unsafe { fseek_locked(self.f, seek, SEEK_SET) }; self.look_ahead += encoded_length as i64; Ok(Some(wc as wint_t)) diff --git a/src/header/wchar/mod.rs b/src/header/wchar/mod.rs index 7caf3dd1d2..88d690253e 100644 --- a/src/header/wchar/mod.rs +++ b/src/header/wchar/mod.rs @@ -10,7 +10,7 @@ use crate::{ stdlib::{malloc, MB_CUR_MAX, MB_LEN_MAX}, string, time::*, - wchar::lookaheadreader::LookAheadReader, + wchar::{lookaheadreader::LookAheadReader, utf8::get_char_encoded_length}, wctype::*, }, iter::{NulTerminated, NulTerminatedInclusive}, @@ -70,14 +70,8 @@ pub unsafe extern "C" fn fgetwc(stream: *mut FILE) -> wint_t { bytes_read += 1; if bytes_read == 1 { - encoded_length = if buf[0] >> 7 == 0 { - 1 - } else if buf[0] >> 5 == 6 { - 2 - } else if buf[0] >> 4 == 0xe { - 3 - } else if buf[0] >> 3 == 0x1e { - 4 + encoded_length = if let Some(el) = get_char_encoded_length(buf[0]) { + el } else { ERRNO.set(EILSEQ); return WEOF; diff --git a/src/header/wchar/utf8.rs b/src/header/wchar/utf8.rs index b1961c1ac8..bb127427e0 100644 --- a/src/header/wchar/utf8.rs +++ b/src/header/wchar/utf8.rs @@ -91,3 +91,18 @@ pub unsafe fn wcrtomb(s: *mut c_char, wc: wchar_t, ps: *mut mbstate_t) -> usize size } + +/// Gets the encoded length of a character. It is used to recognize wide characters +pub fn get_char_encoded_length(first_byte: u8) -> Option { + if first_byte >> 7 == 0 { + Some(1) + } else if first_byte >> 5 == 6 { + Some(2) + } else if first_byte >> 4 == 0xe { + Some(3) + } else if first_byte >> 3 == 0x1e { + Some(4) + } else { + None + } +}