FIXME: This class can handle only (euc-jp/shift_jis -> iso-2022-jp).
Methods
- add_lwsp
- add_text
- add_with_encode
- concat_A_S
- concat_E
- dest
- do_encode
- encode
- encode_value
- extract_A
- extract_J
- extract_S
- flush
- fold
- header_body
- header_line
- header_name
- kv_pair
- lwsp
- max_bytes
- meta
- new
- normalize_encoding
- phrase
- puts
- reset
- restsize
- scanadd
- space
- spc
- terminate
- text
- write
Included Modules
Constants
| BENCODE_DEBUG | = | false unless defined?(BENCODE_DEBUG) |
| SPACER | = | "\t" |
| MAX_LINE_LEN | = | 70 |
| OPTIONS | = | { 'EUC' => '-Ej -m0', 'SJIS' => '-Sj -m0', 'UTF8' => nil, # FIXME 'NONE' => nil |
| METHOD_ID | = | { ?j => :extract_J, ?e => :extract_E, ?a => :extract_A, ?s => :extract_S |
Public Class methods
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 172
172: def Encoder.encode( str )
173: e = new()
174: e.header_body str
175: e.terminate
176: e.dest.string
177: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 189
189: def initialize( dest = nil, encoding = nil, eol = "\r\n", limit = nil )
190: @f = StrategyInterface.create_dest(dest)
191: @opt = OPTIONS[$KCODE]
192: @eol = eol
193: reset
194: end
Public Instance methods
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 214
214: def dest
215: @f
216: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 288
288: def encode_value( str )
289: str.gsub(TOKEN_UNSAFE) {|s| '%%%02x' % s[0] }
290: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 241
241: def header_body( str )
242: scanadd normalize_encoding(str)
243: end
add
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 231
231: def header_line( line )
232: scanadd line
233: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 235
235: def header_name( name )
236: add_text name.split(/-/).map {|i| i.capitalize }.join('-')
237: add_text ':'
238: add_lwsp ' '
239: end
FIXME: implement line folding
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 274
274: def kv_pair( k, v )
275: return if v.nil?
276: v = normalize_encoding(v)
277: if token_safe?(v)
278: add_text k + '=' + v
279: elsif not CONTROL_CHAR === v
280: add_text k + '=' + quote_token(v)
281: else
282: # apply RFC2231 encoding
283: kv = k + '*=' + "iso-2022-jp'ja'" + encode_value(v)
284: add_text kv
285: end
286: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 251
251: def lwsp( str )
252: add_lwsp str.sub(/[\r\n]+[^\r\n]*\z/, '')
253: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 255
255: def meta( str )
256: add_text str
257: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 196
196: def normalize_encoding( str )
197: if @opt
198: then NKF.nkf(@opt, str)
199: else str
200: end
201: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 263
263: def phrase( str )
264: str = normalize_encoding(str)
265: if CONTROL_CHAR === str
266: scanadd str
267: else
268: add_text quote_phrase(str)
269: end
270: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 218
218: def puts( str = nil )
219: @f << str if str
220: @f << @eol
221: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 203
203: def reset
204: @text = ''
205: @lwsp = ''
206: @curlen = 0
207: end
This method is also aliased as
spc
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 245
245: def space
246: add_lwsp ' '
247: end
Alias for space
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 209
209: def terminate
210: add_lwsp ''
211: reset
212: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 259
259: def text( str )
260: scanadd normalize_encoding(str)
261: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 223
223: def write( str )
224: @f << str
225: end
Private Instance methods
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 436
436: def add_lwsp( lwsp )
437: # puts '---- lwsp -------------------------------------'
438: # puts "+ #{lwsp.inspect}"
439: fold if restsize() <= 0
440: flush
441: @lwsp = lwsp
442: end
free length buffer
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 425
425: def add_text( str )
426: @text << str
427: # puts '---- text -------------------------------------'
428: # puts "+ #{str.inspect}"
429: # puts "txt >>>#{@text.inspect}<<<"
430: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 432
432: def add_with_encode( str )
433: @text << "=?iso-2022-jp?B?#{Base64.encode(str)}?="
434: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 355
355: def concat_A_S( types, strs )
356: i = 0
357: types.each_byte do |t|
358: case t
359: when ?a then add_text strs[i]
360: when ?s then add_lwsp strs[i]
361: else
362: raise "TMail FATAL: unknown flag: #{t.chr}"
363: end
364: i += 1
365: end
366: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 375
375: def concat_E( types, strs )
376: if BENCODE_DEBUG
377: puts '---- concat_E'
378: puts "types=#{types.split(//).join(' ')}"
379: puts "strs =#{strs.inspect}"
380: end
381:
382: flush() unless @text.empty?
383:
384: chunk = ''
385: strs.each_with_index do |s,i|
386: mid = METHOD_ID[types[i]]
387: until s.empty?
388: unless c = __send__(mid, chunk.size, s)
389: add_with_encode chunk unless chunk.empty?
390: flush
391: chunk = ''
392: fold
393: c = __send__(mid, 0, s)
394: raise 'TMail FATAL: extract fail' unless c
395: end
396: chunk << c
397: end
398: end
399: add_with_encode chunk unless chunk.empty?
400: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 324
324: def do_encode( types, strs )
325: #
326: # result : (A|E)(S(A|E))*
327: # E : W(SW)*
328: # W : (J|A)+ but must contain J # (J|A)*J(J|A)*
329: # A : <<A character string not to be encoded>>
330: # J : <<A character string to be encoded>>
331: # S : <<LWSP>>
332: #
333: # An encoding unit is `E'.
334: # Input (parameter `types') is (J|A)(J|A|S)*(J|A)
335: #
336: if BENCODE_DEBUG
337: puts
338: puts '-- do_encode ------------'
339: puts types.split(//).join(' ')
340: p strs
341: end
342:
343: e = /[ja]*j[ja]*(?:s[ja]*j[ja]*)*/
344:
345: while m = e.match(types)
346: pre = m.pre_match
347: concat_A_S pre, strs[0, pre.size] unless pre.empty?
348: concat_E m[0], strs[m.begin(0) ... m.end(0)]
349: types = m.post_match
350: strs.slice! 0, m.end(0)
351: end
352: concat_A_S types, strs
353: end
This method is also aliased as
extract_S
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 409
409: def extract_A( chunksize, str )
410: size = max_bytes(chunksize, str.size)
411: return nil if size <= 0
412: str.slice!(0, size)
413: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 402
402: def extract_J( chunksize, str )
403: size = max_bytes(chunksize, str.size) - 6
404: size = (size % 2 == 0) ? (size) : (size - 1)
405: return nil if size <= 0
406: "\e$B#{str.slice!(0, size)}\e(B"
407: end
Alias for extract_A
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 444
444: def flush
445: # puts '---- flush ----'
446: # puts "spc >>>#{@lwsp.inspect}<<<"
447: # puts "txt >>>#{@text.inspect}<<<"
448: @f << @lwsp << @text
449: @curlen += (@lwsp.size + @text.size)
450: @text = ''
451: @lwsp = ''
452: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 454
454: def fold
455: # puts '---- fold ----'
456: @f << @eol
457: @curlen = 0
458: @lwsp = SPACER
459: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 417
417: def max_bytes( chunksize, ssize )
418: (restsize() - '=?iso-2022-jp?B??='.size) / 4 * 3 - chunksize
419: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 461
461: def restsize
462: MAX_LINE_LEN - (@curlen + @lwsp.size + @text.size)
463: end
[ show source ]
# File lib/action_mailer/vendor/tmail/encode.rb, line 294
294: def scanadd( str, force = false )
295: types = ''
296: strs = []
297:
298: until str.empty?
299: if m = /\A[^\e\t\r\n ]+/.match(str)
300: types << (force ? 'j' : 'a')
301: strs.push m[0]
302:
303: elsif m = /\A[\t\r\n ]+/.match(str)
304: types << 's'
305: strs.push m[0]
306:
307: elsif m = /\A\e../.match(str)
308: esc = m[0]
309: str = m.post_match
310: if esc != "\e(B" and m = /\A[^\e]+/.match(str)
311: types << 'j'
312: strs.push m[0]
313: end
314:
315: else
316: raise 'TMail FATAL: encoder scan fail'
317: end
318: (str = m.post_match) unless m.nil?
319: end
320:
321: do_encode types, strs
322: end