rapidyaml 0.16.0
parse and emit YAML, and do it fast
Loading...
Searching...
No Matches
Emitting

Functions

void sample_emit_to_container ()
 emit to memory, eg a string or vector-like container
void sample_emit_to_stream ()
 emit to a stream, eg std::ostream
void sample_emit_to_file ()
 emit to a FILE*
void sample_emit_nested_node ()
 pick a nested node as the root when emitting

Detailed Description

Function Documentation

◆ sample_emit_to_container()

void sample_emit_to_container ( )

emit to memory, eg a string or vector-like container

demonstrates how to emit to a linear container of char

Definition at line 4765 of file quickstart.cpp.

4766{
4767 ryml::csubstr ymla =
4768 "- 1\n"
4769 "- 2\n"
4770 "";
4771 ryml::csubstr ymlb =
4772 "- a" "\n"
4773 "- b" "\n"
4774 "- x0: 1" "\n"
4775 " x1: 2" "\n"
4776 "- champagne: Dom Perignon" "\n"
4777 " coffee: Arabica" "\n"
4778 " more:" "\n"
4779 " vinho verde: Soalheiro" "\n"
4780 " vinho tinto: Redoma 2017" "\n"
4781 " beer:" "\n"
4782 " - Rochefort 10" "\n"
4783 " - Busch" "\n"
4784 " - Leffe Rituel" "\n"
4785 "- foo" "\n"
4786 "- bar" "\n"
4787 "- baz" "\n"
4788 "- bat" "\n"
4789 "";
4790 const ryml::Tree treea = ryml::parse_in_arena(ymla);
4791 const ryml::Tree treeb = ryml::parse_in_arena(ymlb);
4792
4793 // it is possible to emit to any linear container of char.
4794 //
4795 // eg, std::vector<char>
4796 {
4797 // do a blank call on an empty buffer to find the required size.
4798 // no overflow will occur, and returns a substr with the size
4799 // required to output
4800 ryml::csubstr output = ryml::emit_yaml(treea, treea.root_id(), ryml::substr{}, /*error_on_excess*/false);
4801 CHECK(output.str == nullptr);
4802 CHECK(output.len > 0);
4803 size_t num_needed_chars = output.len;
4804 std::vector<char> buf(num_needed_chars);
4805 // now try again with the proper buffer
4806 output = ryml::emit_yaml(treea, treea.root_id(), ryml::to_substr(buf), /*error_on_excess*/true);
4807 CHECK(output == ymla);
4808
4809 // it is possible to reuse the buffer and grow it as needed.
4810 // first do a blank run to find the size:
4811 output = ryml::emit_yaml(treeb, treeb.root_id(), ryml::substr{}, /*error_on_excess*/false);
4812 CHECK(output.str == nullptr);
4813 CHECK(output.len > 0);
4814 CHECK(output.len == ymlb.len);
4815 num_needed_chars = output.len;
4816 buf.resize(num_needed_chars);
4817 // now try again with the proper buffer
4818 output = ryml::emit_yaml(treeb, treeb.root_id(), ryml::to_substr(buf), /*error_on_excess*/true);
4819 CHECK(output == ymlb);
4820
4821 // there is a convenience wrapper performing the same as above:
4822 // provided to_substr() is defined for that container.
4823 output = ryml::emitrs_yaml(treeb, &buf);
4824 CHECK(output == ymlb);
4825
4826 // or you can just output a new container:
4827 // provided to_substr() is defined for that container.
4828 std::vector<char> another = ryml::emitrs_yaml<std::vector<char>>(treeb);
4829 CHECK(ryml::to_csubstr(another) == ymlb);
4830
4831 // you can also emit nested nodes:
4832 another = ryml::emitrs_yaml<std::vector<char>>(treeb[3][2]);
4833 CHECK(ryml::to_csubstr(another) == ""
4834 "more:" "\n"
4835 " vinho verde: Soalheiro" "\n"
4836 " vinho tinto: Redoma 2017" "\n"
4837 "");
4838 }
4839
4840
4841 // eg, std::string. notice this is the same code as above
4842 {
4843 // do a blank call on an empty buffer to find the required size.
4844 // no overflow will occur, and returns a substr with the size
4845 // required to output
4846 ryml::csubstr output = ryml::emit_yaml(treea, treea.root_id(), ryml::substr{}, /*error_on_excess*/false);
4847 CHECK(output.str == nullptr);
4848 CHECK(output.len > 0);
4849 size_t num_needed_chars = output.len;
4850 std::string buf;
4851 buf.resize(num_needed_chars);
4852 // now try again with the proper buffer
4853 output = ryml::emit_yaml(treea, treea.root_id(), ryml::to_substr(buf), /*error_on_excess*/true);
4854 CHECK(output == ymla);
4855
4856 // it is possible to reuse the buffer and grow it as needed.
4857 // first do a blank run to find the size:
4858 output = ryml::emit_yaml(treeb, treeb.root_id(), ryml::substr{}, /*error_on_excess*/false);
4859 CHECK(output.str == nullptr);
4860 CHECK(output.len > 0);
4861 CHECK(output.len == ymlb.len);
4862 num_needed_chars = output.len;
4863 buf.resize(num_needed_chars);
4864 // now try again with the proper buffer
4865 output = ryml::emit_yaml(treeb, treeb.root_id(), ryml::to_substr(buf), /*error_on_excess*/true);
4866 CHECK(output == ymlb);
4867
4868 // there is a convenience wrapper performing the above instructions:
4869 // provided to_substr() is defined for that container
4870 output = ryml::emitrs_yaml(treeb, &buf);
4871 CHECK(output == ymlb);
4872
4873 // or you can just output a new container:
4874 // provided to_substr() is defined for that container.
4875 std::string another = ryml::emitrs_yaml<std::string>(treeb);
4876 CHECK(ryml::to_csubstr(another) == ymlb);
4877
4878 // you can also emit nested nodes:
4879 another = ryml::emitrs_yaml<std::string>(treeb[3][2]);
4880 CHECK(ryml::to_csubstr(another) == ""
4881 "more:" "\n"
4882 " vinho verde: Soalheiro" "\n"
4883 " vinho tinto: Redoma 2017" "\n"
4884 "");
4885 }
4886}
id_type root_id() const
Get the id of the root node. The tree must not be empty. The tree can be empty only when constructed ...
Definition tree.hpp:386
substr emit_yaml(Tree const &t, EmitOptions const &opts, substr buf, bool error_on_excess)
(1) emit YAML to the given buffer.
Definition emit_buf.cpp:28
substr emitrs_yaml(Tree const &t, id_type id, EmitOptions const &opts, CharOwningContainer *cont, bool append=false)
(1) emit+resize: emit YAML to the given std::string/std::vector<char>-like container,...
void parse_in_arena(Parser *parser, csubstr filename, csubstr yaml, Tree *tree, id_type node_id)
(1) parse YAML into an existing tree node. The filename will be used in any error messages arising du...
Definition parse.cpp:209
#define CHECK(predicate)
a testing assertion, used only in this quickstart
substr to_substr(char(&s)[N]) noexcept
Definition substr.hpp:2376
csubstr to_csubstr(const char(&s)[N]) noexcept
Definition substr.hpp:2380
basic_substring< char > substr
a mutable string view
Definition substr.hpp:2355
basic_substring< const char > csubstr
an immutable string view
Definition substr.hpp:2356
size_t len
the length of the substring
Definition substr.hpp:218
C * str
a restricted pointer to the first character of the substring
Definition substr.hpp:216

