Wednesday 28 May 2008

Emacs 23.0.60 and mule-gbk

看来mule-gbk在Emacs 23.0.60是用不着了。注释掉就可以完成迁移:
;; (require 'mule-gbk)
(set-language-environment "Chinese-GBK")
(set-terminal-coding-system 'chinese-gbk)
(set-keyboard-coding-system 'chinese-gbk)
(setq locale-coding-system 'chinese-gbk)
(setq current-language-environment "Chinese-GBK")
还有chinese-gb18030可用。不过gbk对我就足够用了。

Tuesday 27 May 2008

Build Emacs CVS on Cygwin

大约在2008年2月的时候,Unicode的支持进了Emacs CVS。自那之后Emacs的CVS版在
Cygwin上就没有编译成功过。今天编译成功了。加了以下改动:
,----[ `src/sheap.c' changes ]
| #define STATIC_HEAP_SIZE (12 * 1024 * 1024)
| -->
| #define STATIC_HEAP_SIZE (32 * 1024 * 1024)
`----
期望这个改动能早点进Emacs的CVS。

Friday 23 May 2008

亲戚或余泣

亲戚或余泣
他人亦已歌
死去何足道
托体同山阿

Thursday 22 May 2008

大红灯笼高高挂芭蕾版

芭蕾舞和京剧很技术地裱糊了起来。装修大师张艺谋的映景之作。

苏童的原作妻妾成群阴暗潮湿。真实而扭曲的人性在残酷的现实里邪恶地张扬。看了心寒。

到电影版变了一次。月白变成了大红。巩俐在,人性还在吧。

芭蕾适合表达比较纯粹的概念。京剧好似盒子里的艺术。裱起来需要很高的技术。

到芭蕾版人没了。只剩下了性。性是剧情的唯一推动,除此之外想不到其他的理由。

Wednesday 14 May 2008

Java里的移位

在Java里,移位都是基于int的。如果不是int,就转为int再移位。

0xff >> 2 -> 0x3f
0xff >> 4 -> 0x0f

之上都是对int的移位。

那对byte的移位呢,比如:((byte)0xff) >> 2 -> ?

会做以下3步:
1. int 0xff -> byte,byte 0xff就是byte的-1
2. 移位前byte需要转为int, byte 0xff -> int, 变成了int的-1,就是0xffffffff
3. 0xffffffff >> 2 --> 0xffffffff, >>是用符号位1补位

因此下列断言是正确的:
assertEquals(0xffffffff >> 2, ((byte)0xff) >> 2)
或者:
assertEquals(-1 >> 2, ((byte)0xff) >> 2)
或者:
assertEquals(-1, ((byte)0xff) >> 2); // 由于是1补位,-1怎么移位也是-1。

>>补位用的是符号位,也就是说,如果符号位为1,就用1,否则用0

>>>补位只用0。这是两者的区别。

那0xff >> 2 和((byte)0xff) >>> 2是否一样呢?答案是否定的。

这里还牵涉到byte和int相互转化的问题。((byte)0xff) >>> 2相当于:
1. int 0xff -> byte 0xff, byte 0xff = -1
2. 移位前byte需要转为int, byte 0xff -> int, 变成了int的-1,就是0xffffffff
3. 0xffffffff >> 2 --> 0x3fffffff, 0补位,和0xff >> 2 -> 0x3f不同。

关于byte转int,以下断言也是对的:
assertEquals(0xfffffff0, (int)((byte)0xf0))
相当于:
assertEquals(0xfffffff0, (byte)0xf0)
这是有符号位的情况。没符号位的情况:
assertEquals(0x0000000f, (int)((byte)0x0f))

byte的移位并没有太多含糊的地方,只是byte移位之前,会转为int;再加上byte的
符号位,会把人搞糊涂。

一个办法是在byte移位之前显示地转int,别让byte自己转。操作看起来会清晰些:
assertEquals(0x3f, ((byte)0xff)&0xff >> 2)
或者:
assertEquals(0x3f, ((byte)-1)&0xff >> 2)
用0xff并一下,这样byte的-1转为int就是255了。刚好和C里的无符号byte一致。

大部分教科书的移位是按C的无符号byte讲的。

这样这些教科书里的东西也可以用起来了。

Thursday 8 May 2008

猪有两个特点,一个是爱吃,一个是爱睡。

女人靠睡,男人靠喂。可以讲,女人和男人,各有猪的一个特点。

在一个屋檐下,住着一个男人,一个女人。

如果男人能像猪一样的吃,女人能像猪一样的睡,这个屋檐,才可称为一个家。

-- 像猪一样吃比较好实现,像猪一样睡,难啊!

- 因此家是男人的。

Sunday 4 May 2008

MPlayer转音频

MPlayer用来转音频很好用。原因是MPlayer支持的音频格式多,而且MPlayer还是个视频播放器。用熟了之后简直就是万能的转换器。

,----[ mplayer -ao pcm:file=... ]
| mplayer -ao pcm:file=file.wav file.avi
`----

`file.avi'是什么格式无所谓,只要mplayer能播放就可以;当然电影也可以;可以用上面的命令扒电影配音。

转为wav格式后,再转其他的格式别的转换器就接上了。

在Cygwin下,不知为何flac不工作。因此flac的转换就交给MPlayer来完成。做的还不错。

Saturday 3 May 2008

EMF静态模型的序列化

EMF建模生成的静态模型,都派生自class:

org.eclipse.emf.ecore.sdo.impl.EDataObjectImpl

在EDataObjectImpl类里,定义了writeReplace方法:
,----[ writeReplace ]
| public Object writeReplace() throws ObjectStreamException
| {
| return SDOUtil.writeReplace(this);
| }
`----

这样,在做Java序列化的时候,系列化流的处理在此处被截获了。因此,如果想自己处理Java的序列化可以重载`writeReplace'方法。

`SDOUtil.writeReplace'大体上会找找有没有DataGraph,没有就抛错误,有就用DataGraph做序列化了。由此有一个方法就是把DocumentRoot放到DataGraph里去,省得重写`writeReplace'。也是可以的。DataGraph的序列化只能做DocumentRoot;把孤立的类型放进去,序列化可以,反序列化就不行了。

DataGraph序列化出来的是XML格式。对一个EObject,DataGraph的序列化会调用其`eIsSet'方法看看某个feature是否设,如果设了就调eGet拿过来序列化。由此可以看到`writeReplace'和DataGraph的序列化可以共存,并且彼此没什么影响。`eIsSet'和DataGraph序列化有关,这一点很重要,可以结合`writeReplace'用用看,很有意思。