digest_extensions 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec CHANGED
@@ -1 +1,2 @@
1
+ --format doc
1
2
  --color
data/Gemfile CHANGED
@@ -7,7 +7,7 @@ source "http://rubygems.org"
7
7
  # Include everything needed to run rake, tests, features, etc.
8
8
  group :development do
9
9
  gem "rspec", "~> 2.6.0"
10
- gem "bundler", "~> 1.0.0"
10
+ gem "bundler", "~> 1.0"
11
11
  gem "jeweler", "~> 1.6.4"
12
12
  gem "rake-compiler", "~> 0.7.9"
13
13
  # gem "rcov", ">= 0"
@@ -1,9 +1,46 @@
1
1
  = digest_extensions
2
2
 
3
- Description goes here.
3
+ Extension to the Digest module of the ruby standard library to support marshalling
4
+
5
+ With this gem you can accumulatively compute the digest of a byte
6
+ sequence over several executions by storing the marshalled digest
7
+ object in a database:
8
+
9
+ class FakeDatabase
10
+ attr_accessor :value
11
+ end
12
+ @db = FakeDatabase.new
13
+
14
+ def update_digest(part)
15
+ marshalled_digest = Marshal::load(@db.value) # Fetch the last digest from database
16
+ marshalled_digest << part # Compute digest incrementally
17
+ @db.value = Marshal::dump(marshalled_digest) # Store updated digest in database
18
+ end
19
+
20
+ ## parts_array is provided; for example as a series of files
21
+ ## generated with the command split on a larger file.
22
+ @db.value = Marshal::dump(Digest::MD5.new) #An initial value
23
+ parts_array.each do |part|
24
+ # Assume this method is invoked in a new process each time, and
25
+ # the only thing they share is the database (faked in the example with @db)
26
+ update_digest(part)
27
+ end
28
+ Marshal::load(@db.value).hexdigest.should == Digest::MD5.hexdigest(parts_array.inject("", :+))
29
+
30
+ The plan is to have this feature to be included in the ruby standard library.
31
+
32
+ == Known issues
33
+
34
+ Currently the marshalled values are specific to the underlying native
35
+ library used to compute the digest values. That means that if you are
36
+ using a ruby that is compiled with linkage to OpenSSL as the
37
+ underlying md5 library, then the marshalled values (in the database)
38
+ cannot be used with a ruby version compiled with linkage to rubys
39
+ native md5 implementation. So take care of that when you consider
40
+ upgrading your ruby version.
4
41
 
5
42
  == Contributing to digest_extensions
6
-
43
+
7
44
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
45
  * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
46
  * Fork the project
@@ -14,6 +51,6 @@ Description goes here.
14
51
 
15
52
  == Copyright
16
53
 
17
- Copyright (c) 2011 Jarl Friis. See LICENSE.txt for
54
+ Copyright (c) 2011-2012 Jarl Friis. See LICENSE.txt for
18
55
  further details.
19
56
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.3
1
+ 0.1.0
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{digest_extensions}
8
- s.version = "0.0.2"
7
+ s.name = "digest_extensions"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jarl Friis"]
12
- s.date = %q{2011-10-11}
13
- s.description = %q{With marshalling of digest objects, it is possible to compute the digests over several executions by storing the marshalled object on file or database, this is handy for computing digests for large files that comes in parts.}
14
- s.email = %q{jarl@softace.dk}
12
+ s.date = "2012-08-05"
13
+ s.description = "With marshalling of digest objects, it is possible to compute the digests over several executions by storing the marshalled object on file or database, this is handy for computing digests for large files that comes in parts."
14
+ s.email = "jarl@softace.dk"
15
15
  s.extensions = ["ext/digest_extensions/extconf.rb"]
16
16
  s.extra_rdoc_files = [
17
17
  "LICENSE.txt",
@@ -21,7 +21,6 @@ Gem::Specification.new do |s|
21
21
  ".document",
22
22
  ".rspec",
23
23
  "Gemfile",
24
- "Gemfile.lock",
25
24
  "LICENSE.txt",
26
25
  "README.rdoc",
27
26
  "Rakefile",
@@ -34,30 +33,29 @@ Gem::Specification.new do |s|
34
33
  "spec/digest_extensions_spec.rb",
35
34
  "spec/spec_helper.rb"
36
35
  ]
