rb_cObject
YAML::Syck::Resolver#add_type
VALUE
syck_resolver_add_type(VALUE self, VALUE taguri, VALUE cls)
{
VALUE tags = rb_attr_get(self, s_tags);
rb_hash_aset( tags, taguri, cls );
return Qnil;
}
YAML::Syck::Resolver#detect_implicit
VALUE
syck_resolver_detect_implicit(VALUE self, VALUE val)
{
return rb_str_new2( "" );
}
YAML::Syck::Resolver#node_import
VALUE
syck_resolver_node_import(VALUE self, VALUE node)
{
SyckNode *n;
VALUE obj = Qnil;
int i = 0;
Data_Get_Struct(node, SyckNode, n);
switch (n->kind)
{
case syck_str_kind:
obj = rb_str_new( n->data.str->ptr, n->data.str->len );
break;
case syck_seq_kind:
obj = rb_ary_new2( n->data.list->idx );
for ( i = 0; i < n->data.list->idx; i++ )
{
rb_ary_store( obj, i, syck_seq_read( n, i ) );
}
break;
case syck_map_kind:
obj = rb_hash_new();
for ( i = 0; i < n->data.pairs->idx; i++ )
{
VALUE k = syck_map_read( n, map_key, i );
VALUE v = syck_map_read( n, map_value, i );
int skip_aset = 0;
/*
* Handle merge keys
*/
if ( rb_obj_is_kind_of( k, cMergeKey ) )
{
if ( rb_obj_is_kind_of( v, rb_cHash ) )
{
VALUE dup = rb_funcall( v, s_dup, 0 );
rb_funcall( dup, s_update, 1, obj );
obj = dup;
skip_aset = 1;
}
else if ( rb_obj_is_kind_of( v, rb_cArray ) )
{
VALUE end = rb_ary_pop( v );
if ( rb_obj_is_kind_of( end, rb_cHash ) )
{
VALUE dup = rb_funcall( end, s_dup, 0 );
v = rb_ary_reverse( v );
rb_ary_push( v, obj );
rb_block_call( v, s_each, 0, 0, syck_merge_i, dup );
obj = dup;
skip_aset = 1;
}
}
}
else if ( rb_obj_is_kind_of( k, cDefaultKey ) )
{
rb_funcall( obj, s_default_set, 1, v );
skip_aset = 1;
}
if ( ! skip_aset )
{
rb_hash_aset( obj, k, v );
}
}
break;
}
if ( n->type_id != NULL )
{
obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj );
}
return obj;
}
YAML::Syck::Resolver#tagurize
VALUE
syck_resolver_tagurize(VALUE self, VALUE val)
{
VALUE tmp = rb_check_string_type(val);
if ( !NIL_P(tmp) )
{
char *taguri = syck_type_id_to_uri( RSTRING_PTR(tmp) );
val = rb_str_new2( taguri );
S_FREE( taguri );
}
return val;
}
YAML::Syck::Resolver#transfer
VALUE
syck_resolver_transfer(VALUE self, VALUE type, VALUE val)
{
if (NIL_P(type) || RSTRING_LEN(StringValue(type)) == 0)
{
type = rb_funcall( self, s_detect_implicit, 1, val );
}
if ( ! (NIL_P(type) || RSTRING_LEN(StringValue(type)) == 0) )
{
VALUE str_xprivate = rb_str_new2( "x-private" );
VALUE colon = rb_str_new2( ":" );
VALUE tags = rb_attr_get(self, s_tags);
VALUE target_class = rb_hash_aref( tags, type );
VALUE subclass = target_class;
VALUE obj = Qnil;
/*
* Should no tag match exactly, check for subclass format
*/
if ( NIL_P( target_class ) )
{
VALUE subclass_parts = rb_ary_new();
VALUE parts = rb_str_split( type, ":" );
while ( RARRAY_LEN(parts) > 1 )
{
VALUE partial;
rb_ary_unshift( subclass_parts, rb_ary_pop( parts ) );
partial = rb_ary_join( parts, colon );
target_class = rb_hash_aref( tags, partial );
if ( NIL_P( target_class ) )
{
rb_str_append( partial, colon );
target_class = rb_hash_aref( tags, partial );
}
/*
* Possible subclass found, see if it supports subclassing
*/
if ( ! NIL_P( target_class ) )
{
subclass = target_class;
if ( RARRAY_LEN(subclass_parts) > 0 && rb_respond_to( target_class, s_tag_subclasses ) &&
RTEST( rb_funcall( target_class, s_tag_subclasses, 0 ) ) )
{
VALUE subclass_v;
subclass = rb_ary_join( subclass_parts, colon );
subclass = rb_funcall( target_class, s_tag_read_class, 1, subclass );
subclass_v = syck_const_find( subclass );
if ( subclass_v != Qnil )
{
subclass = subclass_v;
}
else if ( rb_cObject == target_class && subclass_v == Qnil )
{
target_class = cYObject;
type = subclass;
subclass = cYObject;
}
else /* workaround for SEGV. real fix please */
{
rb_raise( rb_eTypeError, "invalid subclass" );
}
}
break;
}
}
}
/* rb_raise(rb_eTypeError, "invalid typing scheme: %s given",
* scheme);
*/
if ( rb_respond_to( target_class, s_call ) )
{
obj = rb_funcall( target_class, s_call, 2, type, val );
}
else
{
if ( rb_respond_to( target_class, s_yaml_new ) )
{
obj = rb_funcall( target_class, s_yaml_new, 3, subclass, type, val );
}
else if ( !NIL_P( target_class ) )
{
if ( subclass == rb_cBignum )
{
obj = rb_str2inum( val, 10 ); /* for yaml dumped by 1.8.3 [ruby-core:6159] */
}
else
{
obj = rb_obj_alloc( subclass );
}
if ( rb_respond_to( obj, s_yaml_initialize ) )
{
rb_funcall( obj, s_yaml_initialize, 2, type, val );
}
else if ( !NIL_P( obj ) && rb_obj_is_instance_of( val, rb_cHash ) )
{
rb_block_call( val, s_each, 0, 0, syck_set_ivars, obj );
}
}
else
{
VALUE parts = rb_str_split( type, ":" );
VALUE scheme = rb_ary_shift( parts );
if ( rb_str_cmp( scheme, str_xprivate ) == 0 )
{
VALUE name = rb_ary_join( parts, colon );
obj = rb_funcall( cPrivateType, s_new, 2, name, val );
}
else
{
VALUE domain = rb_ary_shift( parts );
VALUE name = rb_ary_join( parts, colon );
obj = rb_funcall( cDomainType, s_new, 3, domain, name, val );
}
}
}
val = obj;
}
return val;
}