simple-mmap 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,55 @@
1
+ = simple_mmap
2
+
3
+ http://simple-mmap.rubyforge.org/
4
+
5
+ == DESCRIPTION:
6
+
7
+ A simplistic interface for reading memory mapped files
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * mmap a file. Read data from it. Close it when you're done. More fun than the "ball in a cup" game.
12
+ * it ONLY supports reading mmap'ed files, not writing to the mmap'ed region
13
+
14
+ == SYNOPSIS:
15
+
16
+ >> fw = SimpleMmap::FileWindow.open("path/to/large/file")
17
+ >> fw[23467, 200] #=> data between byte 23467 and the next 200 bytes
18
+ # works with the same semantics as Array#[] (eg. fw[10..14] and fw[10...14])
19
+ >> fw.close # you MUST close the FileWindow after you're done (HAHA no blocks for you yet!)
20
+
21
+
22
+ == REQUIREMENTS:
23
+
24
+ * A mmap() capable platform.
25
+
26
+ == INSTALL:
27
+
28
+ $ gem install simple_mmap
29
+ # If you have ruby 1.9+ built with executables having a program-suffix:
30
+ $ env rake=rake1.9 gem install simple_mmap
31
+
32
+ == LICENSE:
33
+
34
+ (The MIT License)
35
+
36
+ Copyright (c) 2009 Johan Sørensen
37
+
38
+ Permission is hereby granted, free of charge, to any person obtaining
39
+ a copy of this software and associated documentation files (the
40
+ 'Software'), to deal in the Software without restriction, including
41
+ without limitation the rights to use, copy, modify, merge, publish,
42
+ distribute, sublicense, and/or sell copies of the Software, and to
43
+ permit persons to whom the Software is furnished to do so, subject to
44
+ the following conditions:
45
+
46
+ The above copyright notice and this permission notice shall be
47
+ included in all copies or substantial portions of the Software.
48
+
49
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
50
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
52
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
53
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
54
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
55
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,157 @@
1
+
2
+ SHELL = /bin/sh
3
+
4
+ #### Start of system configuration section. ####
5
+
6
+ srcdir = .
7
+ topdir = /Users/pieter/.rvm/rubies/ree-1.8.7-2010.01/lib/ruby/1.8/i686-darwin10.2.0
8
+ hdrdir = $(topdir)
9
+ VPATH = $(srcdir):$(topdir):$(hdrdir)
10
+ exec_prefix = $(prefix)
11
+ prefix = $(DESTDIR)/Users/pieter/.rvm/rubies/ree-1.8.7-2010.01
12
+ sharedstatedir = $(prefix)/com
13
+ mandir = $(datarootdir)/man
14
+ psdir = $(docdir)
15
+ oldincludedir = $(DESTDIR)/usr/include
16
+ localedir = $(datarootdir)/locale
17
+ bindir = $(exec_prefix)/bin
18
+ libexecdir = $(exec_prefix)/libexec
19
+ sitedir = $(libdir)/ruby/site_ruby
20
+ htmldir = $(docdir)
21
+ vendorarchdir = $(vendorlibdir)/$(sitearch)
22
+ includedir = $(prefix)/include
23
+ infodir = $(datarootdir)/info
24
+ vendorlibdir = $(vendordir)/$(ruby_version)
25
+ sysconfdir = $(prefix)/etc
26
+ libdir = $(exec_prefix)/lib
27
+ sbindir = $(exec_prefix)/sbin
28
+ rubylibdir = $(libdir)/ruby/$(ruby_version)
29
+ docdir = $(datarootdir)/doc/$(PACKAGE)
30
+ dvidir = $(docdir)
31
+ vendordir = $(libdir)/ruby/vendor_ruby
32
+ datarootdir = $(prefix)/share
33
+ pdfdir = $(docdir)
34
+ archdir = $(rubylibdir)/$(arch)
35
+ sitearchdir = $(sitelibdir)/$(sitearch)
36
+ datadir = $(datarootdir)
37
+ localstatedir = $(prefix)/var
38
+ sitelibdir = $(sitedir)/$(ruby_version)
39
+
40
+ CC = gcc
41
+ LIBRUBY = $(LIBRUBY_A)
42
+ LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
43
+ LIBRUBYARG_SHARED =
44
+ LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
45
+
46
+ RUBY_EXTCONF_H =
47
+ CFLAGS = -fno-common -g -O2 -pipe -fno-common $(cflags)
48
+ INCFLAGS = -I. -I. -I/Users/pieter/.rvm/rubies/ree-1.8.7-2010.01/lib/ruby/1.8/i686-darwin10.2.0 -I.
49
+ DEFS =
50
+ CPPFLAGS = -DHAVE_MMAP -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE
51
+ CXXFLAGS = $(CFLAGS)
52
+ ldflags = -L.
53
+ dldflags =
54
+ archflag =
55
+ DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
56
+ LDSHARED = cc -dynamic -bundle -undefined suppress -flat_namespace
57
+ AR = ar
58
+ EXEEXT =
59
+
60
+ RUBY_INSTALL_NAME = ruby
61
+ RUBY_SO_NAME = ruby
62
+ arch = i686-darwin10.2.0
63
+ sitearch = i686-darwin10.2.0
64
+ ruby_version = 1.8
65
+ ruby = /Users/pieter/.rvm/rubies/ree-1.8.7-2010.01/bin/ruby
66
+ RUBY = $(ruby)
67
+ RM = rm -f
68
+ MAKEDIRS = mkdir -p
69
+ INSTALL = /opt/local/bin/ginstall -c
70
+ INSTALL_PROG = $(INSTALL) -m 0755
71
+ INSTALL_DATA = $(INSTALL) -m 644
72
+ COPY = cp
73
+
74
+ #### End of system configuration section. ####
75
+
76
+ preload =
77
+
78
+ libpath = . $(libdir)
79
+ LIBPATH = -L. -L$(libdir)
80
+ DEFFILE =
81
+
82
+ CLEANFILES = mkmf.log
83
+ DISTCLEANFILES =
84
+
85
+ extout =
86
+ extout_prefix =
87
+ target_prefix =
88
+ LOCAL_LIBS =
89
+ LIBS = -ldl -lobjc
90
+ SRCS = mapped_file.c
91
+ OBJS = mapped_file.o
92
+ TARGET = mapped_file
93
+ DLLIB = $(TARGET).bundle
94
+ EXTSTATIC =
95
+ STATIC_LIB =
96
+
97
+ BINDIR = $(bindir)
98
+ RUBYCOMMONDIR = $(sitedir)$(target_prefix)
99
+ RUBYLIBDIR = $(sitelibdir)$(target_prefix)
100
+ RUBYARCHDIR = $(sitearchdir)$(target_prefix)
101
+
102
+ TARGET_SO = $(DLLIB)
103
+ CLEANLIBS = $(TARGET).bundle $(TARGET).il? $(TARGET).tds $(TARGET).map
104
+ CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak
105
+
106
+ all: $(DLLIB)
107
+ static: $(STATIC_LIB)
108
+
109
+ clean:
110
+ @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
111
+
112
+ distclean: clean
113
+ @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
114
+ @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
115
+
116
+ realclean: distclean
117
+ install: install-so install-rb
118
+
119
+ install-so: $(RUBYARCHDIR)
120
+ install-so: $(RUBYARCHDIR)/$(DLLIB)
121
+ $(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
122
+ $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
123
+ install-rb: pre-install-rb install-rb-default
124
+ install-rb-default: pre-install-rb-default
125
+ pre-install-rb: Makefile
126
+ pre-install-rb-default: Makefile
127
+ $(RUBYARCHDIR):
128
+ $(MAKEDIRS) $@
129
+
130
+ site-install: site-install-so site-install-rb
131
+ site-install-so: install-so
132
+ site-install-rb: install-rb
133
+
134
+ .SUFFIXES: .c .m .cc .cxx .cpp .C .o
135
+
136
+ .cc.o:
137
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
138
+
139
+ .cxx.o:
140
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
141
+
142
+ .cpp.o:
143
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
144
+
145
+ .C.o:
146
+ $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<
147
+
148
+ .c.o:
149
+ $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<
150
+
151
+ $(DLLIB): $(OBJS) Makefile
152
+ @-$(RM) $@
153
+ $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
154
+
155
+
156
+
157
+ $(OBJS): ruby.h defines.h
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+
3
+ dir_config('mapped_file')
4
+ have_func('mmap')
5
+ create_makefile('mapped_file')
@@ -0,0 +1,179 @@
1
+ /* Copyright (c) 2009 Johan Sørensen
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining
4
+ * a copy of this software and associated documentation files (the
5
+ * 'Software'), to deal in the Software without restriction, including
6
+ * without limitation the rights to use, copy, modify, merge, publish,
7
+ * distribute, sublicense, and/or sell copies of the Software, and to
8
+ * permit persons to whom the Software is furnished to do so, subject to
9
+ * the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be
12
+ * included in all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+ */
22
+
23
+ #include <stdio.h>
24
+ #include <sys/stat.h>
25
+ #include <sys/fcntl.h>
26
+ #include <sys/mman.h>
27
+ #include <errno.h>
28
+ #include <unistd.h>
29
+ #include "ruby.h"
30
+
31
+ // a memory mapped file
32
+ typedef struct {
33
+ int fd;
34
+ caddr_t map;
35
+ size_t len;
36
+ } simple_mmap_map;
37
+
38
+ static VALUE mod_simple_mmap;
39
+ static VALUE sm_mapped_file;
40
+ static VALUE sm_map_data;
41
+
42
+ /*
43
+ * Document-method: new
44
+ * call-seq: SimpleMMap::MappedFile.new(path)
45
+ *
46
+ * mmap() the file at +path+
47
+ */
48
+ static VALUE sm_mapped_file_initialize(VALUE vself, VALUE filename)
49
+ {
50
+ int fd = -1;
51
+ size_t length;
52
+ struct stat st;
53
+ caddr_t base = (caddr_t) - 1;
54
+ VALUE vsm_map;
55
+ simple_mmap_map *sm_map;
56
+
57
+ fd = open(RSTRING_PTR(filename), O_RDONLY);
58
+ if (fd == -1) {
59
+ rb_raise(rb_eArgError, "Failed to open file %s", RSTRING_PTR(filename));
60
+ close(fd);
61
+ }
62
+
63
+ // Get the size of the file
64
+ if (fstat(fd, &st) == -1) {
65
+ rb_raise(rb_eArgError, "Failed to stat file %s", RSTRING_PTR(filename));
66
+ close(fd);
67
+ }
68
+ length = st.st_size;
69
+
70
+ // do the mmap
71
+ base = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);
72
+ if (base == (caddr_t) -1) {
73
+ rb_raise(rb_eArgError, "Failed to mmap file %s", RSTRING_PTR(filename));
74
+ close(fd);
75
+ }
76
+
77
+ // set the mmap structure as an ivar
78
+ sm_map = ALLOC(simple_mmap_map);
79
+ vsm_map = Data_Wrap_Struct(sm_map_data, NULL, free, sm_map);
80
+ sm_map->fd = fd;
81
+ sm_map->map = base;
82
+ sm_map->len = length;
83
+ rb_ivar_set(vself, rb_intern("@mmap_data"), vsm_map);
84
+
85
+ return Qnil;
86
+ }
87
+
88
+ /*
89
+ * Document-method: close
90
+ * call-seq: obj.close
91
+ *
92
+ * munmap() the current mmapped file
93
+ */
94
+ static VALUE sm_mapped_file_close(VALUE vself)
95
+ {
96
+ VALUE vsm_map;
97
+ simple_mmap_map *sm_map;
98
+
99
+ sm_map = ALLOC(simple_mmap_map);
100
+ vsm_map = rb_ivar_get(vself, rb_intern("@mmap_data"));
101
+ Data_Get_Struct(vsm_map, simple_mmap_map, sm_map);
102
+
103
+ if (sm_map->map != (caddr_t) -1)
104
+ munmap(sm_map->map, sm_map->len);
105
+ if (sm_map->fd != -1)
106
+ close(sm_map->fd);
107
+
108
+ return Qtrue;
109
+ }
110
+
111
+ /*
112
+ * Document-method: read_window_data
113
+ * call-seq: obj.read_window_data(offset, length)
114
+ *
115
+ * Read +length+ bytes starting at +offset+
116
+ */
117
+ static VALUE sm_mapped_file_read_window_data(VALUE vself, VALUE voffset, VALUE vlength)
118
+ {
119
+ size_t offset = NUM2INT(voffset);
120
+ size_t length = NUM2INT(vlength);
121
+ char buff[length];
122
+ VALUE vsm_map;
123
+ simple_mmap_map *sm_map;
124
+
125
+ sm_map = ALLOC(simple_mmap_map);
126
+ vsm_map = rb_ivar_get(vself, rb_intern("@mmap_data"));
127
+ Data_Get_Struct(vsm_map, simple_mmap_map, sm_map);
128
+
129
+ if (offset > sm_map->len) {
130
+ return Qnil;
131
+ }
132
+
133
+ size_t curr;
134
+ curr = offset;
135
+ size_t i;
136
+ for(i = 0; i < length; ++i) {
137
+ //printf("i=%i offset=%i length=%i curr=%i map->len=%i\n", i, offset, length, curr, sm_map->len);
138
+ if ((curr + i) > sm_map->len)
139
+ break;
140
+ buff[i] = sm_map->map[curr++];
141
+ }
142
+
143
+ // If the range overflows, return part that overlaps
144
+ if ((offset + length) > sm_map->len)
145
+ return rb_str_new(buff, sm_map->len - offset);
146
+
147
+ return rb_str_new(buff, length);
148
+ }
149
+
150
+ /*
151
+ * Document-method: size
152
+ * call-seq: obj.size
153
+ *
154
+ * Return size of mapped file
155
+ */
156
+
157
+ static VALUE sm_mapped_file_size(VALUE vself)
158
+ {
159
+ VALUE vsm_map;
160
+ simple_mmap_map *sm_map;
161
+
162
+ sm_map = ALLOC(simple_mmap_map);
163
+ vsm_map = rb_ivar_get(vself, rb_intern("@mmap_data"));
164
+ Data_Get_Struct(vsm_map, simple_mmap_map, sm_map);
165
+ return UINT2NUM(sm_map->len);
166
+ }
167
+
168
+ void Init_mapped_file()
169
+ {
170
+ mod_simple_mmap = rb_define_module("SimpleMmap");
171
+
172
+ sm_mapped_file = rb_define_class_under(mod_simple_mmap, "MappedFile", rb_cObject);
173
+ rb_define_private_method(sm_mapped_file, "initialize", sm_mapped_file_initialize, 1);
174
+ rb_define_method(sm_mapped_file, "close", sm_mapped_file_close, 0);
175
+ rb_define_method(sm_mapped_file, "read_window_data", sm_mapped_file_read_window_data, 2);
176
+ rb_define_method(sm_mapped_file, "size", sm_mapped_file_size, 0);
177
+
178
+ sm_map_data = rb_define_class_under(sm_mapped_file, "MmapData", rb_cObject);
179
+ }
@@ -0,0 +1,24 @@
1
+ # Copyright (c) 2009 Johan Sørensen
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # 'Software'), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ $:.unshift File.dirname(__FILE__)
23
+ require "simple_mmap/mapped_file"
24
+ require "simple_mmap/file_window"
@@ -0,0 +1,101 @@
1
+ # Copyright (c) 2009 Johan Sørensen
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # 'Software'), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ module SimpleMmap
23
+ # Represents a window into a mmap()'ed file, using a familiar index syntax
24
+ # for getting single bytes or Ranges of bytes within that FileWindow
25
+ class FileWindow
26
+ # Create a mmap'ed window for file at +path+
27
+ # You are responsible for closing it when you're done using #close
28
+ def initialize(path)
29
+ @path = path
30
+ @offset = 0
31
+ @mmap = SimpleMmap::MappedFile.new(@path)
32
+ end
33
+ attr_reader :path, :offset
34
+
35
+ # unmaps the mmap'ed file
36
+ def close
37
+ @mmap.close
38
+ @mmap = nil
39
+ end
40
+ alias_method :unmap, :close
41
+
42
+ # The current offset
43
+ def offset
44
+ @offset
45
+ end
46
+ alias_method :pos, :offset
47
+
48
+ # Set the current offset to +new_offset+
49
+ def offset=(new_offset)
50
+ @offset = new_offset
51
+ end
52
+ alias_method :pos=, :offset=
53
+
54
+ # Move the current offset to +to_pos+
55
+ def seek(to_pos)
56
+ self.pos = to_pos
57
+ end
58
+
59
+ # Read data from the mmap'ed file. Takes the same arguments as
60
+ # Array/String#[] (eg [2], [2,5], [2..5] or [2...5])
61
+ # The current offset will be tracked accordingly
62
+ def [](*index)
63
+ if index.length == 1
64
+ index = index.first
65
+ end
66
+ case index
67
+ when Array
68
+ offset, length = index
69
+ when Fixnum
70
+ offset = index
71
+ length = 0
72
+ when Range
73
+ offset = index.begin
74
+ length = index.end - index.begin
75
+ unless index.exclude_end?
76
+ length += 1
77
+ end
78
+ end
79
+
80
+ @offset = offset + length
81
+
82
+ if length.zero?
83
+ @mmap.read_window_data(offset, 1)
84
+ else
85
+ @mmap.read_window_data(offset, length)
86
+ end
87
+ end
88
+
89
+ # Read +length+ bytes starting from the current offset
90
+ def read(length)
91
+ data = @mmap.read_window_data(@offset, length)
92
+ @offset += length
93
+ data
94
+ end
95
+
96
+ # Return size of mapped file
97
+ def size
98
+ @mmap.size
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,75 @@
1
+ require "test/unit"
2
+
3
+ require File.dirname(__FILE__) + "/../lib/simple_mmap"
4
+
5
+ class TestFileWindow < Test::Unit::TestCase
6
+ def setup
7
+ @file = Tempfile.new("TestFileWindow.data")
8
+ File.open(@file.path, "w"){|f| f.write(('a'..'z').to_a.join) }
9
+ @fw = SimpleMmap::FileWindow.new(@file.path)
10
+ end
11
+
12
+ def teardown
13
+ @fw.close
14
+ end
15
+
16
+ def test_should_start_at_offset_0
17
+ assert_equal 0, @fw.offset
18
+ assert_equal 0, @fw.pos
19
+ end
20
+
21
+ def test_should_be_able_to_set_the_offset
22
+ @fw.offset = 2
23
+ assert_equal 2, @fw.offset
24
+ assert_equal 2, @fw.pos
25
+
26
+ @fw.pos = 4
27
+ assert_equal 4, @fw.offset
28
+ assert_equal 4, @fw.pos
29
+
30
+ @fw.seek(6)
31
+ assert_equal 6, @fw.offset
32
+ assert_equal 6, @fw.pos
33
+ end
34
+
35
+ def test_get_single_byte_at_current_offset_with_index
36
+ assert_equal "c", @fw[2]
37
+ assert_equal 2, @fw.offset
38
+ assert_equal "b", @fw[1]
39
+ assert_equal 1, @fw.offset
40
+ end
41
+
42
+ def test_get_bytes_past_length
43
+ assert_equal "z", @fw[25, 10]
44
+ end
45
+
46
+ def test_nil_on_negative_index
47
+ assert_equal nil, @fw[-1]
48
+ assert_equal nil, @fw[-1, 2]
49
+ end
50
+
51
+ def test_get_from_x_to_y_with_index_comma_notation
52
+ assert_equal "cde", @fw[2, 3]
53
+ assert_equal 5, @fw.pos
54
+ assert_nil @fw[28, 2]
55
+ end
56
+
57
+ def test_get_with_range_including
58
+ assert_equal "cde", @fw[2..4]
59
+ assert_equal 5, @fw.offset
60
+ end
61
+
62
+ def test_get_with_range_excluding
63
+ assert_equal "cd", @fw[2...4]
64
+ assert_equal 4, @fw.offset
65
+ end
66
+
67
+ def test_read
68
+ assert_equal "abc", @fw.read(3)
69
+ assert_equal 3, @fw.offset
70
+ end
71
+
72
+ def test_size
73
+ assert_equal 26, @fw.size
74
+ end
75
+ end
@@ -0,0 +1,27 @@
1
+ require "test/unit"
2
+ require "tempfile"
3
+
4
+ require File.dirname(__FILE__) + "/../lib/simple_mmap"
5
+
6
+ class TestMappedFile < Test::Unit::TestCase
7
+ def setup
8
+ @file = Tempfile.new("TestMappedFile.data")
9
+ File.open(@file.path, "w"){|f| f.puts(('a'..'z').to_a.join) }
10
+ @map = SimpleMmap::MappedFile.new(@file.path)
11
+ end
12
+
13
+ def teardown
14
+ @map.close
15
+ end
16
+
17
+ def test_read_window_data
18
+ assert_equal "abc", @map.read_window_data(0, 3)
19
+ assert_equal "bc", @map.read_window_data(1, 2)
20
+ assert_equal "klmno", @map.read_window_data(10, 5)
21
+ end
22
+
23
+ def test_read_window_beyond_buffer_size
24
+ assert_equal "z\n", @map.read_window_data(25, 5)
25
+ assert_nil @map.read_window_data(28, 5)
26
+ end
27
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple-mmap
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - "Johan S\xC3\xB8rensen"
8
+ - Pieter Noordhuis
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2010-02-10 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description:
18
+ email: pcnoordhuis@gmail.com
19
+ executables: []
20
+
21
+ extensions:
22
+ - ext/extconf.rb
23
+ extra_rdoc_files:
24
+ - README.txt
25
+ files:
26
+ - ext/Makefile
27
+ - ext/extconf.rb
28
+ - ext/mapped_file.c
29
+ - lib/simple_mmap.rb
30
+ - lib/simple_mmap/file_window.rb
31
+ - test/test_file_window.rb
32
+ - test/test_mapped_file.rb
33
+ - README.txt
34
+ has_rdoc: true
35
+ homepage: http://github.com/pietern/simple-mmap
36
+ licenses: []
37
+
38
+ post_install_message:
39
+ rdoc_options:
40
+ - --charset=UTF-8
41
+ require_paths:
42
+ - ext
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.3.5
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Read-only wrapper for mmap
63
+ test_files:
64
+ - test/test_file_window.rb
65
+ - test/test_mapped_file.rb