MSDE安裝

MSDE2000安裝變得十分機車
因此將方法特地紀錄如下
請用指令列輸入
setup sapwd=”your_password” disablenetworkprotocols=0 instancename=”your_instance_name” securitymode=sql
sapwd 指定的是密碼,這是一定要指定的
disablenetworkprotocols 表示是否要對外開放 port, 預設好像是 1 的樣子,表示不對外開放,所以外面也連不進來
instancename 這個則是 instance name, 具名管道會用到,你可以給,也可以不給.
securitymode=sql 指定安全模式,instancename與此合用時,表示是混用模式,預設是 Windows 認證;若不加 instancename,只加此項,表示是 sql 認證模式.
就這樣子囉~~

以 VFP 實作 Singleton Pattern

Singleton,確保類別永遠只有一份實體
Singleton pattern, 簡言之,是一個確保類別永遠只有一份實體的範式(Pattern).
在什麼情況下,我們會用到這個 Pattern 呢??
比如,一台電腦裡在同一時間只能有一個視窗管理員在運行.
一般性的做法,是讓類別自行管理這個唯一個物件實體,讓他確保絕對無法生出第二個物件個體.
那麼在 VFP 裡面要如何實現呢??
讓我們來試試看,首先先定義出 CSingleton 這個Class
*
* Class Singleton
*
DEFINE CLASS CSingleton as Custom
  HIDDEN m_singleton
  m_singleton=.NULL.
  PROCEDURE getInstance
    IF m_singleton==.NULL.
      m_singleton=CREATEOBJECT(“CSingleton”)
    ENDIF
    RETURN m_singleton
  ENDPROC
  PROCEDURE getClassName
    return “I am Singleton Class”
  ENDPROC
ENDDEFINE
我們將 m_singleton 隱藏起來,讓外界無法直接存取,並且提供 getInstance method,讓外界可以透過此 method 取得 m_singleton 這個 instance.
所以當我們需要這個類別的實體時,就可以這麼寫:
lo_object=CSingleton::getInstance()
嘿,等等,別的語言是可以這麼寫,VFP 允許我們這樣用嗎??
此外,我們也沒有辦法隱喻地將 m_instance 放到 heap,像別的語言可以用 static 表明 m_instance 要放到 heap 中,確保只會有一份實體.
VFP 必須要先為 CSingleton 類別產生實體,才能呼叫 getInstance()
也就是要先這樣子
local lo_class, lo_object
lo_class=createobject(“CSingleton”)
lo_object=lo_class.getInstance()
才能讓 lo_object 取得實體.
那這不就違反我們的本意了嗎??
當使用者呼叫了多次 createobject(“CSingleton”), 等於是創建了好幾次 m_singleton,我們就無法讓 m_singleton 是系統中唯一的一個實體了.
那麼還有別的方法嗎??
嗯,用全域變數如何??
我們可以用全域變數搭配一個Function來使用.
所以就可以這麼寫
public m_instance
….
* 主程式
m_instance=.null.

* Function
function getInstance
  if m_instance==.null.
    m_instance=createobject(“CSingleton”)
  endif
  return m_instance
endfunc

* 要使用的時候
lo_object=getInstance()
? lo_object.getClassName()

這樣子總算是解決問題了,只要維持一個良好的撰寫習慣
就可以保證CSingleton的實體是唯一.
可是萬一後繼者不明白,直接去存取了全域變數 m_instance 的話,該怎麼辦呢??
嗯~~再換個方向來想
VFP 不是有個函數叫做 getobject() 嗎??
如果我們將類別轉為 OLEPUBLIC 之後,再使用 getobject() 去取得 instance,就可以取得唯一的實體來使用了.
這也不失為一個不錯的解法.
綜觀上面推論,或許還有其他的方法,是我沒有想到的.(我有想過用 fopen() 或 flock()…等等的)
但是就目前看來,在 VFP 裡面對 Singleton 並沒有一個完美的解法.
只有期待 VFP 未來能加入新的語言特性,讓我們能更靈活的運用了.
附錄: C++ 的解法
class CSingleton {
private:
  static CSingleton* m_instance;
protected: //保護起來,不讓 constructor 直接被叫用.
  Singleton();
  Singleton(const Singleton&);
  Singleton& operator= (const Singleton&);
public:
  CSingleton* getInstance(void) {
    if( m_instance==NULL )
      m_instance=new CSingleton();
    return m_instance;
  }
  char* getClassName(void) {
    return “Hello! Singleton Pattern!!\n”;
  }
}
CSingleton* CSingleton::m_instance=NULL; //因為宣告為 static,所以可以這樣給值.
int main( int argc, char* argv[] ) {
  CSingleton* obj=CSingleton::getInstance;
  printf( “%s”, obj->getClassName());
}

NERV

