前提: Syntax很簡單,不用look ahead,而且都會知道要讀多少byte(沒有那種「讀到0x00為止」)
我的作法看起來長這樣:
const msgParser = expect([10, 10, 20], (datetime, messageType, messageID) => {
switch (messageType) {
case "HI":
expect([10, 10], (senderID, senderName) => {
// connect
})
break
case "Message":
expect([4], (messageLength) => {
expect([messageLength], (message) => {
//
})
})
break
case "File":
expect([10, 4], (fileName, fileLength) => {
expect([fileLength], (fileBytes) => {
// save the file
})
})
break
case "Sticker":
// ...
break
}
})
這個 expect 會接收一個 length array 和 callback function。 expect([10, 20], (a, b) => {})
代表說讀 30 bytes,
前 10 byte 當成第一個參數,後 20 bytes 當成第二個參數傳給 callback。
這個 expect 做的事是:
- 把總共要讀多少 byte 算出來,存在一個 global variable (or instance variable) 叫
expectLength
。 - 把一個 lambda 存在
parsingFunction
。這個 lambda 負責把 buffer 切下 expectLength,按照長度丟給 callback。
其實可以想像 expect 成「install要用哪個parser」。
實際上程式要動起來,必須寫另外一個 feed(),負責看之前剩下的buffer和餵進來的data有沒有到expectLength, 有的話呼叫 parsingFunction,切 buffer 之類的 housekeeping。