xml/reader/parser/
inside_reference.rs
1use std::char;
2
3use common::{is_name_start_char, is_name_char, is_whitespace_str};
4
5use reader::lexer::Token;
6
7use super::{Result, PullParser, State};
8
9impl PullParser {
10 pub fn inside_reference(&mut self, t: Token, prev_st: State) -> Option<Result> {
11 match t {
12 Token::Character(c) if !self.data.ref_data.is_empty() && is_name_char(c) ||
13 self.data.ref_data.is_empty() && (is_name_start_char(c) || c == '#') => {
14 self.data.ref_data.push(c);
15 None
16 }
17
18 Token::ReferenceEnd => {
19 let name = self.data.take_ref_data();
21 let name_len = name.len(); let c = match &name[..] {
23 "lt" => Ok('<'.to_string()),
24 "gt" => Ok('>'.to_string()),
25 "amp" => Ok('&'.to_string()),
26 "apos" => Ok('\''.to_string()),
27 "quot" => Ok('"'.to_string()),
28 "" => Err(self_error!(self; "Encountered empty entity")),
29 _ if name_len > 2 && name.starts_with("#x") => {
30 let num_str = &name[2..name_len];
31 if num_str == "0" {
32 Err(self_error!(self; "Null character entity is not allowed"))
33 } else {
34 match u32::from_str_radix(num_str, 16).ok().and_then(char::from_u32) {
35 Some(c) => Ok(c.to_string()),
36 None => Err(self_error!(self; "Invalid hexadecimal character number in an entity: {}", name))
37 }
38 }
39 }
40 _ if name_len > 1 && name.starts_with('#') => {
41 let num_str = &name[1..name_len];
42 if num_str == "0" {
43 Err(self_error!(self; "Null character entity is not allowed"))
44 } else {
45 match u32::from_str_radix(num_str, 10).ok().and_then(char::from_u32) {
46 Some(c) => Ok(c.to_string()),
47 None => Err(self_error!(self; "Invalid decimal character number in an entity: {}", name))
48 }
49 }
50 },
51 _ => {
52 if let Some(v) = self.config.extra_entities.get(&name) {
53 Ok(v.clone())
54 } else {
55 Err(self_error!(self; "Unexpected entity: {}", name))
56 }
57 }
58 };
59 match c {
60 Ok(c) => {
61 self.buf.push_str(&c);
62 if prev_st == State::OutsideTag && !is_whitespace_str(&c) {
63 self.inside_whitespace = false;
64 }
65 self.into_state_continue(prev_st)
66 }
67 Err(e) => Some(e)
68 }
69 }
70
71 _ => Some(self_error!(self; "Unexpected token inside an entity: {}", t))
72 }
73 }
74}