c_buffer 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -7,16 +7,18 @@
7
7
  # author hugo benichi
8
8
  # email hugo.benichi@m4x.org
9
9
  # copyright 2012 hugo benichi
10
- # version 0.1.0
10
+ # version 0.1.3
11
11
  #
12
12
  ##
13
13
 
14
14
  installation:
15
15
 
16
- run "rake install" in the root directory
16
+ run in the root directory
17
+ rake gem_install
18
+
17
19
  it will compile the gem library and produce a .gem package for ruby
18
20
  it will then install the .gem automatically
19
21
 
20
- usage, test:
22
+ usage:
21
23
 
22
24
  cf test/test_cbuffer.rb
@@ -79,7 +79,7 @@ DLL void
79
79
  }
80
80
 
81
81
 
82
- DLL void
82
+ DLL int
83
83
  cbuffer_open(
84
84
  cbuffer* buf,
85
85
  const char* address
@@ -88,8 +88,12 @@ DLL void
88
88
  buf-> output = fopen(address, "w" );
89
89
 
90
90
  if( !(buf->output) )
91
+ {
91
92
  fprintf(stderr, "cbuffer.c: error while opening file %s\n", address);
92
-
93
+ return -1;
94
+ }
95
+
96
+ return 0;
93
97
  }
94
98
 
95
99
 
@@ -155,7 +159,7 @@ DLL int
155
159
  while(1)
156
160
  {
157
161
  fwrite( buf->outbound->mem, 1, buf-> chunk, buf-> output);
158
- count += 1;
162
+ count += buf->chunk;
159
163
  if( buf->stop == buf->outbound )
160
164
  break;
161
165
  buf->outbound = buf->outbound->next;
@@ -164,3 +168,35 @@ DLL int
164
168
  fclose(buf->output);
165
169
  return count;
166
170
  }
171
+
172
+
173
+ DLL int
174
+ cbuffer_read(cbuffer* buf, int (*reader)(char*, void*) , void* context)
175
+ {
176
+ while( !( buf->start ) || buf->inbound == buf->start);
177
+ // busy wait while the first buffer is written
178
+
179
+ buf->outbound = buf->start;
180
+
181
+ int count = 0;
182
+ while( !( buf->stop ) )
183
+ {
184
+ reader( buf->outbound->mem, context);
185
+
186
+ count += buf->chunk;
187
+
188
+ buf->outbound = buf->outbound->next;
189
+ while(buf->outbound == buf->inbound); //busy wait
190
+ }
191
+
192
+ while(1)
193
+ {
194
+ reader( buf->outbound->mem, context);
195
+ count += buf->chunk;
196
+ if( buf->stop == buf->outbound )
197
+ break;
198
+ buf->outbound = buf->outbound->next;
199
+ }
200
+
201
+ return count;
202
+ }
@@ -11,6 +11,7 @@
11
11
  typedef struct cbuffer cbuffer;
12
12
  typedef struct link link;
13
13
 
14
+ typedef int (*reader)(char*,void*);
14
15
 
15
16
  struct
16
17
  cbuffer // 192 bytes on 32bits machines and 352 bytes on 64bits machines
@@ -32,11 +33,13 @@ struct
32
33
  };
33
34
 
34
35
 
35
- DLL cbuffer* cbuffer_new (int chunk, int size); // size is n_chunk * chunk
36
- DLL void cbuffer_free (cbuffer*); // don't forget to close output if open
37
- DLL void cbuffer_open (cbuffer*, const char* ); // open a new file at the given path
36
+ DLL cbuffer* cbuffer_new (int chunk, int size); // size is n_chunk * chunk
37
+ DLL void cbuffer_free (cbuffer*); // don't forget to close output if open
38
+ DLL int cbuffer_open (cbuffer*, const char* ); // open a new file at the given path
39
+
40
+ DLL char* cbuffer_next (cbuffer*); // blocking, return the next buffer memory inline
41
+ DLL char* cbuffer_has_next (cbuffer*); // non-blocking, return null if not ready
42
+ DLL void cbuffer_stop (cbuffer*); // flag for stopping (cut the circular list)
43
+ DLL int cbuffer_write (cbuffer*); // blocking, write everything untill stop
44
+ DLL int cbuffer_read (cbuffer*, reader, void*); // blocking, passes memory chunk written to to a user defined handling function 'reader'
38
45
 
39
- DLL char* cbuffer_next (cbuffer*); // blocking, return the next buffer memory inline
40
- DLL char* cbuffer_has_next (cbuffer*); // non-blocking, return null if not ready
41
- DLL void cbuffer_stop (cbuffer*); // flag for stopping (cut the circular list)
42
- DLL int cbuffer_write (cbuffer*); // blocking, write everything untill stop
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile 'c_buffer/c_buffer'
data/rakefile.rb CHANGED
@@ -23,10 +23,11 @@ task :test_local do
23
23
  end
24
24
 
25
25
  task :gem_install => :gem_build do
26
- gemfile = Dir.new("./").entries.select{ |f| f =~ /cbuffer-[\d]+\.[\d]+\.[\d]+.gem/ }[0]
27
- sh "gem install %s" % gemfile
26
+ gemfile = Dir.new("./").entries.select{ |f| f =~ /c_buffer-[\d]+\.[\d]+\.[\d]+.gem/ }[0]
27
+ puts "installing %s" % gemfile
28
+ sh "gem install --local %s" % gemfile
28
29
  end
