fossyl 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fossyl.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Adam Tanner
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # Fossyl
2
+
3
+ Pre-historic Bencoding
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'fossyl'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install fossyl
18
+
19
+ ## Usage
20
+
21
+ ```ruby
22
+ require "fossyl"
23
+
24
+ # Encoding
25
+ Fossyl.dump("strings") # => "7:strings"
26
+ Fossyl.dump(12) # => "i12e"
27
+ Fossyl.dump([1, "two", 3]) # => "li1e3:twoi3ee"
28
+ Fossyl.dump(a: 1, b: "two", c: [1]) # => "d1:ai1e1:b3:two1:cli1eee"
29
+
30
+ # Decoding
31
+ Fossyl.load("7:strings") # => "strings"
32
+ Fossyl.load("i12e") # => 12
33
+ Fossyl.load("li1e3:twoi3ee") # => [1, "two", 3]
34
+ Fossyl.load("d1:ai1e1:b3:two1:cli1eee") # => { "a" => 1, "b" => "two", "c" => [1] }
35
+ ```
36
+
37
+ ## Contributing
38
+
39
+ 1. Fork it
40
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
41
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
42
+ 4. Push to the branch (`git push origin my-new-feature`)
43
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.pattern = "spec/**/*_spec.rb"
6
+ end
data/fossyl.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'fossyl/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "fossyl"
8
+ gem.version = Fossyl::VERSION
9
+ gem.authors = ["Adam Tanner"]
10
+ gem.email = ["adam@adamtanner.org"]
11
+ gem.description = %q{Pre-historic Bencoding}
12
+ gem.summary = %q{Pre-historic Bencoding}
13
+ gem.homepage = "https://github.com/adamtanner/fossyl"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
@@ -0,0 +1,39 @@
1
+ class Parser
2
+ attr_reader :scanner
3
+
4
+ def initialize(string)
5
+ @scanner = StringScanner.new(string)
6
+ end
7
+
8
+ def parse
9
+ return parse_string if scanner.scan(/\d+/)
10
+ return parse_integer if scanner.scan(/i/)
11
+ return parse_list if scanner.scan(/l/)
12
+ return parse_dictionary if scanner.scan(/d/)
13
+
14
+ raise Fossyl::InvalidBencoding
15
+ end
16
+
17
+ private
18
+ def parse_string
19
+ length = scanner.matched.to_i
20
+ scanner.getch # Skip the ':'
21
+ length.times.map { scanner.getch }.join
22
+ end
23
+
24
+ def parse_integer
25
+ scanner.scan_until(/e/).chop.to_i
26
+ end
27
+
28
+ def parse_list
29
+ list = []
30
+ list << parse until scanner.scan(/e/)
31
+ list
32
+ end
33
+
34
+ def parse_dictionary
35
+ hash = {}
36
+ hash[parse] = parse until scanner.scan(/e/)
37
+ hash
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module Fossyl
2
+ VERSION = "0.5.0"
3
+ end
data/lib/fossyl.rb ADDED
@@ -0,0 +1,25 @@
1
+ require "fossyl/version"
2
+ require "fossyl/parser"
3
+
4
+ module Fossyl
5
+ InvalidBencoding = Class.new(StandardError)
6
+
7
+ def self.dump(object)
8
+ case object
9
+ when String, Symbol
10
+ "#{object.length}:#{object}"
11
+ when Integer
12
+ "i#{object}e"
13
+ when Array
14
+ list = object.map {|item| dump(item) }.join
15
+ "l#{list}e"
16
+ when Hash
17
+ hash = object.sort.map {|key, value| dump(key) << dump(value) }.join
18
+ "d#{hash}e"
19
+ end
20
+ end
21
+
22
+ def self.load(string)
23
+ Parser.new(string).parse
24
+ end
25
+ end
@@ -0,0 +1,46 @@
1
+ require "minitest/spec"
2
+ require "minitest/autorun"
3
+ require "fossyl"
4
+
5
+ describe Fossyl do
6
+ it "encodes strings" do
7
+ Fossyl.dump("Fossyl").must_equal("6:Fossyl")
8
+ end
9
+
10
+ it "encodes integers" do
11
+ Fossyl.dump(12).must_equal("i12e")
12
+ Fossyl.dump(-12).must_equal("i-12e")
13
+ Fossyl.dump(0).must_equal("i0e")
14
+ Fossyl.dump(-0).must_equal("i0e")
15
+ end
16
+
17
+ it "encodes lists" do
18
+ Fossyl.dump([1, "Fossyl", -12]).must_equal("li1e6:Fossyli-12ee")
19
+ end
20
+
21
+ it "encodes dictionaries" do
22
+ Fossyl.dump(string: "Fossyl", integer: -12, list: [0, 12]).must_equal("d7:integeri-12e4:listli0ei12ee6:string6:Fossyle")
23
+ end
24
+
25
+ it "decodes strings" do
26
+ Fossyl.load("6:Fossyl").must_equal("Fossyl")
27
+ end
28
+
29
+ it "decodes integers" do
30
+ Fossyl.load("i12e").must_equal(12)
31
+ Fossyl.load("i-12e").must_equal(-12)
32
+ Fossyl.load("i0e").must_equal(0)
33
+ end
34
+
35
+ it "decodes lists" do
36
+ Fossyl.load("li1e6:Fossyli-12ee").must_equal([1, "Fossyl", -12])
37
+ end
38
+
39
+ it "decodes dictionaries" do
40
+ Fossyl.load("d7:integeri-12e4:listli0ei12ee6:string6:Fossyle").must_equal("string" => "Fossyl", "integer" => -12, "list" => [0, 12])
41
+ end
42
+
43
+ it "does not decode invalid data" do
44
+ ->{ Fossyl.load("d6:invalidli0e6:stringe") }.must_raise Fossyl::InvalidBencoding
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fossyl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Adam Tanner
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-30 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Pre-historic Bencoding
15
+ email:
16
+ - adam@adamtanner.org
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - LICENSE.txt
24
+ - README.md
25
+ - Rakefile
26
+ - fossyl.gemspec
27
+ - lib/fossyl.rb
28
+ - lib/fossyl/parser.rb
29
+ - lib/fossyl/version.rb
30
+ - spec/fossyl_spec.rb
31
+ homepage: https://github.com/adamtanner/fossyl
32
+ licenses: []
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ segments:
44
+ - 0
45
+ hash: -3067863346800401168
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ segments:
53
+ - 0
54
+ hash: -3067863346800401168
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 1.8.23
58
+ signing_key:
59
+ specification_version: 3
60
+ summary: Pre-historic Bencoding
61
+ test_files:
62
+ - spec/fossyl_spec.rb