rdf-raptor 0.4.0 → 0.4.1

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.
@@ -0,0 +1,128 @@
1
+ module RDF::Raptor::FFI::V1
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
+ layout :world, :pointer # the actual layout is private
10
+
11
+ ##
12
+ # @overload initialize(ptr)
13
+ # @param [FFI::Pointer] ptr
14
+ #
15
+ # @overload initialize(name)
16
+ # @param [Symbol, String] name
17
+ #
18
+ def initialize(ptr_or_name)
19
+ ptr = case ptr_or_name
20
+ when FFI::Pointer then ptr_or_name
21
+ when Symbol then V1.raptor_new_serializer(ptr_or_name.to_s)
22
+ when String then V1.raptor_new_serializer(ptr_or_name)
23
+ else nil
24
+ end
25
+ raise ArgumentError, "invalid argument: #{ptr_or_name.inspect}" if ptr.nil? || ptr.null?
26
+ super(ptr)
27
+ end
28
+
29
+ ##
30
+ # Releases `libraptor` memory associated with this structure.
31
+ #
32
+ # @param [FFI::Pointer] ptr
33
+ # @return [void]
34
+ def self.release(ptr)
35
+ V1.raptor_free_serializer(ptr)
36
+ end
37
+
38
+ ##
39
+ # @param [Proc] handler
40
+ # @return [void]
41
+ def error_handler=(handler)
42
+ V1.raptor_serializer_set_error_handler(self, self, handler)
43
+ end
44
+
45
+ ##
46
+ # @param [Proc] handler
47
+ # @return [void]
48
+ def warning_handler=(handler)
49
+ V1.raptor_serializer_set_warning_handler(self, self, handler)
50
+ end
51
+
52
+ ##
53
+ # @param [Object] output
54
+ # where output should be written to
55
+ # @param [Hash{Symbol => Object}] options
56
+ # any additional options for serializing
57
+ # @option options [String, #to_s] :base_uri (nil)
58
+ # the base URI to use when resolving relative URIs
59
+ # @return [void]
60
+ def start_to(output, options = {})
61
+ case output
62
+ when IO, StringIO
63
+ start_to_stream(output, options)
64
+ else
65
+ raise ArgumentError, "don't know how to serialize to #{output.inspect}"
66
+ end
67
+ end
68
+
69
+ ##
70
+ # @param [IO, StringIO] stream
71
+ # @param [Hash{Symbol => Object}] options
72
+ # any additional options for serializing (see {#start_to})
73
+ # @return [void]
74
+ def start_to_stream(stream, options = {})
75
+ iostream = V1::IOStream.new(V1::IOStreamHandler.new(stream))
76
+ start_to_iostream(iostream, options)
77
+ end
78
+
79
+ ##
80
+ # @param [V1::IOStream] iostream
81
+ # @param [Hash{Symbol => Object}] options
82
+ # any additional options for serializing (see {#start_to})
83
+ # @return [void]
84
+ def start_to_iostream(iostream, options = {})
85
+ @iostream = iostream # prevents premature GC
86
+ @base_uri = options[:base_uri].to_s.empty? ? nil : V1::URI.new(options[:base_uri].to_s)
87
+ if V1.raptor_serialize_start_to_iostream(self, @base_uri, @iostream).nonzero?
88
+ raise RDF::WriterError, "raptor_serialize_start_to_iostream() failed"
89
+ end
90
+ end
91
+
92
+ ##
93
+ # @return [void]
94
+ def finish
95
+ if V1.raptor_serialize_end(self).nonzero?
96
+ raise RDF::WriterError, "raptor_serialize_end() failed"
97
+ end
98
+ @iostream = @base_uri = nil # allows GC
99
+ end
100
+
101
+ ##
102
+ # @param [RDF::Resource] subject
103
+ # @param [RDF::URI] predicate
104
+ # @param [RDF::Term] object
105
+ # @return [void]
106
+ def serialize_triple(subject, predicate, object)
107
+ raptor_statement = V1::Statement.new
108
+ raptor_statement.subject = subject
109
+ raptor_statement.predicate = predicate
110
+ raptor_statement.object = object
111
+ begin
112
+ serialize_raw_statement(raptor_statement)
113
+ ensure
114
+ raptor_statement.release
115
+ raptor_statement = nil
116
+ end
117
+ end
118
+
119
+ ##
120
+ # @param [V1::Statement] statement
121
+ # @return [void]
122
+ def serialize_raw_statement(statement)
123
+ if V1.raptor_serialize_statement(self, statement).nonzero?
124
+ raise RDF::WriterError, "raptor_serialize_statement() failed"
125
+ end
126
+ end
127
+ end # Serializer
128
+ end # RDF::Raptor::FFI::V1
@@ -0,0 +1,233 @@
1
+ module RDF::Raptor::FFI::V1
2
+ ##
3
+ # @see http://librdf.org/raptor/api-1.4/raptor-section-triples.html
4
+ class Statement < ::FFI::Struct
5
+ include RDF::Raptor::FFI
6
+ layout :subject, :pointer,
7
+ :subject_type, :int,
8
+ :predicate, :pointer,
9
+ :predicate_type, :int,
10
+ :object, :pointer,
11
+ :object_type, :int,
12
+ :object_literal_datatype, :pointer,
13
+ :object_literal_language, :pointer
14
+
15
+ ##
16
+ # @param [FFI::Pointer] ptr
17
+ # @param [#create_node] factory
18
+ def initialize(ptr = nil, factory = nil)
19
+ super(ptr)
20
+ @factory = factory if factory
21
+ end
22
+
23
+ ##
24
+ # Releases `libraptor` memory associated with this structure.
25
+ #
26
+ # @param [FFI::Pointer] ptr
27
+ # @return [void]
28
+ def self.release(ptr)
29
+ raptor_free_memory(ptr) unless ptr.null?
30
+ end
31
+
32
+ # @return [Object]
33
+ attr_accessor :id
34
+
35
+ # @return [RDF::Resource]
36
+ attr_accessor :context
37
+
38
+ ##
39
+ # @return [RDF::Resource]
40
+ def subject
41
+ @subject ||= case self[:subject_type]
42
+ when RAPTOR_IDENTIFIER_TYPE_ANONYMOUS
43
+ @factory.create_node(self[:subject].read_string)
44
+ when RAPTOR_IDENTIFIER_TYPE_RESOURCE
45
+ @factory.create_uri(V1.raptor_uri_as_string(self[:subject]))
46
+ end
47
+ end
48
+
49
+ ##
50
+ # Sets the subject term from an `RDF::Resource`.
51
+ #
52
+ # @param [RDF::Resource] value
53
+ # @return [void]
54
+ def subject=(resource)
55
+ @subject = nil
56
+ case resource
57
+ when RDF::Node
58
+ self[:subject_type] = RAPTOR_IDENTIFIER_TYPE_ANONYMOUS
59
+ self[:subject] = V1.raptor_new_string(resource.id.to_s)
60
+ when RDF::URI
61
+ self[:subject_type] = RAPTOR_IDENTIFIER_TYPE_RESOURCE
62
+ self[:subject] = V1.raptor_new_uri(resource.to_s)
63
+ else
64
+ raise ArgumentError, "subject term must be an RDF::Node or RDF::URI"
65
+ end
66
+ @subject = resource
67
+ end
68
+
69
+ ##
70
+ # @return [String]
71
+ def subject_as_string
72
+ V1.raptor_statement_part_as_string(
73
+ self[:subject],
74
+ self[:subject_type],
75
+ nil, nil)
76
+ end
77
+
78
+ ##
79
+ # @return [RDF::URI]
80
+ def predicate
81
+ @predicate ||= case self[:predicate_type]
82
+ when RAPTOR_IDENTIFIER_TYPE_RESOURCE
83
+ RDF::URI.intern(V1.raptor_uri_as_string(self[:predicate]))
84
+ end
85
+ end
86
+
87
+ ##
88
+ # Sets the predicate term from an `RDF::URI`.
89
+ #
90
+ # @param [RDF::URI] value
91
+ # @return [void]
92
+ def predicate=(uri)
93
+ @predicate = nil
94
+ raise ArgumentError, "predicate term must be an RDF::URI" unless uri.is_a?(RDF::URI)
95
+ self[:predicate_type] = RAPTOR_IDENTIFIER_TYPE_RESOURCE
96
+ self[:predicate] = V1.raptor_new_uri(uri.to_s)
97
+ @predicate = uri
98
+ end
99
+
100
+ ##
101
+ # @return [String]
102
+ def predicate_as_string
103
+ V1.raptor_statement_part_as_string(
104
+ self[:predicate],
105
+ self[:predicate_type],
106
+ nil, nil)
107
+ end
108
+
109
+ ##
110
+ # @return [RDF::Term]
111
+ def object
112
+ @object ||= case self[:object_type]
113
+ when RAPTOR_IDENTIFIER_TYPE_ANONYMOUS
114
+ @factory.create_node(self[:object].read_string)
115
+ when RAPTOR_IDENTIFIER_TYPE_RESOURCE
116
+ @factory.create_uri(V1.raptor_uri_as_string(self[:object]))
117
+ when RAPTOR_IDENTIFIER_TYPE_LITERAL
118
+ str = self[:object].read_string.unpack('U*').pack('U*')
119
+ case
120
+ when !self[:object_literal_language].null?
121
+ RDF::Literal.new(str, :language => self[:object_literal_language].read_string)
122
+ when !self[:object_literal_datatype].null?
123
+ RDF::Literal.new(str, :datatype => V1.raptor_uri_as_string(self[:object_literal_datatype]))
124
+ else
125
+ RDF::Literal.new(str)
126
+ end
127
+ end
128
+ end
129
+
130
+ ##
131
+ # Sets the object term from an `RDF::Term`.
132
+ #
133
+ # The value must be one of `RDF::Resource` or `RDF::Literal`.
134
+ #
135
+ # @param [RDF::Term] value
136
+ # @return [void]
137
+ def object=(value)
138
+ @object = nil
139
+ case value
140
+ when RDF::Node
141
+ self[:object_type] = RAPTOR_IDENTIFIER_TYPE_ANONYMOUS
142
+ self[:object] = V1.raptor_new_string(value.id.to_s)
143
+ when RDF::URI
144
+ self[:object_type] = RAPTOR_IDENTIFIER_TYPE_RESOURCE
145
+ self[:object] = V1.raptor_new_uri(value.to_s)
146
+ when RDF::Literal
147
+ self[:object_type] = RAPTOR_IDENTIFIER_TYPE_LITERAL
148
+ self[:object] = V1.raptor_new_string(value.value)
149
+ self[:object_literal_datatype] = V1.raptor_new_uri(value.datatype.to_s) if value.datatype
150
+ self[:object_literal_language] = V1.raptor_new_string(value.language.to_s) if value.language?
151
+ else
152
+ raise ArgumentError, "object term must be an RDF::Node, RDF::URI, or RDF::Literal"
153
+ end
154
+ @object = value
155
+ end
156
+
157
+ ##
158
+ # @return [String]
159
+ def object_as_string
160
+ V1.raptor_statement_part_as_string(
161
+ self[:object],
162
+ self[:object_type],
163
+ self[:object_literal_datatype],
164
+ self[:object_literal_language])
165
+ end
166
+
167
+ ##
168
+ # @return [Array(RDF::Resource, RDF::URI, RDF::Term)]
169
+ # @see RDF::Statement#to_triple
170
+ def to_triple
171
+ [subject, predicate, object]
172
+ end
173
+
174
+ ##
175
+ # @return [Array(RDF::Resource, RDF::URI, RDF::Term, nil)]
176
+ # @see RDF::Statement#to_quad
177
+ def to_quad
178
+ [subject, predicate, object, context]
179
+ end
180
+
181
+ ##
182
+ # @return [RDF::Statement]
183
+ def to_rdf
184
+ RDF::Statement.new(subject, predicate, object, :context => context)
185
+ end
186
+
187
+ ##
188
+ # @return [void]
189
+ def reset!
190
+ @subject = @predicate = @object = @context = nil
191
+ end
192
+
193
+ ##
194
+ # Releases `libraptor` memory associated with this structure.
195
+ #
196
+ # @return [void]
197
+ def free
198
+ if self[:subject_type].nonzero? && !(self[:subject].null?)
199
+ self[:subject] = case self[:subject_type]
200
+ when RAPTOR_IDENTIFIER_TYPE_ANONYMOUS
201
+ V1.raptor_free_string(self[:subject])
202
+ when RAPTOR_IDENTIFIER_TYPE_RESOURCE
203
+ V1.raptor_free_uri(self[:subject])
204
+ end
205
+ self[:subject_type] = RAPTOR_IDENTIFIER_TYPE_UNKNOWN
206
+ end
207
+
208
+ if self[:predicate_type].nonzero? && !(self[:predicate].null?)
209
+ self[:predicate] = V1.raptor_free_uri(self[:predicate])
210
+ self[:predicate_type] = RAPTOR_IDENTIFIER_TYPE_UNKNOWN
211
+ end
212
+
213
+ if self[:object_type].nonzero? && !(self[:object].null?)
214
+ self[:object] = case self[:object_type]
215
+ when RAPTOR_IDENTIFIER_TYPE_ANONYMOUS
216
+ V1.raptor_free_string(self[:object])
217
+ when RAPTOR_IDENTIFIER_TYPE_RESOURCE
218
+ V1.raptor_free_uri(self[:object])
219
+ when RAPTOR_IDENTIFIER_TYPE_LITERAL
220
+ V1.raptor_free_string(self[:object])
221
+ unless self[:object_literal_datatype].null?
222
+ self[:object_literal_datatype] = V1.raptor_free_uri(self[:object_literal_datatype])
223
+ end
224
+ unless self[:object_literal_language].null?
225
+ self[:object_literal_language] = V1.raptor_free_string(self[:object_literal_language])
226
+ end
227
+ end
228
+ self[:object_type] = RAPTOR_IDENTIFIER_TYPE_UNKNOWN
229
+ end
230
+ end
231
+ alias_method :release, :free
232
+ end # Statement
233
+ end # RDF::Raptor::FFI::V1
@@ -0,0 +1,111 @@
1
+ module RDF::Raptor::FFI::V1
2
+ ##
3
+ # Raptor has a `raptor_uri` class which must be used for manipulating and
4
+ # passing URI references. The default internal implementation uses `char*`
5
+ # strings for URIs, manipulating them and constructing them.
6
+ #
7
+ # @see http://librdf.org/raptor/api-1.4/raptor-section-uri.html
8
+ class URI < ::FFI::ManagedStruct
9
+ include RDF::Raptor::FFI
10
+ include RDF::Resource
11
+ layout :string, [:char, 1] # a safe dummy layout, since it is \0-terminated
12
+
13
+ ##
14
+ # @overload initialize(ptr)
15
+ # @param [FFI::Pointer] ptr
16
+ #
17
+ # @overload initialize(name)
18
+ # @param [RDF::URI, String] name
19
+ #
20
+ def initialize(ptr_or_name)
21
+ ptr = case ptr_or_name
22
+ when FFI::Pointer then ptr_or_name
23
+ when RDF::URI then V1.raptor_new_uri(ptr_or_name.to_s)
24
+ when String then V1.raptor_new_uri(ptr_or_name)
25
+ else nil
26
+ end
27
+ raise ArgumentError, "invalid argument: #{ptr_or_name.inspect}" if ptr.nil? || ptr.null?
28
+ super(ptr)
29
+ end
30
+
31
+ ##
32
+ # Releases `libraptor` memory associated with this structure.
33
+ #
34
+ # @param [FFI::Pointer] ptr
35
+ # @return [void]
36
+ def self.release(ptr)
37
+ V1.raptor_free_uri(ptr)
38
+ end
39
+
40
+ ##
41
+ # @return [Boolean] `true`
42
+ def uri?
43
+ true
44
+ end
45
+
46
+ ##
47
+ # @return [URI] a copy of `self`
48
+ def dup
49
+ copy = self.class.new(V1.raptor_uri_copy(self))
50
+ copy.taint if tainted?
51
+ copy
52
+ end
53
+
54
+ ##
55
+ # @return [URI] a copy of `self`
56
+ def clone
57
+ copy = self.class.new(V1.raptor_uri_copy(self))
58
+ copy.taint if tainted?
59
+ copy.freeze if frozen?
60
+ copy
61
+ end
62
+
63
+ ##
64
+ # @return [Integer]
65
+ def length
66
+ LibC.strlen(self)
67
+ end
68
+ alias_method :size, :length
69
+
70
+ ##
71
+ # @return [Boolean] `true` or `false`
72
+ def ==(other)
73
+ return true if self.equal?(other)
74
+ case other
75
+ when self.class
76
+ !(V1.raptor_uri_equals(self, other).zero?)
77
+ when RDF::URI, String
78
+ to_str == other.to_str
79
+ else false
80
+ end
81
+ end
82
+ alias_method :===, :==
83
+
84
+ ##
85
+ # @return [Boolean] `true` or `false`
86
+ def eql?(other)
87
+ return true if self.equal?(other)
88
+ other.is_a?(self.class) && !(V1.raptor_uri_equals(self, other).zero?)
89
+ end
90
+
91
+ ##
92
+ # @return [Fixnum]
93
+ def hash
94
+ to_str.hash
95
+ end
96
+
97
+ ##
98
+ # @return [String] the URI string
99
+ def to_str
100
+ V1.raptor_uri_as_string(self)
101
+ end
102
+ alias_method :to_s, :to_str
103
+
104
+ ##
105
+ # @return [RDF::URI]
106
+ def to_rdf
107
+ RDF::URI.intern(to_str)
108
+ end
109
+ alias_method :to_uri, :to_rdf
110
+ end # URI
111
+ end # RDF::Raptor::FFI::V1