29
30
 
30
- task :gem_build => :compile do
31
+ task :gem_build do
31
32
  sh "gem build %s.gemspec" % name
32
33
  end
@@ -1,17 +1,21 @@
1
1
  require 'c_buffer'
2
2
 
3
- repet = 126
3
+ repet = 16 #126
4
4
  chunk = 1024*126
5
5
  length = chunk * 64
6
+ data = Array.new(chunk){rand 255}
6
7
 
8
+ puts "data dump test"
9
+ CBuffer.new( path: "./data", chunk: chunk, length: length ).tap{ |buf|
10
+ buf.output
11
+ repet.times{ |i| buf.input.put_array_of_uchar 0, data }
12
+ buf.stop
13
+ }
7
14
 
8
- buf = CBuffer.new( path: "./data", chunk: chunk, length: length )
9
- buf.write{ |count| puts "wrote #{count} bytes of data" }
10
-
11
- data = Array.new(chunk){rand 255}
12
-
13
- repet.times do |i|
14
- buf.next.put_array_of_uchar 0, data
15
- end
16
-
17
- buf.stop
15
+ puts "reader test"
16
+ CBuffer.new( chunk: chunk, length: length ).tap{ |buf|
17
+ count = 0
18
+ buf.read{ |data| puts "total data read: %i bytes" % count += data.length }
19
+ repet.times{ |i| buf.input.put_array_of_uchar 0, data }
20
+ buf.stop
21
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: c_buffer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-05 00:00:00.000000000 Z
12
+ date: 2012-07-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
16
- requirement: &19284820 !ruby/object:Gem::Requirement
16
+ requirement: &22493360 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,19 +21,18 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *19284820
24
+ version_requirements: *22493360
25
25
  description: A simple circular buffer and its Ruby interface to go along RbScope and
26
26
  RbVisa. Perfect for staging high throughput input data to low throughput I/O.
27
27
  email: hugo.benichi@m4x.org
28
28
  executables: []
29
- extensions: []
29
+ extensions:
30
+ - ext/c_buffer/extconf.rb
30
31
  extra_rdoc_files: []
31
32
  files:
32
- - lib/c_buffer.rb
33
- - lib/c_buffer/c_buffer.so
34
- - lib/c_buffer/c_buffer.dll
35
33
  - ext/c_buffer/c_buffer.c
36
34
  - ext/c_buffer/c_buffer.h
35
+ - ext/c_buffer/extconf.rb
37
36
  - rakefile.rb
38
37
  - README
39
38
  - test/test_c_buffer.rb
Binary file
Binary file
data/lib/c_buffer.rb DELETED
@@ -1,79 +0,0 @@
1
- ##
2
- #
3
- # CBuffer
4
- #
5
- # Simple circular buffer for staging data before writing to disk
6
- #
7
- # author hugo benichi
8
- # email hugo.benichi@m4x.org
9
- # copyright 2012 hugo benichi
10
- # version 0.1.1
11
- #
12
- ##
13
-
14
- # Main class and namespace of the program
15
- # This class should be instancied to use a buffer
16
- class CBuffer
17
-
18
- require 'ffi'
19
-
20
- # the API module wraps the native functions of cbuffer.c
21
- module API
22
- extend FFI::Library
23
- lib_type = ENV["OS"] ? "dll" : "so"
24
- #ffi_lib $LOAD_PATH.map{ |p| p + "/cbuffer/cbuffer.#{lib_type}" }
25
- ffi_lib File.dirname(__FILE__) + "/c_buffer/c_buffer.#{lib_type}"
26
- [
27
- [ :cbuffer_new, [:int32, :int32], :pointer ],
28
- [ :cbuffer_free, [:pointer], :void ],
29
- [ :cbuffer_open, [:pointer, :pointer], :void ],
30
- [ :cbuffer_next, [:pointer], :pointer, :blocking => true ],
31
- [ :cbuffer_has_next, [:pointer], :pointer ],
32
- [ :cbuffer_stop, [:pointer], :void ],
33
- [ :cbuffer_write, [:pointer], :int32, :blocking => true ],
34
- ].each{ |sig| attach_function *sig }
35
- end
36
-
37
- # the CBufferRaw class wraps the native struct memory used to store the buffer memory
38
- # not used at the momentm here for reference only
39
- class CBufferRaw < FFI::Struct
40
- layout :inbound, :pointer,
41
- :outbound, :pointer,
42
- :start, :pointer,
43
- :stop, :pointer,
44
- :output, :pointer,
45
- :chunk, :int
46
- end
47
-
48
- def initialize args
49
- chunk = args[:chunk] || 1
50
- length = args[:length] || 2
51
- path = args[:path] || 1
52
- @struct = API::cbuffer_new chunk, length
53
- API::cbuffer_open @struct, path
54
- self
55
- end
56
-
57
- def write &block
58
- running = true
59
- self.define_singleton_method :stop do
60
- API.cbuffer_stop @struct
61
- sleep 1 while running
62
- API.cbuffer_free @struct
63
- end
64
- Thread.new do
65
- begin
66
- count = API.cbuffer_write @struct
67
- running = false
68
- block.call(count) if block
69
- catch
70
- puts "error in writing thread"
71
- end
72
- end
73
- end
74
-
75
- def next
76
- API.cbuffer_next @struct
77
- end
78
-
79
- end