mail 2.1.3 → 2.1.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of mail might be problematic. Click here for more details.

Files changed (106) hide show
  1. data/CHANGELOG.rdoc +37 -0
  2. data/README.rdoc +1 -1
  3. data/Rakefile +2 -3
  4. data/TODO.rdoc +2 -12
  5. data/lib/mail.rb +7 -4
  6. data/lib/mail/attachments_list.rb +28 -10
  7. data/lib/mail/body.rb +44 -15
  8. data/lib/mail/core_extensions/string.rb +4 -0
  9. data/lib/mail/elements/content_transfer_encoding_element.rb +4 -1
  10. data/lib/mail/encodings/7bit.rb +29 -0
  11. data/lib/mail/encodings/8bit.rb +29 -0
  12. data/lib/mail/encodings/base64.rb +18 -5
  13. data/lib/mail/encodings/binary.rb +29 -0
  14. data/lib/mail/encodings/encodings.rb +22 -6
  15. data/lib/mail/encodings/quoted_printable.rb +27 -4
  16. data/lib/mail/encodings/transfer_encoding.rb +58 -0
  17. data/lib/mail/field.rb +4 -2
  18. data/lib/mail/fields/common/parameter_hash.rb +12 -3
  19. data/lib/mail/fields/content_disposition_field.rb +12 -2
  20. data/lib/mail/fields/content_location_field.rb +2 -2
  21. data/lib/mail/fields/content_transfer_encoding_field.rb +5 -3
  22. data/lib/mail/fields/content_type_field.rb +14 -4
  23. data/lib/mail/fields/mime_version_field.rb +2 -2
  24. data/lib/mail/fields/received_field.rb +8 -4
  25. data/lib/mail/fields/structured_field.rb +4 -0
  26. data/lib/mail/fields/unstructured_field.rb +5 -0
  27. data/lib/mail/header.rb +13 -6
  28. data/lib/mail/mail.rb +1 -1
  29. data/lib/mail/message.rb +100 -28
  30. data/lib/mail/network/delivery_methods/smtp.rb +1 -1
  31. data/lib/mail/parsers/address_lists.rb +4 -1
  32. data/lib/mail/parsers/content_disposition.rb +24 -6
  33. data/lib/mail/parsers/content_location.rb +8 -2
  34. data/lib/mail/parsers/content_transfer_encoding.rb +73 -83
  35. data/lib/mail/parsers/content_transfer_encoding.treetop +5 -10
  36. data/lib/mail/parsers/content_type.rb +36 -9
  37. data/lib/mail/parsers/date_time.rb +4 -1
  38. data/lib/mail/parsers/envelope_from.rb +8 -2
  39. data/lib/mail/parsers/message_ids.rb +4 -1
  40. data/lib/mail/parsers/mime_version.rb +4 -1
  41. data/lib/mail/parsers/phrase_lists.rb +4 -1
  42. data/lib/mail/parsers/received.rb +4 -1
  43. data/lib/mail/parsers/rfc2045.rb +75 -17
  44. data/lib/mail/parsers/rfc2045.treetop +2 -1
  45. data/lib/mail/parsers/rfc2822.rb +316 -79
  46. data/lib/mail/parsers/rfc2822_obsolete.rb +200 -50
  47. data/lib/mail/part.rb +21 -6
  48. data/lib/mail/patterns.rb +3 -3
  49. data/lib/mail/utilities.rb +4 -4
  50. data/lib/mail/vendor/treetop-1.4.3/Or +0 -0
  51. data/lib/mail/vendor/treetop-1.4.3/Rakefile +11 -6
  52. data/lib/mail/vendor/treetop-1.4.3/Treetop.tmbundle/Preferences/Comments.tmPreferences +22 -0
  53. data/lib/mail/vendor/treetop-1.4.3/Treetop.tmbundle/Syntaxes/Treetop Grammar.tmLanguage +28 -1
  54. data/lib/mail/vendor/treetop-1.4.3/bin/tt +5 -5
  55. data/lib/mail/vendor/treetop-1.4.3/lib/treetop.rb +3 -19
  56. data/lib/mail/vendor/treetop-1.4.3/lib/treetop/bootstrap_gen_1_metagrammar.rb +4 -7
  57. data/lib/mail/vendor/treetop-1.4.3/lib/treetop/compiler.rb +7 -6
  58. data/lib/mail/vendor/treetop-1.4.3/lib/treetop/compiler/metagrammar.rb +1 -1
  59. data/lib/mail/vendor/treetop-1.4.3/lib/treetop/compiler/node_classes.rb +19 -20
  60. data/lib/mail/vendor/treetop-1.4.3/lib/treetop/polyglot.rb +9 -0
  61. data/lib/mail/vendor/treetop-1.4.3/lib/treetop/ruby_extensions.rb +1 -2
  62. data/lib/mail/vendor/treetop-1.4.3/lib/treetop/runtime.rb +6 -5
  63. data/lib/mail/vendor/treetop-1.4.3/lib/treetop/runtime/interval_skip_list.rb +3 -4
  64. data/lib/mail/vendor/treetop-1.4.3/lib/treetop/runtime/syntax_node.rb +7 -7
  65. data/lib/mail/vendor/treetop-1.4.3/lib/treetop/version.rb +1 -1
  66. data/lib/mail/vendor/treetop-1.4.3/script/generate_metagrammar.rb +3 -4
  67. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/and_predicate_spec.rb +2 -2
  68. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/anything_symbol_spec.rb +2 -2
  69. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/character_class_spec.rb +1 -1
  70. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/choice_spec.rb +2 -2
  71. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/circular_compilation_spec.rb +3 -1
  72. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/failure_propagation_functional_spec.rb +2 -2
  73. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/grammar_compiler_spec.rb +1 -1
  74. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/grammar_spec.rb +1 -1
  75. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/multibyte_chars_spec.rb +1 -9
  76. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/nonterminal_symbol_spec.rb +2 -2
  77. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/not_predicate_spec.rb +2 -2
  78. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/one_or_more_spec.rb +2 -2
  79. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/optional_spec.rb +1 -1
  80. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/parenthesized_expression_spec.rb +1 -1
  81. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/parsing_rule_spec.rb +1 -1
  82. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/repeated_subrule_spec.rb +1 -1
  83. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/semantic_predicate_spec.rb +1 -1
  84. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/sequence_spec.rb +1 -1
  85. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/terminal_spec.rb +1 -1
  86. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/terminal_symbol_spec.rb +1 -1
  87. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/tt_compiler_spec.rb +1 -1
  88. data/lib/mail/vendor/treetop-1.4.3/spec/compiler/zero_or_more_spec.rb +1 -1
  89. data/lib/mail/vendor/treetop-1.4.3/spec/composition/grammar_composition_spec.rb +1 -1
  90. data/lib/mail/vendor/treetop-1.4.3/spec/ruby_extensions/string_spec.rb +1 -1
  91. data/lib/mail/vendor/treetop-1.4.3/spec/runtime/compiled_parser_spec.rb +1 -1
  92. data/lib/mail/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/delete_spec.rb +2 -2
  93. data/lib/mail/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/expire_range_spec.rb +2 -2
  94. data/lib/mail/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/insert_spec.rb +1 -1
  95. data/lib/mail/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/interval_skip_list_spec.rb +2 -2
  96. data/lib/mail/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/palindromic_fixture_spec.rb +2 -3
  97. data/lib/mail/vendor/treetop-1.4.3/spec/runtime/interval_skip_list/spec_helper.rb +2 -2
  98. data/lib/mail/vendor/treetop-1.4.3/spec/runtime/syntax_node_spec.rb +1 -1
  99. data/lib/mail/vendor/treetop-1.4.3/spec/spec_helper.rb +4 -5
  100. data/lib/mail/vendor/treetop-1.4.3/treetop.gemspec +2 -2
  101. data/lib/mail/version.rb +1 -1
  102. data/lib/mail/version_specific/ruby_1_8.rb +1 -3
  103. data/lib/mail/version_specific/ruby_1_9.rb +1 -2
  104. data/lib/tasks/treetop.rake +1 -1
  105. metadata +33 -14
  106. data/lib/mail/vendor/treetop-1.4.3/spec/spec_suite.rb +0 -4
