Skip to content

Commit 00c4be9

Browse files
author
Pierre-Alexandre Meyer
committed
ruby: add extension using the C library
To use it: DYLD_INSERT_LIBRARIES=./c/.libs/libsmile_decode-1.0.0.dylib irb > require 'smile' > p = Smile::Parser.new("data.smile") > puts p.check_header => true Signed-off-by: Pierre-Alexandre Meyer <pierre@ning.com>
1 parent dfa55a9 commit 00c4be9

File tree

5 files changed

+98
-2
lines changed

5 files changed

+98
-2
lines changed

.gitignore

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
.sconsign.dblite
2-
smile
2+
c/smile
33
a.out
44
*.c.out
55
*.o
@@ -22,3 +22,13 @@ config.status
2222
c/src/.dirstamp
2323
c/src/.deps
2424
Makefile
25+
mkmf.log
26+
.libs/
27+
config.guess
28+
config.sub
29+
*.la
30+
*.so
31+
libtool
32+
ltmain.sh
33+
*.lo
34+
*.bundle

c/Makefile.am

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,8 @@ AUTOMAKE_OPTIONS = subdir-objects
22
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS}
33

44
bin_PROGRAMS = smile
5-
smile_SOURCES = src/smile_decode.h src/smile_decode.c src/printer.h src/printer.c src/api.h
5+
smile_SOURCES = src/printer.c
6+
smile_LDADD = libsmile_decode
7+
8+
lib_LTLIBRARIES = libsmile_decode-1.0.la
9+
libsmile_decode_1_0_la_SOURCES = src/smile_decode.c

c/configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ AC_PROG_CC
1212
AM_PROG_CC_C_O
1313

1414
# Checks for libraries.
15+
AC_PROG_LIBTOOL
1516

1617
# Checks for header files.
1718
AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h unistd.h])

ruby/src/extconf.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Loads mkmf which is used to make makefiles for Ruby extensions
2+
require 'mkmf'
3+
4+
extension_name = "smile"
5+
6+
unless $CFLAGS.gsub!(/ -O[\dsz]?/, ' -O3')
7+
$CFLAGS << ' -O3'
8+
end
9+
if CONFIG['CC'] =~ /gcc/
10+
$CFLAGS << ' -Wall -Werror'
11+
end
12+
13+
dir_config(extension_name, "../../c/src", "../../c/src")
14+
find_header("smile_decode.h")
15+
find_library("smile_decode", "smile_decode_header")
16+
17+
create_makefile(extension_name)

ruby/src/smile.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include "ruby.h"
2+
3+
#include "smile_decode.h"
4+
5+
static VALUE rb_mSmile;
6+
static VALUE rb_cParser;
7+
8+
static FILE* file;
9+
10+
static void file_mark(FILE *f)
11+
{
12+
/* Nothing needed */
13+
}
14+
15+
static void file_free(FILE *f)
16+
{
17+
if (f) {
18+
fclose(f);
19+
}
20+
}
21+
22+
static VALUE file_alloc(VALUE klass)
23+
{
24+
FILE *f = NULL;
25+
return Data_Wrap_Struct(klass, file_mark, file_free, f);
26+
}
27+
static VALUE file_init(VALUE obj, VALUE path)
28+
{
29+
file = fopen(RSTRING(path)->ptr, "r");
30+
31+
if (file == NULL) {
32+
rb_raise(rb_eRuntimeError, "Invalid file specified");
33+
}
34+
35+
return Qnil;
36+
}
37+
38+
static VALUE check_header(VALUE self)
39+
{
40+
u8 header[4];
41+
42+
int bytes_read = fread(header, sizeof(header), 4, file);
43+
44+
if (bytes_read != 4) {
45+
rb_raise(rb_eRuntimeError, "Could not read header");
46+
return Qfalse;
47+
} else {
48+
if (smile_decode_header(header)) {
49+
return Qtrue;
50+
} else {
51+
return Qfalse;
52+
}
53+
}
54+
}
55+
56+
void Init_smile()
57+
{
58+
rb_mSmile = rb_define_module("Smile");
59+
rb_cParser = rb_define_class_under(rb_mSmile, "Parser", rb_cObject);
60+
rb_define_alloc_func(rb_cParser, file_alloc);
61+
rb_define_method(rb_cParser, "initialize", file_init, 1);
62+
63+
rb_define_method(rb_cParser, "check_header", check_header, 0);
64+
}

0 commit comments

Comments
 (0)