Referenced by main().

◆ sample_emit_to_stream()

void sample_emit_to_stream ( )

emit to a stream, eg std::ostream

demonstrates how to emit to a stream-like structure

Definition at line 4892 of file quickstart.cpp.

4893{
4894 ryml::csubstr ymlb =
4895 "- a" "\n"
4896 "- b" "\n"
4897 "- x0: 1" "\n"
4898 " x1: 2" "\n"
4899 "- champagne: Dom Perignon" "\n"
4900 " coffee: Arabica" "\n"
4901 " more:" "\n"
4902 " vinho verde: Soalheiro" "\n"
4903 " vinho tinto: Redoma 2017" "\n"
4904 " beer:" "\n"
4905 " - Rochefort 10" "\n"
4906 " - Busch" "\n"
4907 " - Leffe Rituel" "\n"
4908 "- foo" "\n"
4909 "- bar" "\n"
4910 "- baz" "\n"
4911 "- bat" "\n"
4912 "";
4913 const ryml::Tree tree = ryml::parse_in_arena(ymlb);
4914
4915 std::string s;
4916
4917 // emit a full tree
4918 {
4919 std::stringstream ss;
4920 ss << tree; // works with any stream having .operator<<() and .write()
4921 s = ss.str();
4922 CHECK(ryml::to_csubstr(s) == ymlb);
4923 }
4924
4925 // emit a full tree as json
4926 {
4927 std::stringstream ss;
4928 ss << ryml::as_json(tree); // works with any stream having .operator<<() and .write()
4929 s = ss.str();
4930 CHECK(s ==
4931 "[" "\n"
4932 " \"a\"," "\n"
4933 " \"b\"," "\n"
4934 " {" "\n"
4935 " \"x0\": 1," "\n"
4936 " \"x1\": 2" "\n"
4937 " }," "\n"
4938 " {" "\n"
4939 " \"champagne\": \"Dom Perignon\"," "\n"
4940 " \"coffee\": \"Arabica\"," "\n"
4941 " \"more\": {" "\n"
4942 " \"vinho verde\": \"Soalheiro\"," "\n"
4943 " \"vinho tinto\": \"Redoma 2017\"" "\n"
4944 " }," "\n"
4945 " \"beer\": [" "\n"
4946 " \"Rochefort 10\"," "\n"
4947 " \"Busch\"," "\n"
4948 " \"Leffe Rituel\"" "\n"
4949 " ]" "\n"
4950 " }," "\n"
4951 " \"foo\"," "\n"
4952 " \"bar\"," "\n"
4953 " \"baz\"," "\n"
4954 " \"bat\"" "\n"
4955 "]" "\n"
4956 "");
4957 }
4958
4959 // emit a nested node
4960 {
4961 std::stringstream ss;
4962 ss << tree[3][2]; // works with any stream having .operator<<() and .write()
4963 s = ss.str();
4964 CHECK(s == ""
4965 "more:" "\n"
4966 " vinho verde: Soalheiro" "\n"
4967 " vinho tinto: Redoma 2017" "\n"
4968 "");
4969 }
4970
4971 // emit a nested node as json
4972 {
4973 std::stringstream ss;
4974 ss << ryml::as_json(tree[3][2]); // works with any stream having .operator<<() and .write()
4975 s = ss.str();
4977 "\"more\": {" "\n"
4978 " \"vinho verde\": \"Soalheiro\"," "\n"
4979 " \"vinho tinto\": \"Redoma 2017\"" "\n"
4980 "}" "\n"
4981 "");
4982 }
4983}
tag type to mark a tree or node to be emitted as yaml when using operator<<, with options.