data/CHANGELOG.rdoc CHANGED
@@ -1,9 +1,46 @@
1
+ == Sun Mar 28 02:55:42 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
2
+
3
+ * Version bump to 2.1.4
4
+
5
+ == Sun Mar 28 00:26:27 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
6
+
7
+ * Merged in Jeremy/treetop to vendored treetop
8
+ * Merged in nathansobo/treetop to vendored treetop
9
+ * Merged in pzbowen/mail into mail - Adds body auto encoding - awesome work
10
+ * Fixed content-transfer-encoding parser to be more compliant per RFC, also now handles trailing semi-colons correctly
11
+ * Fixed content-transfer-encoding parser to handle weird "from the wild" misspellings
12
+ * Added message.errors, header.errors arrays, returns array of [field_name, value, error_object] for each field that failed to parse
13
+ * Removed bundler require from Rakefile
14
+
15
+ == Sun Mar 17 03:03:03 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
16
+
17
+ * Keep header name case when failing to unstructured field
18
+
19
+ == Wed Feb 24 09:14:56 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
20
+
21
+ * Fixed multiaddress bounce messages crashing when calling .bounced? Now just take the first report and return that.
22
+ * Closes issue 38 - final_recipient method give problem when one bounce email for multiple email ids
23
+ * Fixing up TODO and Docs
24
+
25
+ == Sun Mar 22 03:24:15 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
26
+
27
+ * Version bump to 2.1.3
28
+
1
29
  == Thu Jan 28 00:25:02 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