37
- s.homepage = %q{http://github.com/jarl-dk/digest_extensions}
36
+ s.homepage = "http://github.com/jarl-dk/digest_extensions"
38
37
  s.licenses = ["GPL"]
39
38
  s.require_paths = ["lib"]
40
- s.rubygems_version = %q{1.3.7}
41
- s.summary = %q{Extensions to the Digest module of the ruby standard library to support marshalling}
39
+ s.rubygems_version = "1.8.24"
40
+ s.summary = "Extensions to the Digest module of the ruby standard library to support marshalling"
42
41
 
43
42
  if s.respond_to? :specification_version then
44
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
45
43
  s.specification_version = 3
46
44
 
47
45
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
48
46
  s.add_development_dependency(%q<rspec>, ["~> 2.6.0"])
49
- s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
47
+ s.add_development_dependency(%q<bundler>, ["~> 1.0"])
50
48
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
51
49
  s.add_development_dependency(%q<rake-compiler>, ["~> 0.7.9"])
52
50
  else
53
51
  s.add_dependency(%q<rspec>, ["~> 2.6.0"])
54
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
52
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
55
53
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
56
54
  s.add_dependency(%q<rake-compiler>, ["~> 0.7.9"])
57
55
  end
58
56
  else
59
57
  s.add_dependency(%q<rspec>, ["~> 2.6.0"])
60
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
58
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
61
59
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
62
60
  s.add_dependency(%q<rake-compiler>, ["~> 0.7.9"])
63
61
  end
@@ -4,29 +4,42 @@ require 'digest/md5'
4
4
 
5
5
  describe Digest::MD5 do
6
6
  describe "#marshal_dump" do
7
+ it "can marshal md5 sum for empty object " do
8
+ digest = Digest::MD5.new
9
+ digest.marshal_dump
10
+ end
11
+
7
12
  it "returns a byte sequence that is larger than 176" do
8
13
  ## 88 bytes is minum state information for MD5
9
14
  digest = Digest::MD5.new
10
15
  digest.marshal_dump.should have_at_least(176).bytes.to_a
11
16
  end
12
17
 
13
- it "returns a byte sequence that is accepted by marshal_load" do
14
- Digest::MD5.new.marshal_load(Digest::MD5.new.marshal_dump)
15
- end
16
- end
17
- it "can marshal md5 sum for empty object " do
18
- digest = Digest::MD5.new
19
- digest.marshal_load(Digest::MD5.new.marshal_dump)
20
- digest.hexdigest.should == Digest::MD5.new.hexdigest
21
18
  end
22
- it "can marshal md5 sum objects " do
23
- byte_sequence = rand(256).chr("binary") * 100000
24
- hex_digest = Digest::MD5.hexdigest(byte_sequence)
25
- d = Digest::MD5.new
26
- d << byte_sequence
27
- md = d.marshal_dump
28
- Digest::MD5.new.tap{|h|h.marshal_load(md)}.hexdigest.should == hex_digest
19
+
20
+ describe "#marshal_load" do
21
+ context "with a marshalled digest of empty byte sequence" do
22
+ digest = Digest::MD5.new
23
+ marshalled_digest = digest.marshal_dump
24
+
25
+ it "can load to the correct digest" do
26
+ Digest::MD5.new.tap{|h|h.marshal_load(marshalled_digest)}.hexdigest.should == digest.hexdigest
27
+ end
28
+ end
29
+
30
+ context "with marshalled digest of a random byte sequence" do
31
+ size = 10000
32
+ byte_sequence = (0...size).map{|i| rand(256)}.pack('c*')
33
+ digest = Digest::MD5.new
34
+ digest << byte_sequence
35
+ marshalled_digest = digest.marshal_dump
36
+
37
+ it "can load to the correct digest " do
38
+ Digest::MD5.new.tap{|h|h.marshal_load(marshalled_digest)}.hexdigest.should == digest.hexdigest
39
+ end
40
+ end
29
41
  end
42
+
30
43
  it "can continue on partial digestions " do
31
44
  size = 10000
32
45
  byte_sequence = (0...size).map{|i| rand(256)}.pack('c*')
@@ -39,4 +52,35 @@ describe Digest::MD5 do
39
52
  continue << byte_sequence[split+1..-1]
40
53
  continue.hexdigest.should == hex_digest
41
54
  end
55
+
56
+ context "with an array of parts" do
57
+ size = 1000000
58
+ byte_sequence = (0...size).map{|i| rand(256)}.pack('c*')
59
+ parts = 100 + rand(900)
60
+ max_size = size/parts #Integer
61
+ parts_array = (0..parts).map{|p| byte_sequence[(p*max_size)...((p+1)*max_size)]}
62
+
63
+ it "can be used to take a series of parts and compute the digest of the concatenation" do
64
+ class FakeDatabase
65
+ attr_accessor :value
66
+ end
67
+ @db = FakeDatabase.new
68
+
69
+ def update_digest(part)
70
+ marshalled_digest = Marshal::load(@db.value) # Fetch the last digest from database
71
+ marshalled_digest << part # Compute digest incrementally
72
+ @db.value = Marshal::dump(marshalled_digest) # Store updated digest in database
73
+ end
74
+
75
+ ## parts_array is provided; for example as a series of files
76
+ ## generated with the command split on a larger file.
77
+ @db.value = Marshal::dump(Digest::MD5.new) #An initial value
78
+ parts_array.each do |part|
79
+ # Assume this method is invoked in a new process each time, and
80
+ # the only thing they share is the database (faked in the example with @db)
81
+ update_digest(part)
82
+ end
83
+ Marshal::load(@db.value).hexdigest.should == Digest::MD5.hexdigest(parts_array.inject("", :+))
84
+ end
85
+ end
42
86
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: digest_extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-12 00:00:00.000000000Z
12
+ date: 2012-08-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &26019580 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,21 +21,31 @@ dependencies:
21
21
  version: 2.6.0
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *26019580
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.6.0
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: bundler
27
- requirement: &26018820 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ~>
31
36
  - !ruby/object:Gem::Version
32
- version: 1.0.0
37
+ version: '1.0'
33
38
  type: :development
34
39
  prerelease: false
35
- version_requirements: *26018820
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: jeweler
38
- requirement: &26017280 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ~>
@@ -43,10 +53,15 @@ dependencies:
43
53
  version: 1.6.4
44
54
  type: :development
45
55
  prerelease: false
46
- version_requirements: *26017280
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.6.4
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: rake-compiler
49
- requirement: &26008460 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
67
  - - ~>
@@ -54,7 +69,12 @@ dependencies:
54
69
  version: 0.7.9
55
70
  type: :development
56
71
  prerelease: false
57
- version_requirements: *26008460
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.7.9
58
78
  description: With marshalling of digest objects, it is possible to compute the digests
59
79
  over several executions by storing the marshalled object on file or database, this
60
80
  is handy for computing digests for large files that comes in parts.
@@ -69,7 +89,6 @@ files:
69
89
  - .document
70
90
  - .rspec
71
91
  - Gemfile
72
- - Gemfile.lock
73
92
  - LICENSE.txt
74
93
  - README.rdoc
75
94
  - Rakefile
@@ -96,7 +115,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
96
115
  version: '0'
97
116
  segments:
98
117
  - 0
99
- hash: -1639069279099423950
118
+ hash: 42947112275077556
100
119
  required_rubygems_version: !ruby/object:Gem::Requirement
101
120
  none: false
102
121
  requirements:
@@ -105,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
124
  version: '0'
106
125
  requirements: []
107
126
  rubyforge_project:
108
- rubygems_version: 1.8.6
127
+ rubygems_version: 1.8.24
109
128
  signing_key:
110
129
  specification_version: 3
111
130
  summary: Extensions to the Digest module of the ruby standard library to support marshalling
@@ -1,29 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- diff-lcs (1.1.2)
5
- git (1.2.5)
6
- jeweler (1.6.4)
7
- bundler (~> 1.0)
8
- git (>= 1.2.5)
9
- rake
10
- rake (0.9.2)
11
- rake-compiler (0.7.9)
12
- rake
13
- rspec (2.6.0)
14
- rspec-core (~> 2.6.0)
15
- rspec-expectations (~> 2.6.0)
16
- rspec-mocks (~> 2.6.0)
17
- rspec-core (2.6.4)
18
- rspec-expectations (2.6.0)
19
- diff-lcs (~> 1.1.2)
20
- rspec-mocks (2.6.0)
21
-
22
- PLATFORMS
23
- ruby
24
-
25
- DEPENDENCIES
26
- bundler (~> 1.0.0)
27
- jeweler (~> 1.6.4)
28
- rake-compiler (~> 0.7.9)
29
- rspec (~> 2.6.0)