X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=ext%2Fcomments.c;h=fb3ae82f653d727d751cc9975626caabfb1b5f8c;hb=de09557fdbeb5648cc66ea5fca28b3d769003ee8;hp=98dd73c4e04b34ccf1876102bab67f2be59bcacc;hpb=310e91e26bebf168b6081e91da123b4a8cfb9b67;p=ruby-vorbistagger.git diff --git a/ext/comments.c b/ext/comments.c index 98dd73c..fb3ae82 100644 --- a/ext/comments.c +++ b/ext/comments.c @@ -17,38 +17,29 @@ */ #include +#include #include #include #include #include "vcedit.h" -typedef struct { - vcedit_state *state; - - VALUE items; -} RbVorbisComments; - static ID id_casecmp, id_replace, id_compare; void comments_init (VALUE self, vcedit_state *state) { - RbVorbisComments *o; + VALUE items; vorbis_comment *vc; int i; - Data_Get_Struct (self, RbVorbisComments, o); - - o->state = state; - vcedit_state_ref (state); + vc = vcedit_comments (state); - vc = vcedit_comments (o->state); - - o->items = rb_ary_new2 (vc->comments); + items = rb_iv_get (self, "items"); + rb_ary_clear (items); for (i = 0; i < vc->comments; i++) { - VALUE k, v; + VALUE k, v, pair; char *ptr, *content = vc->user_comments[i]; ptr = strchr (content, '='); @@ -59,29 +50,26 @@ comments_init (VALUE self, vcedit_state *state) v = rb_str_new2 (ptr + 1); - rb_ary_store (o->items, i, - rb_ary_new3 (2, k, v)); - } + pair = rb_ary_new3 (2, k, v); + OBJ_FREEZE (pair); - rb_iv_set (self, "@items", o->items); + rb_ary_store (items, i, pair); + } } void -comments_sync (VALUE self) +comments_sync (VALUE self, vcedit_state *state) { - RbVorbisComments *o; vorbis_comment *vc; struct RArray *items; int i; - Data_Get_Struct (self, RbVorbisComments, o); - - vc = vcedit_comments (o->state); + vc = vcedit_comments (state); vorbis_comment_clear (vc); vorbis_comment_init (vc); - items = RARRAY (o->items); + items = RARRAY (rb_iv_get (self, "items")); for (i = 0; i < items->len; i++) { struct RArray *pair = RARRAY (items->ptr[i]); @@ -91,27 +79,18 @@ comments_sync (VALUE self) StringValuePtr (pair->ptr[1])); } } - -static void -c_mark (RbVorbisComments *o) -{ - rb_gc_mark (o->items); -} - -static void -c_free (RbVorbisComments *o) -{ - vcedit_state_unref (o->state); - - ruby_xfree (o); -} - +/* + * call-seq: + * Ogg::Vorbis::Comments.new -> object + * + * Creates an Ogg::Vorbis::Comments object. + */ static VALUE -c_alloc (VALUE klass) +c_init (VALUE self) { - RbVorbisComments *o; + rb_iv_set (self, "items", rb_ary_new ()); - return Data_Make_Struct (klass, RbVorbisComments, c_mark, c_free, o); + return self; } /* @@ -124,13 +103,10 @@ static VALUE c_inspect (VALUE self) { VALUE ret; - RbVorbisComments *o; struct RArray *items; int i; - Data_Get_Struct (self, RbVorbisComments, o); - - items = RARRAY (o->items); + items = RARRAY (rb_iv_get (self, "items")); ret = rb_str_buf_new (128); rb_str_buf_cat (ret, "{", 1); @@ -138,12 +114,12 @@ c_inspect (VALUE self) for (i = 0; i < items->len; i++) { struct RArray *pair = RARRAY (items->ptr[i]); + if (i) + rb_str_buf_cat (ret, ", ", 2); + rb_str_buf_append (ret, rb_inspect (pair->ptr[0])); rb_str_buf_cat (ret, "=>", 2); rb_str_buf_append (ret, rb_inspect (pair->ptr[1])); - - if (i < items->len - 1) - rb_str_buf_cat (ret, ", ", 2); } rb_str_buf_cat (ret, "}", 1); @@ -160,11 +136,7 @@ c_inspect (VALUE self) static VALUE c_clear (VALUE self) { - RbVorbisComments *o; - - Data_Get_Struct (self, RbVorbisComments, o); - - rb_ary_clear (o->items); + rb_ary_clear (rb_iv_get (self, "items")); return self; } @@ -180,13 +152,10 @@ static VALUE c_delete (VALUE self, VALUE key) { VALUE ret = Qnil; - RbVorbisComments *o; struct RArray *items; int i, pos = -1; - Data_Get_Struct (self, RbVorbisComments, o); - - items = RARRAY (o->items); + items = RARRAY (rb_iv_get (self, "items")); for (i = 0; i < items->len; i++) { struct RArray *pair = RARRAY (items->ptr[i]); @@ -201,7 +170,7 @@ c_delete (VALUE self, VALUE key) } if (pos != -1) - rb_ary_delete_at (o->items, pos); + rb_ary_delete_at (rb_iv_get (self, "items"), pos); return ret; } @@ -216,13 +185,10 @@ static VALUE c_keys (VALUE self) { VALUE ret; - RbVorbisComments *o; struct RArray *items; int i; - Data_Get_Struct (self, RbVorbisComments, o); - - items = RARRAY (o->items); + items = RARRAY (rb_iv_get (self, "items")); ret = rb_ary_new2 (items->len); for (i = 0; i < items->len; i++) { @@ -244,13 +210,10 @@ static VALUE c_values (VALUE self) { VALUE ret; - RbVorbisComments *o; struct RArray *items; int i; - Data_Get_Struct (self, RbVorbisComments, o); - - items = RARRAY (o->items); + items = RARRAY (rb_iv_get (self, "items")); ret = rb_ary_new2 (items->len); for (i = 0; i < items->len; i++) { @@ -271,11 +234,11 @@ c_values (VALUE self) static VALUE c_length (VALUE self) { - RbVorbisComments *o; + struct RArray *items; - Data_Get_Struct (self, RbVorbisComments, o); + items = RARRAY (rb_iv_get (self, "items")); - return LONG2NUM (RARRAY (o->items)->len); + return LONG2NUM (items->len); } /* @@ -287,11 +250,11 @@ c_length (VALUE self) static VALUE c_get_empty (VALUE self) { - RbVorbisComments *o; + struct RArray *items; - Data_Get_Struct (self, RbVorbisComments, o); + items = RARRAY (rb_iv_get (self, "items")); - return !RARRAY(o->items)->len; + return items->len ? Qfalse : Qtrue; } /* @@ -304,13 +267,10 @@ c_get_empty (VALUE self) static VALUE c_aref (VALUE self, VALUE key) { - RbVorbisComments *o; struct RArray *items; int i; - Data_Get_Struct (self, RbVorbisComments, o); - - items = RARRAY (o->items); + items = RARRAY (rb_iv_get (self, "items")); for (i = 0; i < items->len; i++) { struct RArray *pair = RARRAY (items->ptr[i]); @@ -333,13 +293,11 @@ c_aref (VALUE self, VALUE key) static VALUE c_aset (VALUE self, VALUE key, VALUE value) { - RbVorbisComments *o; + VALUE tmp; struct RArray *items; int i; - Data_Get_Struct (self, RbVorbisComments, o); - - items = RARRAY (o->items); + items = RARRAY (rb_iv_get (self, "items")); for (i = 0; i < items->len; i++) { struct RArray *pair = RARRAY (items->ptr[i]); @@ -352,7 +310,10 @@ c_aset (VALUE self, VALUE key, VALUE value) } } - rb_ary_push (o->items, rb_ary_new3 (2, key, value)); + tmp = rb_ary_new3 (2, rb_str_dup_frozen (key), value); + OBJ_FREEZE (tmp); + + rb_ary_push (rb_iv_get (self, "items"), tmp); return value; } @@ -367,13 +328,10 @@ c_aset (VALUE self, VALUE key, VALUE value) static VALUE c_has_key (VALUE self, VALUE key) { - RbVorbisComments *o; struct RArray *items; int i; - Data_Get_Struct (self, RbVorbisComments, o); - - items = RARRAY (o->items); + items = RARRAY (rb_iv_get (self, "items")); for (i = 0; i < items->len; i++) { struct RArray *pair = RARRAY (items->ptr[i]); @@ -387,6 +345,45 @@ c_has_key (VALUE self, VALUE key) return Qfalse; } +static int +merge_cb (VALUE key, VALUE value, VALUE self) +{ + c_aset (self, key, value); + + return ST_CONTINUE; +} + +/* + * call-seq: + * object.merge!(hash) -> object + * + * Adds the key-value pairs from *hash* to *object*, overwriting existing + * values if a key already existed in *object*. + */ +static VALUE +c_merge (VALUE self, VALUE hash) +{ + Check_Type (hash, T_HASH); + + rb_hash_foreach (hash, merge_cb, self); + + return self; +} + +/* + * call-seq: + * object.shift(hash) -> array or nil + * + * Removes the first key-value pair from *object* and returns it + * as the two-item array [key, value]. + * If *object* is empty, +nil+ is returned. + */ +static VALUE +c_shift (VALUE self) +{ + return rb_ary_shift (rb_iv_get (self, "items")); +} + /* * call-seq: * object <=> other -> -1, 0 or 1 @@ -397,18 +394,14 @@ c_has_key (VALUE self, VALUE key) static VALUE c_compare (VALUE self, VALUE other) { - RbVorbisComments *o, *o2; struct RArray *a, *b; int i, j; if (rb_obj_is_kind_of (other, CLASS_OF (self)) != Qtrue) rb_raise (rb_eArgError, "invalid argument"); - Data_Get_Struct (self, RbVorbisComments, o); - Data_Get_Struct (other, RbVorbisComments, o2); - - a = RARRAY (o->items); - b = RARRAY (o2->items); + a = RARRAY (rb_iv_get (self, "items")); + b = RARRAY (rb_iv_get (other, "items")); if (a->len < b->len) return -1; @@ -443,13 +436,10 @@ c_compare (VALUE self, VALUE other) static VALUE c_each (VALUE self) { - RbVorbisComments *o; struct RArray *items; int i; - Data_Get_Struct (self, RbVorbisComments, o); - - items = RARRAY (o->items); + items = RARRAY (rb_iv_get (self, "items")); for (i = 0; i < items->len; i++) { struct RArray *pair = RARRAY (items->ptr[i]); @@ -471,13 +461,10 @@ c_each (VALUE self) static VALUE c_each_key (VALUE self) { - RbVorbisComments *o; struct RArray *items; int i; - Data_Get_Struct (self, RbVorbisComments, o); - - items = RARRAY (o->items); + items = RARRAY (rb_iv_get (self, "items")); for (i = 0; i < items->len; i++) { struct RArray *pair = RARRAY (items->ptr[i]); @@ -498,13 +485,10 @@ c_each_key (VALUE self) static VALUE c_each_value (VALUE self) { - RbVorbisComments *o; struct RArray *items; int i; - Data_Get_Struct (self, RbVorbisComments, o); - - items = RARRAY (o->items); + items = RARRAY (rb_iv_get (self, "items")); for (i = 0; i < items->len; i++) { struct RArray *pair = RARRAY (items->ptr[i]); @@ -522,8 +506,7 @@ Init_Comments (VALUE mVorbis) c = rb_define_class_under (mVorbis, "Comments", rb_cObject); - rb_define_alloc_func (c, c_alloc); - + rb_define_method (c, "initialize", c_init, 0); rb_define_method (c, "inspect", c_inspect, 0); rb_define_method (c, "clear", c_clear, 0); rb_define_method (c, "delete", c_delete, 1); @@ -534,6 +517,8 @@ Init_Comments (VALUE mVorbis) rb_define_method (c, "empty?", c_get_empty, 0); rb_define_method (c, "keys", c_keys, 0); rb_define_method (c, "values", c_values, 0); + rb_define_method (c, "merge!", c_merge, 1); + rb_define_method (c, "shift", c_shift, 0); rb_include_module (c, rb_mComparable); rb_define_method (c, "<=>", c_compare, 1); @@ -545,6 +530,9 @@ Init_Comments (VALUE mVorbis) rb_define_alias (c, "size", "length"); rb_define_alias (c, "each_pair", "each"); + rb_define_alias (c, "key?", "has_key?"); + rb_define_alias (c, "include?", "has_key?"); + rb_define_alias (c, "member?", "has_key?"); id_casecmp = rb_intern ("casecmp"); id_replace = rb_intern ("replace");