rims-rfc822 0.2.1 → 0.2.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0825e7fac6f422946c68301c42abcce200e31d32a96ed83d6b1879a5a2b7c6cf'
4
- data.tar.gz: '091affd6b8394475774ea160b56eb870f01785f72c1b737ea41fe4a5c6698d82'
3
+ metadata.gz: 6d5fb16811b51a21112bde75cf3afb370097c69205b0351847382a19debeaac9
4
+ data.tar.gz: c7a0b7ee568f34e324f2fe3cef2db7908346a09ab7c9131fc6ae96bdd39c06e0
5
5
  SHA512:
6
- metadata.gz: 210d959c67edec519382dfcb24e7aa1069a93e8da0b001badff3c8e643b2aaf83c5a0f84e54f0354fe1740e86b4a2467f5c5f503420fd6e2b2e89b15c0585dc7
7
- data.tar.gz: ad09d49a4f5caab505893a90e5c309d3d2878178aa73dcec2784fbbf38ad24ac5028710c3f62ece160bc7ccbbbdbf1969fe70c38ae13d1a322f0a99cad5e1cd3
6
+ metadata.gz: 0f4e32a989c3f2d49a304133eba4109d6f058eca263bcf4c593ee81aafce43ef54aae91bd74f8e0cba9dd571c5c4892a0dcfe2b31b4d96cedd4adfe6574509ca
7
+ data.tar.gz: 67c9fccdca18ccb61c91f5c416e650a7525de89827654173fd9cc09f403190a5cd586d2eac7934be73080956499be2bdf373f8251a7b79504e513a641d263d50
data/README.md CHANGED
@@ -37,8 +37,13 @@ p msg.body
37
37
  p msg.header[name]
38
38
  p msg.header.fetch_upcase(name)
39
39
  p msg.header.field_value_list(name)
40
+ p msg.header.empty?
40
41
  p msg.header.key? name
41
- msg.header.each do |name, value|
42
+ p msg.header.keys
43
+ msg.header.each_key do |name|
44
+ p name
45
+ end
46
+ msg.header.each_pair do |name, value|
42
47
  p [ name, value ]
43
48
  end
44
49
 
data/lib/rims/rfc822.rb CHANGED
@@ -10,7 +10,7 @@ module RIMS
10
10
  def split_message(msg_txt)
11
11
  header_txt, body_txt = msg_txt.lstrip.split(/\r?\n\r?\n/, 2)
12
12
  if ($&) then
13
- header_txt << $& if $&
13
+ header_txt << $&
14
14
  else
15
15
  body_txt = header_txt
16
16
  header_txt = nil
@@ -57,7 +57,10 @@ module RIMS
57
57
  when '('
58
58
  state = :comment
59
59
  when "\\"
60
- src_txt.sub!(/\A./, '') and dst_txt << $&
60
+ unless (src_txt.empty?) then
61
+ dst_txt << src_txt[0]
62
+ src_txt[0] = ''
63
+ end
61
64
  else
62
65
  dst_txt << match_txt
63
66
  end
@@ -66,7 +69,10 @@ module RIMS
66
69
  when '"'
67
70
  state = :raw
68
71
  when "\\"
69
- src_txt.sub!(/\A./, '') && dst_txt << $&
72
+ unless (src_txt.empty?) then
73
+ dst_txt << src_txt[0]
74
+ src_txt[0] = ''
75
+ end
70
76
  else
71
77
  dst_txt << match_txt
72
78
  end
@@ -75,7 +81,7 @@ module RIMS
75
81
  when ')'
76
82
  state = :raw
77
83
  when "\\"
78
- src_txt.sub!(/\A./, '')
84
+ src_txt[0] = ''
79
85
  else
80
86
  # ignore comment text.
81
87
  end
@@ -90,7 +96,16 @@ module RIMS
90
96
 
91
97
  def parse_parameters(parameters_txt)
92
98
  params = {}
