Created
December 27, 2011 09:51
-
-
Save seraphy/1523176 to your computer and use it in GitHub Desktop.
PL/SQLでメールの添付ファイルのファイル名のエンコードをRFC2231により行う
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| declare | |
| -- UTF8のOracle表現 | |
| UTF8 constant nvarchar2(250) := 'AL32UTF8'; | |
| -- 改行コード | |
| CRLF CONSTANT VARCHAR2(2) := chr(13) || chr(10); | |
| -- タブコード | |
| TAB CONSTANT VARCHAR2(1) := chr(9); | |
| /** | |
| * 添付ファイルのファイル名のエンコードをRFC2231により行う. | |
| * 「filename*N*=xxxx」の形式の複数行となり、継続する場合は末尾はセミコロンとなる。 | |
| * エンコードは文字コード名の識別子につづいて16進数でエンコードされた文字が続く. | |
| * (例) filename*0*=UTF-8''%E6%96%B0%E8%A6 | |
| * http://www.asahi-net.or.jp/~BD9Y-KTU/htmlrel_f/dtd_f/rfc_f/rfc2231j.html | |
| * http://adiary.blog.abk.nu/0253 | |
| * @param filename 添付ファイル名 | |
| * @return UTF8の16進数表現でエンコードされたファイル名表現 | |
| */ | |
| FUNCTION MAKE_ATTACHED_FILE_NAME(filename NVARCHAR2) RETURN RAW AS | |
| buf RAW(32760); | |
| c RAW(1); | |
| pos PLS_INTEGER := 1; | |
| mxlen PLS_INTEGER; | |
| linebuf VARCHAR2(80) := 'UTF-8'''''; | |
| TYPE t_lines IS TABLE OF VARCHAR2(80) INDEX BY binary_integer; | |
| lines t_lines; | |
| BEGIN | |
| IF filename IS NULL THEN | |
| RETURN NULL; | |
| END IF; | |
| -- ファイル名をUTF8のバイナリに変換 | |
| buf := UTL_I18N.STRING_TO_RAW(filename, UTF8); | |
| -- バイナリから「16進数」の文字列に変換。 | |
| -- 54文字を超えた場合は次の行に折り返す. | |
| mxlen := UTL_RAW.LENGTH(buf); | |
| LOOP | |
| EXIT WHEN pos > mxlen; | |
| IF LENGTH(linebuf) > 54 THEN | |
| lines(lines.COUNT) := linebuf || ';'; | |
| linebuf := NULL; | |
| END IF; | |
| c := utl_raw.substr(buf, pos, 1); | |
| linebuf := linebuf || '%' || rawtohex(c); | |
| pos := pos + 1; | |
| END LOOP; | |
| lines(lines.COUNT) := linebuf; | |
| -- ヘッダを構築してバイナリとして構築する. | |
| buf := NULL; | |
| FOR idx IN lines.FIRST .. lines.LAST | |
| LOOP | |
| IF lines.COUNT > 1 THEN | |
| linebuf := TAB || 'filename*' || idx || '*=' || lines(idx); | |
| ELSE | |
| linebuf := TAB || 'filename*=' || lines(0); | |
| END IF; | |
| buf := UTL_RAW.CONCAT( | |
| buf, | |
| UTL_RAW.CAST_TO_RAW(linebuf), | |
| UTL_RAW.CAST_TO_RAW(CRLF) | |
| ); | |
| END LOOP; | |
| RETURN buf; | |
| END; | |
| begin | |
| declare | |
| mes nvarchar2(80) := '新規テキスト ドキュメント~森鷗外.txt'; | |
| begin | |
| dbms_output.put_line( | |
| UTL_RAW.CAST_TO_VARCHAR2( | |
| MAKE_ATTACHED_FILE_NAME(mes) | |
| ) | |
| ); | |
| end; | |
| end; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment