aboutsummaryrefslogtreecommitdiff
path: root/libcore/char.rs
diff options
context:
space:
mode:
Diffstat (limited to 'libcore/char.rs')
-rw-r--r--libcore/char.rs52
1 files changed, 32 insertions, 20 deletions
diff --git a/libcore/char.rs b/libcore/char.rs
index b2b1dc5..1404038 100644
--- a/libcore/char.rs
+++ b/libcore/char.rs
@@ -299,7 +299,20 @@ impl CharExt for char {
#[inline]
fn escape_unicode(self) -> EscapeUnicode {
- EscapeUnicode { c: self, state: EscapeUnicodeState::Backslash }
+ let c = self as u32;
+
+ // or-ing 1 ensures that for c==0 the code computes that one
+ // digit should be printed and (which is the same) avoids the
+ // (31 - 32) underflow
+ let msb = 31 - (c | 1).leading_zeros();
+
+ // the index of the most significant hex digit
+ let ms_hex_digit = msb / 4;
+ EscapeUnicode {
+ c: self,
+ state: EscapeUnicodeState::Backslash,
+ hex_digit_idx: ms_hex_digit as usize,
+ }
}
#[inline]
@@ -392,7 +405,12 @@ impl CharExt for char {
#[stable(feature = "rust1", since = "1.0.0")]
pub struct EscapeUnicode {
c: char,
- state: EscapeUnicodeState
+ state: EscapeUnicodeState,
+
+ // The index of the next hex digit to be printed (0 if none),
+ // i.e. the number of remaining hex digits to be printed;
+ // increasing from the least significant digit: 0x543210
+ hex_digit_idx: usize,
}
#[derive(Clone, Debug)]
@@ -400,7 +418,7 @@ enum EscapeUnicodeState {
Backslash,
Type,
LeftBrace,
- Value(usize),
+ Value,
RightBrace,
Done,
}
@@ -420,19 +438,16 @@ impl Iterator for EscapeUnicode {
Some('u')
}
EscapeUnicodeState::LeftBrace => {
- let mut n = 0;
- while (self.c as u32) >> (4 * (n + 1)) != 0 {
- n += 1;
- }
- self.state = EscapeUnicodeState::Value(n);
+ self.state = EscapeUnicodeState::Value;
Some('{')
}
- EscapeUnicodeState::Value(offset) => {
- let c = from_digit(((self.c as u32) >> (offset * 4)) & 0xf, 16).unwrap();
- if offset == 0 {
+ EscapeUnicodeState::Value => {
+ let hex_digit = ((self.c as u32) >> (self.hex_digit_idx * 4)) & 0xf;
+ let c = from_digit(hex_digit, 16).unwrap();
+ if self.hex_digit_idx == 0 {
self.state = EscapeUnicodeState::RightBrace;
} else {
- self.state = EscapeUnicodeState::Value(offset - 1);
+ self.hex_digit_idx -= 1;
}
Some(c)
}
@@ -445,18 +460,15 @@ impl Iterator for EscapeUnicode {
}
fn size_hint(&self) -> (usize, Option<usize>) {
- let mut n = 0;
- while (self.c as usize) >> (4 * (n + 1)) != 0 {
- n += 1;
- }
let n = match self.state {
- EscapeUnicodeState::Backslash => n + 5,
- EscapeUnicodeState::Type => n + 4,
- EscapeUnicodeState::LeftBrace => n + 3,
- EscapeUnicodeState::Value(offset) => offset + 2,
+ EscapeUnicodeState::Backslash => 5,
+ EscapeUnicodeState::Type => 4,
+ EscapeUnicodeState::LeftBrace => 3,
+ EscapeUnicodeState::Value => 2,
EscapeUnicodeState::RightBrace => 1,
EscapeUnicodeState::Done => 0,
};
+ let n = n + self.hex_digit_idx;
(n, Some(n))
}
}