xml/reader/parser/
inside_declaration.rs
1
2use common::XmlVersion;
3
4use reader::events::XmlEvent;
5use reader::lexer::Token;
6
7use super::{
8 Result, PullParser, State, DeclarationSubstate, QualifiedNameTarget,
9 DEFAULT_VERSION, DEFAULT_ENCODING
10};
11
12impl PullParser {
13 pub fn inside_declaration(&mut self, t: Token, s: DeclarationSubstate) -> Option<Result> {
15 macro_rules! unexpected_token(
16 ($this:expr; $t:expr) => (Some($this.error(format!("Unexpected token inside XML declaration: {}", $t))));
17 ($t:expr) => (unexpected_token!(self; $t));
18 );
19
20 #[inline]
21 fn emit_start_document(this: &mut PullParser) -> Option<Result> {
22 this.parsed_declaration = true;
23 let version = this.data.take_version();
24 let encoding = this.data.take_encoding();
25 let standalone = this.data.take_standalone();
26 this.into_state_emit(State::OutsideTag, Ok(XmlEvent::StartDocument {
27 version: version.unwrap_or(DEFAULT_VERSION),
28 encoding: encoding.unwrap_or(DEFAULT_ENCODING.into()),
29 standalone: standalone
30 }))
31 }
32
33 match s {
34 DeclarationSubstate::BeforeVersion => match t {
35 Token::Whitespace(_) => None, Token::Character('v') => self.into_state_continue(State::InsideDeclaration(DeclarationSubstate::InsideVersion)),
37 _ => unexpected_token!(t)
38 },
39
40 DeclarationSubstate::InsideVersion => self.read_qualified_name(t, QualifiedNameTarget::AttributeNameTarget, |this, token, name| {
41 match &name.local_name[..] {
42 "ersion" if name.namespace.is_none() =>
43 this.into_state_continue(State::InsideDeclaration(
44 if token == Token::EqualsSign {
45 DeclarationSubstate::InsideVersionValue
46 } else {
47 DeclarationSubstate::AfterVersion
48 }
49 )),
50 _ => unexpected_token!(this; name)
51 }
52 }),
53
54 DeclarationSubstate::AfterVersion => match t {
55 Token::Whitespace(_) => None,
56 Token::EqualsSign => self.into_state_continue(State::InsideDeclaration(DeclarationSubstate::InsideVersionValue)),
57 _ => unexpected_token!(t)
58 },
59
60 DeclarationSubstate::InsideVersionValue => self.read_attribute_value(t, |this, value| {
61 this.data.version = match &value[..] {
62 "1.0" => Some(XmlVersion::Version10),
63 "1.1" => Some(XmlVersion::Version11),
64 _ => None
65 };
66 if this.data.version.is_some() {
67 this.into_state_continue(State::InsideDeclaration(DeclarationSubstate::AfterVersionValue))
68 } else {
69 Some(self_error!(this; "Unexpected XML version value: {}", value))
70 }
71 }),
72
73 DeclarationSubstate::AfterVersionValue => match t {
74 Token::Whitespace(_) => None, Token::Character('e') => self.into_state_continue(State::InsideDeclaration(DeclarationSubstate::InsideEncoding)),
76 Token::Character('s') => self.into_state_continue(State::InsideDeclaration(DeclarationSubstate::InsideStandaloneDecl)),
77 Token::ProcessingInstructionEnd => emit_start_document(self),
78 _ => unexpected_token!(t)
79 },
80
81 DeclarationSubstate::InsideEncoding => self.read_qualified_name(t, QualifiedNameTarget::AttributeNameTarget, |this, token, name| {
82 match &name.local_name[..] {
83 "ncoding" if name.namespace.is_none() =>
84 this.into_state_continue(State::InsideDeclaration(
85 if token == Token::EqualsSign { DeclarationSubstate::InsideEncodingValue } else { DeclarationSubstate::AfterEncoding }
86 )),
87 _ => unexpected_token!(this; name)
88 }
89 }),
90
91 DeclarationSubstate::AfterEncoding => match t {
92 Token::Whitespace(_) => None,
93 Token::EqualsSign => self.into_state_continue(State::InsideDeclaration(DeclarationSubstate::InsideEncodingValue)),
94 _ => unexpected_token!(t)
95 },
96
97 DeclarationSubstate::InsideEncodingValue => self.read_attribute_value(t, |this, value| {
98 this.data.encoding = Some(value);
99 this.into_state_continue(State::InsideDeclaration(DeclarationSubstate::BeforeStandaloneDecl))
100 }),
101
102 DeclarationSubstate::BeforeStandaloneDecl => match t {
103 Token::Whitespace(_) => None, Token::Character('s') => self.into_state_continue(State::InsideDeclaration(DeclarationSubstate::InsideStandaloneDecl)),
105 Token::ProcessingInstructionEnd => emit_start_document(self),
106 _ => unexpected_token!(t)
107 },
108
109 DeclarationSubstate::InsideStandaloneDecl => self.read_qualified_name(t, QualifiedNameTarget::AttributeNameTarget, |this, token, name| {
110 match &name.local_name[..] {
111 "tandalone" if name.namespace.is_none() =>
112 this.into_state_continue(State::InsideDeclaration(
113 if token == Token::EqualsSign {
114 DeclarationSubstate::InsideStandaloneDeclValue
115 } else {
116 DeclarationSubstate::AfterStandaloneDecl
117 }
118 )),
119 _ => unexpected_token!(this; name)
120 }
121 }),
122
123 DeclarationSubstate::AfterStandaloneDecl => match t {
124 Token::Whitespace(_) => None,
125 Token::EqualsSign => self.into_state_continue(State::InsideDeclaration(DeclarationSubstate::InsideStandaloneDeclValue)),
126 _ => unexpected_token!(t)
127 },
128
129 DeclarationSubstate::InsideStandaloneDeclValue => self.read_attribute_value(t, |this, value| {
130 let standalone = match &value[..] {
131 "yes" => Some(true),
132 "no" => Some(false),
133 _ => None
134 };
135 if standalone.is_some() {
136 this.data.standalone = standalone;
137 this.into_state_continue(State::InsideDeclaration(DeclarationSubstate::AfterStandaloneDeclValue))
138 } else {
139 Some(self_error!(this; "Invalid standalone declaration value: {}", value))
140 }
141 }),
142
143 DeclarationSubstate::AfterStandaloneDeclValue => match t {
144 Token::Whitespace(_) => None, Token::ProcessingInstructionEnd => emit_start_document(self),
146 _ => unexpected_token!(t)
147 }
148 }
149 }
150
151}