1 |
/* |
2 |
* This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 |
* |
4 |
* Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 |
* |
6 |
* Deliantra is free software: you can redistribute it and/or modify it under |
7 |
* the terms of the Affero GNU General Public License as published by the |
8 |
* Free Software Foundation, either version 3 of the License, or (at your |
9 |
* option) any later version. |
10 |
* |
11 |
* This program is distributed in the hope that it will be useful, |
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
* GNU General Public License for more details. |
15 |
* |
16 |
* You should have received a copy of the Affero GNU General Public License |
17 |
* and the GNU General Public License along with this program. If not, see |
18 |
* <http://www.gnu.org/licenses/>. |
19 |
* |
20 |
* The authors can be reached via e-mail to <support@deliantra.net> |
21 |
*/ |
22 |
|
23 |
#ifndef FREEZETHAW_H__ |
24 |
#define FREEZETHAW_H__ |
25 |
|
26 |
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
27 |
|
28 |
// a little dirty hack, maybe unify with something else at a later time |
29 |
// it is used to communicate as much info about the keyword string |
30 |
// to the consuemr as possible, for maximum performance. |
31 |
struct keyword_string |
32 |
{ |
33 |
const char *s; |
34 |
const int l; |
35 |
|
36 |
keyword_string (const char *s, int l) |
37 |
: s(s), l(l) |
38 |
{ } |
39 |
|
40 |
keyword_string (keyword kw) |
41 |
: s(keyword_str [kw]), l(keyword_len [kw]) |
42 |
{ |
43 |
} |
44 |
|
45 |
keyword_string (shstr_tmp sh) |
46 |
: s(&sh), l(sh.length ()) |
47 |
{ |
48 |
} |
49 |
}; |
50 |
|
51 |
#define CS(keyword) keyword_string (# keyword, sizeof (# keyword) - 1) |
52 |
#define KW(keyword) CS(keyword) |
53 |
|
54 |
INTERFACE_CLASS(object_freezer) |
55 |
struct object_freezer : dynbuf_text |
56 |
{ |
57 |
AV *av; |
58 |
|
59 |
object_freezer (); |
60 |
~object_freezer (); |
61 |
|
62 |
// serialise perl part |
63 |
void put_ (attachable *ext); |
64 |
void put (attachable *ext) |
65 |
{ |
66 |
if (expect_false (ext->self)) |
67 |
put_ (ext); |
68 |
} |
69 |
|
70 |
// null value (== no space after keyword) |
71 |
void put (const keyword_string k) |
72 |
{ |
73 |
char *p = force (k.l + 1); |
74 |
memcpy (p, k.s, k.l); p += k.l; *p++ = '\n'; |
75 |
alloc (p); |
76 |
} |
77 |
|
78 |
void put (const keyword_string k, const keyword_string v) |
79 |
{ |
80 |
char *p = force (k.l + 1 + v.l + 1); |
81 |
memcpy (p, k.s, k.l); p += k.l; *p++ = ' '; |
82 |
memcpy (p, v.s, v.l); p += v.l; *p++ = '\n'; |
83 |
alloc (p); |
84 |
} |
85 |
|
86 |
void put (const keyword_string k, const_utf8_string v) |
87 |
{ |
88 |
if (expect_true (v)) |
89 |
put (k, keyword_string (v, strlen (v))); |
90 |
else |
91 |
put (k); |
92 |
} |
93 |
|
94 |
void put (const keyword_string k, shstr_tmp v) |
95 |
{ |
96 |
put (k, keyword_string (v)); |
97 |
} |
98 |
|
99 |
void put (const keyword_string k, double v) |
100 |
{ |
101 |
char *p = force (MAX_KEYWORD_LEN + 2 + 32); |
102 |
memcpy (p, k.s, k.l); p += k.l; *p++ = ' '; |
103 |
p += sprintf (p, "%.7g", v); *p++ = '\n'; |
104 |
alloc (p); |
105 |
} |
106 |
|
107 |
void put_(const keyword_string k, sint64 v) |
108 |
{ |
109 |
force (MAX_KEYWORD_LEN + 2 + sint64_digits); |
110 |
fadd (k.s, k.l); |
111 |
fadd (' '); |
112 |
add (v); |
113 |
fadd ('\n'); |
114 |
} |
115 |
|
116 |
void put_(const keyword_string k, sint32 v) |
117 |
{ |
118 |
force (MAX_KEYWORD_LEN + 2 + sint32_digits); |
119 |
fadd (k.s, k.l); |
120 |
fadd (' '); |
121 |
add (v); |
122 |
fadd ('\n'); |
123 |
} |
124 |
|
125 |
void put (const keyword_string k, float v) { put (k, (double)v); } |
126 |
void put (const keyword_string k, signed char v) { put_(k, (sint32)v); } |
127 |
void put (const keyword_string k, unsigned char v) { put_(k, (sint32)v); } |
128 |
void put (const keyword_string k, signed short v) { put_(k, (sint32)v); } |
129 |
void put (const keyword_string k, unsigned short v) { put_(k, (sint32)v); } |
130 |
void put (const keyword_string k, signed int v) { put_(k, (sint32)v); } |
131 |
void put (const keyword_string k, unsigned int v) { put_(k, (sint64)v); } |
132 |
void put (const keyword_string k, signed long v) { put_(k, (sint64)v); } |
133 |
void put (const keyword_string k, unsigned long v) { put_(k, (sint64)v); } |
134 |
void put (const keyword_string k, signed long long v) { put_(k, (sint64)v); } |
135 |
void put (const keyword_string k, unsigned long long v) { put_(k, (sint64)v); } |
136 |
|
137 |
void put (const keyword_string kbeg, const keyword_string kend, shstr_tmp v) |
138 |
{ |
139 |
force (MAX_KEYWORD_LEN + 1); |
140 |
fadd (kbeg.s, kbeg.l); fadd ('\n'); |
141 |
|
142 |
if (expect_true (v)) |
143 |
{ |
144 |
add (v); |
145 |
add ('\n'); |
146 |
} |
147 |
|
148 |
force (MAX_KEYWORD_LEN + 1); |
149 |
fadd (kend.s, kend.l); fadd ('\n'); |
150 |
} |
151 |
|
152 |
void put (const keyword_string k, archetype *v); |
153 |
void put (const keyword_string k, treasurelist *v); |
154 |
void put (const keyword_string k, faceinfo *v); |
155 |
|
156 |
template<typename T> |
157 |
void put (const keyword_string k, const refptr<T> &v) |
158 |
{ |
159 |
put (k, (T *)v); |
160 |
} |
161 |
|
162 |
MTH bool save (const_octet_string path); |
163 |
utf8_string as_string (); // like strdup |
164 |
|
165 |
operator bool () { return !!av; } |
166 |
}; |
167 |
|
168 |
INTERFACE_CLASS(object_thawer) |
169 |
struct object_thawer |
170 |
{ |
171 |
char *line; // current beginning of line |
172 |
SV *text; // text part |
173 |
AV *av; // perl part |
174 |
int linenum; |
175 |
keyword kw; |
176 |
char *kw_str; // the keyword parsed, as string |
177 |
char *value; // the value, or 0 if no value |
178 |
const char *value_nn; // the value, or the empty string if no value |
179 |
const char *name; |
180 |
|
181 |
operator bool () const { return !!text; } |
182 |
|
183 |
object_thawer (const_utf8_string path = 0); |
184 |
object_thawer (const_utf8_string data, AV *perlav); |
185 |
~object_thawer (); |
186 |
|
187 |
void get (attachable *obj, int oid); |
188 |
|
189 |
// parse next line as keyword-value pair |
190 |
MTH void next (); |
191 |
|
192 |
// parse next line, as a single value |
193 |
// skips initial whitespace and comments |
194 |
// and sets kw to KW_value on success. |
195 |
MTH bool next_line (); |
196 |
|
197 |
// skip the current key-value (usually fetch next line, for |
198 |
// multiline-fields, skips till the corresponding end-kw |
199 |
MTH void skip (); |
200 |
MTH void skip_block (); // skips till and over KW_end |
201 |
|
202 |
bool has_value () { return value; } |
203 |
const_utf8_string get_str () { return value_nn; } // empty string when missing |
204 |
void get_ml (keyword kend, shstr &sh); |
205 |
|
206 |
void get_ornull (shstr &sh) const { sh = value; } |
207 |
void get (shstr &sh) const { sh = value; } // might want to check for non-null here |
208 |
|
209 |
bool get_bool () const { return *value_nn == '1'; } |
210 |
sint32 get_sint32 () const; |
211 |
sint64 get_sint64 () const { return strtoll (value_nn, 0, 10); } |
212 |
double get_double () const { return strtod (value_nn, 0); } |
213 |
|
214 |
void get (float &v) { v = get_double (); } |
215 |
void get (double &v) { v = get_double (); } |
216 |
|
217 |
void get (bool &i) { i = get_bool (); } |
218 |
void get (sint8 &i) { i = get_sint32 (); } |
219 |
void get (uint8 &i) { i = get_sint32 (); } |
220 |
void get (sint16 &i) { i = get_sint32 (); } |
221 |
void get (uint16 &i) { i = get_sint32 (); } |
222 |
void get (sint32 &i) { i = get_sint32 (); } |
223 |
|
224 |
void get (uint32 &i) { i = get_sint64 (); } |
225 |
void get (sint64 &i) { i = get_sint64 (); } |
226 |
|
227 |
MTH void parse_warn (const_utf8_string msg); |
228 |
MTH bool parse_error (const_utf8_string type = 0, const_utf8_string name = 0, bool skip = true); |
229 |
|
230 |
struct delayed_ref { |
231 |
attachable *op; |
232 |
object_ptr *ptr; |
233 |
const_utf8_string ref; |
234 |
}; |
235 |
std::vector<delayed_ref> delrefs; |
236 |
|
237 |
void delayed_deref (attachable *op, object_ptr &ptr, const_utf8_string ref); |
238 |
MTH void resolve_delayed_derefs (bool deref = true); |
239 |
}; |
240 |
|
241 |
#endif |
242 |
|