A toolkit for working with phylogenetic data.
v0.19.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
utils/formats/json/writer.cpp
Go to the documentation of this file.
1 /*
2  Genesis - A toolkit for working with phylogenetic data.
3  Copyright (C) 2014-2017 Lucas Czech
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Contact:
19  Lucas Czech <lucas.czech@h-its.org>
20  Exelixis Lab, Heidelberg Institute for Theoretical Studies
21  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
22 */
23 
32 
33 #include <cassert>
34 #include <fstream>
35 #include <ostream>
36 #include <stdexcept>
37 
43 
44 namespace genesis {
45 namespace utils {
46 
47 // =================================================================================================
48 // Writing
49 // =================================================================================================
50 
51 void JsonWriter::to_stream( JsonDocument const& document, std::ostream& out ) const
52 {
53  print_value( document, out );
54 }
55 
56 void JsonWriter::to_file( JsonDocument const& document, std::string const& filename ) const
57 {
58  std::ofstream ofs;
59  utils::file_output_stream( filename, ofs );
60  print_value( document, ofs );
61 }
62 
63 void JsonWriter::to_string( JsonDocument const& document, std::string& output ) const
64 {
65  output = to_string(document);
66 }
67 
68 std::string JsonWriter::to_string( JsonDocument const& document ) const
69 {
70  std::stringstream sstr;
71  print_value( document, sstr );
72  return sstr.str();
73 }
74 
75 // =================================================================================================
76 // Printing
77 // =================================================================================================
78 
79 void JsonWriter::print_value(
80  JsonDocument const& value,
81  std::ostream& out
82 ) const {
83  switch(value.type()) {
85  out << "null";
86  break;
87  }
89  out << ( value.get_boolean() ? "true" : "false" );
90  break;
91  }
93  out << to_string_precise( value.get_number_float(), precision_ );
94  break;
95  }
97  out << value.get_number_signed();
98  break;
99  }
101  out << value.get_number_unsigned();
102  break;
103  }
105  out << "\"" + utils::escape( value.get_string() ) + "\"";
106  break;
107  }
109  print_array( value, out, 0 );
110  break;
111  }
113  print_object( value, out, 0 );
114  break;
115  }
116  default: {
117  assert( false );
118  }
119  }
120 }
121 
122 void JsonWriter::print_array(
123  JsonDocument const& value,
124  std::ostream& out,
125  int indent_level
126 ) const {
127  int il = indent_level + 1;
128  std::string in (il * indent_, ' ');
129 
130  // Check if array contains non-primitive values.
131  // If so, we use better bracket placement to make document look nicer.
132  bool has_large = false;
133  for( auto const& elem : value ) {
134  has_large |= ( elem.is_array() || elem.is_object());
135  }
136 
137  out << "[ ";
138  bool first = true;
139  for( auto const& elem : value ) {
140  if (!first) {
141  out << ", ";
142  }
143  if (has_large) {
144  out << "\n" << in;
145  }
146  if (elem.is_array()) {
147  print_array( elem, out, il );
148  } else if ( elem.is_object() ) {
149  print_object( elem, out, il );
150  } else {
151  print_value( elem, out );
152  }
153  first = false;
154  }
155 
156  if (has_large) {
157  out << "\n" << std::string(indent_level * indent_, ' ');
158  } else {
159  out << " ";
160  }
161  out << "]";
162 }
163 
164 void JsonWriter::print_object(
165  JsonDocument const& value,
166  std::ostream& out,
167  int indent_level
168 ) const {
169  int il = indent_level + 1;
170  std::string in (il * indent_, ' ');
171  out << "{";
172 
173  bool first = true;
174  for( auto it = value.begin(); it != value.end(); ++it ) {
175  if (!first) {
176  out << ",";
177  }
178  out << "\n" << in << "\"" << it.key() << "\": ";
179  if ( it.value().is_array() ) {
180  print_array( it.value(), out, il );
181  } else if( it.value().is_object() ) {
182  print_object( it.value(), out, il );
183  } else {
184  print_value( it.value(), out );
185  }
186  first = false;
187  }
188 
189  out << "\n" << std::string(indent_level * indent_, ' ') << "}";
190 }
191 
192 } // namespace utils
193 } // namespace genesis
void file_output_stream(std::string const &filename, std::ofstream &out_stream, std::ios_base::openmode mode=std::ios_base::out)
Helper function to obtain an output stream to a file.
void to_string(JsonDocument const &document, std::string &output) const
Give the Json string representation of a JsonDocument.
std::string escape(std::string const &text)
Return a string where special chars are replaces by their escape sequence.
Definition: string.cpp:322
NumberFloatType & get_number_float()
NumberUnsignedType & get_number_unsigned()
std::string to_string_precise(double const value, int const precision)
Return a precise string representation of the input value, using the provided precision value (determ...
Definition: string.cpp:397
ValueType type() const
Return the type of the JSON value.
Provides some commonly used string utility functions.
Provides functions for accessing the file system.
Store a Json value of any kind.
NumberSignedType & get_number_signed()
void to_stream(JsonDocument const &document, std::ostream &out) const
Write a JsonDocument to a stream.
void to_file(JsonDocument const &document, std::string const &filename) const
Write a JsonDocument to a file.