# $Id: util.rb,v 1.33 2004/04/22 02:37:45 eto Exp $
# Copyright (C) 2003-2004 Kouichirou Eto, All rights reserved.
# This is free software with ABSOLUTELY NO WARRANTY.
# You can redistribute it and/or modify it under the terms of the GNU GPL2.

require 'md5'
require 'pathname'
require 'iconv'
require 'webrick'
require 'qwik/qp'

class Iconv
  def self.iconv_to_utf8(from, str)
    iconv = Iconv.new(from, "UTF-8")
    out = ""
    begin
      out << iconv.iconv(str)
    rescue Iconv::IllegalSequence => e
      out << e.success
      ch, str = e.failed.split(//u, 2)
      out << if respond_to?(:unknown_unicode_handler)
	       u = ch.unpack('U').first
	       unknown_unicode_handler(u)
	     else
	       "?"
	     end
      retry
    end
    out
  end

  def self.unknown_unicode_handler (u)
    sprintf("&#x%04x;", u)
  end

  def self.iconv_to_from(to, from, str)
    iconv = Iconv.new(to, from)
    out = ""
    begin
      out << iconv.iconv(str)
    rescue Iconv::IllegalSequence => e
      out << e.success
      ch, str = e.failed.split(//u, 2)
      out << "?"
      retry
    rescue Iconv::InvalidCharacter => e
      out << e.success
      ch, str = e.failed.split(//u, 2)
      out << "?"
      retry
    end
    out
  end
end

class String # copied from cgi.rb
  def escape()
    self.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
      '%' + $1.unpack('H2' * $1.size).join('%').upcase
    }.tr(' ', '+')
  end

  def unescape()
    self.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n) {
      [$1.delete('%')].pack('H*')
    }
  end

  def escapeHTML()
    WEBrick::HTMLUtils.escape(self)
  end

  def unescapeHTML()
    self.gsub(/&(.*?);/n) {
      match = $1.dup
      case match
      when /\Aamp\z/ni	then '&'
      when /\Aquot\z/ni	then '"'
      when /\Agt\z/ni	then '>'
      when /\Alt\z/ni	then '<'
      else
	"&#{match};"
      end
    }
  end

  def euctou8()  Iconv.iconv_to_from("UTF-8", "EUC-JP", self)	end
  def u8toeuc()  Iconv.iconv_to_from("EUC-JP", "UTF-8", self)	end
  def sjistou8() Iconv.iconv_to_from("UTF-8", "Shift_JIS", self)	end
  def u8tosjis() Iconv.iconv_to_from("Shift_JIS", "UTF-8", self)	end
  def jistou8()  Iconv.iconv_to_from("UTF-8", "ISO-2022-JP", self)	end
  def u8tojis()
    i = Iconv.new("ISO-2022-JP", "UTF-8")
    i.iconv(self)+i.close
  end

  def md5()	MD5.new(self).digest;	end
  def md5hex()	MD5.new(self).hexdigest; end
  def path()	Pathname.new(self);	end
end

unless File.respond_to?(:extname)
  def File.extname(filename)
    return "."+suffix if suffix = (/\.(\w+)$/ =~ filename && $1)
    ""
  end
end

class Pathname
  def path()	self;	end
end

# modified from fsdb-0.1
#unless Dir.chdir {:worked} == :worked
class << Dir
  alias old_chdir chdir
  def chdir(*args)
    return old_chdir(*args) unless block_given?
    begin
      old_dir = Dir.pwd
      old_chdir(*args)
      yield
    ensure
      old_chdir(old_dir)
    end
  end
end

class Time
  def md()	strftime("%m-%d") end
  def ymd()	strftime("%Y-%m-%d") end
  def ymdx()	strftime("%Y-%m-%d %X") end
  def ymdax()	strftime("%Y-%m-%d(%a) %X") end
  def format_date()
    day = %w(日 月 火 水 木 金 土)
    strftime("%Y-%m-%d #DAY# %H:%M:%S").sub(/#DAY#/, "(#{day[wday()]})")
  end
  def rfc1123_date()
    strftime("%a, %d %b %Y %H:%M:%S GMT")
  end
  def rfc_date()
    strftime("%Y-%m-%dT%H:%M:%S")
  end
end
