From 37e4ca938b10acde659f03f69035dda34c49f437 Mon Sep 17 00:00:00 2001 From: guy Decoux Date: Sat, 28 Feb 2009 20:04:27 +0100 Subject: mmap-0.1.3 --- Changes | 7 +++ b.rb | 1 + extconf.rb | 13 +++++ mmap.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++-------------- mmap.html | 15 +++++ mmap.rd | 10 ++++ 6 files changed, 190 insertions(+), 41 deletions(-) diff --git a/Changes b/Changes index cc5c763..019dad4 100644 --- a/Changes +++ b/Changes @@ -4,3 +4,10 @@ * fixed some bugs (options & new) (Thanks Joseph McDonald ) * added anonymous map * added mlock, munlock, etc + +-- 0.1.3 + +* added #count, #slice, #slice! +* added #insert, #casecmp (>= 171) +* corrected NEW2LONG + diff --git a/b.rb b/b.rb index 2bc2475..2acbcf2 100755 --- a/b.rb +++ b/b.rb @@ -1,4 +1,5 @@ #!/usr/bin/ruby +$LOAD_PATH.unshift "." require "mmap" PAGESIZE = 4096 f = File.open("aa", "w") diff --git a/extconf.rb b/extconf.rb index 602c79a..32dbd06 100644 --- a/extconf.rb +++ b/extconf.rb @@ -1,2 +1,15 @@ require "mkmf" create_makefile "mmap" +begin + make = open("Makefile", "a") + make.print <<-EOT + +unknown: $(DLLIB) +\t@echo "main() {}" > /tmp/a.c +\t$(CC) -static /tmp/a.c $(OBJS) $(CPPFLAGS) $(DLDFLAGS) -lruby #{CONFIG["LIBS"]} $(LIBS) $(LOCAL_LIBS) +\t@-rm /tmp/a.c a.out + EOT +ensure + make.close +end + diff --git a/mmap.c b/mmap.c index 15027df..b7faae1 100644 --- a/mmap.c +++ b/mmap.c @@ -6,6 +6,7 @@ #include #include #include +#include "version.h" #include @@ -353,7 +354,7 @@ mm_extend(obj, a) mm_mmap *t_mm; GetMmap(obj, t_mm, MM_MODIFY); - mm_realloc(t_mm, t_mm->len + NEW2LONG(a)); + mm_realloc(t_mm, t_mm->len + NUM2LONG(a)); return INT2NUM(t_mm->len); } @@ -438,36 +439,69 @@ mm_madvise(obj, a) return Qnil; } +#define StringMmap(b, bp, bl) \ + do { \ + if (TYPE(b) == T_DATA && rb_obj_is_kind_of(b, mm_cMap)) { \ + mm_mmap *b_mm; \ + \ + GetMmap(b, b_mm, 0); \ + bp = b_mm->addr; \ + bl = b_mm->real; \ + } \ + else { \ + if (TYPE(b) != T_STRING) b = rb_str_to_str(b); \ + bp = RSTRING(b)->ptr; \ + bl = RSTRING(b)->len; \ + } \ + } while (0); + + static void -mm_replace(str, beg, len, val) +mm_update(str, beg, len, val) mm_mmap *str; VALUE val; long beg; long len; { + char *valp; + long vall; + if (str->frozen & MM_FROZEN) rb_error_frozen("mmap"); + if (len < 0) rb_raise(rb_eIndexError, "negative length %d", len); + if (beg < 0) { + beg += str->real; + } + if (beg < 0 || str->real < beg) { + if (beg < 0) { + beg -= str->real; + } + rb_raise(rb_eIndexError, "index %d out of string", beg); + } if (str->real < beg + len) { len = str->real - beg; } - if ((str->frozen & MM_FIXED) && RSTRING(val)->len != len) { + + StringMmap(val, valp, vall); + + if ((str->frozen & MM_FIXED) && vall != len) { rb_raise(rb_eTypeError, "try to change the size of a fixed map"); } - if (len < RSTRING(val)->len) { - mm_realloc(str, str->real+RSTRING(val)->len-len); + if (len < vall) { + mm_realloc(str, str->real + vall - len); } - if (RSTRING(val)->len != len) { - memmove(str->addr + beg + RSTRING(val)->len, + if (vall != len) { + memmove(str->addr + beg + vall, str->addr + beg + len, str->real - (beg + len)); } if (str->real < beg && len < 0) { MEMZERO(str->addr + str->real, char, -len); } - if (RSTRING(val)->len > 0) { - memmove(str->addr+beg, RSTRING(val)->ptr, RSTRING(val)->len); + if (vall > 0) { + memmove(str->addr+beg, valp, vall); } - str->real += RSTRING(val)->len - len; + str->real += vall - len; } static VALUE @@ -720,8 +754,7 @@ mm_aset(str, indx, val) ((char *)t_mm->addr)[idx] = NUM2INT(val) & 0xff; } else { - if (TYPE(val) != T_STRING) val = rb_str_to_str(val); - mm_replace(t_mm, idx, 1, val); + mm_update(t_mm, idx, 1, val); } return val; @@ -737,8 +770,7 @@ mm_aset(str, indx, val) case T_STRING: beg = mm_index(1, &indx, str); if (beg != -1) { - if (TYPE(val) != T_STRING) val = rb_str_to_str(val); - mm_replace(str, beg, RSTRING(indx)->len, val); + mm_update(str, beg, RSTRING(indx)->len, val); } return val; @@ -747,8 +779,7 @@ mm_aset(str, indx, val) { long beg, len; if (rb_range_beg_len(indx, &beg, &len, t_mm->real, 2)) { - if (TYPE(val) != T_STRING) val = rb_str_to_str(val); - mm_replace(t_mm, beg, len, val); + mm_update(t_mm, beg, len, val); return val; } } @@ -772,20 +803,7 @@ mm_aset_m(argc, argv, str) if (TYPE(argv[2]) != T_STRING) argv[2] = rb_str_to_str(argv[2]); beg = NUM2INT(argv[0]); len = NUM2INT(argv[1]); - if (len < 0) rb_raise(rb_eIndexError, "negative length %d", len); - if (beg < 0) { - beg += t_mm->real; - } - if (beg < 0 || t_mm->real < beg) { - if (beg < 0) { - beg -= t_mm->real; - } - rb_raise(rb_eIndexError, "index %d out of string", beg); - } - if (beg + len > t_mm->real) { - len = t_mm->real - beg; - } - mm_replace(t_mm, beg, len, argv[2]); + mm_update(t_mm, beg, len, argv[2]); return argv[2]; } if (argc != 2) { @@ -795,6 +813,48 @@ mm_aset_m(argc, argv, str) } static VALUE +mm_insert(str, idx, str2) + VALUE str, idx, str2; +{ + mm_mmap *t_mm; + long pos = NUM2LONG(idx); + + GetMmap(str, t_mm, MM_MODIFY); + if (pos == -1) { + pos = RSTRING(str)->len; + } + else if (pos < 0) { + pos++; + } + mm_update(t_mm, pos, 0, str2); + return str; +} + +static VALUE mm_aref_m _((int, VALUE *, VALUE)); + +static VALUE +mm_slice_bang(argc, argv, str) + int argc; + VALUE *argv; + VALUE str; +{ + VALUE result; + VALUE buf[3]; + int i; + + if (argc < 1 || 2 < argc) { + rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)", argc); + } + for (i = 0; i < argc; i++) { + buf[i] = argv[i]; + } + buf[i] = rb_str_new(0,0); + result = mm_aref_m(argc, buf, str); + mm_aset_m(argc+1, buf, str); + return result; +} + +static VALUE mm_cat(str, ptr, len) VALUE str; const char *ptr; @@ -879,6 +939,19 @@ mm_strip_bang(str) return str; } + +#define MmapStr(b, recycle) \ +do { \ + recycle = 0; \ + if (TYPE(b) == T_DATA && rb_obj_is_kind_of(b, mm_cMap) == Qtrue) { \ + recycle = 1; \ + b = mm_str(b, MM_ORIGIN); \ + } \ + else { \ + b = rb_str_to_str(b); \ + } \ +} while (0); + static VALUE mm_cmp(a, b) @@ -888,16 +961,32 @@ mm_cmp(a, b) int recycle = 0; a = mm_str(a, MM_ORIGIN); - if (TYPE(b) == T_DATA && rb_obj_is_kind_of(b, mm_cMap) == Qtrue) { - recycle = 1; - b = mm_str(b, MM_ORIGIN); - } + MmapStr(b, recycle); result = rb_str_cmp(a, b); rb_gc_force_recycle(a); if (recycle) rb_gc_force_recycle(b); return INT2FIX(result); } +#if RUBY_VERSION_CODE >= 171 + +static VALUE +mm_casecmp(a, b) + VALUE a, b; +{ + VALUE result; + int recycle = 0; + + a = mm_str(a, MM_ORIGIN); + MmapStr(b, recycle); + result = rb_funcall2(a, rb_intern("casecmp"), 1, &b); + rb_gc_force_recycle(a); + if (recycle) rb_gc_force_recycle(b); + return result; +} + +#endif + static VALUE mm_equal(a, b) VALUE a, b; @@ -906,10 +995,7 @@ mm_equal(a, b) int recycle = 0; a = mm_str(a, MM_ORIGIN); - if (TYPE(b) == T_DATA && rb_obj_is_kind_of(b, mm_cMap) == Qtrue) { - recycle = 1; - b = mm_str(b, MM_ORIGIN); - } + MmapStr(b, recycle); result = rb_funcall2(a, rb_intern("=="), 1, &b); rb_gc_force_recycle(a); if (recycle) rb_gc_force_recycle(b); @@ -1121,7 +1207,7 @@ mm_rindex(argc, argv, obj) } static VALUE -mm_aref(argc, argv, obj) +mm_aref_m(argc, argv, obj) int argc; VALUE *argv, obj; { @@ -1145,6 +1231,14 @@ mm_split(argc, argv, obj) } static VALUE +mm_count(argc, argv, obj) + int argc; + VALUE *argv, obj; +{ + return mm_bang_i(obj, MM_ORIGIN, rb_intern("count"), argc, argv); +} + +static VALUE mm_internal_each(tmp) VALUE *tmp; { @@ -1338,11 +1432,17 @@ Init_mmap() rb_define_method(mm_cMap, "===", mm_equal, 1); rb_define_method(mm_cMap, "eql?", mm_equal, 1); rb_define_method(mm_cMap, "hash", mm_hash, 0); +#if RUBY_VERSION_CODE >= 171 + rb_define_method(mm_cMap, "casecmp", mm_casecmp, 1); +#endif rb_define_method(mm_cMap, "+", mm_undefined, -1); rb_define_method(mm_cMap, "*", mm_undefined, -1); rb_define_method(mm_cMap, "%", mm_undefined, -1); - rb_define_method(mm_cMap, "[]", mm_aref, -1); + rb_define_method(mm_cMap, "[]", mm_aref_m, -1); rb_define_method(mm_cMap, "[]=", mm_aset_m, -1); +#if RUBY_VERSION_CODE >= 171 + rb_define_method(mm_cMap, "insert", mm_insert, 2); +#endif rb_define_method(mm_cMap, "length", mm_size, 0); rb_define_method(mm_cMap, "size", mm_size, 0); rb_define_method(mm_cMap, "empty?", mm_empty, 0); @@ -1408,7 +1508,7 @@ Init_mmap() rb_define_method(mm_cMap, "tr_s", mm_undefined, -1); rb_define_method(mm_cMap, "delete", mm_undefined, -1); rb_define_method(mm_cMap, "squeeze", mm_undefined, -1); - + rb_define_method(mm_cMap, "count", mm_count, -1); rb_define_method(mm_cMap, "tr!", mm_tr_bang, 2); rb_define_method(mm_cMap, "tr_s!", mm_tr_s_bang, 2); rb_define_method(mm_cMap, "delete!", mm_delete_bang, -1); @@ -1419,4 +1519,7 @@ Init_mmap() rb_define_method(mm_cMap, "each_byte", mm_each_byte, -1); rb_define_method(mm_cMap, "sum", mm_sum, -1); + + rb_define_method(mm_cMap, "slice", mm_aref_m, -1); + rb_define_method(mm_cMap, "slice!", mm_slice_bang, -1); } diff --git a/mmap.html b/mmap.html index eaac054..cae24b2 100644 --- a/mmap.html +++ b/mmap.html @@ -229,6 +229,9 @@ self <=> other <<(other)

+casecmp(other) >= 1.7.1 +

+

concat(other)

@@ -241,6 +244,9 @@ chop! chomp!([rs])

+count(o1 [, o2, ...]) +

+

crypt(salt)

@@ -280,6 +286,9 @@ include?(other) index(substr[, pos])

+insert(index, str) >= 1.7.1 +

+

length

@@ -298,6 +307,12 @@ scan(pattern) {...} size

+slice +

+

+slice! +

+

split([sep[, limit]])

diff --git a/mmap.rd b/mmap.rd index d73f2b2..ac109df 100644 --- a/mmap.rd +++ b/mmap.rd @@ -123,6 +123,8 @@ self <=> other <<(other) +casecmp(other) >= 1.7.1 + concat(other) capitalize! @@ -131,6 +133,8 @@ chop! chomp!([rs]) +count(o1 [, o2, ...]) + crypt(salt) delete!(str) @@ -157,6 +161,8 @@ include?(other) index(substr[, pos]) +insert(index, str) >= 1.7.1 + length reverse! @@ -169,6 +175,10 @@ scan(pattern) {...} size +slice + +slice! + split([sep[, limit]]) squeeze!([str]) -- cgit v1.1-2-g2b99