7 #define st_delete STUPID_PROTOTYPING_st_delete
8 #define st_insert STUPID_PROTOTYPING_st_insert
13 int st_delete( register st_table
*, register char **, char **value
);
14 int st_insert( register st_table
*, register char *, char * );
18 extern "C" char *strndup(const char *s
, size_t n
);
29 bool emitter::anchor_handled(serialize
*s
)
31 if (anchors
.find(s
) != anchors
.end()) {
32 yll_emitter_alias(e
, anchors
[s
]);
36 anchors
[s
] = yll_emitter_anchor(e
);
40 void serialize::collect_references(refset
& refs
)
45 void serialize::free()
48 collect_references(references
);
50 for (i
= references
.begin(); i
!= references
.end(); ++i
) {
56 SyckNode
* serialize::bad_anchor_handler(SyckParser
*p
, char *a
)
58 SyckNode
* n
= syck_new_str(a
, scalar_none
);
59 serialize_p s
= new bad_anchor();
61 anchor_map
*anchors
= (anchor_map
*) p
->bonus
;
63 n
->id
= syck_add_sym(p
, (char *)s
);
65 anchors
->add(s
, n
->id
);
70 // We may need to replace inside the replacers as well XXX
71 serialize
* anchor_map::replace(SYMID id
, serialize
*replacement
)
74 st_delete( p
->syms
, (char **)&id
, (char **)&orig
);
75 assert(anchors
[orig
].first
== id
);
77 vector
<replacer_base
*> & replacements
= anchors
[orig
].second
;
78 anchors
[replacement
].first
= id
;
79 vector
<replacer_base
*> & new_replacements
= anchors
[replacement
].second
;
80 for (int i
=0; i
< replacements
.size(); ++i
) {
81 replacements
[i
]->with(replacement
);
82 new_replacements
.push_back(replacements
[i
]);
85 st_insert( p
->syms
, (char *)id
, (char *)replacement
);
89 anchor_map::~anchor_map()
91 map
<serialize
*, rep_pair
>::iterator i
;
92 for (i
= anchors
.begin(); i
!= anchors
.end(); ++i
) {
93 for (int j
=0; j
< i
->second
.second
.size(); ++j
) {
94 delete i
->second
.second
[j
];
99 SYMID
serialize::syck_handler(SyckParser
*p
, SyckNode
*n
)
102 anchor_map
*anchors
= (anchor_map
*) p
->bonus
;
105 if (s_desc().find(string(n
->type_id
)) != s_desc().end())
106 s
= (s_desc())[n
->type_id
]->create(anchors
->user
);
111 s
= str::create(anchors
->user
);
117 s
= seq
<serialize
>::create();
124 SYMID id
= (n
->id
== 0) ? syck_add_sym(p
, (char *)s
) : 0;
126 if (id
&& n
->anchor
) {
135 serialize
*anchor
= anchors
->replace(n
->id
, s
);
143 serialize
*serialize::Load(SyckParser
*parser
, const type_info
*type
,
147 serialize_p y
= NULL
;
149 anchor_map
anchors(parser
, user
);
150 parser
->bonus
= &anchors
;
151 syck_parser_handler(parser
, syck_handler
);
152 syck_parser_bad_anchor_handler(parser
, bad_anchor_handler
);
153 syck_parser_implicit_typing( parser
, 1 );
154 v
= syck_parse(parser
);
155 syck_lookup_sym(parser
, v
, (char **)&y
);
158 if (*type
!= typeid(*y
)) {
159 description
*desc
= t_desc()[type
];
161 y
= desc
->convert(&anchors
, y
, type
);
165 syck_free_parser(parser
);
170 serialize_p
serialize::Load(char *str
, const type_info
*type
, void *user
)
172 SyckParser
*parser
= syck_new_parser();
173 syck_parser_str_auto(parser
, str
, NULL
);
174 return Load(parser
, type
, user
);
177 serialize_p
Load(char *str
, const type_info
*type
, void *user
)
179 return serialize::Load(str
, type
, user
);
182 serialize_p
serialize::Load(FILE *fp
, const type_info
*type
, void *user
)
184 SyckParser
*parser
= syck_new_parser();
185 syck_parser_file(parser
, fp
, NULL
);
186 return Load(parser
, type
, user
);
189 serialize_p
Load(FILE *fp
, const type_info
*type
, void *user
)
191 return serialize::Load(fp
, type
, user
);
194 void serialize::syck_output_handler(YllEmitter
*p
, char *s
, long len
)
198 void serialize::Dump(FILE *out
)
202 collect_references(e
.refs
);
203 yll_emitter_handler(e
.e
, syck_output_handler
);
207 void serialize::register_type(const char * type
, const type_info
*ti
,
214 void str::register_type()
216 static description str_d
= { create
, NULL
, &typeid(str
) };
217 serialize::register_type("str", &typeid(str
), &str_d
);
218 serialize::register_type("int", &typeid(str
), &str_d
);
221 serialize
*str::create(void *user
)
226 void str::init(SyckParser
*p
, SyckNode
*n
)
228 s
= string(n
->data
.str
->ptr
, n
->data
.str
->len
);
231 at_init
register_str(str::register_type
);
233 void integer::register_type()
235 static description integer_d
= { create
, NULL
, &typeid(integer
) };
236 integer_d
.convert
= convert
;
237 serialize::register_type("integer", &typeid(integer
), &integer_d
);
240 serialize
*integer::create(void *user
)
245 void integer::init(SyckParser
*p
, SyckNode
*n
)
247 char *s
= strndup(n
->data
.str
->ptr
, n
->data
.str
->len
);
252 serialize_p
integer::convert (anchor_map
* am
, serialize
* s
, const type_info
*type
)
254 str
*st
= dynamic_cast<str
*>(s
);
259 i
->v
= atoi(st
->s
.c_str());
267 at_init
register_integer(integer::register_type
);
269 serialize_p
dict::create()
275 static void dict_init(sermap
& d
, SyckParser
*p
, SyckNode
*n
)
277 anchor_map
*anchors
= (anchor_map
*) p
->bonus
;
278 for (int i
= 0; i
< n
->data
.pairs
->idx
; i
++) {
281 SYMID oidk
= syck_map_read( n
, map_key
, i
);
282 syck_lookup_sym( p
, oidk
, (char **)&key
);
283 SYMID oidv
= syck_map_read( n
, map_value
, i
);
284 syck_lookup_sym( p
, oidv
, (char **)&val
);
288 // In a second iteration, since we wouldn't want the
289 // memory locations to change for the replacer
290 map
<string
,serialize_p
>::iterator i
;
291 for (i
= d
.begin(); i
!= d
.end(); ++i
) {
292 if (anchors
->is_anchor(i
->second
)) {
293 anchors
->replace(i
->second
, new replacer
<serialize
>(i
->second
));
298 void dict::init(SyckParser
*p
, SyckNode
*n
)
300 d
= new map
<string
,serialize_p
>;
304 static void dict_collect(sermap
& d
, refset
& refs
)
306 map
<string
,serialize_p
>::iterator i
;
307 for (i
= d
.begin(); i
!= d
.end(); ++i
) {
308 serialize
*el
= i
->second
;
309 if (refs
.find(el
) == refs
.end())
310 el
->collect_references(refs
);
316 void dict::collect_references(refset
& refs
)
318 serialize::collect_references(refs
);
319 dict_collect(*d
, refs
);
322 static void dict_dump(sermap
& d
, emitter
& e
)
324 map
<string
,serialize_p
>::iterator i
;
325 for (i
= d
.begin(); i
!= d
.end(); ++i
) {
326 yll_emitter_write_string(e
.e
, i
->first
.c_str());
330 yll_emitter_write_null(e
.e
);
334 void dict::dump(emitter
& e
)
336 yll_emitter_start_map(e
.e
);
338 yll_emitter_end_map(e
.e
);
341 void structure::init(SyckParser
*p
, SyckNode
*n
)
345 d
= new map
<string
,serialize_p
>;
347 anchor_map
*anchors
= (anchor_map
*) p
->bonus
;
348 fill_fields(anchors
);
353 void structure::fill_fields(anchor_map
*am
)
355 struct_description
* sd
= (struct_description
*)(t_desc())[&typeid(*this)];
357 map
<string
,serialize_p
>::iterator i
;
358 for (i
= d
->begin(); i
!= d
->end(); ) {
359 map
<string
,serialize_p
>::iterator j
= i
++;
360 if (sd
->m
.find(j
->first
) != sd
->m
.end()) {
361 serialize
*el
= j
->second
;
363 if (sd
->m
[j
->first
]->set(am
, this, j
->second
))
369 serialize_p
structure::convert (anchor_map
* am
,
370 serialize
* s
, const type_info
*type
)
372 dict
* d
= dynamic_cast<dict
*>(s
);
373 structure
* c
= NULL
;
376 c
= dynamic_cast<structure
*>(t_desc()[type
]->create(am
->user
));
377 assert(t_desc().find(type
) != t_desc().end());
379 if (am
->is_anchor(s
)) {
380 serialize
*anchor
= am
->replace(s
, c
);
395 void structure::collect_references(refset
& refs
)
397 serialize::collect_references(refs
);
399 dict_collect(*d
, refs
);
400 struct_description
* sd
= (struct_description
*)(t_desc())[&typeid(*this)];
401 fieldmap::iterator j
;
402 for (j
= sd
->m
.begin(); j
!= sd
->m
.end(); ++j
) {
403 sd
->m
[j
->first
]->collect(this, refs
);
407 void structure::dump(emitter
& e
)
409 yll_emitter_start_map(e
.e
);
411 struct_description
* sd
= (struct_description
*)(t_desc())[&typeid(*this)];
412 fieldmap::iterator j
;
413 for (j
= sd
->m
.begin(); j
!= sd
->m
.end(); ++j
) {
414 if (sd
->m
[j
->first
]->is_empty(this))
417 yll_emitter_write_string(e
.e
, j
->first
.c_str());
418 sd
->m
[j
->first
]->dump(this, e
);
423 yll_emitter_end_map(e
.e
);
426 void structure::register_type(const char * type
, const type_info
*ti
,
430 c
->convert
= convert
;
432 serialize::register_type(type
, ti
, c
);
435 bool ptr_field::set(anchor_map
*am
, structure
* c
, serialize
*& el
)
437 map
<const type_info
*, description
*>& desc
= serialize::t_desc();
438 serialize
* new_el
= el
;
440 if (*desc
[type
]->type
!= typeid(*el
))
441 new_el
= desc
[type
]->convert(am
, el
, type
);
445 if (am
->is_anchor(el
)) {
446 am
->replace(el
, new replacer_base(el
),
447 new replacer
<serialize
>((c
->*pos
)));
454 void ptr_field::collect(structure
* c
, refset
& refs
)
456 serialize
*el
= c
->*pos
;
460 if (refs
.find(el
) == refs
.end())
461 el
->collect_references(refs
);
466 void ptr_field::dump(structure
* c
, emitter
& e
)
468 serialize
*el
= c
->*pos
;
472 yll_emitter_write_null(e
.e
);
475 bool int_field::set(anchor_map
*am
, structure
* c
, serialize
*& el
)
477 c
->*pos
= atoi(((str
*)el
)->s
.c_str());
483 void int_field::collect(structure
* c
, refset
& refs
)
487 void int_field::dump(structure
* c
, emitter
& e
)
489 yll_emitter_write_int(e
.e
, c
->*pos
);