rdf-raptor 0.4.2 → 1.0.0.beta1
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 +32 -11
- data/VERSION +1 -1
- data/lib/rdf/raptor/cli.rb +0 -1
- data/lib/rdf/raptor/ffi/v1/parser.rb +1 -1
- data/lib/rdf/raptor/ffi/v2/iostream.rb +56 -0
- data/lib/rdf/raptor/ffi/v2/iostream_handler.rb +153 -0
- data/lib/rdf/raptor/ffi/v2/parser.rb +205 -0
- data/lib/rdf/raptor/ffi/v2/serializer.rb +137 -0
- data/lib/rdf/raptor/ffi/v2/statement.rb +143 -0
- data/lib/rdf/raptor/ffi/v2/term.rb +95 -0
- data/lib/rdf/raptor/ffi/v2/uri.rb +111 -0
- data/lib/rdf/raptor/ffi/v2/world.rb +20 -0
- data/lib/rdf/raptor/ffi/v2.rb +156 -0
- data/lib/rdf/raptor/ffi.rb +13 -14
- data/lib/rdf/raptor/format.rb +1 -1
- data/lib/rdf/raptor.rb +1 -1
- metadata +19 -10
data/README
CHANGED
@@ -2,8 +2,8 @@ Raptor RDF Parser Plugin for RDF.rb
|
|
2
2
|
===================================
|
3
3
|
[](http://travis-ci.org/ruby-rdf/rdf-raptor)
|
4
4
|
|
5
|
-
This is an [RDF.rb][] plugin that adds support for parsing/serializing
|
6
|
-
[RDF/XML][], [Turtle][] and [
|
5
|
+
This is an [RDF.rb][] plugin that adds support for parsing/serializing [NTriples][],
|
6
|
+
[RDF/XML][], [Turtle][], [RDFa][], and [Graphviz][] data using the [Raptor RDF Parser][Raptor]
|
7
7
|
library.
|
8
8
|
|
9
9
|
* <http://github.com/ruby-rdf/rdf-raptor>
|
@@ -12,12 +12,13 @@ library.
|
|
12
12
|
Features
|
13
13
|
--------
|
14
14
|
|
15
|
-
*
|
16
|
-
* Parses and serializes RDF data from/into the RDF/XML
|
15
|
+
* Uses the fast [Raptor][] C library.
|
16
|
+
* Parses and serializes RDF data from/into the NTriples, RDF/XML, and Turtle formats.
|
17
17
|
* Extracts RDF statements from XHTML+RDFa documents.
|
18
|
+
* Serializes RDF statements into Graphviz format.
|
18
19
|
* Provides serialization format autodetection for RDF/XML, Turtle and RDFa.
|
19
20
|
* Compatible with any operating system supported by Raptor and Ruby.
|
20
|
-
* Compatible with MRI 1.8.x, 1.9.x
|
21
|
+
* Compatible with MRI 1.8.x, 1.9.x, REE, JRuby and Rubinius (1.8 and 1.9 mode).
|
21
22
|
|
22
23
|
Examples
|
23
24
|
--------
|
@@ -27,7 +28,15 @@ Examples
|
|
27
28
|
### Ensuring Raptor is installed and obtaining the version number
|
28
29
|
|
29
30
|
RDF::Raptor.available? #=> true
|
30
|
-
RDF::Raptor.version #=> "
|
31
|
+
RDF::Raptor.version #=> "2.0.8"
|
32
|
+
|
33
|
+
### Parsing RDF statements from an NTriples file
|
34
|
+
|
35
|
+
RDF::Reader.open("http://datagraph.org/jhacker/foaf.nt") do |reader|
|
36
|
+
reader.each_statement do |statement|
|
37
|
+
puts statement.inspect
|
38
|
+
end
|
39
|
+
end
|
31
40
|
|
32
41
|
### Parsing RDF statements from an RDF/XML file
|
33
42
|
|
@@ -105,6 +114,14 @@ Examples
|
|
105
114
|
RDF::Format.for(:file_extension => "html")
|
106
115
|
RDF::Format.for(:content_type => "application/xhtml+xml")
|
107
116
|
|
117
|
+
### Obtaining the Graphviz format specification class
|
118
|
+
|
119
|
+
RDF::Format.for(:graphviz) #=> RDF::Raptor::Graphviz::Format
|
120
|
+
RDF::Format.for("output.dot")
|
121
|
+
RDF::Format.for(:file_name => "output.dot")
|
122
|
+
RDF::Format.for(:file_extension => "")
|
123
|
+
RDF::Format.for(:content_type => "text/vnd.graphviz")
|
124
|
+
|
108
125
|
Documentation
|
109
126
|
-------------
|
110
127
|
|
@@ -120,9 +137,9 @@ Documentation
|
|
120
137
|
Dependencies
|
121
138
|
------------
|
122
139
|
|
123
|
-
* [RDF.rb](http://rubygems.org/gems/rdf) (>= 0.3.
|
140
|
+
* [RDF.rb](http://rubygems.org/gems/rdf) (>= 0.3.8)
|
124
141
|
* [FFI](http://rubygems.org/gems/ffi) (>= 1.0.0)
|
125
|
-
* [Raptor][] (>=
|
142
|
+
* [Raptor][] (>= 2.0), the `libraptor` library or the `rapper` binary
|
126
143
|
|
127
144
|
Installation
|
128
145
|
------------
|
@@ -140,7 +157,8 @@ Mac and the most common Linux and BSD distributions:
|
|
140
157
|
% [sudo] port install raptor # Mac OS X with MacPorts
|
141
158
|
% [sudo] fink install raptor-bin # Mac OS X with Fink
|
142
159
|
% brew install raptor # Mac OS X with Homebrew
|
143
|
-
% [sudo] aptitude install raptor-utils # Ubuntu / Debian
|
160
|
+
% [sudo] aptitude install raptor-utils # Ubuntu / Debian with aptitude
|
161
|
+
% [sudo] apt-get install libraptor2-0 # Ubuntu / Debian with apt-get
|
144
162
|
% [sudo] yum install raptor # Fedora / CentOS / RHEL
|
145
163
|
% [sudo] zypper install raptor # openSUSE
|
146
164
|
% [sudo] emerge raptor # Gentoo Linux
|
@@ -175,18 +193,21 @@ Contributors
|
|
175
193
|
------------
|
176
194
|
|
177
195
|
* [Ben Lavender](http://github.com/bhuga) - <http://bhuga.net/>
|
178
|
-
* [David Butler](http://github.com/dwbutler)
|
196
|
+
* [David Butler](http://github.com/dwbutler) - <http://github.com/dwbutler>
|
179
197
|
* [Gregg Kellogg](http://github.com/gkellogg) - <http://greggkellogg.net/>
|
180
198
|
|
181
199
|
License
|
182
200
|
-------
|
183
201
|
|
184
202
|
This is free and unencumbered public domain software. For more information,
|
185
|
-
see <http://unlicense.org/> or the accompanying
|
203
|
+
see <http://unlicense.org/> or the accompanying [UNLICENSE][] file.
|
186
204
|
|
187
205
|
[RDF.rb]: http://rdf.rubyforge.org/
|
206
|
+
[NTriples]: http://en.wikipedia.org/wiki/N-Triples
|
188
207
|
[RDF/XML]: http://www.w3.org/TR/REC-rdf-syntax/
|
189
208
|
[Turtle]: http://en.wikipedia.org/wiki/Turtle_(syntax)
|
190
209
|
[RDFa]: http://rdfa.info/
|
210
|
+
[Graphviz]: http://www.graphviz.org/
|
191
211
|
[Raptor]: http://librdf.org/raptor/
|
192
212
|
[rapper]: http://librdf.org/raptor/rapper.html
|
213
|
+
[UNLICENSE]:https://github.com/ruby-rdf/rdf-raptor/blob/master/UNLICENSE
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0.beta1
|
data/lib/rdf/raptor/cli.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
module RDF::Raptor::FFI::V2
|
2
|
+
##
|
3
|
+
# This class provides an I/O stream that can write to filenames, `FILE*`,
|
4
|
+
# strings and user-defined output via callbacks.
|
5
|
+
#
|
6
|
+
# @see http://librdf.org/raptor/api-1.4/raptor-section-iostream.html
|
7
|
+
class IOStream < ::FFI::ManagedStruct
|
8
|
+
include RDF::Raptor::FFI
|
9
|
+
layout :world, :pointer,
|
10
|
+
:user_data, :pointer,
|
11
|
+
:handler, :pointer,
|
12
|
+
:offset, :size_t,
|
13
|
+
:mode, :int,
|
14
|
+
:flags, :int
|
15
|
+
|
16
|
+
##
|
17
|
+
# @overload initialize(ptr)
|
18
|
+
# @param [FFI::Pointer] ptr
|
19
|
+
#
|
20
|
+
# @overload initialize(handler)
|
21
|
+
# @param [V2::IOStreamHandler] handler
|
22
|
+
#
|
23
|
+
# @overload initialize(file)
|
24
|
+
# @param [File, Tempfile] file
|
25
|
+
#
|
26
|
+
def initialize(ptr_or_obj, options = {})
|
27
|
+
ptr = case ptr_or_obj
|
28
|
+
when FFI::Pointer
|
29
|
+
ptr_or_obj
|
30
|
+
when V2::IOStreamHandler
|
31
|
+
@handler = ptr_or_obj # prevents premature GC
|
32
|
+
V2.raptor_new_iostream_from_handler(V2.world, self, @handler)
|
33
|
+
when File, Tempfile
|
34
|
+
V2.raptor_new_iostream_to_filename(V2.world, File.expand_path(ptr_or_obj.path))
|
35
|
+
when false
|
36
|
+
V2.raptor_new_iostream_to_sink(V2.world)
|
37
|
+
else nil
|
38
|
+
end
|
39
|
+
raise ArgumentError, "invalid argument: #{ptr_or_obj.inspect}" if ptr.nil? || ptr.null?
|
40
|
+
|
41
|
+
@free_iostream = options[:free_iostream] || true
|
42
|
+
super(ptr)
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Releases `libraptor` memory associated with this structure.
|
47
|
+
#
|
48
|
+
# @param [FFI::Pointer] ptr
|
49
|
+
# @return [void]
|
50
|
+
def self.release(ptr)
|
51
|
+
if @free_iostream
|
52
|
+
V2.raptor_free_iostream(ptr)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end # IOStream
|
56
|
+
end # RDF::Raptor::FFI::V2
|
@@ -0,0 +1,153 @@
|
|
1
|
+
module RDF::Raptor::FFI::V2
|
2
|
+
##
|
3
|
+
# @see http://librdf.org/raptor/api-1.4/raptor-section-iostream.html
|
4
|
+
class IOStreamHandler < ::FFI::Struct
|
5
|
+
include RDF::Raptor::FFI
|
6
|
+
layout :version, :int,
|
7
|
+
:init, :raptor_iostream_init_func,
|
8
|
+
:finish, :raptor_iostream_finish_func,
|
9
|
+
:write_byte, :raptor_iostream_write_byte_func,
|
10
|
+
:write_bytes, :raptor_iostream_write_bytes_func,
|
11
|
+
:write_end, :raptor_iostream_write_end_func,
|
12
|
+
:read_bytes, :raptor_iostream_read_bytes_func,
|
13
|
+
:read_eof, :raptor_iostream_read_eof_func
|
14
|
+
|
15
|
+
HANDLERS = [:init, :finish, :write_byte, :write_bytes, :read_bytes, :read_eof]
|
16
|
+
|
17
|
+
##
|
18
|
+
# The IO object to operate upon.
|
19
|
+
#
|
20
|
+
# @return [IO]
|
21
|
+
attr_accessor :io
|
22
|
+
|
23
|
+
##
|
24
|
+
# @overload initialize(ptr)
|
25
|
+
# @param [FFI::Pointer] ptr
|
26
|
+
#
|
27
|
+
# @overload initialize(io)
|
28
|
+
# @param [IO, StringIO] io
|
29
|
+
#
|
30
|
+
def initialize(ptr_or_io = nil)
|
31
|
+
if ptr_or_io.respond_to?(:write)
|
32
|
+
@io = ptr_or_io
|
33
|
+
super()
|
34
|
+
else
|
35
|
+
case ptr_or_io
|
36
|
+
when FFI::Pointer
|
37
|
+
super(ptr_or_io)
|
38
|
+
when nil
|
39
|
+
super()
|
40
|
+
else
|
41
|
+
raise ArgumentError, "invalid argument: #{ptr_or_io.inspect}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
initialize!
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# @return [void]
|
49
|
+
def initialize!
|
50
|
+
self[:version] = 2
|
51
|
+
|
52
|
+
#define_handler(:init) do |context|
|
53
|
+
# $stderr.puts("#{self.class}: init")
|
54
|
+
#end
|
55
|
+
#define_handler(:finish) do |context|
|
56
|
+
# $stderr.puts("#{self.class}: finish")
|
57
|
+
#end
|
58
|
+
define_handler(:write_byte) do |context, byte|
|
59
|
+
begin
|
60
|
+
@io.putc(byte)
|
61
|
+
0
|
62
|
+
rescue => e
|
63
|
+
$stderr.puts("#{e} in #{self.class}#write_byte")
|
64
|
+
1
|
65
|
+
end
|
66
|
+
end
|
67
|
+
define_handler(:write_bytes) do |context, data, size, nmemb|
|
68
|
+
begin
|
69
|
+
@io.write(data.read_string(size * nmemb))
|
70
|
+
0
|
71
|
+
rescue => e
|
72
|
+
$stderr.puts("#{e} in #{self.class}#write_bytes")
|
73
|
+
1
|
74
|
+
end
|
75
|
+
end
|
76
|
+
#define_handler(:write_end) do |context|
|
77
|
+
# $stderr.puts("#{self.class}: write_end")
|
78
|
+
#end
|
79
|
+
#define_handler(:read_bytes) do |context, data, size, nmemb|
|
80
|
+
# $stderr.puts("#{self.class}: read_bytes")
|
81
|
+
#end
|
82
|
+
#define_handler(:read_eof) do |context|
|
83
|
+
# $stderr.puts("#{self.class}: read_eof")
|
84
|
+
#end
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# @param [Proc] func
|
89
|
+
# @return [void]
|
90
|
+
def init_handler=(func)
|
91
|
+
define_handler(:init, &func)
|
92
|
+
end
|
93
|
+
alias_method :init=, :init_handler=
|
94
|
+
|
95
|
+
##
|
96
|
+
# @param [Proc] func
|
97
|
+
# @return [void]
|
98
|
+
def finish_handler=(func)
|
99
|
+
define_handler(:finish, &func)
|
100
|
+
end
|
101
|
+
alias_method :finish=, :finish_handler=
|
102
|
+
|
103
|
+
##
|
104
|
+
# @param [Proc] func
|
105
|
+
# @return [void]
|
106
|
+
def write_byte_handler=(func)
|
107
|
+
define_handler(:write_byte, &func)
|
108
|
+
end
|
109
|
+
alias_method :write_byte=, :write_byte_handler=
|
110
|
+
|
111
|
+
##
|
112
|
+
# @param [Proc] func
|
113
|
+
# @return [void]
|
114
|
+
def write_bytes_handler=(func)
|
115
|
+
define_handler(:write_bytes, &func)
|
116
|
+
end
|
117
|
+
alias_method :write_bytes=, :write_bytes_handler=
|
118
|
+
|
119
|
+
##
|
120
|
+
# @param [Proc] func
|
121
|
+
# @return [void]
|
122
|
+
def write_end_handler=(func)
|
123
|
+
define_handler(:write_end, &func)
|
124
|
+
end
|
125
|
+
alias_method :write_end=, :write_end_handler=
|
126
|
+
|
127
|
+
##
|
128
|
+
# @param [Proc] func
|
129
|
+
# @return [void]
|
130
|
+
def read_bytes_handler=(func)
|
131
|
+
define_handler(:read_bytes, &func)
|
132
|
+
end
|
133
|
+
alias_method :read_bytes=, :read_bytes_handler=
|
134
|
+
|
135
|
+
##
|
136
|
+
# @param [Proc] func
|
137
|
+
# @return [void]
|
138
|
+
def read_eof_handler=(func)
|
139
|
+
define_handler(:read_eof, &func)
|
140
|
+
end
|
141
|
+
alias_method :read_eof=, :read_eof_handler=
|
142
|
+
|
143
|
+
##
|
144
|
+
# @param [Symbol, #to_sym] name
|
145
|
+
# @return [void]
|
146
|
+
def define_handler(name, &block)
|
147
|
+
name = name.to_sym
|
148
|
+
raise ArgumentError, "invalid IOStreamHandler function name: #{name}" unless HANDLERS.include?(name)
|
149
|
+
@procs ||= {} # prevents premature GC of the procs
|
150
|
+
@procs[name] = self[name] = block
|
151
|
+
end
|
152
|
+
end # IOStreamHandler
|
153
|
+
end # RDF::Raptor::FFI::V1
|
@@ -0,0 +1,205 @@
|
|
1
|
+
module RDF::Raptor::FFI::V2
|
2
|
+
##
|
3
|
+
# This class provides the functionality of turning syntaxes into RDF
|
4
|
+
# triples - RDF parsing.
|
5
|
+
#
|
6
|
+
# @see http://librdf.org/raptor/api-1.4/raptor-section-parser.html
|
7
|
+
class Parser < ::FFI::ManagedStruct
|
8
|
+
include RDF::Raptor::FFI
|
9
|
+
layout :world, :pointer # the actual layout is private
|
10
|
+
|
11
|
+
# The default base URI
|
12
|
+
BASE_URI = 'file:///dev/stdin'
|
13
|
+
|
14
|
+
# The maximum chunk size for `#parse_stream`
|
15
|
+
BUFFER_SIZE = 64 * 1024
|
16
|
+
|
17
|
+
##
|
18
|
+
# @overload initialize(ptr)
|
19
|
+
# @param [FFI::Pointer] ptr
|
20
|
+
#
|
21
|
+
# @overload initialize(name)
|
22
|
+
# @param [Symbol, String] name
|
23
|
+
#
|
24
|
+
def initialize(ptr_or_name)
|
25
|
+
ptr = case ptr_or_name
|
26
|
+
when FFI::Pointer then ptr_or_name
|
27
|
+
when Symbol then V2.raptor_new_parser(V2.world, ptr_or_name.to_s)
|
28
|
+
when String then V2.raptor_new_parser(V2.world, ptr_or_name)
|
29
|
+
else nil
|
30
|
+
end
|
31
|
+
raise ArgumentError, "invalid argument: #{ptr_or_name.inspect}" if ptr.nil? || ptr.null?
|
32
|
+
super(ptr)
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Releases `libraptor` memory associated with this structure.
|
37
|
+
#
|
38
|
+
# @param [FFI::Pointer] ptr
|
39
|
+
# @return [void]
|
40
|
+
def self.release(ptr)
|
41
|
+
V2.raptor_free_parser(ptr)
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# @param [Proc] handler
|
46
|
+
# @return [void]
|
47
|
+
def error_handler=(handler)
|
48
|
+
#V2.raptor_set_error_handler(self, self, handler)
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# @param [Proc] handler
|
53
|
+
# @return [void]
|
54
|
+
def warning_handler=(handler)
|
55
|
+
#V2.raptor_set_warning_handler(self, self, handler)
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# @param [Proc] handler
|
60
|
+
# @return [void]
|
61
|
+
def statement_handler=(handler)
|
62
|
+
V2.raptor_parser_set_statement_handler(self, self, handler)
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# @param [Object] input
|
67
|
+
# the input to parse
|
68
|
+
# @param [Hash{Symbol => Object}] options
|
69
|
+
# any additional options for parsing
|
70
|
+
# @option options [String, #to_s] :base_uri (nil)
|
71
|
+
# the base URI to use when resolving relative URIs
|
72
|
+
# @yield [parser, statement]
|
73
|
+
# each statement in the input
|
74
|
+
# @yieldparam [FFI::Pointer] parser
|
75
|
+
# @yieldparam [FFI::Pointer] statement
|
76
|
+
# @yieldreturn [void] ignored
|
77
|
+
# @return [void]
|
78
|
+
def parse(input, options = {}, &block)
|
79
|
+
case input
|
80
|
+
when RDF::URI, URI, %r(^(file|https|http|ftp)://)
|
81
|
+
parse_url(input, options, &block)
|
82
|
+
when File, Tempfile
|
83
|
+
parse_file(input, options, &block)
|
84
|
+
when IO, StringIO
|
85
|
+
parse_stream(input, options, &block)
|
86
|
+
when String
|
87
|
+
parse_buffer(input, options, &block)
|
88
|
+
else
|
89
|
+
raise ArgumentError, "don't know how to parse #{input.inspect}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# @param [RDF::URI, String, #to_s] url
|
95
|
+
# the input URL to parse
|
96
|
+
# @param [Hash{Symbol => Object}] options
|
97
|
+
# any additional options for parsing (see {#parse})
|
98
|
+
# @yield [parser, statement]
|
99
|
+
# each statement in the input
|
100
|
+
# @yieldparam [FFI::Pointer] parser
|
101
|
+
# @yieldparam [FFI::Pointer] statement
|
102
|
+
# @yieldreturn [void] ignored
|
103
|
+
# @return [void]
|
104
|
+
def parse_url(url, options = {}, &block)
|
105
|
+
self.statement_handler = block if block_given?
|
106
|
+
|
107
|
+
data_url = V2::URI.new((url.respond_to?(:to_uri) ? url.to_uri : url).to_s)
|
108
|
+
base_uri = options[:base_uri].to_s.empty? ? nil : V2::URI.new(options[:base_uri].to_s)
|
109
|
+
|
110
|
+
result = V2.raptor_parser_parse_uri(self, data_url, base_uri)
|
111
|
+
# TODO: error handling if result.nonzero?
|
112
|
+
end
|
113
|
+
alias_method :parse_uri, :parse_url
|
114
|
+
|
115
|
+
##
|
116
|
+
# @param [File, Tempfile, #path] file
|
117
|
+
# the input file to parse
|
118
|
+
# @param [Hash{Symbol => Object}] options
|
119
|
+
# any additional options for parsing (see {#parse})
|
120
|
+
# @yield [parser, statement]
|
121
|
+
# each statement in the input
|
122
|
+
# @yieldparam [FFI::Pointer] parser
|
123
|
+
# @yieldparam [FFI::Pointer] statement
|
124
|
+
# @yieldreturn [void] ignored
|
125
|
+
# @return [void]
|
126
|
+
def parse_file(file, options = {}, &block)
|
127
|
+
self.statement_handler = block if block_given?
|
128
|
+
|
129
|
+
data_url = V2::URI.new("file://#{File.expand_path(file.path)}")
|
130
|
+
base_uri = options[:base_uri].to_s.empty? ? nil : V2::URI.new(options[:base_uri].to_s)
|
131
|
+
|
132
|
+
result = V2.raptor_parser_parse_file(self, data_url, base_uri)
|
133
|
+
# TODO: error handling if result.nonzero?
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# @param [IO, StringIO, #readpartial] stream
|
138
|
+
# the input stream to parse
|
139
|
+
# @param [Hash{Symbol => Object}] options
|
140
|
+
# any additional options for parsing (see {#parse})
|
141
|
+
# @yield [parser, statement]
|
142
|
+
# each statement in the input
|
143
|
+
# @yieldparam [FFI::Pointer] parser
|
144
|
+
# @yieldparam [FFI::Pointer] statement
|
145
|
+
# @yieldreturn [void] ignored
|
146
|
+
# @return [void]
|
147
|
+
def parse_stream(stream, options = {}, &block)
|
148
|
+
self.statement_handler = block if block_given?
|
149
|
+
|
150
|
+
begin
|
151
|
+
parse_start!(options[:base_uri] || BASE_URI)
|
152
|
+
loop do
|
153
|
+
parse_chunk(stream.sysread(BUFFER_SIZE))
|
154
|
+
end
|
155
|
+
rescue EOFError => e
|
156
|
+
parse_end!
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# @param [String, #to_str] buffer
|
162
|
+
# the input buffer to parse
|
163
|
+
# @param [Hash{Symbol => Object}] options
|
164
|
+
# any additional options for parsing (see {#parse})
|
165
|
+
# @yield [parser, statement]
|
166
|
+
# each statement in the input
|
167
|
+
# @yieldparam [FFI::Pointer] parser
|
168
|
+
# @yieldparam [FFI::Pointer] statement
|
169
|
+
# @yieldreturn [void] ignored
|
170
|
+
# @return [void]
|
171
|
+
def parse_buffer(buffer, options = {}, &block)
|
172
|
+
self.statement_handler = block if block_given?
|
173
|
+
|
174
|
+
parse_start!((options[:base_uri] || BASE_URI).to_s)
|
175
|
+
parse_chunk(buffer.to_str)
|
176
|
+
parse_end!
|
177
|
+
end
|
178
|
+
|
179
|
+
##
|
180
|
+
# @private
|
181
|
+
# @param [String] base_uri
|
182
|
+
# @return [void]
|
183
|
+
def parse_start!(base_uri = BASE_URI)
|
184
|
+
result = V2.raptor_parser_parse_start(self, V2::URI.new(base_uri))
|
185
|
+
# TODO: error handling if result.nonzero?
|
186
|
+
end
|
187
|
+
|
188
|
+
##
|
189
|
+
# @private
|
190
|
+
# @param [String] buffer
|
191
|
+
# the input chunk to parse
|
192
|
+
# @return [void]
|
193
|
+
def parse_chunk(buffer)
|
194
|
+
result = V2.raptor_parser_parse_chunk(self, buffer, buffer.bytesize, 0)
|
195
|
+
# TODO: error handling if result.nonzero?
|
196
|
+
end
|
197
|
+
|
198
|
+
##
|
199
|
+
# @private
|
200
|
+
# @return [void]
|
201
|
+
def parse_end!
|
202
|
+
result = V2.raptor_parser_parse_chunk(self, nil, 0, 1) # EOF
|
203
|
+
end
|
204
|
+
end # Parser
|
205
|
+
end # RDF::Raptor::FFI::V2
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module RDF::Raptor::FFI::V2
|
2
|
+
##
|
3
|
+
# This class provides the functionality of turning RDF triples into
|
4
|
+
# syntaxes - RDF serializing.
|
5
|
+
#
|
6
|
+
# @see http://librdf.org/raptor/api-1.4/raptor-section-serializer.html
|
7
|
+
class Serializer < ::FFI::ManagedStruct
|
8
|
+
include RDF::Raptor::FFI
|
9
|
+
|
10
|
+
# Note this layout is private
|
11
|
+
layout :world, :pointer,
|
12
|
+
:locator, :pointer,
|
13
|
+
:failed, :bool,
|
14
|
+
:base_uri, :pointer,
|
15
|
+
:context, :pointer,
|
16
|
+
:iostream, :pointer,
|
17
|
+
:free_iostream_on_end, :bool,
|
18
|
+
:factory, :pointer,
|
19
|
+
:options, :pointer
|
20
|
+
|
21
|
+
##
|
22
|
+
# @overload initialize(ptr)
|
23
|
+
# @param [FFI::Pointer] ptr
|
24
|
+
#
|
25
|
+
# @overload initialize(name)
|
26
|
+
# @param [Symbol, String] name
|
27
|
+
#
|
28
|
+
def initialize(ptr_or_name)
|
29
|
+
ptr = case ptr_or_name
|
30
|
+
when FFI::Pointer then ptr_or_name
|
31
|
+
when Symbol then V2.raptor_new_serializer(V2.world, ptr_or_name.to_s)
|
32
|
+
when String then V2.raptor_new_serializer(V2.world, ptr_or_name)
|
33
|
+
else nil
|
34
|
+
end
|
35
|
+
raise ArgumentError, "invalid argument: #{ptr_or_name.inspect}" if ptr.nil? || ptr.null?
|
36
|
+
super(ptr)
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Releases `libraptor` memory associated with this structure.
|
41
|
+
#
|
42
|
+
# @param [FFI::Pointer] ptr
|
43
|
+
# @return [void]
|
44
|
+
def self.release(ptr)
|
45
|
+
V2.raptor_free_serializer(ptr)
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# @param [Proc] handler
|
50
|
+
# @return [void]
|
51
|
+
def error_handler=(handler)
|
52
|
+
V2.raptor_serializer_set_error_handler(self, self, handler)
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# @param [Proc] handler
|
57
|
+
# @return [void]
|
58
|
+
def warning_handler=(handler)
|
59
|
+
V2.raptor_serializer_set_warning_handler(self, self, handler)
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# @param [Object] output
|
64
|
+
# where output should be written to
|
65
|
+
# @param [Hash{Symbol => Object}] options
|
66
|
+
# any additional options for serializing
|
67
|
+
# @option options [String, #to_s] :base_uri (nil)
|
68
|
+
# the base URI to use when resolving relative URIs
|
69
|
+
# @return [void]
|
70
|
+
def start_to(output, options = {})
|
71
|
+
if output.respond_to?(:write)
|
72
|
+
start_to_stream(output, options)
|
73
|
+
else
|
74
|
+
raise ArgumentError, "don't know how to serialize to #{output.inspect}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# @param [IO, StringIO] stream
|
80
|
+
# @param [Hash{Symbol => Object}] options
|
81
|
+
# any additional options for serializing (see {#start_to})
|
82
|
+
# @return [void]
|
83
|
+
def start_to_stream(stream, options = {})
|
84
|
+
iostream = V2::IOStream.new(V2::IOStreamHandler.new(stream), :free_iostream => self[:free_iostream_on_end])
|
85
|
+
start_to_iostream(iostream, options)
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# @param [V2::IOStream] iostream
|
90
|
+
# @param [Hash{Symbol => Object}] options
|
91
|
+
# any additional options for serializing (see {#start_to})
|
92
|
+
# @return [void]
|
93
|
+
def start_to_iostream(iostream, options = {})
|
94
|
+
@iostream = iostream # prevents premature GC
|
95
|
+
@base_uri = options[:base_uri].to_s.empty? ? nil : V2::URI.new(options[:base_uri].to_s)
|
96
|
+
if V2.raptor_serializer_start_to_iostream(self, @base_uri, @iostream).nonzero?
|
97
|
+
raise RDF::WriterError, "raptor_serialize_start_to_iostream() failed"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# @return [void]
|
103
|
+
def finish
|
104
|
+
if V2.raptor_serializer_serialize_end(self).nonzero?
|
105
|
+
raise RDF::WriterError, "raptor_serialize_end() failed"
|
106
|
+
end
|
107
|
+
@iostream = @base_uri = nil # allows GC
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# @param [RDF::Resource] subject
|
112
|
+
# @param [RDF::URI] predicate
|
113
|
+
# @param [RDF::Term] object
|
114
|
+
# @return [void]
|
115
|
+
def serialize_triple(subject, predicate, object)
|
116
|
+
raptor_statement = V2::Statement.new
|
117
|
+
raptor_statement.subject = subject
|
118
|
+
raptor_statement.predicate = predicate
|
119
|
+
raptor_statement.object = object
|
120
|
+
begin
|
121
|
+
serialize_raw_statement(raptor_statement)
|
122
|
+
ensure
|
123
|
+
raptor_statement.release
|
124
|
+
raptor_statement = nil
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
##
|
129
|
+
# @param [V2::Statement] statement
|
130
|
+
# @return [void]
|
131
|
+
def serialize_raw_statement(statement)
|
132
|
+
if V2.raptor_serializer_serialize_statement(self, statement).nonzero?
|
133
|
+
raise RDF::WriterError, "raptor_serialize_statement() failed"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end # Serializer
|
137
|
+
end # RDF::Raptor::FFI::V2
|