cgv
Loading...
Searching...
No Matches
ascii_io_reflection_handlers.cxx
1#include "ascii_io_reflection_handlers.h"
2#include <cgv/utils/scan.h>
3
4using namespace cgv::reflect;
5namespace cgv {
6 namespace reflect {
7
10 }
11 }
12}
13
14namespace cgv {
15 namespace data {
16
17
18std::string ascii_reflection_handler::extend_name(const std::string& name, bool assign)
19{
20 NamingConvention nc = naming_convention;
21 if (in_header)
22 nc = NC_SHORT;
23 if (nc == NC_NONE)
24 return "";
25
26 std::string res;
27 for (unsigned i=0; i<nesting_info_stack.size(); ++i) {
28 res += *nesting_info_stack[i].name;
29 switch (nesting_info_stack[i].group_kind) {
30 case GK_BASE_CLASS :
31 case GK_STRUCTURE :
32 res += ".";
33 break;
34 case GK_VECTOR :
35 case GK_ARRAY :
36 res += "[";
37 res += cgv::utils::to_string(nesting_info_stack[i].idx) + "]";
38 break;
39 }
40 }
41 res += name;
42
43 size_t p = res.find_last_of(".");
44 if (p != std::string::npos) {
45 res = res.substr(p+1);
46 for (size_t j=0; j<nr_idents*tab_size; ++j)
47 res = std::string(" ") + res;
48 }
49 if (assign)
50 res += "=";
51 return res;
52}
53
56{
57 return true;
58}
59
60bool ascii_reflection_handler::reflect_header()
61{
62 in_header = true;
63 bool res = reflect_member("version", version) &&
64 reflect_member("content", file_content) &&
65 reflect_member("tab_size", tab_size) &&
66 reflect_member("naming_convention", naming_convention);
67 in_header = false;
68 return res;
69}
70
71ascii_reflection_handler::ascii_reflection_handler(const std::string& _content, unsigned _ver, unsigned _tab) : io_reflection_handler(_content, _ver)
72{
73 nr_idents = 0;
74 tab_size = _tab;
75}
76
78int ascii_reflection_handler::reflect_group_begin(GroupKind group_kind, const std::string& group_name, void* group_ptr, abst_reflection_traits* rt, unsigned grp_size)
79{
80 ++nr_idents;
81 return GT_COMPLETE;
82}
85{
86 if (group_kind != reflection_handler::GK_BASE_CLASS)
87 --nr_idents;
88}
89
90bool ascii_read_reflection_handler::read_reflect_header(const std::string& _content, unsigned _ver)
91{
92 reflect_header();
93 if (failed())
94 return false;
95 if (_content != file_content)
96 last_error = RE_CONTENT_MISMATCH;
97 else if (_ver != version)
98 last_error = RE_VERSION_MISMATCH;
99 else return true;
100 return false;
101}
102
103ascii_read_reflection_handler::ascii_read_reflection_handler(const std::string& file_name, const std::string& _content, unsigned _ver, NamingConvention _nc, unsigned _tab) :
104 ascii_reflection_handler(_content, _ver, _tab), is(file_is)
105{
106#if defined (WIN32) && !defined(__MINGW32__)
107 file_is.open(cgv::utils::str2wstr(file_name).c_str());
108#else
109 file_is.open(file_name.c_str());
110#endif
111 if (file_is.fail())
112 last_error = RE_FILE_OPEN_ERROR;
113 else
114 read_reflect_header(_content, _ver);
115}
116
118ascii_read_reflection_handler::ascii_read_reflection_handler(std::istream& _is, const std::string& _content, unsigned _ver, NamingConvention _nc, unsigned _tab) :
119 ascii_reflection_handler(_content, _ver, _tab), is(_is)
120{
121 read_reflect_header(_content, _ver);
122}
124void ascii_read_reflection_handler::close()
125{
126 if (&is == &file_is)
127 file_is.close();
128}
129
130int ascii_read_reflection_handler::reflect_group_begin(GroupKind group_kind, const std::string& group_name, void* group_ptr, abst_reflection_traits* rt, unsigned grp_size)
131{
132 if (group_kind != reflection_handler::GK_BASE_CLASS) {
133 char buffer[10000];
134 is.getline(buffer, 10000);
135 if (is.fail()) {
136 last_error = RE_FILE_READ_ERROR;
137 return false;
138 }
139 ++nr_idents;
140 }
141 return GT_COMPLETE;
142}
144bool ascii_read_reflection_handler::reflect_member_void(const std::string& member_name,
145 void* member_ptr, abst_reflection_traits* rt)
146{
147 char buffer[10000];
148 is.getline(buffer, 10000);
149 if (is.fail()) {
150 last_error = RE_FILE_READ_ERROR;
151 return false;
152 }
154 std::string val_str(buffer + extend_name(member_name).size()+1);
155 *((std::string*)member_ptr) = cgv::utils::interpret_special(val_str.substr(0, val_str.size()-1));
156 }
157 else if (rt->has_string_conversions()) {
158 std::string val_str(buffer + extend_name(member_name).size());
159 rt->set_from_string(member_ptr, val_str);
160 }
161 return true;
162}
163
164ascii_write_reflection_handler::ascii_write_reflection_handler(const std::string& file_name, const std::string& _content, unsigned _ver, NamingConvention _nc, unsigned _tab) :
165 ascii_reflection_handler(_content, _ver, _tab), os(file_os)
166{
167 naming_convention = _nc;
168#if defined(WIN32) && !defined(__MINGW32__)
169 file_os.open(cgv::utils::str2wstr(file_name).c_str());
170#else
171 file_os.open(file_name.c_str());
172#endif
173 if (file_os.fail())
174 last_error = RE_FILE_OPEN_ERROR;
175 else
176 reflect_header();
177}
178ascii_write_reflection_handler::ascii_write_reflection_handler(std::ostream& _os, const std::string& _content, unsigned _ver, NamingConvention _nc, unsigned _tab) :
179 ascii_reflection_handler(_content, _ver, _tab), os(_os)
180{
181 naming_convention = _nc;
182 reflect_header();
183}
185bool ascii_write_reflection_handler::failed() const { return os.fail(); }
187void ascii_write_reflection_handler::close()
188{
189 if(&os == &file_os)
190 file_os.close();
191}
193int ascii_write_reflection_handler::reflect_group_begin(GroupKind group_kind, const std::string& group_name, void* group_ptr, abst_reflection_traits* rt, unsigned grp_size)
194{
195 if (group_kind != reflection_handler::GK_BASE_CLASS) {
196 os << extend_name(group_name, false) << std::endl;
197 if (os.fail()) {
198 last_error = RE_FILE_WRITE_ERROR;
199 return GT_TERMINATE;
200 }
201 ++nr_idents;
202 }
203 return GT_COMPLETE;
204}
206bool ascii_write_reflection_handler::reflect_member_void(const std::string& member_name,
207 void* member_ptr, abst_reflection_traits* rt)
208{
209 os << extend_name(member_name);
211 os << '"' << cgv::utils::escape_special(*((const std::string*)member_ptr)) << '"';
212 else if (rt->has_string_conversions()) {
213 std::string s;
214 rt->get_to_string(member_ptr, s);
215 os << s;
216 }
217 os << std::endl;
218 if (os.fail()) {
219 last_error = RE_FILE_WRITE_ERROR;
220 return false;
221 }
222 return true;
223}
224
225 }
226}
227
bool reflect_member_void(const std::string &member_name, void *member_ptr, cgv::reflect::abst_reflection_traits *rt)
abstract interface to reflect a member variable, where the member type is specified as a string.
int reflect_group_begin(GroupKind group_kind, const std::string &group_name, void *group_ptr, cgv::reflect::abst_reflection_traits *rt, unsigned grp_size)
abstract interface to start reflection of a group of members.
int reflect_group_begin(GroupKind group_kind, const std::string &group_name, void *group_ptr, cgv::reflect::abst_reflection_traits *rt, unsigned grp_size)
abstract interface to start reflection of a group of members.
void reflect_group_end(GroupKind group_kind)
abstract interface to terminate reflection of a group of members
int reflect_group_begin(GroupKind group_kind, const std::string &group_name, void *group_ptr, cgv::reflect::abst_reflection_traits *rt, unsigned grp_size)
abstract interface to start reflection of a group of members.
bool reflect_member_void(const std::string &member_name, void *member_ptr, cgv::reflect::abst_reflection_traits *rt)
abstract interface to reflect a member variable, where the member type is specified as a string.
ascii_write_reflection_handler(const std::string &file_name, const std::string &_content, unsigned _ver, NamingConvention _nc=NC_SHORT, unsigned _tab=3)
construct from file_name by opening file in ascii mode
std::vector< nesting_info > nesting_info_stack
stack of nesting_info used during the reflection process
GroupKind
different support group types
bool reflect_member(const std::string &member_name, T &member_ref, bool hard_cast=false)
call this to reflect a member by member name and reference to the member.
NamingConvention
different naming conventions for member names
in this namespace reflection of types is implemented
@ TI_STRING
wide character type
Definition type_id.h:31
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
std::string interpret_special(const std::string &s)
interprets the C++ special characters \a, \b, \f, \n, \r, \t, \v, \\', \", \\, \?,...
Definition scan.cxx:227
std::string escape_special(const std::string &s)
escapes the C++ special characters \a, \b, \f, \n, \r, \t, \v, \\', \", \\, \?
Definition scan.cxx:205
std::wstring str2wstr(const std::string &s)
convert a 8-bit string to a 16-bit string
Definition convert.cxx:11
the cgv namespace
Definition print.h:11
Helper functions to process strings.
abstract interface for type reflection with basic type management and optional string conversion
virtual bool has_string_conversions() const
whether type can be converted to string, defaults to false
virtual cgv::type::info::TypeId get_type_id() const =0
return the type id
virtual void get_to_string(const void *instance_ptr, std::string &str_val)
convert given instance into a string value
virtual bool set_from_string(void *instance_ptr, const std::string &str_val)
convert a given string value to the reflected type and store in the instance pointer
this type specific reflection traits class is used by the reflect_enum function to reflect enum types