Referenced by main().

◆ sample_emit_to_file()

void sample_emit_to_file ( )

emit to a FILE*

demonstrates how to emit to a FILE*

Definition at line 4989 of file quickstart.cpp.

4990{
4991 ryml::csubstr yml = ""
4992 "- a" "\n"
4993 "- b" "\n"
4994 "- x0: 1" "\n"
4995 " x1: 2" "\n"
4996 "- champagne: Dom Perignon" "\n"
4997 " coffee: Arabica" "\n"
4998 " more:" "\n"
4999 " vinho verde: Soalheiro" "\n"
5000 " vinho tinto: Redoma 2017" "\n"
5001 " beer:" "\n"
5002 " - Rochefort 10" "\n"
5003 " - Busch" "\n"
5004 " - Leffe Rituel" "\n"
5005 "- foo" "\n"
5006 "- bar" "\n"
5007 "- baz" "\n"
5008 "- bat" "\n"
5009 "";
5010 const ryml::Tree tree = ryml::parse_in_arena(yml);
5011 // this is emitting to stdout, but of course you can pass in any
5012 // FILE* obtained from fopen()
5013 ryml::emit_yaml(tree, tree.root_id(), stdout);
5014}

Referenced by main().

◆ sample_emit_nested_node()

void sample_emit_nested_node ( )

