FIXME: This class can handle only (euc-jp/shift_jis -> iso-2022-jp).

Methods
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
encode( str )
     # 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
new( dest = nil, encoding = nil, eol = "\r\n", limit = nil )
     # 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
dest()
     # File lib/action_mailer/vendor/tmail/encode.rb, line 214
214:     def dest
215:       @f
216:     end
encode_value( str )
     # 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
header_body( str )
     # File lib/action_mailer/vendor/tmail/encode.rb, line 241
241:     def header_body( str )
242:       scanadd normalize_encoding(str)
243:     end
header_line( line )

add

     # File lib/action_mailer/vendor/tmail/encode.rb, line 231
231:     def header_line( line )
232:       scanadd line
233:     end
header_name( name )
     # 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
kv_pair( k, v )

FIXME: implement line folding

     # 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
lwsp( str )
     # 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
meta( str )
     # File lib/action_mailer/vendor/tmail/encode.rb, line 255
255:     def meta( str )
256:       add_text str
257:     end
normalize_encoding( str )
     # 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
phrase( str )
     # 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
puts( str = nil )
     # 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
reset()
     # File lib/action_mailer/vendor/tmail/encode.rb, line 203
203:     def reset
204:       @text = ''
205:       @lwsp = ''
206:       @curlen = 0
207:     end
space()
This method is also aliased as spc
     # File lib/action_mailer/vendor/tmail/encode.rb, line 245
245:     def space
246:       add_lwsp ' '
247:     end
spc()

Alias for space

terminate()
     # File lib/action_mailer/vendor/tmail/encode.rb, line 209
209:     def terminate
210:       add_lwsp ''
211:       reset
212:     end
text( str )
     # File lib/action_mailer/vendor/tmail/encode.rb, line 259
259:     def text( str )
260:       scanadd normalize_encoding(str)
261:     end
write( str )
     # File lib/action_mailer/vendor/tmail/encode.rb, line 223
223:     def write( str )
224:       @f << str
225:     end
Private Instance methods
add_lwsp( lwsp )
     # 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
add_text( str )

free length buffer

     # 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
add_with_encode( str )
     # 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
concat_A_S( types, strs )
     # 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
concat_E( types, strs )
     # 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
do_encode( types, strs )
     # 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
extract_A( chunksize, str )
This method is also aliased as extract_S
     # 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
extract_J( chunksize, str )
     # 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
extract_S( chunksize, str )

Alias for extract_A

flush()
     # 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
fold()
     # 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
max_bytes( chunksize, ssize )
     # 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
restsize()
     # File lib/action_mailer/vendor/tmail/encode.rb, line 461
461:     def restsize
462:       MAX_LINE_LEN - (@curlen + @lwsp.size + @text.size)
463:     end
scanadd( str, force = false )
     # 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