Yao Lu / BasicWeb

Dependents:   uVGAII_WebBrowser

Revision:
0:7fac52628f4e
Child:
1:41f0491dcc4c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BasicWeb.cpp	Wed Mar 06 16:13:02 2013 +0000
@@ -0,0 +1,340 @@
+#include "BasicWeb.h"
+
+// table used to convert keyboard scan codes to ASCII
+const unsigned char BasicWeb::table[] = {
+//  0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,'~',  0,      // 0
+    0,  0,  0,  0,  0,'q','1',  0,  0,  0,'z','s','a','w','2',  0,      // 1
+    0,'c','x','d','e','4','3',  0,  0,' ','v','f','t','r','5',  0,      // 2
+    0,'n','b','h','g','y','6',  0,  0,  0,'m','j','u','7','8',  0,      // 3
+    0,  0,'k','i','o','0','9',  0,  0,'.','/','l',':','p',  0,  0,      // 4
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,      // 5
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,      // 6
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,      // 7
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,      // 8
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0};      // 9
+
+BasicWeb::BasicWeb(PinName tx, PinName rx, PinName reset)
+    :vga(tx, rx, reset),
+    urlStr("http://www.batw.net/htmllessons/example_page.html"),
+    urlIndex(63), str(NULL), bold(false), font(0), color(0x000000), index(0), title(false) {
+    
+    // initialize uVGA
+    vga.baudrate(115200);
+    vga.display_control(0x0c, 0x01);      // Set display to VGA 640x480
+}
+
+void BasicWeb::browser(){
+    led = 1;
+    // draw browser
+    vga.background_color(WHITE);
+    vga.rectangle(0, 0, 640, 38, 0xBBBBBB);
+    vga.rectangle(30, 20, 636, 34, WHITE);
+    displayUrl();
+    
+    // connect to internet and display IP
+    eth.init();
+    eth.connect();
+    vga.text_string("IP address is:", 50, 1, 1, 0x000000);
+    vga.text_string(eth.getIPAddress(), 65, 1, 1, 0x000000);
+    led2 = 1;
+}
+
+void BasicWeb::displayUrl(){
+    vga.rectangle(30, 20, 636, 34, WHITE);      // clear url
+    vga.text_string(urlStr, 4, 3, 1, 0x000000);
+}
+
+// process new key
+void BasicWeb::newKey(char scancode){
+    char c = table[scancode];
+    if(c != 0){                                 // if a alpha numeric
+        urlStr[urlIndex] = c;
+        char s[] = {c, 0};
+        vga.text_string(s, 4 + urlIndex, 3, 1, 0x000000);
+        urlIndex += 1;
+        urlStr[urlIndex] = '\0';
+    }else{
+        if(scancode == 0x66){                   // backspace
+            if(urlIndex != 0){
+                urlIndex -= 1;
+                urlStr[urlIndex] = '\0';
+                vga.rectangle(31 + urlIndex*8, 20, 39 + urlIndex*8, 34, WHITE);
+            }
+        }else if(scancode == 0x5A){             // enter
+            int ret = http.get(urlStr, text, 10240);
+            if(!ret){
+                removeRL(text, 10240);
+                index = 0;
+                lineIndex = 40;
+                vga.rectangle(0, 0, 640, 19, 0xBBBBBB);         // clear title
+                vga.rectangle(0, 39, 640, 480, 0xFFFFFF);       // clear page
+                displayPage();
+            }else{
+                vga.graphic_string("Could not fetch page", 21, 0, 1, color, 1, 1);
+            }
+        }
+    }
+}
+
+void BasicWeb::modKey(char scancode1, char scancode2){
+    if(scancode1 == 0xE0){
+        if(scancode2 == 0x72 || scancode2 == 0x74){             // up and right arrow
+            led3 = 1;
+            vga.rectangle(0, 39, 640, 480, 0xFFFFFF);           // clear page
+            lineIndex = 40;
+            displayPage();
+        }
+    }
+}
+
+void BasicWeb::displayPage(){
+    parseStr();
+    while(printText(str)){
+        parseStr();
+        if(title){
+            title = false;
+            vga.rectangle(0, 0, 640, 19, 0xBBBBBB);
+            vga.text_string(titleStr, 1, 1, 1, 0x000000);
+        }
+    }
+}
+
+/* processes tags up until a string to display is found */
+void BasicWeb::parseStr(){
+    bool cont = true;
+    while(cont){
+        while(text[index] == ' ') index++;       // skip white space
+        if(text[index] == '\0'){
+            str = NULL;
+            return;
+        }
+        if(text[index] == '<'){
+            cont = applyTag();
+        }else{
+            cont = extractStr();
+        }
+    }
+}
+
+/* processes the tag and increment index past it */
+bool BasicWeb::applyTag(){
+    index++;
+    
+    // skip comments
+    bool comment = true;
+    if(text[index] == '!'){
+        if(text[index+1] == '-' && text[index+2] == '-'){
+            index += 3;
+            while(comment){                     // while still in comment body
+            
+                // check for ending sequence
+                if(text[index] == '-'){
+                    index += 1;
+                    if(text[index] == '-'){
+                        index += 1;
+                        if(text[index] == '>'){
+                            comment = false;    // break out of comment
+                        }
+                    }
+                }else{
+                    index++;
+                }
+            }
+            comment = true;                     // reset comment flag
+        }
+        while(text[index] != '>') index++;
+        index++;
+        return true;
+    }
+    
+    // process tag
+    int i = 0;
+    if(compareTag(text + index, "title")){
+        index += 6;
+        title = true;
+        while(text[index+i] != '<' && text[index+i] != '\0'){
+            i++;
+        }
+        if(i < 30){
+            copyStr(text + index, titleStr, i);
+        }else{
+            copyStr(text + index, titleStr, 30);
+        }
+        index += i;
+    }else if(compareTag(text + index, "script")){               // skip script
+        index += 7;
+        while(text[index] != '\0'){
+            if(text[index] == '<'){
+                index++;
+                if(compareTag(text + index, "/script")){
+                    index += 8;
+                    break;
+                }
+            }
+            index++;
+        }
+    }else if(compareTag(text + index, "style")){                // skip style
+        index += 6;
+        while(text[index] != '\0'){
+            if(text[index] == '<'){
+                index++;
+                if(compareTag(text + index, "/style")){
+                    index += 7;
+                    break;
+                }
+            }
+            index++;
+        }
+    }else if(compareTag(text + index, "br")){
+        index += 3;
+        lineIndex += 10;
+    }else if(compareTag(text + index, "/br")){
+        index += 3;
+        lineIndex += 10;
+    }else if(compareTag(text + index, "b")){
+        index += 2;
+        font += 1;
+    }else if(compareTag(text + index, "/b")){
+        index += 3;
+        font -= 1;
+    }else if(compareTag(text + index, "h1")){
+        index += 3;
+        font = 3;
+    }else if(compareTag(text + index, "/h1")){
+        index += 4;
+        font = 0;
+    }else if(compareTag(text + index, "h2")){
+        index += 3;
+        font = 2;
+    }else if(compareTag(text + index, "/h2")){
+        index += 4;
+        font = 0;
+    }else if(compareTag(text + index, "h3")){
+        index += 3;
+        font = 1;
+    }else if(compareTag(text + index, "/h3")){
+        index += 4;
+        font = 0;
+    }else{
+        while(text[index+i] != '>') i++;
+        index += i + 1;
+    }
+    
+    return true;
+}
+
+/* checks string against given tag */
+bool BasicWeb::compareTag(char* s, char* tag){
+    int i = 0;
+    while(s[i] != '>' && s[i] != '\0'){
+        if(s[i] != tag[i]) return false;
+        i++;
+    }
+    if(tag[i] != '\0'){
+        return false;
+    }else{
+        return true;
+    }
+}
+
+/* stores string up to the start of the next tag into str variable */
+bool BasicWeb::extractStr(){
+    int i = 0;
+    while(text[index+i] != '<' && text[index+i] != '\0'){
+        i++;
+    }
+    delete[] str;
+    str = new char[i + 1];
+    copyStr(text + index, str, i);
+    index += i;
+    strSize = i;
+    return false;
+}
+
+/* copies s1 into s2 upto given size */
+void BasicWeb::copyStr(char* s1, char* s2, int size){
+    int i;
+    for(i = 0; i < size; i++){
+        s2[i] = s1[i];
+        if(s1[i] == '\0') return;
+    }
+    s2[i] = '\0';
+}
+
+/* removes CR and LR because they causes problems for vga print function */
+void BasicWeb::removeRL(char* s, int size){
+    for(int i = 0; i < size; i++){
+        if(s[i] == '\r' || s[i] == '\n') s[i] = ' ';
+    }
+}
+
+/* prints text one line at a time, returning false if at end of screen */
+bool BasicWeb::printText(char* s){
+
+    if(s == NULL){
+        index = 0;
+        return false;
+    }
+
+    int maxChar;
+    font = 3;
+    switch(font){
+        case 0:
+            maxChar = 105;
+            break;
+        case 1:
+            maxChar = 70;
+            break;
+        case 2:
+            maxChar = 65;
+            break;
+        case 3:
+            maxChar = 50;
+            break;
+        default:
+            maxChar = 100;
+    }
+    
+    char* temp;
+    int i = strSize;
+    int lineNum = 0;
+    
+    if(i < maxChar){
+        vga.graphic_string(s, 0, lineIndex, font, color, 1, 1);
+        if(font == 3){
+            lineIndex += 20;
+        }else{
+            lineIndex += 10;
+        }
+        if(lineIndex < 480){
+            return true;
+        }else{
+            return false;
+        }
+    }else{
+        temp = new char[maxChar + 1];
+        while(i > 0){
+            if(i > maxChar){
+                copyStr(s + lineNum * maxChar, temp, maxChar);
+                i -= maxChar;
+            }else{
+                copyStr(s + lineNum * maxChar, temp, i);
+                i = 0;
+            }
+            vga.graphic_string(temp, 0, lineIndex, font, color, 1, 1);
+            lineNum++;
+            if(font == 3){
+                lineIndex += 20;
+            }else{
+                lineIndex += 10;
+            }
+            if(lineIndex >= 480){
+                delete[] temp;
+                return false;
+            }
+        }
+        delete[] temp;
+    }
+    return true;
+}