2
30
 
3
31
  * Added TMM1's patch to not raise errors if a email is not multipart/report
4
32
  * Added html_part and text_part now return the first text/html or text/plain part they find. Order is from top to bottom of the email, all parts, flattened.
33
+ * Cleaning up register_interceptor and register_observer including documentation
34
+ * Renamed #register_for_delivery_notification to #register_observer
35
+ * Renamed #register_for_delivery_interception to #register_interceptor
36
+ * Adding spec to check for folding of non ASCII words that have been encoded
37
+ * Updating Message#inspect to be a bit more friendly... it is for us mere mortals after all
5
38
  * Version bump to 2.1.2
6
39
 
40
+ == Sun Jan 28 02:59:34 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
41
+
42
+ * Removed old method of setting delivery_method
43
+
7
44
  == Mon Jan 25 11:36:13 UTC 2010 Mikel Lindsaar <raasdnil@gmail.com>
8
45
 
9
46
  * Added ability for address fields to init on an array instead of just a string.
data/README.rdoc CHANGED
@@ -471,7 +471,7 @@ will try and guess the mime_type for you.
471
471
  @mail.attachments.first.mime_type #=> 'application/pdf'
472
472
  @mail.attachments.first.decoded == File.read('path/to/myfile.pdf') #=> true
473
473
 
474
- You can also override the guessed mime type if you really know better
474
+ You can also override the guessed MIME media type if you really know better
475
475
  than mail (this should be rarely needed)
476
476
 
477
477
  @mail = Mail.new
data/Rakefile CHANGED
@@ -8,11 +8,10 @@ require 'rake/gempackagetask'
8
8
  require 'rake/testtask'
9
9
  require 'spec/rake/spectask'
10
10
  require 'cucumber/rake/task'
11
- require 'bundler'
12
11
 
13
12
  spec = Gem::Specification.new do |s|
14
13
  s.name = "mail"
15
- s.version = "2.1.3"
14
+ s.version = "2.1.5"
16
15
  s.author = "Mike Lindsaar"
17
16
  s.email = "raasdnil@gmail.com"
18
17
  s.homepage = "http://github.com/mikel/mail"
@@ -42,7 +41,7 @@ end
42
41
  Spec::Rake::SpecTask.new(:rcov) do |t|
43
42
  t.spec_files = FileList['test/**/tc_*.rb', 'spec/**/*_spec.rb']
44
43
  t.rcov = true
45
- t.rcov_opts = t.rcov_opts << ['--exclude', '/Library,/opt,/System']
44
+ t.rcov_opts = t.rcov_opts << ['--exclude', '/Library,/opt,/System,/usr']
46
45
  end
47
46
 
48
47
  Spec::Rake::SpecTask.new(:spec) do |t|
data/TODO.rdoc CHANGED
@@ -1,17 +1,7 @@
1
1
  == Not really in any order:
2
2
 
3
- * Make body, part, field, header, message all responding correctly to :encoded
4
- and :decoded messages. And remove ":to_s" as a method on these
5
- classes. Encoded needs to return the field, encoded, ready to send in the
6
- mail system, that is, US-ASCII. Decoded needs to return the field decoded ready to
7
- view. :to_s is (unfortunately) ambiguous in this case. Maybe return a warning
8
- with :to_s and say "please use encoded or decoded instead" or :to_s returns
9
- "Showing you the encoded view by default, call :decoded to see the decoded view"
10
-
11
- * Refactor out the multibyte and string handling. Make ActiveSupport a dependancy
12
-
13
- * Clean up the relationship between message, parts and bodies. Need to make sure
14
- once parsed, that a body knows what encoding it is, for example.
3
+ * Add multibyte handling to fields, if they get a multibyte string, try encoding it into
4
+ UTF-8 B first, if this fails, throw an error.
15
5
 
16
6
  * Cleanup the treetop parsers......... do I _really_ need that many entrance files?
17
7
 
data/lib/mail.rb CHANGED
@@ -102,10 +102,13 @@ module Mail # :doc:
102
102
  end
103
103
 
104
104
  # Load in all transfer encodings
105
- elems = Dir.glob(File.join(File.dirname(__FILE__), 'mail', 'encodings', '*.rb'))
106
- elems.each do |elem|
107
- require "mail/encodings/#{File.basename(elem, '.rb')}"
108
- end
105
+ require "mail/encodings/encodings"
106
+ require "mail/encodings/transfer_encoding"
107
+ require "mail/encodings/binary"
108
+ require "mail/encodings/8bit"
109
+ require "mail/encodings/7bit"
110
+ require "mail/encodings/base64"
111
+ require "mail/encodings/quoted_printable"
109
112
 
110
113
  # Finally... require all the Mail.methods
111
114
  require File.join('mail', 'mail')
@@ -30,7 +30,7 @@ module Mail
30
30
 
31
31
  def []=(name, value)
32
32
  default_values = { :content_type => "#{set_mime_type(name)}; filename=\"#{name}\"",
33
- :content_transfer_encoding => 'Base64',
33
+ :content_transfer_encoding => "#{guess_encoding}",
34
34
  :content_disposition => "attachment; filename=\"#{name}\"" }
35
35
 
36
36
  if value.is_a?(Hash)
@@ -39,28 +39,46 @@ module Mail
39
39
 
40
40
  default_values[:body] = value.delete(:data) if value[:data]
41
41
 
42
- # Only force encode base64 if the user has not specified an encoding
43
- if value[:transfer_encoding]
44
- default_values[:content_transfer_encoding] = value.delete(:transfer_encoding)
45
- elsif value[:encoding]
46
- default_values[:content_transfer_encoding] = value.delete(:encoding)
47
- else
48
- default_values[:body] = Mail::Encodings::Base64.encode(default_values[:body])
42
+ encoding = value.delete(:transfer_encoding) || value.delete(:encoding)
43
+ if encoding
44
+ if Mail::Encodings.defined? encoding
45
+ default_values[:content_transfer_encoding] = encoding
46
+ else
47
+ raise "Do not know how to handle Content Transfer Encoding #{encoding}, please choose either quoted-printable or base64"
48
+ end
49
49
  end
50
50
 
51
51
  if value[:mime_type]
52
52
  default_values[:content_type] = value.delete(:mime_type)
53
+ @mime_type = MIME::Types[default_values[:content_type]].first
54
+ default_values[:content_transfer_encoding] = guess_encoding
53
55
  end
54
56
 
55
57
  hash = default_values.merge(value)
56
58
  else
57
- default_values[:body] = Mail::Encodings::Base64.encode(value)
59
+ default_values[:body] = value
58
60
  hash = default_values
59
61
  end
60
62
 
63
+ if hash[:body].respond_to? :force_encoding and hash[:body].respond_to? :valid_encoding?
64
+ if not hash[:body].valid_encoding? and default_values[:content_transfer_encoding].downcase == "binary"
65
+ hash[:body].force_encoding("BINARY")
66
+ end
67
+ end
68
+
61
69
  @parts_list << Part.new(hash)
62
70
  end
63
-
71
+
72
+ # Uses the mime type to try and guess the encoding, if it is a binary type, or unknown, then we
73
+ # set it to binary, otherwise as set to plain text
74
+ def guess_encoding
75
+ if @mime_type && !@mime_type.binary?
76
+ "7bit"
77
+ else
78
+ "binary"
79
+ end
80
+ end
81
+
64
82
  def set_mime_type(filename)
