1 use std::io; 2 use std::io::prelude::*; 3 use std::fmt; 4 use std::result; 5 use std::borrow::Cow; 6 use std::error::Error; 7 8 use common; 9 use name::{Name, OwnedName}; 10 use attribute::Attribute; 11 use escape::{escape_str_attribute, escape_str_pcdata}; 12 use common::XmlVersion; 13 use namespace::{NamespaceStack, NS_NO_PREFIX, NS_EMPTY_URI, NS_XMLNS_PREFIX, NS_XML_PREFIX}; 14 15 use writer::config::EmitterConfig; 16 17 /// An error which may be returned by `XmlWriter` when writing XML events. 18 #[derive(Debug)] 19 pub enum EmitterError { 20 /// An I/O error occured in the underlying `Write` instance. 21 Io(io::Error), 22 23 /// Document declaration has already been written to the output stream. 24 DocumentStartAlreadyEmitted, 25 26 /// The name of the last opening element is not available. 27 LastElementNameNotAvailable, 28 29 /// The name of the last opening element is not equal to the name of the provided 30 /// closing element. 31 EndElementNameIsNotEqualToLastStartElementName, 32 33 /// End element name is not specified when it is needed, for example, when automatic 34 /// closing is not enabled in configuration. 35 EndElementNameIsNotSpecified 36 } 37 38 impl From<io::Error> for EmitterError { from(err: io::Error) -> EmitterError39 fn from(err: io::Error) -> EmitterError { 40 EmitterError::Io(err) 41 } 42 } 43 44 impl fmt::Display for EmitterError { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result45 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 46 47 write!(f, "emitter error: ")?; 48 match *self { 49 EmitterError::Io(ref e) => 50 write!(f, "I/O error: {}", e), 51 ref other => 52 write!(f, "{}", other.description()), 53 } 54 } 55 } 56 57 impl Error for EmitterError { description(&self) -> &str58 fn description(&self) -> &str { 59 match *self { 60 EmitterError::Io(_) => 61 "I/O error", 62 EmitterError::DocumentStartAlreadyEmitted => 63 "document start event has already been emitted", 64 EmitterError::LastElementNameNotAvailable => 65 "last element name is not available", 66 EmitterError::EndElementNameIsNotEqualToLastStartElementName => 67 "end element name is not equal to last start element name", 68 EmitterError::EndElementNameIsNotSpecified => 69 "end element name is not specified and can't be inferred", 70 } 71 } 72 } 73 74 /// A result type yielded by `XmlWriter`. 75 pub type Result<T> = result::Result<T, EmitterError>; 76 77 // TODO: split into a low-level fast writer without any checks and formatting logic and a 78 // high-level indenting validating writer 79 pub struct Emitter { 80 config: EmitterConfig, 81 82 nst: NamespaceStack, 83 84 indent_level: usize, 85 indent_stack: Vec<IndentFlags>, 86 87 element_names: Vec<OwnedName>, 88 89 start_document_emitted: bool, 90 just_wrote_start_element: bool 91 } 92 93 impl Emitter { new(config: EmitterConfig) -> Emitter94 pub fn new(config: EmitterConfig) -> Emitter { 95 Emitter { 96 config, 97 98 nst: NamespaceStack::empty(), 99 100 indent_level: 0, 101 indent_stack: vec![IndentFlags::WroteNothing], 102 103 element_names: Vec::new(), 104 105 start_document_emitted: false, 106 just_wrote_start_element: false 107 } 108 } 109 } 110 111 #[derive(Copy, Clone, Eq, PartialEq, Debug)] 112 enum IndentFlags { 113 WroteNothing, 114 WroteMarkup, 115 WroteText, 116 } 117 118 impl Emitter { 119 /// Returns the current state of namespaces. 120 #[inline] namespace_stack_mut(&mut self) -> &mut NamespaceStack121 pub fn namespace_stack_mut(&mut self) -> &mut NamespaceStack { 122 &mut self.nst 123 } 124 125 #[inline] wrote_text(&self) -> bool126 fn wrote_text(&self) -> bool { 127 *self.indent_stack.last().unwrap() == IndentFlags::WroteText 128 } 129 130 #[inline] wrote_markup(&self) -> bool131 fn wrote_markup(&self) -> bool { 132 *self.indent_stack.last().unwrap() == IndentFlags::WroteMarkup 133 } 134 135 #[inline] set_wrote_text(&mut self)136 fn set_wrote_text(&mut self) { 137 *self.indent_stack.last_mut().unwrap() = IndentFlags::WroteText; 138 } 139 140 #[inline] set_wrote_markup(&mut self)141 fn set_wrote_markup(&mut self) { 142 *self.indent_stack.last_mut().unwrap() = IndentFlags::WroteMarkup; 143 } 144 145 #[inline] reset_state(&mut self)146 fn reset_state(&mut self) { 147 *self.indent_stack.last_mut().unwrap() = IndentFlags::WroteNothing; 148 } 149 write_newline<W: Write>(&mut self, target: &mut W, level: usize) -> Result<()>150 fn write_newline<W: Write>(&mut self, target: &mut W, level: usize) -> Result<()> { 151 target.write(self.config.line_separator.as_bytes())?; 152 for _ in 0..level { 153 target.write(self.config.indent_string.as_bytes())?; 154 } 155 Ok(()) 156 } 157 before_markup<W: Write>(&mut self, target: &mut W) -> Result<()>158 fn before_markup<W: Write>(&mut self, target: &mut W) -> Result<()> { 159 if self.config.perform_indent && !self.wrote_text() && 160 (self.indent_level > 0 || self.wrote_markup()) { 161 let indent_level = self.indent_level; 162 self.write_newline(target, indent_level)?; 163 if self.indent_level > 0 && self.config.indent_string.len() > 0 { 164 self.after_markup(); 165 } 166 } 167 Ok(()) 168 } 169 after_markup(&mut self)170 fn after_markup(&mut self) { 171 self.set_wrote_markup(); 172 } 173 before_start_element<W: Write>(&mut self, target: &mut W) -> Result<()>174 fn before_start_element<W: Write>(&mut self, target: &mut W) -> Result<()> { 175 self.before_markup(target)?; 176 self.indent_stack.push(IndentFlags::WroteNothing); 177 Ok(()) 178 } 179 after_start_element(&mut self)180 fn after_start_element(&mut self) { 181 self.after_markup(); 182 self.indent_level += 1; 183 } 184 before_end_element<W: Write>(&mut self, target: &mut W) -> Result<()>185 fn before_end_element<W: Write>(&mut self, target: &mut W) -> Result<()> { 186 if self.config.perform_indent && self.indent_level > 0 && self.wrote_markup() && 187 !self.wrote_text() { 188 let indent_level = self.indent_level; 189 self.write_newline(target, indent_level - 1) 190 } else { 191 Ok(()) 192 } 193 } 194 after_end_element(&mut self)195 fn after_end_element(&mut self) { 196 if self.indent_level > 0 { 197 self.indent_level -= 1; 198 self.indent_stack.pop(); 199 } 200 self.set_wrote_markup(); 201 } 202 after_text(&mut self)203 fn after_text(&mut self) { 204 self.set_wrote_text(); 205 } 206 emit_start_document<W: Write>(&mut self, target: &mut W, version: XmlVersion, encoding: &str, standalone: Option<bool>) -> Result<()>207 pub fn emit_start_document<W: Write>(&mut self, target: &mut W, 208 version: XmlVersion, 209 encoding: &str, 210 standalone: Option<bool>) -> Result<()> { 211 if self.start_document_emitted { 212 return Err(EmitterError::DocumentStartAlreadyEmitted); 213 } 214 self.start_document_emitted = true; 215 216 self.before_markup(target)?; 217 let result = { 218 let mut write = move || { 219 write!(target, "<?xml version=\"{}\" encoding=\"{}\"", version, encoding)?; 220 221 if let Some(standalone) = standalone { 222 write!(target, " standalone=\"{}\"", if standalone { "yes" } else { "no" })?; 223 } 224 225 write!(target, "?>")?; 226 227 Ok(()) 228 }; 229 write() 230 }; 231 self.after_markup(); 232 233 result 234 } 235 check_document_started<W: Write>(&mut self, target: &mut W) -> Result<()>236 fn check_document_started<W: Write>(&mut self, target: &mut W) -> Result<()> { 237 if !self.start_document_emitted && self.config.write_document_declaration { 238 self.emit_start_document(target, common::XmlVersion::Version10, "utf-8", None) 239 } else { 240 Ok(()) 241 } 242 } 243 fix_non_empty_element<W: Write>(&mut self, target: &mut W) -> Result<()>244 fn fix_non_empty_element<W: Write>(&mut self, target: &mut W) -> Result<()> { 245 if self.config.normalize_empty_elements && self.just_wrote_start_element { 246 self.just_wrote_start_element = false; 247 target.write(b">").map(|_| ()).map_err(From::from) 248 } else { 249 Ok(()) 250 } 251 } 252 emit_processing_instruction<W: Write>(&mut self, target: &mut W, name: &str, data: Option<&str>) -> Result<()>253 pub fn emit_processing_instruction<W: Write>(&mut self, 254 target: &mut W, 255 name: &str, 256 data: Option<&str>) -> Result<()> { 257 self.check_document_started(target)?; 258 self.fix_non_empty_element(target)?; 259 260 self.before_markup(target)?; 261 262 let result = { 263 let mut write = || { 264 write!(target, "<?{}", name)?; 265 266 if let Some(data) = data { 267 write!(target, " {}", data)?; 268 } 269 270 write!(target, "?>")?; 271 272 Ok(()) 273 }; 274 write() 275 }; 276 277 self.after_markup(); 278 279 result 280 } 281 emit_start_element_initial<W>(&mut self, target: &mut W, name: Name, attributes: &[Attribute]) -> Result<()> where W: Write282 fn emit_start_element_initial<W>(&mut self, target: &mut W, 283 name: Name, 284 attributes: &[Attribute]) -> Result<()> 285 where W: Write 286 { 287 self.check_document_started(target)?; 288 self.fix_non_empty_element(target)?; 289 self.before_start_element(target)?; 290 write!(target, "<{}", name.repr_display())?; 291 self.emit_current_namespace_attributes(target)?; 292 self.emit_attributes(target, attributes)?; 293 self.after_start_element(); 294 Ok(()) 295 } 296 emit_start_element<W>(&mut self, target: &mut W, name: Name, attributes: &[Attribute]) -> Result<()> where W: Write297 pub fn emit_start_element<W>(&mut self, target: &mut W, 298 name: Name, 299 attributes: &[Attribute]) -> Result<()> 300 where W: Write 301 { 302 if self.config.keep_element_names_stack { 303 self.element_names.push(name.to_owned()); 304 } 305 306 self.emit_start_element_initial(target, name, attributes)?; 307 self.just_wrote_start_element = true; 308 309 if !self.config.normalize_empty_elements { 310 write!(target, ">")?; 311 } 312 313 Ok(()) 314 } 315 emit_current_namespace_attributes<W>(&mut self, target: &mut W) -> Result<()> where W: Write316 pub fn emit_current_namespace_attributes<W>(&mut self, target: &mut W) -> Result<()> 317 where W: Write 318 { 319 for (prefix, uri) in self.nst.peek() { 320 match prefix { 321 // internal namespaces are not emitted 322 NS_XMLNS_PREFIX | NS_XML_PREFIX => Ok(()), 323 //// there is already a namespace binding with this prefix in scope 324 //prefix if self.nst.get(prefix) == Some(uri) => Ok(()), 325 // emit xmlns only if it is overridden 326 NS_NO_PREFIX => if uri != NS_EMPTY_URI { 327 write!(target, " xmlns=\"{}\"", uri) 328 } else { Ok(()) }, 329 // everything else 330 prefix => write!(target, " xmlns:{}=\"{}\"", prefix, uri) 331 }?; 332 } 333 Ok(()) 334 } 335 emit_attributes<W: Write>(&mut self, target: &mut W, attributes: &[Attribute]) -> Result<()>336 pub fn emit_attributes<W: Write>(&mut self, target: &mut W, 337 attributes: &[Attribute]) -> Result<()> { 338 for attr in attributes.iter() { 339 write!( 340 target, " {}=\"{}\"", 341 attr.name.repr_display(), 342 if self.config.perform_escaping { escape_str_attribute(attr.value) } else { Cow::Borrowed(attr.value) } 343 )? 344 } 345 Ok(()) 346 } 347 emit_end_element<W: Write>(&mut self, target: &mut W, name: Option<Name>) -> Result<()>348 pub fn emit_end_element<W: Write>(&mut self, target: &mut W, 349 name: Option<Name>) -> Result<()> { 350 let owned_name = if self.config.keep_element_names_stack { 351 Some(self.element_names.pop().ok_or(EmitterError::LastElementNameNotAvailable)?) 352 } else { 353 None 354 }; 355 356 // Check that last started element name equals to the provided name, if there are both 357 if let Some(ref last_name) = owned_name { 358 if let Some(ref name) = name { 359 if last_name.borrow() != *name { 360 return Err(EmitterError::EndElementNameIsNotEqualToLastStartElementName); 361 } 362 } 363 } 364 365 if let Some(name) = owned_name.as_ref().map(|n| n.borrow()).or(name) { 366 if self.config.normalize_empty_elements && self.just_wrote_start_element { 367 self.just_wrote_start_element = false; 368 let termination = if self.config.pad_self_closing { " />" } else { "/>" }; 369 let result = target.write(termination.as_bytes()).map_err(From::from); 370 self.after_end_element(); 371 result.map(|_| ()) 372 } else { 373 self.just_wrote_start_element = false; 374 375 self.before_end_element(target)?; 376 let result = write!(target, "</{}>", name.repr_display()).map_err(From::from); 377 self.after_end_element(); 378 379 result 380 } 381 } else { 382 Err(EmitterError::EndElementNameIsNotSpecified) 383 } 384 } 385 emit_cdata<W: Write>(&mut self, target: &mut W, content: &str) -> Result<()>386 pub fn emit_cdata<W: Write>(&mut self, target: &mut W, content: &str) -> Result<()> { 387 self.fix_non_empty_element(target)?; 388 if self.config.cdata_to_characters { 389 self.emit_characters(target, content) 390 } else { 391 // TODO: escape ']]>' characters in CDATA as two adjacent CDATA blocks 392 target.write(b"<![CDATA[")?; 393 target.write(content.as_bytes())?; 394 target.write(b"]]>")?; 395 396 self.after_text(); 397 398 Ok(()) 399 } 400 } 401 emit_characters<W: Write>(&mut self, target: &mut W, content: &str) -> Result<()>402 pub fn emit_characters<W: Write>(&mut self, target: &mut W, 403 content: &str) -> Result<()> { 404 self.fix_non_empty_element(target)?; 405 target.write( 406 (if self.config.perform_escaping { 407 escape_str_pcdata(content) 408 } else { 409 Cow::Borrowed(content) 410 }).as_bytes() 411 )?; 412 self.after_text(); 413 Ok(()) 414 } 415 emit_comment<W: Write>(&mut self, target: &mut W, content: &str) -> Result<()>416 pub fn emit_comment<W: Write>(&mut self, target: &mut W, content: &str) -> Result<()> { 417 self.fix_non_empty_element(target)?; 418 419 // TODO: add escaping dashes at the end of the comment 420 421 let autopad_comments = self.config.autopad_comments; 422 let write = |target: &mut W| -> Result<()> { 423 target.write(b"<!--")?; 424 425 if autopad_comments && !content.starts_with(char::is_whitespace) { 426 target.write(b" ")?; 427 } 428 429 target.write(content.as_bytes())?; 430 431 if autopad_comments && !content.ends_with(char::is_whitespace) { 432 target.write(b" ")?; 433 } 434 435 target.write(b"-->")?; 436 437 Ok(()) 438 }; 439 440 self.before_markup(target)?; 441 let result = write(target); 442 self.after_markup(); 443 444 result 445 } 446 } 447