2009年1月20日星期二

从解码Base64的宏想起

从找到那天起,一直都很爱EmEditor。轻巧快速,完善的正则表达式和多内码支持。除了编辑超大文件时的表现不如UEdit32外,我几乎找不到别的缺点。而且在没有丢失已有优点的前提下,EmEditor也有在一点点变得更好更强大,是个用起来很窝心的编辑器。

好了,工商时间结束。话说最近一次升级到EmEditor v8后发现,以前的Base64解码插件不能用了。正好现在的EmEditor借助Windows Scripting Host(WSH)提供了宏功能,于是想自己写个解码宏试试感觉。

这个宏需要做的有两件事:一、将Base64字符串解码;二、如需要,进行内码转换。

WSH的标准配备Javascript和VBScript都没有直接提供解决这两件事的函数或对象,也没有所谓标准库一说,要用JS或VBS的话就必须找现成的纯实现或自己写。当然,如果喜欢Perl、PHP、Python、Ruby等等等,WSH其实也能够支持。

这两种法子都不好。Base64肯定有成熟的纯实现,内码转换却是个很复杂的问题,UTF-8至GBK或许OK,Big5至GBK呢?但如果用Ruby一类的语言,写出来的宏就只有自己用了,普通人哪会去装个Ruby解释器?

其实,所谓的“完美”解决办法是有的,而且看起来很简洁,很清晰:

#title = "Base64Decode"
#tooltip = "Decode Selected Base64 String."

function Base64DecodeText(Base64Str, sCharset){
 var xml_dom = new ActiveXObject("MSXML2.DOMDocument");
 var tmpNode = xml_dom.createElement("tmpNode");
 tmpNode.dataType = "bin.base64";
 tmpNode.text = Base64Str;

 var ado_stream = new ActiveXObject("ADODB.Stream");
 // Default gb2312
 ado_stream.Charset = (typeof(sCharset) == "undefined") ? "gb2312" : sCharset;
 ado_stream.Type = 1; // 1=adTypeBinary 2=adTypeText
 ado_stream.Open();
 ado_stream.Write(tmpNode.nodeTypedValue);
 ado_stream.Position = 0;
 ado_stream.Type = 2; // 1=adTypeBinary 2=adTypeText
 var str = ado_stream.ReadText(-1); // -1=adReadAll
 ado_stream.Close();

 return str;
}

if (!document.selection.IsEmpty) {
 var s = document.selection.Text;
 //s = Base64DecodeText(s); // gb2312
 s = Base64DecodeText(s, "UTF-8");
 OutputBar.Clear();
 OutputBar.writeln(s);
 OutputBar.Visible = true;
 OutputBar.SetFocus();
} else {
 alert('Select First!');
}

这一小段东西至少说明了一个问题:那些所谓《YY天精通XX语言》的书,纯属胡扯。

没有评论 :