c_buffer 0.1.2 → 0.1.3

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.
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