閒聊的時候,聊到NERV與福音戰士,於是查了一下,在這裡居然有解釋.
NERV:在德文中,這個詞是指”神志”.在劇中,NERV是”人類補完計劃”委員會的一個直屬特務機關,負責開發和使用EVA機與使徒進行戰鬥,他們擁有很高的科技成果和極高的軍事許可權,從三賢人超級電腦和葛城在必要的時候可以調動整個日本的電力就可見一斑.
SEELE:這個詞在德文中是指”心靈”.不要忘記,日本人一直都喜歡在作品中提到德國,而明日香更是有德國血統呢.庵野秀明有意的運用NERV和SEELE做劇中兩個組織的名字,其用心在向觀衆表明一些什麽呢?

Design Pattern-Dispatcher

看完 RUN!PC 六月號由李維先生所寫的”由軟體品質檢驗談Design Pattern的應用”一文,我覺得用 VFP 就可以很簡單的作到,所以就以 VFP 實作.
該文以計算牌照稅為引子
計算牌照稅的時候,會需要依照汽缸的cc數以及私人/營業用車來判定收費的標準,照一般的寫法,很自然就會用到很多 If…Then…Else 或 do case…endcase, 可是這樣子程式碼就會變得很長很長,而難以維護.
像是這樣:
If cc < 500
  money=900
else
  if cc < 600
    money=1200
    &&….. 略
  endif
endif
用 do case 的話則是這樣
do case
  case between( 0, 500 )
    money=900
  case between( 501, 599 )
    money=1200
  && … 略
endcase
李先生以一個 Dispatcher pattern 解決此一問題.
在 VFP 裡面可以直接結合資料庫作更好的解法
*
* ITax.prg
*
DEFINE CLASS ITax as custom
  PROCEDURE Init()
    create cursor crTax( cc_lo I, cc_hi I, PrivateTax Y, BusinesTax Y )
    insert into crTax values ( 0, 500, $ 1620, $ 900 )
    insert into crTax values ( 501, 599, $ 2160, $ 1200 )
    insert into crTax values ( 600, 1199, $ 4320, $ 2160 )
    insert into crTax values ( 1200, 1799, $ 7120, $ 3060 )
    insert into crTax values ( 1800, 2399, $11230, $ 6480 )
    insert into crTax values ( 2400, 2999, $15210, $ 9900 )
    insert into crTax values ( 3000, 4199, $28220, $16380 )
    insert into crTax values ( 4200, 5399, $46170, $24300 )
    insert into crTax values ( 5400, 6599, $69690, $33660 )
    insert into crTax values ( 6600, 7799, $117000, $44460 )
    insert into crTax values ( 7800, 9999999, $117000, $44460 )
  ENDPROC
  PROCEDURE Destroy()
    use in crTax
  ENDPROC
  PROCEDURE GetTax( cc, theKind )
    local ly_result
    local lc_oldalias
    lc_oldalias=alias()
    select("crTax")
    go top
    locate for between( cc, crTax.cc_lo, crTax.cc_hi )
    if found()
      ly_result=crTax.&theKind
    else
      ly_result=0
    endif
    select( lc_oldalias )
    return ly_result
  ENDPROC
  PROCEDURE GetPrivateTax( cc )
    return this.GetTax( cc, "PrivateTax" )
  ENDPROC
  PROCEDURE GetBusinessTax( cc )
    return this.GetTax( cc, "BusinesTax" )
  ENDPROC
ENDDEFINE
*
* test_itax.prg
*
LOCAL lo_obj
set procedure to itax.prg
lo_obj=createobject("ITax")
? lo_obj.GetPrivateTax( 1000 )
? lo_obj.GetBusinessTax( 2000 )
瞧,這樣不是簡單多了嗎??
在這裡拋磚引玉一下,希望大家如果有更好的解法
也 post 上來,讓大家觀摩一下
^_^

讓你的 Apache 支援 SSL

Linux 版本 Red Hat 7.3
安裝:
確定有安裝 openssl 與 mod_ssl 相關套件.
步驟:
請切換到 /etc/httpd/conf 下
輸入 make server.crt
依照指示輸入答案後,目錄下應會產生 server.crt 與 server.key 兩個檔案
將 server.key 放到 ssl.key/ 下
將 server.crt 放到 ssl.crt/ 下
編輯 httpd.conf
作如下修改:
SSLCertificateFile /etc/httpd.conf/ssl.crt/server.crt
SSLCertificateKeyFile /etc/httpd.conf/ssl.key/server.key
重新啟動 httpd ,應該就可以了~
這樣子產生的認證在使用上,瀏覽器會提出警告,告知這個憑證並非放在一個具公信力的地方,容易造成使用者困擾.
因此仍要向具公信力的機構申請才是.
目前產生的認證,期限是一年,你可以編輯 Makefile ,找尋 -days 365
將其改為你所需要的天數即可.
若不使用 mod_ssl 提供的 Makefile
你也可以手動使用 openssl 指令來產生
步驟如下:
– 產生 .key (public)
openssl genrsa -des3 -out ca.key 1024
– 驗證 .key
openssl rsa -noout -text -in ca.key
– 產生 .crt (public)
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
– 驗證 .crt
openssl x509 -noout -in ca.crt
– 產生 .key (private)
openssl genrsa -des3 -out server.key 1024
– 驗證 .key
openssl rsa -noout -text -in server.key
– 產生 .csr
openssl req -new -key server.key -out server.csr
– 查看 .csr
openssl req -noout -text -in server.csr
– 產生 .crt
一種是使用 sign.sh, 它會依據 server.csr 來產生 server.crt , 但我怎麼找都找不到 sign.sh
以下是看 Makefile 而得來的
openssl req -new -key server.key -x509 -days 3650 -out server.crt
資料參考: 永遠的UNIX論壇 (http://www.fanqiang.com/)

mp4player trace 筆記

mp4player 是 mpeg4ip 內附的一個 player
RFC 1889 RTP 被 RFC 3550 淘汰(obsolete)
video 繼承 video_sdl
– 由 player_session 建立之,用以 sync video/audio
– 主要由 player_media 使用,player_session貫穿主軸,在建立video和player_media實體時,都會把自己傳入.
player_media 建立 plugin 時,會把 video_sync(m_video_sync)傳入codec_plugin中.
各個 codec_plugin 為 xxxx_file.cpp
codec_plugin 利用 check_for_video_codec() 傳回之.
plugin實作檔案最後都有一個 macro 定出 structure: mpeg4ip_codec_plugin.
如此一來,codec_plugin_cpp的 check_for_video_codec()/check_for_audio_codec() 即可利用 dlsym() 找到它,並依據此 structure 去叫用 plugin 中的 function.
rtsp_thread()
+-> get_rtp_packet()
 +-> callback_for_rtp_packet()
  +-> 呼叫設置的 callback
在 rtsp_thread 中,作完 callback 後,會呼叫 periodic(), 這也是藉由 rtsp_thread_set_rtp_callback() 去設置的.
c_rtp_periodic(), 用 rtsp_thread_set_rtp_callback()設進去.
mp4player 中,callback function (CPlayerMedia::rtp_receive_packet(),此 function 會被包在 c_rtp_packet_callback, 再被上面的 rtsp_thread_set_rtp_callback() 設進去)
判斷 interleaved 而決定呼叫 rtp_process_recv_data() 或 rtp_process_ctrol().
periodic function 則呼叫 rtp_byte_stream() 去 recv_task (在 rtp_bytestream.cpp )
上面的那個段落又會呼叫 rtp_update(), rtp_update() 收 packet, 呼叫 callback.
rtp_update()(or callback??) 會執行 timeout_rr(), 而 timeout_rr() 中會執行 rtp_init_extern_net().
指定的 callback: c_recv_callback() => player_media->recv_callback() => stream->recv_callback() 放在 queue 中.
systems.h
– include necessary headers and redefine data types.
sdp.h
– session description protocol
rtsp_private.h
– the major rtsp interface
sdl.h
-> needed, for thread-control (create, mutex…and so on)
rtsp_create_client_for_rtp_tcp()
– create mutex
– create thread, 同時亦建立 unix socket, 之後的 function 會透過此 socket 與 thread 溝通, thread 主體在 rtsp_thread.c (rtsp_thread())中.
圖片及相關檔案:

Continue reading “mp4player trace 筆記”

lvm – simple usage

須將 partition type 設為 0x8e
pvcreate /dev/hdxn 初始化 lvm partition
vgcreate 建立 volume group
lvcreate 向 volume group 索取 logical volume
之後就可以去 format, 或 mount 或做些你要做的事情啦
lvremove 則是移除 logical volume
vgremove 則是移除 volume group
變更大小或屬性時,則使用 XXextend, XXchange….

風雲亂搞版

五年後……
在台北的某街頭
使徒偶遇兩人
A:”嘿,你撞到我們了”
B:”對呀對呀”
使徒:”抱歉…….”
A:”算了,相遇即是有緣,請問貴姓?”
使徒:”小姓使,名徒”.
A:”啊~~你就是使徒,我是 XX風,他是 XX雲…..我們終於找到你了….”
使徒:”啊~~難道你們就是風雲…..我出運啦啦啦啦~~~~”
話畢,三人化為龍,往天際飛去.
在場的人盡皆錯愕….
“新聞快報”
“傍晚,台北街頭,發生怪事……..”
後記:
風雲這部漫畫中很有名的一句話,”金麟豈是池中物,一遇風雲化成龍”.
起因是因為有人把這句話當作簽名檔,一時靈機一動,拿來寫成一個小故事,作為調侃之用.

天殺的 ARM gcc

今天學到很重要的事情
靜態連結 library (.a) 在下編譯指令時,最好把它放在所有的 .c, .o 之後,然後再放 -lxxxx
這樣子呢
編譯起來就會比較順利~

就因為這種事情
昨天晚上預計九點半回家,卻變成十點鍛羽而歸地回家~
今天早上差點因為此事而翻桌~
真是好一個天殺的 ARM gcc
正所謂”不經一事,不長一智”!!

Monday Blue

Monday Blue
Thursday Green
Friday Greed
星期一的憂鬱,這應該沒問題
星期四的忌妒,因為隔天有人請特休假,自己卻沒請,所以忌妒
星期五的貪婪,因為快放假了,開始拼命想接下來要去哪裡玩.