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 +5 -3
- data/ext/c_buffer/c_buffer.c +39 -3
- data/ext/c_buffer/c_buffer.h +10 -7
- data/ext/c_buffer/extconf.rb +3 -0
- data/rakefile.rb +4 -3
- data/test/test_c_buffer.rb +15 -11
- metadata +7 -8
- data/lib/c_buffer/c_buffer.dll +0 -0
- data/lib/c_buffer/c_buffer.so +0 -0
- data/lib/c_buffer.rb +0 -79
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.
|
10
|
+
# version 0.1.3
|
11
11
|
#
|
12
12
|
##
|
13
13
|
|
14
14
|
installation:
|
15
15
|
|
16
|
-
run
|
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
|
22
|
+
usage:
|
21
23
|
|
22
24
|
cf test/test_cbuffer.rb
|
data/ext/c_buffer/c_buffer.c
CHANGED
@@ -79,7 +79,7 @@ DLL void
|
|
79
79
|
}
|
80
80
|
|
81
81
|
|
82
|
-
DLL
|
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 +=
|
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
|
+
}
|
data/ext/c_buffer/c_buffer.h
CHANGED
@@ -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);
|
36
|
-
DLL void cbuffer_free (cbuffer*);
|
37
|
-
DLL
|
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
|
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 =~ /
|
27
|
-
|
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
|
31
|
+
task :gem_build do
|
31
32
|
sh "gem build %s.gemspec" % name
|
32
33
|
end
|
data/test/test_c_buffer.rb
CHANGED
@@ -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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
data
|
12
|
-
|
13
|
-
|
14
|
-
|
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.
|
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-
|
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: &
|
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: *
|
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
|
data/lib/c_buffer/c_buffer.dll
DELETED
Binary file
|
data/lib/c_buffer/c_buffer.so
DELETED
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
|