93
- parameters_txt.scan(%r'(?<name>\S+?) \s* = \s* (?: (?<quoted_string>".*?") | (?<token>\S+?) ) \s* (?:;|\Z)'x) do
99
+ parameters_txt.scan(%r{
100
+ (?<name> \S+? )
101
+ \s* = \s*
102
+ (?:
103
+ (?<quoted_string> ".*?" ) |
104
+ (?<token> \S+? )
105
+ )
106
+ \s*
107
+ (?: ; | \Z )
108
+ }x) do
94
109
  name = $~[:name]
95
110
  if ($~[:quoted_string]) then
96
111
  quoted_value = $~[:quoted_string]
@@ -139,9 +154,18 @@ module RIMS
139
154
  end
140
155
  end
141
156
 
142
- [ 'application'.dup.force_encoding(type_txt.encoding).freeze,
143
- 'octet-stream'.dup.force_encoding(type_txt.encoding).freeze,
144
- params
157
+ # See RFC2045 / 5.2. Content-Type Defaults
158
+ # <https://tools.ietf.org/html/rfc2045#section-5.2>
159
+ #
160
+ # Default RFC 822 messages without a MIME Content-Type header are taken
161
+ # by this protocol to be plain text in the US-ASCII character set,
162
+ # which can be explicitly specified as:
163
+ #
164
+ # Content-type: text/plain; charset=us-ascii
165
+ #
166
+ [ 'text'.dup.force_encoding(type_txt.encoding).freeze,
167
+ 'plain'.dup.force_encoding(type_txt.encoding).freeze,
168
+ params # default is no charset, it will be `ASCII-8BIT'.
145
169
  ].freeze
146
170
  end
147
171
  module_function :parse_content_type
@@ -201,20 +225,22 @@ module RIMS
201
225
  if (src_txt.sub!(%r{
202
226
  \A
203
227
  \s*
204
- (?<display_name>\S.*?) \s* : (?<group_list>.*?) ;
228
+ (?<display_name> \S.*? ) \s* : (?<group_list> .*? ) ;
205
229
  \s*
206
230
  ,?
207
231
  }x, ''))
208
232
  then
209
233
  display_name = $~[:display_name]
210
234
  group_list = $~[:group_list]
211
- addr_list << Address.new( nil, nil, unquote_phrase(display_name), nil).freeze
235
+ addr_list << Address.new(nil, nil, unquote_phrase(display_name), nil).freeze
212
236
  addr_list.concat(parse_mail_address_list(group_list))
213
237
  addr_list << Address.new(nil, nil, nil, nil).freeze
214
238
  elsif (src_txt.sub!(%r{
215
239
  \A
216
240
  \s*
217
- (?<local_part>[^<>@",\s]+) \s* @ \s* (?<domain>[^<>@",\s]+)
241
+ (?<local_part> [^<>@",\s]+ )
242
+ \s* @ \s*
243
+ (?<domain> [^<>@",\s]+ )
218
244
  \s*
219
245
  ,?
220
246
  }x, ''))
@@ -223,17 +249,25 @@ module RIMS
223
249
  elsif (src_txt.sub!(%r{
224
250
  \A
225
251
  \s*
226
- (?<display_name>\S.*?)
252
+ (?<display_name> \S.*? )
227
253
  \s*
228
254
  <
229
255
  \s*
230
256
  (?:
231
- (?<route>@[^<>@",]* (?:, \s* @[^<>@",]*)*)
257
+ (?<route>
258
+ @[^<>@",]*
259
+ (?:
260
+ , \s*
261
+ @[^<>@",]*
262
+ )*
263
+ )
232
264
  \s*
233
265
  :
234
266
  )?
235
267
  \s*
236
- (?<local_part>[^<>@",\s]+) \s* @ \s* (?<domain>[^<>@",\s]+)
268
+ (?<local_part> [^<>@",\s]+ )
269
+ \s* @ \s*
270
+ (?<domain> [^<>@",\s]+ )
237
271
  \s*
238
272
  >
239
273
  \s*
@@ -402,7 +436,7 @@ module RIMS
402
436
  # run the slow `String#encode' only when really needed
403
437
  # because of a premise that the strings other than
404
438
  # encoded words are ASCII only.
405
- foreword.encode!(decode_charset_encoding, charset_convert_options)
439
+ foreword.encode!(dst.encoding, charset_convert_options)
406
440
  end
407
441
  dst << foreword
408
442
  end
@@ -449,8 +483,6 @@ module RIMS
449
483
  end
450
484
 
451
485
  class Header
452
- include Enumerable
453
-
454
486
  def initialize(header_txt)
455
487
  @raw_source = header_txt
456
488
  @field_list = nil
@@ -464,7 +496,7 @@ module RIMS
464
496
  @field_list = Parse.parse_header(@raw_source)
465
497
  @field_table = {}
466
498
  for name, value in @field_list
467
- key = name.downcase
499
+ key = name.downcase.freeze
468
500
  @field_table[key] = [] unless (@field_table.key? key)
469
501
  @field_table[key] << value
470
502
  end
@@ -478,13 +510,34 @@ module RIMS
478
510
  end
479
511
  private :setup_header
480
512
 
481
- def each
513
+ # API methods
514
+
515
+ def [](name)
482
516
  setup_header
483
- return enum_for(:each) unless block_given?
484
- for name, value in @field_list
485
- yield(name, value)
517
+ if (value_list = @field_table[name.downcase]) then
518
+ value_list[0]
486
519
  end
487
- self
520
+ end
521
+
522
+ def fetch_upcase(name)
523
+ setup_header
524
+ if (value_list = @field_table[name.downcase]) then
525
+ value_list[0].upcase
526
+ end
527
+ end
528
+
529
+ def field_value_list(name)
530
+ setup_header
531
+ @field_table[name.downcase]
532
+ end
533
+
534
+ # minimal methods like `Hash'
535
+
536
+ include Enumerable
537
+
538
+ def empty?
539
+ setup_header
540
+ @field_list.empty?
488
541
  end
489
542
 
490
543
  def key?(name)
@@ -497,26 +550,30 @@ module RIMS
497
550
  alias include? key?
498
551
  alias member? key?
499
552
 
500
- def [](name)
553
+ def keys
501
554
  setup_header
502
- if (value_list = @field_table[name.downcase]) then
503
- value_list[0]
504
- end
555
+ @field_table.keys
505
556
  end
506
557
 
507
- def fetch_upcase(name)
558
+ def each_key
508
559
  setup_header
509
- if (value_list = @field_table[name.downcase]) then
510
- if (value = value_list[0]) then
511
- value.upcase
512
- end
560
+ return enum_for(:each_key) unless block_given?
561
+ @field_table.each_key do |key|
562
+ yield(key)
513
563
  end
564
+ self
514
565
  end
515
566
 
516
- def field_value_list(name)
567
+ def each_pair
517
568
  setup_header
518
- @field_table[name.downcase]
569
+ return enum_for(:each_pair) unless block_given?
570
+ for name, value in @field_list
571
+ yield(name, value)
572
+ end
573
+ self
519
574
  end
575
+
576
+ alias each each_pair
520
577
  end
521
578
 
522
579
  class Body
@@ -609,6 +666,7 @@ module RIMS
609
666
  alias media_subtype_upcase media_sub_type_upcase
610
667
 
611
668
  def content_type_upcase
669
+ # not return `nil'
612
670
  content_type.upcase
613
671
  end
614
672
 
@@ -635,8 +693,10 @@ module RIMS
635
693
  end
636
694
 
637
695
  def setup_content_disposition
638
- if (header.key? 'Content-Disposition') then
639
- @content_disposition ||= Parse.parse_content_disposition(header['Content-Disposition'])
696
+ if (@content_disposition.nil?) then
697
+ if (header.key? 'Content-Disposition') then
698
+ @content_disposition = Parse.parse_content_disposition(header['Content-Disposition'])
699
+ end
640
700
  end
641
701
 
642
702
  nil
@@ -649,9 +709,7 @@ module RIMS
649
709
  end
650
710
 
651
711
  def content_disposition_upcase
652
- if (type = content_disposition) then
653
- type.upcase
654
- end
712
+ content_disposition&.upcase
655
713
  end
656
714
 
657
715
  def content_disposition_parameter(name)
@@ -671,8 +729,8 @@ module RIMS
671
729
  alias content_disposition_parameters content_disposition_parameter_list
672
730
 
673
731
  def setup_content_language
674
- if (header.key? 'Content-Language') then
675
- if (@content_language.nil?) then
732
+ if (@content_language.nil?) then
733
+ if (header.key? 'Content-Language') then
676
734
  @content_language = header.field_value_list('Content-Language').map{|tags_txt| Parse.parse_content_language(tags_txt) }
677
735
  @content_language.flatten!
678
736
  @content_language.freeze
@@ -689,9 +747,7 @@ module RIMS
689
747
  end
690
748
 
691
749
  def content_language_upcase
692
- if (tag_list = content_language) then
693
- tag_list.map{|tag| tag.upcase }
694
- end
750
+ content_language&.map{|tag| tag.upcase }
695
751
  end
696
752
 
697
753
  def text?
@@ -703,8 +759,8 @@ module RIMS
703
759
  end
704
760
 
705
761
  def parts
706
- if (multipart?) then
707
- if (@parts.nil?) then
762
+ if (@parts.nil?) then
763
+ if (multipart?) then
708
764
  if (boundary = self.boundary) then
709
765
  part_list = Parse.parse_multipart_body(boundary, body.raw_source)
710
766
  @parts = part_list.map{|msg_txt| Message.new(msg_txt) }
@@ -713,9 +769,9 @@ module RIMS
713
769
  end
714
770
  @parts.freeze
715
771
  end
716
-
717
- @parts
718
772
  end
773
+
774
+ @parts
719
775
  end
720
776
 
721
777
  def message?
@@ -723,14 +779,18 @@ module RIMS
723
779
  end
724
780
 
725
781
  def message
726
- if (message?) then
727
- @message ||= Message.new(body.raw_source)
782
+ if (@message.nil?) then
783
+ if (message?) then
784
+ @message = Message.new(body.raw_source)
785
+ end
728
786
  end
787
+
788
+ @message
729
789
  end
730
790
 
731
791
  def date
732
- if (header.key? 'Date') then
733
- if (@date.nil?) then
792
+ if (@date.nil?) then
793
+ if (header.key? 'Date') then
734
794
  begin
735
795
  @date = Time.parse(header['Date'])
736
796
  rescue ArgumentError
@@ -738,14 +798,14 @@ module RIMS
738
798
  end
739
799
  @date.freeze
740
800
  end
741
-
742
- @date
743
801
  end
802
+
803
+ @date
744
804
  end
745
805
 
746
806
  def mail_address_header_field(field_name)
747
807
  if (header.key? field_name) then
748
- ivar_name = '@' + field_name.downcase.gsub('-', '_')
808
+ ivar_name = '@' + field_name.downcase.tr('-', '_')
749
809
  addr_list = instance_variable_get(ivar_name)
750
810
  if (addr_list.nil?) then
751
811
  addr_list = header.field_value_list(field_name).map{|addr_list_txt| Parse.parse_mail_address_list(addr_list_txt) }
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RIMS
4
4
  module RFC822
5
- VERSION = '0.2.1'
5
+ VERSION = '0.2.2'
6
6
  end
7
7
  end
8
8
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rims-rfc822
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - TOKI Yoshinori
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-14 00:00:00.000000000 Z
11
+ date: 2019-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler