///|
fn hex_digit(c : Int32) -> Int32 {
if c >= 48 && c <= 57 {
c - 48
} else if c >= 65 && c <= 70 {
c - 55
} else if c >= 97 && c <= 102 {
c - 87
} else {
-1
}
}
///|
fn Reader::text(self : Reader) -> Bytes raise ConfigError {
let output : Array[Byte] = []
while self.peek() == 34 {
self.advance()
while self.peek() != 34 {
if self.peek() == -1 {
raise self.error("unterminated_string", "expected closing quote")
}
let mut c = self.peek()
self.advance()
if c == 92 {
c = match self.peek() {
34 => 34
92 => 92
97 => 7
98 => 8
102 => 12
110 => 10
114 => 13
116 => 9
118 => 11
120 => {
self.advance()
let hi = hex_digit(self.peek())
if hi < 0 {
raise self.error(
"invalid_escape", "expected two hexadecimal digits",
)
}
self.advance()
let lo = hex_digit(self.peek())
if lo < 0 {
raise self.error(
"invalid_escape", "expected two hexadecimal digits",
)
}
hi * 16 + lo
}
_ => raise self.error("invalid_escape", "unknown string escape")
}
self.advance()
}
if c == 0 {
raise self.error(
"unsupported_nul", "NUL bytes are not representable by libconfig string APIs",
)
}
if output.length() >= self.limits.max_string {
raise self.error("string_limit", "decoded string exceeds byte limit")
}
output.push(c.to_byte())
}
self.advance()
self.skip()
}
Bytes::from_array(output)
}