65
83
  # Have to do this because MIME::Types is not Ruby 1.9 safe yet
66
84
  if RUBY_VERSION >= '1.9'
data/lib/mail/body.rb CHANGED
@@ -44,7 +44,7 @@ module Mail
44
44
  raise "You can only assign a string or an object that responds_to? :join or :to_s to a body."
45
45
  end
46
46
  end
47
- @encoding = nil
47
+ @encoding = (only_us_ascii? ? '7bit' : '8bit')
48
48
  set_charset
49
49
  end
50
50
 
@@ -123,22 +123,39 @@ module Mail
123
123
  def raw_source
124
124
  @raw_source
125
125
  end
126
-
127
- # Returns a US-ASCII 7-bit compliant body. Right now just returns the
128
- # raw source. Need to implement
129
- def encoded
126
+
127
+ def get_best_encoding(target)
128
+ te = Mail::Encodings.get_encoding(target)
129
+ te.get_best_compatible(encoding, raw_source)
130
+ end
131
+
132
+ # Returns a body encoded using transfer_encoding. Multipart always uses an
133
+ # identiy encoding (i.e. no encoding).
134
+ # Calling this directly is not a good idea, but supported for compatibility
135
+ # TODO: Validate that preamble and epilogue are valid for requested encoding
136
+ def encoded(transfer_encoding = '8bit')
130
137
  if multipart?
131
138
  self.sort_parts!
132
139
  encoded_parts = parts.map { |p| p.encoded }
133
140
  ([preamble] + encoded_parts).join(crlf_boundary) + end_boundary + epilogue.to_s
134
141
  else
135
- raw_source.to_crlf
142
+ be = get_best_encoding(transfer_encoding)
143
+ dec = Mail::Encodings::get_encoding(encoding)
144
+ enc = Mail::Encodings::get_encoding(be)
145
+ if transfer_encoding == encoding and dec.nil?
146
+ # Cannot decode, so skip normalization
147
+ raw_source
148
+ else
149
+ # Decode then encode to normalize and allow transforming
150
+ # from base64 to Q-P and vice versa
151
+ enc.encode(dec.decode(raw_source))
152
+ end
136
153
  end
137
154
  end
138
155
 
139
156
  def decoded
140
- if encoding.nil? || !Encodings.defined?(encoding)
141
- raw_source.to_lf
157
+ if !Encodings.defined?(encoding)
158
+ raise UnknownEncodingType, "Don't know how to decode #{encoding}, please call #encoded and decode it yourself."
142
159
  else
143
160
  Encodings.get_encoding(encoding).decode(raw_source)
144
161
  end
@@ -156,12 +173,19 @@ module Mail
156
173
  @charset = val
157
174
  end
158
175
 
159
- def encoding
160
- @encoding
176
+ def encoding(val = nil)
177
+ if val
178
+ self.encoding = val
179
+ else
180
+ @encoding
181
+ end
161
182
  end
162
183
 
163
184
  def encoding=( val )
164
- @encoding = val
185
+ if val == "text" || val.blank? then
186
+ val = "8bit"
187
+ end
188
+ @encoding = (val == "text") ? "8bit" : val
165
189
  end
166
190
 
167
191
  # Returns the preamble (any text that is before the first MIME boundary)
@@ -169,7 +193,7 @@ module Mail
169
193
  @preamble
170
194
  end
171
195
 
172
- # Sets the preamble to a string (adds text before the first mime boundary)
196
+ # Sets the preamble to a string (adds text before the first MIME boundary)
173
197
  def preamble=( val )
174
198
  @preamble = val
175
199
  end
@@ -179,7 +203,7 @@ module Mail
179
203
  @epilogue
180
204
  end
181
205
 
182
- # Sets the epilogue to a string (adds text after the last mime boundary)
206
+ # Sets the epilogue to a string (adds text after the last MIME boundary)
183
207
  def epilogue=( val )
184
208
  @epilogue = val
185
209
  end
@@ -223,7 +247,12 @@ module Mail
223
247
  end
224
248
 
225
249
  def only_us_ascii?
226
- !!raw_source.to_s.ascii_only?
250
+ raw_source.each_byte {|b| return false if (b == 0 || b > 127)}
251
+ true
252
+ end
253
+
254
+ def empty?
255
+ !!raw_source.to_s.empty?
227
256
  end
228
257
 
229
258
  private
@@ -237,7 +266,7 @@ module Mail
237
266
  end
238
267
 
239
268
  def set_charset
240
- raw_source.ascii_only? ? @charset = 'US-ASCII' : @charset = nil
269
+ only_us_ascii? ? @charset = 'US-ASCII' : @charset = nil
241
270
  end
242
271
  end
243
272
  end
@@ -16,4 +16,8 @@ class String #:nodoc:
16
16
  !(self =~ /[^#{US_ASCII_REGEXP}]/)
17
17
  end
18
18
  end
19
+
20
+ unless method_defined?(:bytesize)
21
+ alias :bytesize :length
22
+ end
19
23
  end
@@ -6,7 +6,10 @@ module Mail
6
6
 
7
7
  def initialize( string )
8
8
  parser = Mail::ContentTransferEncodingParser.new
9
- if tree = parser.parse(string.downcase)
9
+ case
10
+ when string.blank?
11
+ @encoding = ''
12
+ when tree = parser.parse(string.downcase)
10
13
  @encoding = tree.encoding.text_value
11
14
  else
12
15
  raise Mail::Field::ParseError, "ContentTransferEncodingElement can not parse |#{string}|\nReason was: #{parser.failure_reason}\n"
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ module Mail
3
+ module Encodings
4
+ class SevenBit < EightBit
5
+ NAME = '7bit'
6
+
7
+ PRIORITY = 1
8
+
9
+ # 7bit and 8bit operate the same
10
+
11
+ # Decode the string
12
+ def self.decode(str)
13
+ super
14
+ end
15
+
16
+ # Encode the string
17
+ def self.encode(str)
18
+ super
19
+ end
20
+
21
+ # Idenity encodings have a fixed cost, 1 byte out per 1 byte in
22
+ def self.cost(str)
23
+ super
24
+ end
25
+
26
+ Encodings.register(NAME, self)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ module Mail
3
+ module Encodings
4
+ class EightBit < Binary
5
+ NAME = '8bit'
6
+
7
+ PRIORITY = 4
8
+
9
+ # 8bit is an identiy encoding, meaning nothing to do
10
+
11
+ # Decode the string
12
+ def self.decode(str)
13
+ str.to_lf
14
+ end
15
+
16
+ # Encode the string
17
+ def self.encode(str)
18
+ str.to_crlf
19
+ end
20
+
21
+ # Idenity encodings have a fixed cost, 1 byte out per 1 byte in
22
+ def self.cost(str)
23
+ 1.0
24
+ end
25
+
26
+ Encodings.register(NAME, self)
27
+ end
28
+ end
29
+ end
@@ -1,8 +1,15 @@
1
1
  # encoding: utf-8
2
2
  module Mail
3
3
  module Encodings
4
- class Base64
5
-
4
+ class Base64 < SevenBit
5
+ NAME = 'base64'
6
+
7
+ PRIORITY = 3
8
+
9
+ def self.can_encode?(enc)
10
+ true
11
+ end
12
+
6
13
  # Decode the string from Base64
7
14
  def self.decode(str)
8
15
  RubyVer.decode_base64( str )
@@ -10,9 +17,15 @@ module Mail
10
17
 
11
18
  # Encode the string to Base64
12
19
  def self.encode(str)
13
- RubyVer.encode_base64( str )
20
+ RubyVer.encode_base64( str ).to_crlf
21
+ end
22
+
23
+ # Base64 has a fixed cost, 4 bytes out per 3 bytes in
24
+ def self.cost(str)
25
+ 4.0/3
14
26
  end
15
-
27
+
28
+ Encodings.register(NAME, self)
16
29
  end
17
30
  end
18
- end
31
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ module Mail
3
+ module Encodings
4
+ class Binary < TransferEncoding
5
+ NAME = 'binary'
6
+
7
+ PRIORITY = 5
8
+
9
+ # Binary is an identiy encoding, meaning nothing to do
10
+
11
+ # Decode the string
12
+ def self.decode(str)
13
+ str
14
+ end
15
+
16
+ # Encode the string
17
+ def self.encode(str)
18
+ str
19
+ end
20
+
21
+ # Idenity encodings have a fixed cost, 1 byte out per 1 byte in
22
+ def self.cost(str)
23
+ 1.0
24
+ end
25
+
26
+ Encodings.register(NAME, self)
27
+ end
28
+ end
29
+ end