|
From: <set...@us...> - 2006-04-25 01:00:20
|
Revision: 1334 Author: sethdill Date: 2006-04-24 18:00:13 -0700 (Mon, 24 Apr 2006) ViewCVS: http://svn.sourceforge.net/frontierkernel/?rev=1334&view=rev Log Message: ----------- RFC2047 describes how an internet (mail, web, etc) header should be encoded if it contains characters outside of the ASCII 7-bit range. The script-based (for now) verb, string.mimeHeaderDecode(), decodes headers in that format back to unencoded characters. (It also returns the name of the character set in which the string is encoded, so that it can be converted to the platform native set (or normalized to an app's default set) with string.convertcharset() Added Paths: ----------- ODBs/trunk/frontierRoot/system/verbs/builtins/string/mimeHeaderDecode.fvc Added: ODBs/trunk/frontierRoot/system/verbs/builtins/string/mimeHeaderDecode.fvc =================================================================== --- ODBs/trunk/frontierRoot/system/verbs/builtins/string/mimeHeaderDecode.fvc (rev 0) +++ ODBs/trunk/frontierRoot/system/verbs/builtins/string/mimeHeaderDecode.fvc 2006-04-25 01:00:13 UTC (rev 1334) @@ -0,0 +1,111 @@ +FrontierVcsFile:2:scpt:system.verbs.builtins.string.mimeHeaderDecode + +«2006/04/10 by Seth Dillingham. + «Description: + «See RFC 2047 + «Textual header informtaion in character sets other than US-ASCII must be encoded correctly, including a reference to the character set that was used. + «This verb attempts to decode a RFC2047-encoded string back to text + «Example input: + «=?utf-8?q?this=20is=20a=20test?= + «Output + «this is a test + «(plus, "utf-8" would be placed at adrCharsetName^) + «Parameters: + «s [string]: the mime-encoded header string to be decoded + «adrCharsetName [@string]: if the string contains any encoded "words", the name of the character set (specified in the string) will be placed here. If the string did not appear to contain any encoding, then "" will be placed here. + «Return: + «[string] the decoded string + «Errors: + «Poorly-formed input may produce incorrect output. (GIGO) + «For example, if the input string uses two different character sets, only the last one will be return at adrCharSet^ + «(This is an error condition anyway, mime header strings can only use one character set at a time) + «Revisions: + « +«~~~~~~~~~~~~~~~~~~~~~~~~ +on mimeHeaderDecode( s, adrCharsetName ) { + local ( working, ct ); + local ( ix, output = "" ); + local ( charsetEnd, charsetLength ); + local ( encodingEnd, encoding ); // B or Q + local ( wordEnd, word ); + + adrCharsetName^ = ""; + + working = string.replaceAll( string.replaceAll( s, tab, ' ' ), "\r\n ", ' ' ); + ct = sizeof( working ); + + ix = string.patternMatch( "=?", working ); + if ( ix == 0 ) { + return s}; + + output = string.mid( s, 1, ix - 1 ); + + while ( ( ix != 0 ) and ( ix < ct ) ) { + charsetEnd = string.patternMatch( "?", working, ix + 2 ); + + if ( charsetEnd == 0 ) { // badly formed, just return the input + adrCharsetName^ = ""; + return s}; + + charsetLength = ( charsetEnd - ix ) - 2; + adrCharsetName^ = string.lower( string.mid( working, ix + 2, charsetLength ) ); + ix = charsetEnd + 1; + + encodingEnd = string.patternMatch( "?", working, ix ); + if ( encodingEnd == 0 ) { + adrCharsetName^ = ""; + return s}; + + encoding = string.upper( string.mid( working, ix, encodingEnd - ix ) ); + case encoding { + "Q"; // quoted-printable + "B" { // base64 + ;}} + else { // we don't handle any other type of encoding + adrCharsetName^ = ""; + return s}; + + ix = encodingEnd + 1; + + wordEnd = string.patternMatch( "?=", working, ix ); + if ( wordEnd == 0 ) { + adrCharsetName^ = ""; + return s}; + + word = string.mid( working, ix, wordEnd - ix ); + + case encoding { + "Q" { + output = output + string.quotedPrintableDecode( string.replaceAll( word, '_', ' ' ) );}; + "B" { + output = output + base64.decode( word );}}; + + ix = string.patternMatch( "=?", working, wordEnd + 2 ); + if ( ix == 0 ) { + output = output + string.mid( working, wordEnd + 2, infinity );; + break;}}; + + return output} +«bundle // test + «local ( charset ) + «local ( s = "=?utf-8?q?my_name_=E2=80=93_such_as_it_is_=E2=80=93_is_?=\r\n\tbr=?utf-8?q?not=20andr=C3=A9=20radke=20=E2=80=94=20nor=20arturo=20pe=C3=B1a?=" ) + « + «s = mimeHeaderDecode( s, @charset ) + «msg( charset ) + «dialog.alert( "Decoded string:\r\n" + s ) + « + «case charset + «"iso-8859-1" + «case sys.os() + «"MacOS" + «s = string.utf8ToMacRoman( string.ansiToUtf8( s ) ); + «"WinNT" + «; + «"utf-8" + «case sys.os() + «"MacOS" + «s = string.utf8ToMacRoman( s ); + «"WinNT" + «s = string.utf8ToAnsi( s ); + « + «dialog.alert( "Charset Transformed string:\r\n" + s ) \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |