rapidyaml 0.15.2
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 4681 of file quickstart.cpp.

4682{
4683 ryml::csubstr ymla =
4684 "- 1\n"
4685 "- 2\n"
4686 "";
4687 ryml::csubstr ymlb =
4688 "- a" "\n"
4689 "- b" "\n"
4690 "- x0: 1" "\n"
4691 " x1: 2" "\n"
4692 "- champagne: Dom Perignon" "\n"
4693 " coffee: Arabica" "\n"
4694 " more:" "\n"
4695 " vinho verde: Soalheiro" "\n"
4696 " vinho tinto: Redoma 2017" "\n"
4697 " beer:" "\n"
4698 " - Rochefort 10" "\n"
4699 " - Busch" "\n"
4700 " - Leffe Rituel" "\n"
4701 "- foo" "\n"
4702 "- bar" "\n"
4703 "- baz" "\n"
4704 "- bat" "\n"
4705 "";
4706 const ryml::Tree treea = ryml::parse_in_arena(ymla);
4707 const ryml::Tree treeb = ryml::parse_in_arena(ymlb);
4708
4709 // it is possible to emit to any linear container of char.
4710 //
4711 // eg, std::vector<char>
4712 {
4713 // do a blank call on an empty buffer to find the required size.
4714 // no overflow will occur, and returns a substr with the size
4715 // required to output
4716 ryml::csubstr output = ryml::emit_yaml(treea, treea.root_id(), ryml::substr{}, /*error_on_excess*/false);
4717 CHECK(output.str == nullptr);
4718 CHECK(output.len > 0);
4719 size_t num_needed_chars = output.len;
4720 std::vector<char> buf(num_needed_chars);
4721 // now try again with the proper buffer
4722 output = ryml::emit_yaml(treea, treea.root_id(), ryml::to_substr(buf), /*error_on_excess*/true);
4723 CHECK(output == ymla);
4724
4725 // it is possible to reuse the buffer and grow it as needed.
4726 // first do a blank run to find the size:
4727 output = ryml::emit_yaml(treeb, treeb.root_id(), ryml::substr{}, /*error_on_excess*/false);
4728 CHECK(output.str == nullptr);
4729 CHECK(output.len > 0);
4730 CHECK(output.len == ymlb.len);
4731 num_needed_chars = output.len;
4732 buf.resize(num_needed_chars);
4733 // now try again with the proper buffer
4734 output = ryml::emit_yaml(treeb, treeb.root_id(), ryml::to_substr(buf), /*error_on_excess*/true);
4735 CHECK(output == ymlb);
4736
4737 // there is a convenience wrapper performing the same as above:
4738 // provided to_substr() is defined for that container.
4739 output = ryml::emitrs_yaml(treeb, &buf);
4740 CHECK(output == ymlb);
4741
4742 // or you can just output a new container:
4743 // provided to_substr() is defined for that container.
4744 std::vector<char> another = ryml::emitrs_yaml<std::vector<char>>(treeb);
4745 CHECK(ryml::to_csubstr(another) == ymlb);
4746
4747 // you can also emit nested nodes:
4748 another = ryml::emitrs_yaml<std::vector<char>>(treeb[3][2]);
4749 CHECK(ryml::to_csubstr(another) == ""
4750 "more:" "\n"
4751 " vinho verde: Soalheiro" "\n"
4752 " vinho tinto: Redoma 2017" "\n"
4753 "");
4754 }
4755
4756
4757 // eg, std::string. notice this is the same code as above
4758 {
4759 // do a blank call on an empty buffer to find the required size.
4760 // no overflow will occur, and returns a substr with the size
4761 // required to output
4762 ryml::csubstr output = ryml::emit_yaml(treea, treea.root_id(), ryml::substr{}, /*error_on_excess*/false);
4763 CHECK(output.str == nullptr);
4764 CHECK(output.len > 0);
4765 size_t num_needed_chars = output.len;
4766 std::string buf;
4767 buf.resize(num_needed_chars);
4768 // now try again with the proper buffer
4769 output = ryml::emit_yaml(treea, treea.root_id(), ryml::to_substr(buf), /*error_on_excess*/true);
4770 CHECK(output == ymla);
4771
4772 // it is possible to reuse the buffer and grow it as needed.
4773 // first do a blank run to find the size:
4774 output = ryml::emit_yaml(treeb, treeb.root_id(), ryml::substr{}, /*error_on_excess*/false);
4775 CHECK(output.str == nullptr);
4776 CHECK(output.len > 0);
4777 CHECK(output.len == ymlb.len);
4778 num_needed_chars = output.len;
4779 buf.resize(num_needed_chars);
4780 // now try again with the proper buffer
4781 output = ryml::emit_yaml(treeb, treeb.root_id(), ryml::to_substr(buf), /*error_on_excess*/true);
4782 CHECK(output == ymlb);
4783
4784 // there is a convenience wrapper performing the above instructions:
4785 // provided to_substr() is defined for that container
4786 output = ryml::emitrs_yaml(treeb, &buf);
4787 CHECK(output == ymlb);
4788
4789 // or you can just output a new container:
4790 // provided to_substr() is defined for that container.
4791 std::string another = ryml::emitrs_yaml<std::string>(treeb);
4792 CHECK(ryml::to_csubstr(another) == ymlb);
4793
4794 // you can also emit nested nodes:
4795 another = ryml::emitrs_yaml<std::string>(treeb[3][2]);
4796 CHECK(ryml::to_csubstr(another) == ""
4797 "more:" "\n"
4798 " vinho verde: Soalheiro" "\n"
4799 " vinho tinto: Redoma 2017" "\n"
4800 "");
4801 }
4802}
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 4808 of file quickstart.cpp.

4809{
4810 ryml::csubstr ymlb =
4811 "- a" "\n"
4812 "- b" "\n"
4813 "- x0: 1" "\n"
4814 " x1: 2" "\n"
4815 "- champagne: Dom Perignon" "\n"
4816 " coffee: Arabica" "\n"
4817 " more:" "\n"
4818 " vinho verde: Soalheiro" "\n"
4819 " vinho tinto: Redoma 2017" "\n"
4820 " beer:" "\n"
4821 " - Rochefort 10" "\n"
4822 " - Busch" "\n"
4823 " - Leffe Rituel" "\n"
4824 "- foo" "\n"
4825 "- bar" "\n"
4826 "- baz" "\n"
4827 "- bat" "\n"
4828 "";
4829 const ryml::Tree tree = ryml::parse_in_arena(ymlb);
4830
4831 std::string s;
4832
4833 // emit a full tree
4834 {
4835 std::stringstream ss;
4836 ss << tree; // works with any stream having .operator<<() and .write()
4837 s = ss.str();
4838 CHECK(ryml::to_csubstr(s) == ymlb);
4839 }
4840
4841 // emit a full tree as json
4842 {
4843 std::stringstream ss;
4844 ss << ryml::as_json(tree); // works with any stream having .operator<<() and .write()
4845 s = ss.str();
4846 CHECK(s ==
4847 "[" "\n"
4848 " \"a\"," "\n"
4849 " \"b\"," "\n"
4850 " {" "\n"
4851 " \"x0\": 1," "\n"
4852 " \"x1\": 2" "\n"
4853 " }," "\n"
4854 " {" "\n"
4855 " \"champagne\": \"Dom Perignon\"," "\n"
4856 " \"coffee\": \"Arabica\"," "\n"
4857 " \"more\": {" "\n"
4858 " \"vinho verde\": \"Soalheiro\"," "\n"
4859 " \"vinho tinto\": \"Redoma 2017\"" "\n"
4860 " }," "\n"
4861 " \"beer\": [" "\n"
4862 " \"Rochefort 10\"," "\n"
4863 " \"Busch\"," "\n"
4864 " \"Leffe Rituel\"" "\n"
4865 " ]" "\n"
4866 " }," "\n"
4867 " \"foo\"," "\n"
4868 " \"bar\"," "\n"
4869 " \"baz\"," "\n"
4870 " \"bat\"" "\n"
4871 "]" "\n"
4872 "");
4873 }
4874
4875 // emit a nested node
4876 {
4877 std::stringstream ss;
4878 ss << tree[3][2]; // works with any stream having .operator<<() and .write()
4879 s = ss.str();
4880 CHECK(s == ""
4881 "more:" "\n"
4882 " vinho verde: Soalheiro" "\n"
4883 " vinho tinto: Redoma 2017" "\n"
4884 "");
4885 }
4886
4887 // emit a nested node as json
4888 {
4889 std::stringstream ss;
4890 ss << ryml::as_json(tree[3][2]); // works with any stream having .operator<<() and .write()
4891 s = ss.str();
4893 "\"more\": {" "\n"
4894 " \"vinho verde\": \"Soalheiro\"," "\n"
4895 " \"vinho tinto\": \"Redoma 2017\"" "\n"
4896 "}" "\n"
4897 "");
4898 }
4899}
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 4905 of file quickstart.cpp.

4906{
4907 ryml::csubstr yml = ""
4908 "- a" "\n"
4909 "- b" "\n"
4910 "- x0: 1" "\n"
4911 " x1: 2" "\n"
4912 "- champagne: Dom Perignon" "\n"
4913 " coffee: Arabica" "\n"
4914 " more:" "\n"
4915 " vinho verde: Soalheiro" "\n"
4916 " vinho tinto: Redoma 2017" "\n"
4917 " beer:" "\n"
4918 " - Rochefort 10" "\n"
4919 " - Busch" "\n"
4920 " - Leffe Rituel" "\n"
4921 "- foo" "\n"
4922 "- bar" "\n"
4923 "- baz" "\n"
4924 "- bat" "\n"
4925 "";
4926 const ryml::Tree tree = ryml::parse_in_arena(yml);
4927 // this is emitting to stdout, but of course you can pass in any
4928 // FILE* obtained from fopen()
4929 ryml::emit_yaml(tree, tree.root_id(), stdout);
4930}

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 4936 of file quickstart.cpp.

4937{
4938 const ryml::Tree tree = ryml::parse_in_arena(""
4939 "- a" "\n"
4940 "- b" "\n"
4941 "- x0: 1" "\n"
4942 " x1: 2" "\n"
4943 "- champagne: Dom Perignon" "\n"
4944 " coffee: Arabica" "\n"
4945 " more:" "\n"
4946 " vinho verde: Soalheiro" "\n"
4947 " vinho tinto: Redoma 2017" "\n"
4948 " beer:" "\n"
4949 " - Rochefort 10" "\n"
4950 " - Busch" "\n"
4951 " - Leffe Rituel" "\n"
4952 " - - and so" "\n"
4953 " - many other" "\n"
4954 " - wonderful beers" "\n"
4955 "- more" "\n"
4956 "- seq" "\n"
4957 "- members" "\n"
4958 "- here" "\n"
4959 "");
4960 // Let's now emit the beer node. Note that its key is also
4961 // emitted, making the result a map with a single child:
4962 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["beer"]) == ""
4963 "beer:" "\n"
4964 " - Rochefort 10" "\n"
4965 " - Busch" "\n"
4966 " - Leffe Rituel" "\n"
4967 " - - and so" "\n"
4968 " - many other" "\n"
4969 " - wonderful beers" "\n"
4970 "");
4971 // You can use EmitOptions to prevent the key from being
4972 // emitted. Note how the result is now just the contents without
4973 // the key, and therefore the root is now a seq:
4974 auto without_key = ryml::EmitOptions{}.emit_nonroot_key(false);
4975 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["beer"], without_key) == ""
4976 "- Rochefort 10" "\n"
4977 "- Busch" "\n"
4978 "- Leffe Rituel" "\n"
4979 "- - and so" "\n"
4980 " - many other" "\n"
4981 " - wonderful beers" "\n"
4982 "");
4983 // For sequences, the behavior is opposite. Notice how the leading
4984 // dash defaults to omit:
4985 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["beer"][3]) == ""
4986 "- and so" "\n"
4987 "- many other" "\n"
4988 "- wonderful beers" "\n"
4989 "");
4990 // And likewise, you can use EmitOptions to force the dash:
4991 auto with_dash = ryml::EmitOptions{}.emit_nonroot_dash(true);
4992 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["beer"][3], with_dash) == ""
4993 "- - and so" "\n" // note the added dash and indentation
4994 " - many other" "\n"
4995 " - wonderful beers" "\n"
4996 "");
4997 // Example: emit a scalar node (seq member):
4998 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["beer"][0]) == "Rochefort 10");
4999 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["beer"][0], with_dash) == "- Rochefort 10\n");
5000 // Example: emit a scalar node (map member):
5001 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["more"][0]) == "vinho verde: Soalheiro\n");
5002 CHECK(ryml::emitrs_yaml<std::string>(tree[3]["more"][0], without_key) == "Soalheiro");
5003}
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().