pick a nested node as the root when emitting

just like parsing into a nested node, you can also emit from a nested node.

Definition at line 5020 of file quickstart.cpp.

5021{
5022 const ryml::Tree tree = ryml::parse_in_arena(""
5023 "- a" "\n"
5024 "- b" "\n"
5025 "- x0: 1" "\n"
5026 " x1: 2" "\n"
5027 "- champagne: Dom Perignon" "\n"
5028 " coffee: Arabica" "\n"
5029 " more:" "\n"
5030 " vinho verde: Soalheiro" "\n"
5031 " vinho tinto: Redoma 2017" "\n"
5032 " beer:" "\n"
5033 " - Rochefort 10" "\n"
5034 " - Busch" "\n"
5035 " - Leffe Rituel" "\n"
5036 " - - and so" "\n"
5037 " - many other" "\n"
5038 " - wonderful beers" "\n"
5039 "- more" "\n"
5040 "- seq" "\n"
5041 "- members" "\n"
5042 "- here" "\n"
5043 "");
5044 // Let's now emit the beer node. Note that its key is also
5045 // emitted, making the result a map with a single child:
5046 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["beer"]) == ""
5047 "beer:" "\n"
5048 " - Rochefort 10" "\n"
5049 " - Busch" "\n"
5050 " - Leffe Rituel" "\n"
5051 " - - and so" "\n"
5052 " - many other" "\n"
5053 " - wonderful beers" "\n"
5054 "");
5055 // You can use EmitOptions to prevent the key from being
5056 // emitted. Note how the result is now just the contents without
5057 // the key, and therefore the root is now a seq:
5058 auto without_key = ryml::EmitOptions{}.emit_nonroot_key(false);
5059 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["beer"], without_key) == ""
5060 "- Rochefort 10" "\n"
5061 "- Busch" "\n"
5062 "- Leffe Rituel" "\n"
5063 "- - and so" "\n"
5064 " - many other" "\n"
5065 " - wonderful beers" "\n"
5066 "");
5067 // For sequences, the behavior is opposite. Notice how the leading
5068 // dash defaults to omit:
5069 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["beer"][3]) == ""
5070 "- and so" "\n"
5071 "- many other" "\n"
5072 "- wonderful beers" "\n"
5073 "");
5074 // And likewise, you can use EmitOptions to force the dash:
5075 auto with_dash = ryml::EmitOptions{}.emit_nonroot_dash(true);
5076 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["beer"][3], with_dash) == ""
5077 "- - and so" "\n" // note the added dash and indentation
5078 " - many other" "\n"
5079 " - wonderful beers" "\n"
5080 "");
5081 // Example: emit a scalar node (seq member):
5082 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["beer"][0]) == "Rochefort 10");
5083 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["beer"][0], with_dash) == "- Rochefort 10\n");
5084 // Example: emit a scalar node (map member):
5085 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["more"][0]) == "vinho verde: Soalheiro\n");
5086 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["more"][0], without_key) == "Soalheiro");
5087}
A lightweight object containing options to be used when emitting.
EmitOptions & emit_nonroot_key(bool enabled) noexcept
When emit starts on a nested (non-root) node, emit the node's key as well.
EmitOptions & emit_nonroot_dash(bool enabled) noexcept
When emit starts on a nested (non-root) node, emit a leading dash.

Referenced by main().