Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Emitter.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file basic/Emitter.cc
11 ///
12 /// @brief Lightweight class to ease writting YAML documents
13 /// @author Ian W. Davis
14 
15 #include <basic/Emitter.hh>
16 
17 // Boost Headers
18 #include <boost/foreach.hpp>
19 
20 #include <cstddef>
21 #include <iosfwd>
22 #include <ostream>
23 
24 namespace basic {
25 
26 
27 void Emitter::start_list(bool indent/*=true*/)
28 {
29  assert_in(false, "Tried to write list data inside a map");
30  do_indent();
31  start_raw(false, indent);
32 }
33 
34 void Emitter::start_map(bool indent/*=true*/)
35 {
36  assert_in(false, "Tried to write list data inside a map");
37  do_indent();
38  start_raw(true, indent);
39 }
40 
41 void Emitter::start_list(const char * label, bool indent/*=true*/)
42 {
43  assert_in(true, "Tried to write map data inside a list");
44  do_indent();
45  write_label(label);
46  start_raw(false, indent);
47 }
48 
49 void Emitter::start_map(const char * label, bool indent/*=true*/)
50 {
51  assert_in(true, "Tried to write map data inside a list");
52  do_indent();
53  write_label(label);
54  start_raw(true, indent);
55 }
56 
58 {
59  if ( assert_in(false, "Tried to end list inside map") ) end_raw();
60 }
61 
63 {
64  if ( assert_in(true, "Tried to end map inside list") ) end_raw();
65 }
66 
67 void Emitter::end(size_t desired_depth/*=0*/)
68 {
69  //while( depth() > desired_depth ) end_raw();
70  for ( size_t i = depth(); i > desired_depth; --i ) end_raw();
71 }
72 
73 /// @details Anything but the most basic characters needs to be quoted and escaped.
74 /// For normal YAML, very simple text can be output without quotes, though.
75 /// @param needs_quotes_out will be set to true if string contains "special" characters.
76 std::string Emitter::escape_string(std::string const & s, bool & needs_quotes_out)
77 {
78  using std::string;
79  // Characters that need no escaping, and no quoting (conservative)
80  // Most punctuation characters have special meaning in YAML!
81  static string bare_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_. ";
82  static string hex = "0123456789ABCDEF";
83  // If all chars in s are also in bare_chars, no quotes are needed in YAML
84  needs_quotes_out = !(s.find_first_not_of(bare_chars) == string::npos);
85  // Special cases: starts/ends with whitespace, zero length
86  if ( s.empty() || s[0] == ' ' || s[s.size()-1] == ' ' ) needs_quotes_out = true;
87  if ( !needs_quotes_out ) return s;
88 
89  std::ostringstream o;
90 
91  BOOST_FOREACH ( char ch, s ) {
92  if ( ' ' <= ch && ch <= '~' ) o << ch; // the range of printable ASCII characters
93  else if ( ch == '"' ) o << "\\\"";
94  else if ( ch == '\\' ) o << "\\\\";
95  else if ( ch == '\n' ) o << "\\n";
96  else if ( ch == '\r' ) o << "\\r";
97  else if ( ch == '\t' ) o << "\\t";
98  else if ( ch == '\f' ) o << "\\f";
99  else if ( ch == '\b' ) o << "\\b";
100  else { // Unicode escape
101  o << "\\u";
102  o << hex[ ((ch>>24)&0x000F) ];
103  o << hex[ ((ch>>16)&0x000F) ];
104  o << hex[ ((ch>> 8)&0x000F) ];
105  o << hex[ ((ch )&0x000F) ];
106  }
107  }
108  return o.str();
109 }
110 
111 
112 } // basic
113 
int depth() const
Number of closing brackets/braces required to end document (non-negative)
Definition: Emitter.hh:110
void end_list()
Counterpart to start_list() – writes closing bracket.
Definition: Emitter.cc:57
bool assert_in(bool in_map, std::string const &msg)
Check that we're in the expected context (either map or list)
Definition: Emitter.hh:129
void end_map()
Counterpart to start_map() – writes closing brace.
Definition: Emitter.cc:62
void start_list(bool indent=true)
Write method for use inside lists / arrays.
Definition: Emitter.cc:27
void end(size_t desired_depth=0)
By default, closes all open maps/lists, ending the document.
Definition: Emitter.cc:67
void start_map(bool indent=true)
Write method for use inside lists / arrays.
Definition: Emitter.cc:34
virtual void start_raw(bool is_map, bool indent)=0
Actual implementation of start_map() and start_list().
Lightweight class to ease writting YAML documents.
virtual void end_raw()=0
Actual implementation of end_map() and end_list().
virtual void do_indent(bool write_comma=true)=0
Handle pretty-printing indentation. Don't want to use commas for opening/closing brace/bracket.
void write_label(std::string const &label)
Write the key part of a key-value pair.
Definition: Emitter.hh:138
std::string escape_string(std::string const &s, bool &needs_quotes_out)
Converts special characters (newlines, etc) to escape codes ( , etc).
Definition: Emitter.cc:76