diff --git a/README.md b/README.md index 7e0b039..9b8cfdd 100644 --- a/README.md +++ b/README.md @@ -3,17 +3,21 @@ [![License](https://img.shields.io/badge/license-Public%20Domain-blue.svg)](https://unlicense.org) [![Compatibility](https://img.shields.io/badge/ruby-3.0%2B-blue)](https://rubygems.org/gems/rdf-borsh) [![Package](https://img.shields.io/gem/v/rdf-borsh)](https://rubygems.org/gems/rdf-borsh) +[![Documentation](https://img.shields.io/badge/rubydoc-latest-blue)](https://rubydoc.info/gems/rdf-borsh) -An [RDF.rb] extension for encoding and decoding [RDF] knowledge graphs in -the [Borsh] binary serialization format. +**RDF/Borsh** is a [Ruby] library and [RDF.rb] extension for encoding +and decoding [RDF] knowledge graphs in the [Borsh] binary serialization +format. -[Borsh]: https://borsh.io -[RDF]: https://www.w3.org/TR/rdf12-concepts/ -[RDF.rb]: https://github.com/ruby-rdf/rdf +## ✨ Features + +- 100% pure Ruby with minimal dependencies and no bloat. +- Plays nice with others: entirely contained in the `RDF::Borsh` module. +- 100% free and unencumbered public domain software. ## 🛠️ Prerequisites -- [Ruby](https://ruby-lang.org) 3.0+ +- [Ruby] 3.0+ ## ⬇️ Installation @@ -54,6 +58,10 @@ graph.to_a RDF::Borsh::Reader.new($stdin).to_a ``` +## 📚 Reference + +https://rubydoc.info/gems/rdf-borsh + ## 👨‍💻 Development ```bash @@ -66,3 +74,8 @@ git clone https://github.com/ruby-rdf/rdf-borsh.git [![Share on Reddit](https://img.shields.io/badge/share%20on-reddit-red?logo=reddit)](https://reddit.com/submit?url=https://github.com/ruby-rdf/rdf-borsh&title=RDF%2FBorsh+for+Ruby) [![Share on Hacker News](https://img.shields.io/badge/share%20on-hacker%20news-orange?logo=ycombinator)](https://news.ycombinator.com/submitlink?u=https://github.com/ruby-rdf/rdf-borsh&t=RDF%2FBorsh+for+Ruby) [![Share on Facebook](https://img.shields.io/badge/share%20on-facebook-1976D2?logo=facebook)](https://www.facebook.com/sharer/sharer.php?u=https://github.com/ruby-rdf/rdf-borsh) + +[Borsh]: https://borsh.io +[RDF]: https://www.w3.org/TR/rdf12-concepts/ +[RDF.rb]: https://github.com/ruby-rdf/rdf +[Ruby]: https://ruby-lang.org diff --git a/lib/rdf/borsh.rb b/lib/rdf/borsh.rb index f35e119..52bbb5a 100644 --- a/lib/rdf/borsh.rb +++ b/lib/rdf/borsh.rb @@ -1,8 +1,10 @@ # This is free and unencumbered software released into the public domain. +require 'rdf' + module RDF ## - # RDF/Borsh. + # RDF/Borsh extension for RDF.rb. module Borsh autoload :Format, 'rdf/borsh/format' autoload :Reader, 'rdf/borsh/reader' @@ -10,4 +12,4 @@ module Borsh end end -require 'rdf/borsh/version' +require_relative 'borsh/version' diff --git a/lib/rdf/borsh/reader.rb b/lib/rdf/borsh/reader.rb index 00cb912..4866f60 100644 --- a/lib/rdf/borsh/reader.rb +++ b/lib/rdf/borsh/reader.rb @@ -1,5 +1,6 @@ # This is free and unencumbered software released into the public domain. +require 'borsh' require 'extlz4' require 'rdf' require 'stringio' @@ -15,15 +16,17 @@ class Reader < RDF::Reader def initialize(input = $stdin, **options, &block) super(input, **options) do input = @input + + @input.extend(Borsh::Readable) @version, @flags, @quad_count = self.read_header - input_size = input.read(4).unpack('V').first - @input = StringIO.new(self.decompress(input.read(input_size)), 'rb') + input_size = input.read_u32 + @input = Borsh::Buffer.new(self.decompress(input.read(input_size))) @terms = [nil] + self.read_terms - input_size = input.read(4).unpack('V').first - @input = StringIO.new(self.decompress(input.read(input_size)), 'rb') - _ = @input.read(4).unpack('V').first + input_size = input.read_u32 + @input = Borsh::Buffer.new(self.decompress(input.read(input_size))) + _ = @input.read_u32 if block_given? case block.arity @@ -46,9 +49,9 @@ def read_triple; self.read_statement.to_triple; end ## # Reads the compressed terms dictionary. def read_terms - term_count = @input.read(4).unpack('V').first + term_count = @input.read_u32 term_count.times.map do - term_kind, term_string_size = @input.read(5).unpack('CV') + term_kind, term_string_size = @input.read_u8, @input.read_u32 term_string = @input.read(term_string_size) case term_kind @@ -56,10 +59,10 @@ def read_terms when 2 then RDF::Node(term_string) when 3 then RDF::Literal(term_string) when 4 - term_datatype_size = @input.read(4).unpack('V') + term_datatype_size = @input.read_u32 RDF::Literal(term_string, datatype: @input.read(term_datatype_size)) when 5 - term_language_size = @input.read(4).unpack('V') + term_language_size = @input.read_u32 RDF::Literal(term_string, language: @input.read(term_language_size)) else raise RDF::ReaderError, "unknown RDF/Borsh term type: #{term_kind}" @@ -73,13 +76,13 @@ def read_header magic = @input.read(4).unpack('a4').first raise RDF::ReaderError, "invalid RDF/Borsh header: #{magic.inspect}" if magic != MAGIC - version = @input.read(1).unpack('C').first + version = @input.read_u8 raise RDF::ReaderError, "invalid RDF/Borsh version: #{version}" if version != VERSION - flags = @input.read(1).unpack('C').first + flags = @input.read_u8 raise RDF::ReaderError, "invalid RDF/Borsh flags: #{flags}" if flags != FLAGS - quad_count = @input.read(4).unpack('V').first + quad_count = @input.read_u32 [version, flags, quad_count] end diff --git a/rdf-borsh.gemspec b/rdf-borsh.gemspec index f87955b..dc7f77b 100644 --- a/rdf-borsh.gemspec +++ b/rdf-borsh.gemspec @@ -10,7 +10,7 @@ Gem::Specification.new do |gem| gem.metadata = { 'bug_tracker_uri' => "https://github.com/ruby-rdf/rdf-borsh/issues", 'changelog_uri' => "https://github.com/ruby-rdf/rdf-borsh/blob/master/CHANGES.md", - 'documentation_uri' => "https://github.com/ruby-rdf/rdf-borsh/blob/master/README.md", + 'documentation_uri' => "https://rubydoc.info/gems/rdf-borsh", 'homepage_uri' => gem.homepage, 'source_code_uri' => "https://github.com/ruby-rdf/rdf-borsh", } @@ -24,7 +24,7 @@ Gem::Specification.new do |gem| gem.executables = %w() gem.required_ruby_version = '>= 3.0' # RDF.rb 3.3 - gem.add_runtime_dependency 'borsh', '~> 0.0' + gem.add_runtime_dependency 'borsh', '~> 0.1' gem.add_runtime_dependency 'extlz4', '~> 0.3' gem.add_runtime_dependency 'rdf', '~> 3.3' gem.add_runtime_dependency 'sorted_set', '~> 1.0'