基于Linux 的嵌入式瀏覽器的研究
隨著信息技術(shù)與網(wǎng)絡(luò)技術(shù)的快速發(fā)展, 以及人們?nèi)粘I顚?duì)網(wǎng)絡(luò)信息的需求的不斷增加。掌上電腦、上網(wǎng)本、手機(jī)、導(dǎo)航儀器、智能電視、智能家電等對(duì)嵌入式系統(tǒng)提出了更多更高的要求。在嵌入式系統(tǒng)中利用嵌入式瀏覽器獲取網(wǎng)絡(luò)信息是必不可少的, 因此嵌入式瀏覽器技術(shù)成為現(xiàn)如今的技術(shù)熱點(diǎn)之一。而且Linux 操作系統(tǒng)完全開(kāi)源, 可以降低產(chǎn)品開(kāi)發(fā)成本, 因此對(duì)基于Linux 操作系統(tǒng)的嵌入式瀏覽器開(kāi)發(fā)技術(shù)的研究有著重要意義。
1 嵌入式瀏覽器的結(jié)構(gòu)
根據(jù)嵌入式瀏覽器的特點(diǎn), 分析嵌入式瀏覽器的各個(gè)部分功能。下面介紹嵌入式瀏覽器的主要功能:
(1) 詞法分析, 主要是對(duì)HTML 語(yǔ)言進(jìn)行詞法分析, 并且要求HTML 詞法分析可以兼容XML 等其他標(biāo)簽語(yǔ)言,達(dá)到只需更換語(yǔ)言的元素名稱(chēng)就可以進(jìn)行詞法分析的效果;(2) 語(yǔ)法分析與布局, 在非嵌入式瀏覽器中語(yǔ)法分析是獨(dú)立的一個(gè)模塊, 但是在嵌入式瀏覽器中不作為一個(gè)獨(dú)立模塊, 簡(jiǎn)化系統(tǒng)結(jié)構(gòu), 即實(shí)現(xiàn)語(yǔ)法分析與布局同步化, 節(jié)省了語(yǔ)法分析數(shù)據(jù)存儲(chǔ)的內(nèi)存空間; (3) 嵌入式瀏覽器的用戶(hù)界面, 設(shè)計(jì)高效快捷的用戶(hù)界面是應(yīng)用軟件的重要部分;(4) 嵌入式瀏覽器JavaScript 支持,JavaScript 在瀏覽器里主要是用于操縱界面元素并與瀏覽器內(nèi)部命令進(jìn)行結(jié)合;(5)I/O 端, 主要是通過(guò)HTTP 協(xié)議和文本系統(tǒng)來(lái)讀取頁(yè)面信息;(6) 控制機(jī)制, 負(fù)責(zé)命令響應(yīng)和消息處理。嵌入式瀏覽器功能結(jié)構(gòu)如圖1 所示。
圖1 嵌入式瀏覽器功能結(jié)構(gòu)圖
2 HTML 詞法分析
2.1 組成及功能
HTML 詞法分析是嵌入式瀏覽器開(kāi)發(fā)的基礎(chǔ), 是整個(gè)嵌入式瀏覽器整體設(shè)計(jì)的最前端部分,HTML 詞法分析的數(shù)據(jù)結(jié)構(gòu)是語(yǔ)法分析與布局的重要依據(jù)。HTML詞法分析的效率、準(zhǔn)確率以及容錯(cuò)率的高低在一定程度上決定了整個(gè)嵌入式瀏覽器的工作效率。下面對(duì)HTML詞法分析的組成和功能進(jìn)行解析。
HTML 詞法分析的功能主要是負(fù)責(zé)接收從I/O 端讀取到的HTML 代碼并進(jìn)行詞法分析, 提取網(wǎng)頁(yè)中HTML代碼中的各元素信息, 按照定義的數(shù)據(jù)結(jié)構(gòu)保存元素的屬性和名稱(chēng)等, 實(shí)現(xiàn)數(shù)據(jù)的結(jié)構(gòu)化。
根據(jù)HTML 詞法分析的功能可以解析為幾個(gè)組成部分:(1) 初始化。完成對(duì)數(shù)據(jù)結(jié)構(gòu)的初始化, 主要是分配內(nèi)存, 變量賦初值; (2) 主體的數(shù)據(jù)流分析, 逐字符地進(jìn)行判斷, 確定數(shù)據(jù)的歸屬類(lèi)型; (3) 元素的分析, 提取元素的名稱(chēng)、屬性和值域; (4) 釋放, 主要是對(duì)數(shù)據(jù)內(nèi)存空間的釋放。
2.2 算法
根據(jù)HTML 詞法分析的功能以及組成部分, 可以很清晰地得到一個(gè)簡(jiǎn)單的算法。其算法過(guò)程具體如下:
(1)從I/O 端讀取的字符串流中,順序讀取一個(gè)字符;(2) 如果遇到< , 表示將遇到元素, 處理該元素( 使用元素處理函數(shù)來(lái)處理該元素) , 元素處理結(jié)束后, 指針指向該元素的尾部;(3) 如果遇到空格或回車(chē), 則跳過(guò);(4) 如果遇到>, 則跳過(guò)(因?yàn)椴豢赡艽嬖?lt;>這種不包含任何元素的情況, 只是為了增強(qiáng)程序的容錯(cuò)性);(5) 如果遇到的不是上述幾種情況, 則遇到的是文字( 使用文字處理函數(shù)來(lái)處理該文字) , 文字處理結(jié)束后,指針指向下一個(gè)元素的首部;(6) 循環(huán)(1)~(5 ) 步驟, 直到I/O 端讀取的字符串流全部分析完。
根據(jù)上述詞法分析算法過(guò)程可以得到相應(yīng)的流程圖, 如圖2 所示。
圖2 詞法分析算法流程圖 2.3 詞法分析的設(shè)計(jì) 根據(jù)上述提出的詞法分析的算法, 通過(guò)掃描I/O 端讀取的字符串, 來(lái)檢測(cè)字符是否為標(biāo)簽元素、提取標(biāo)簽元素屬性等。設(shè)計(jì)詞法分析的基礎(chǔ)要定義數(shù)據(jù)結(jié)構(gòu), 為詞法分析算法的實(shí)現(xiàn)提供基礎(chǔ)。根據(jù)功能需要設(shè)計(jì)基本的數(shù)據(jù)結(jié)構(gòu), 定義如下: char token[]; // 標(biāo)簽元素表 char * tokenPointer; //指向標(biāo)簽元素表的指針 char chText[]; // 字符表 char *chPointer; // 字符表指針 char text[]; // 字符串表 char *textPointer; // 字符串表指針 char textRead[]; //存放待識(shí)別的源程序字符串 char *textReadPointer; //讀取字符串指針 char ch; //存放最讀取的源程序字符 char STrToken[]; //存放構(gòu)成單詞符號(hào)的字符串 bool flag=false; //是否掃描過(guò)一次 3 瀏覽器JavaScript 支持 3.1 JavaScript 簡(jiǎn)介 JavaScript 是一種基于對(duì)象和事件驅(qū)動(dòng)并具有相對(duì)安全性的客戶(hù)端腳本語(yǔ)言。它的一個(gè)重要功能就是面向?qū)ο蟮墓δ埽?通過(guò)基于對(duì)象的程序設(shè)計(jì), 可以用更直觀、模塊化和可重復(fù)使用的方式進(jìn)行程序開(kāi)發(fā)。一組包含數(shù)據(jù)的屬性和對(duì)屬性中包含數(shù)據(jù)進(jìn)行操作的方法, 稱(chēng)為對(duì)象。用戶(hù)與網(wǎng)頁(yè)交互時(shí)產(chǎn)生的操作, 稱(chēng)為事件。事件可以由用戶(hù)引發(fā), 也可能是頁(yè)面發(fā)生改變, 甚至還有看不見(jiàn)的事件( 如Ajax 的交互進(jìn)度改變) 。絕大部分事件都由用戶(hù)的動(dòng)作所引發(fā), 例如用戶(hù)按鼠標(biāo)的按鍵, 就產(chǎn)生click 事件, 若鼠標(biāo)的指針在鏈接上移動(dòng), 就產(chǎn)生MouseOver 事件等。在JavaScript 中, 事件與事件處理程序配套使用。而對(duì)事件的處理用addEventListener() 函數(shù), 它有3 個(gè)參數(shù): 事件、引發(fā)的函數(shù)以及是否使用事件捕捉。 為了保障安全性, 將第三個(gè)參數(shù)始終設(shè)置為false。 JavaScript 具有幾個(gè)特性: 能使網(wǎng)頁(yè)增加互動(dòng)性; 能使有規(guī)律地重復(fù)的HTML 源代碼簡(jiǎn)化, 減少下載時(shí)間;能及時(shí)響應(yīng)用戶(hù)的操作, 對(duì)提交表單做即時(shí)的檢查, 無(wú)需浪費(fèi)額外的驗(yàn)證時(shí)間。 3.2 JavaScript 引擎 JavaScript 引擎一般作為共享庫(kù)使用, 應(yīng)用程序調(diào)用引擎提供的API 函數(shù)。引擎API 函數(shù)大致分為以下幾種: 數(shù)據(jù)類(lèi)型操作、RunTime 控制、類(lèi)與對(duì)象的創(chuàng)建和維護(hù)、函數(shù)與腳本執(zhí)行、字符串操作、錯(cuò)誤處理、安全控制、Debug 支持。一般情況下, 在應(yīng)用程序中只需使用某幾類(lèi)函數(shù)。例如, 在進(jìn)行JavaScript 調(diào)用之前必須調(diào)用JS_NewRuntime 函數(shù)來(lái)創(chuàng)建并初始化JavaScript 引擎。有些類(lèi)型的函數(shù)(像安全控制類(lèi))提供可選擇的特征。 JavaScript 引擎是系統(tǒng)上的一個(gè)共享資源。通過(guò)將引擎API 調(diào)用嵌入到應(yīng)用程序中, 可以請(qǐng)求JavaScript 引擎進(jìn)行操作。引擎處理請(qǐng)求, 并將結(jié)果或狀態(tài)信息返回給應(yīng)用程序。例如, 假定使用JavaScript 引擎自動(dòng)化應(yīng)用程序, 腳本應(yīng)用程序鑒別用戶(hù)并設(shè)置權(quán)限。首先, 應(yīng)用程序創(chuàng)建JavaScript 對(duì)象, 該對(duì)象描述用戶(hù)信息, 包括姓名、ID、權(quán)限和可用的函數(shù)列表。在這種情況下, 應(yīng)用程序首先調(diào)用JS_NewObject 創(chuàng)建對(duì)象。當(dāng)JavaScript 引擎創(chuàng)建對(duì)象后, 返回一個(gè)指針給應(yīng)用程序。應(yīng)用程序再調(diào)用JavaScript 引擎執(zhí)行腳本。在創(chuàng)建用戶(hù)對(duì)象后, 應(yīng)用程序即刻傳遞腳本給JS_EvaluateScript 以便編譯和運(yùn)行。腳本獲許取得并校驗(yàn)用戶(hù)信息, 然后建立用戶(hù)存取的權(quán)利。 JavaScript 引擎收到初始化請(qǐng)求后,給JavaScript Run-Time 分配內(nèi)存, 應(yīng)用程序使用的變量、對(duì)象和上下文都保存在RunTime 中。一個(gè)上下文是腳本的執(zhí)行狀態(tài)(JavaScript 引擎使用的) 。每個(gè)同時(shí)存在的腳本或線(xiàn)程都必須有自己的上下文。單個(gè)的JavaScript RunTime 可以包含多個(gè)上下文、對(duì)象和變量。幾乎所有的JavaScript 引擎調(diào)用都需要一個(gè)上下文變量, 應(yīng)用程序在創(chuàng)建RunTime后, 首先應(yīng)調(diào)用至少一次JS_NewCONtext 來(lái)創(chuàng)建一個(gè)上下文。上下文的實(shí)際數(shù)量依賴(lài)于程序中同時(shí)使用的腳本數(shù)。程序中每個(gè)同時(shí)存在的腳本都需要一個(gè)上下文。另一方面, 如果某個(gè)時(shí)刻只有一個(gè)腳本編譯和運(yùn)行, 則只需一個(gè)上下文給每個(gè)腳本重復(fù)使用即可。 3.3 JavaScript 與瀏覽器結(jié)合 3.3.1 直接加入方式 絕大部分含有JavaScript 代碼的網(wǎng)頁(yè)都采用直接加入的方式。 <script type="test/javascript"> document.write("This is Javascript! "); </script> 其中,<script> </script> 是JavaScript 的標(biāo)簽。<scripttype = "test/javascript" > 用來(lái)提示瀏覽器該程序采用JavaScript 語(yǔ)言編寫(xiě), 需要調(diào)動(dòng)相應(yīng)的解釋程序進(jìn)行解釋。 除此之外, 還有一個(gè)更高版本的嵌入腳本, 使用HTML 中的CDATA 語(yǔ)法, 就是把CDATA 中的文本全部當(dāng)作純文本處理, 當(dāng)遇到CDATA 時(shí)結(jié)束。 <script language="javascript" type="test/javascript"> <! CDATA[[> <! ]]> </script> 3.3.2 引用方式 如果已經(jīng)存在一個(gè)JavaScript 源文件(以js 為擴(kuò)展名),則可以采用引用的方式提高程序代碼的利用率。其基本格式如下: <script src="url" type="test/javascript"> </script> 其中url 就是程序文件的地址。 同樣地, 這樣的JavaScript 程序語(yǔ)句可以放在HTML文檔頭部或主體的任何部分。如果要實(shí)現(xiàn)直接加入JavaScript 程序代碼, 可以首先創(chuàng)建一個(gè)JavaScript 源代碼文件“javascript.js ” , 其代碼為document.write ("This isJavascript! ") 。在網(wǎng)頁(yè)中調(diào)用程序的方法, 如: <script src="javascript.js" type="test/javascript"> </script> 也可以同時(shí)在導(dǎo)入文件時(shí)指定JavaScript 的版本,如: <script src = "javascript.js" type = "test/javascript; version =2.0"> </script> 本文對(duì)Linux 操作系統(tǒng)的嵌入式瀏覽器進(jìn)行了研究與分析。分析了嵌入式瀏覽器的結(jié)構(gòu), 并對(duì)嵌入式瀏覽器的各部分功能進(jìn)行闡述, 其中包括詞法分析、語(yǔ)法分析與布局、瀏覽器JavaScript 支持、I/O 端等部分。其中,在嵌入式瀏覽器的研究過(guò)程中, 詞法分析的算法是開(kāi)發(fā)技術(shù)的核心。在后續(xù)研究工作中, 可以對(duì)詞法分析算法做進(jìn)一步的研究, 提高詞法分析的效率, 完善嵌入式瀏覽器功能實(shí)現(xiàn)的效果。