home *** CD-ROM | disk | FTP | other *** search
/ linuxmafia.com 2016 / linuxmafia.com.tar / linuxmafia.com / pub / palmos / wapuniverse-src-0.3.5.build9.tar.gz / wapuniverse-src-0.3.5.build9.tar / wapuniverse-0.3.5.build9 / wml.c < prev    next >
C/C++ Source or Header  |  2000-11-12  |  25KB  |  925 lines

  1. //---------------------------------------------------------------------------
  2. // wml.c
  3. // Contains all platform independant WAP/WML code 
  4. //
  5. // Project: WAPUniverse for PalmOS
  6. // Copyright ⌐ 1999-2000 Filip Onkelinx
  7. //
  8. // http://www.wapuniverse.com/
  9. // filip@onkelinx.com
  10. //
  11. // This program is free software; you can redistribute it and/or
  12. // modify it under the terms of the GNU General Public License
  13. // as published by the Free Software Foundation; either version 2
  14. // of the License, or (at your option) any later version.
  15. //
  16. // This program is distributed in the hope that it will be useful,
  17. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. // GNU General Public License for more details.
  20. //
  21. // You should have received a copy of the GNU General Public License
  22. // along with this program; if not, write to the Free Software 
  23. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
  24. //
  25. //
  26. // $Workfile: wml.c $  
  27. // $Author: wapuniverse $  
  28. // $Date: 2000/11/11 20:51:09 $     
  29. // $Revision: 1.19 $
  30. //
  31. // $Header: /cvsroot/wapuniverse/wapuniverse/src/wml.c,v 1.19 2000/11/11 20:51:09 wapuniverse Exp $
  32. //
  33. //---------------------------------------------------------------------------
  34.  
  35. #include "wml.h"
  36. #include "WAP.h"
  37. #include "formBrowser.h"
  38. #include "WAPUniverse.h"
  39. #include "wsp.h"
  40.  
  41. #ifndef __palmos__
  42.     #include <stdio.h>
  43. #endif __palmos__
  44.  
  45. static char *wmltag[] = { 
  46.     "-", // 05
  47.     "-", // 06
  48.     "-", // 07
  49.     "-", // 08
  50.     "-", // 09
  51.     "-", // 0A
  52.     "-", // 0B
  53.     "-", // 0C
  54.     "-", // 0D
  55.     "-", // 0E
  56.     "-", // 0F
  57.     "-", // 10
  58.     "-", // 11
  59.     "-", // 12
  60.     "-", // 13
  61.     "-", // 14
  62.     "-", // 15
  63.     "-", // 16
  64.     "-", // 17
  65.     "-", // 18
  66.     "-", // 19
  67.     "-", // 1A
  68.     "-", // 1B
  69.     "a",  // 1C
  70.     "td", // 1D
  71.     "tr", // 1E
  72.     "table", // 1F
  73.     "p", // 20
  74.     "postfield", // 21
  75.     "anchor", // 22
  76.     "access", // 23
  77.     "b",  // 24
  78.     "big", // 25
  79.     "br", // 26
  80.     "card", // 27
  81.     "do", // 28
  82.     "em", // 29
  83.     "fieldset", // 2A
  84.     "go", // 2B
  85.     "head", // 2C
  86.     "i", // 2D
  87.     "img", // 2E
  88.     "input", // 2F
  89.     "meta", // 30
  90.     "noop", // 31
  91.     "prev", // 32
  92.     "onevent", // 33
  93.     "optgroup", // 34
  94.     "option", // 35
  95.     "refresh", // 36
  96.     "select", // 37
  97.     "small", // 38
  98.     "strong", // 39
  99.     "-", // 3A
  100.     "template", // 3B
  101.     "timer", // 3C
  102.     "u", // 3D
  103.     "setvar", // 3E
  104.     "wml" // 3F
  105. };
  106.  
  107. static char *attrStart[] = { 
  108.     "accept-charset", // 05
  109.     "align=\"bottom\"", // 06
  110.     "align=\"center\"", // 07
  111.     "align=\"left\"", // 08
  112.     "align=\"middle\"", // 09
  113.     "align=\"right\"", // 0A
  114.     "align=\"top\"", // 0B
  115.     "alt=\"", // 0C
  116.     "content", // 0D
  117.     "-", // 0E
  118.     "domain", // 0F
  119.  
  120.     "emptyok=\"false\"", // 10
  121.     "emptyok=\"true\"", // 11
  122.     "=\"", // 12
  123.     "height=\"", // 13
  124.     "hspace=\"", // 14
  125.     "ivalue", // 15
  126.     "iname", // 16
  127.     "-", // 17
  128.     "label=\"", // 18
  129.     "localsrc", // 19
  130.     "maxlength", // 1A
  131.     "method=\"get\"", // 1B
  132.     "method=\"post\"", // 1C
  133.     "mode=\"nowrap\"", // 1D
  134.     "mode=\"wrap\"", // 1E
  135.     "multiple=\"false\"", // 1F
  136.  
  137.     "multiple=\"true\"", // 20
  138.     "name=\"", // 21
  139.     "newcontext=\"false\"", // 22
  140.     "newcontext=\"true\"", // 23
  141.     "onpick", // 24
  142.     "onenterbackward", // 25
  143.     "onenterforward", // 26
  144.     "ontimer", // 27
  145.     "optimal=\"false\"", // 28
  146.     "optimal=\"true\"", // 29
  147.     "path", // 2A
  148.     "-", // 2B
  149.     "-", // 2C
  150.     "-", // 2D
  151.     "scheme", // 2E
  152.     "sendreferer=false", // 2F
  153.  
  154.     "sendreferer=true", // 30
  155.     "size", // 31
  156.     "src=\"", // 32
  157.     "ordered=\"true\"", // 33
  158.     "ordered=\"false\"", // 34
  159.     "tabindex", // 35
  160.     "title=\"", // 36
  161.     "type", // 37
  162.     "type=\"accept\"", // 38
  163.     "type=\"delete\"", // 39
  164.     "type=\"help\"", // 3A
  165.     "type=\"password\"", // 3B
  166.     "type=\"onpick\"", // 3C
  167.     "type=\"onenterbackward\"", // 3D
  168.     "type=\"onenterforward\"", // 3E
  169.     "type=\"ontimer\"", // 3F
  170.  
  171.     "-", // 40
  172.     "-", // 41
  173.     "-", // 42
  174.     "-", // 43
  175.     "-", // 44
  176.     "type=\"options\"", // 45
  177.     "type=\"prev\"", // 46
  178.     "type=\"reset\"", // 47
  179.     "type=\"text\"", // 48
  180.     "type=\"vnd.", // 49
  181.     "href=\"", // 4A
  182.     "href=\"http://", // 4B
  183.     "href=\"https://", // 4C
  184.     "value=\"", // 4D
  185.     "vspace=\"", // 4E
  186.     "width=\"", // 4F
  187.  
  188.     "xml:lang", // 50
  189.     "-", // 51
  190.     "align", // 52
  191.     "columns", // 53
  192.     "class", // 54
  193.     "id=\"", // 55
  194.     "forua=\"false\"", // 56
  195.     "forua=\"true\"", // 57
  196.     "src=\"http://", // 58
  197.     "src=\"https://", // 59
  198.     "http-equiv", // 5A
  199.     "http-equiv=\"Content-Type\"", // 5B
  200.     "content=\"application/vnd.wap.wmlc;charset=", // 5C
  201.     "http-equiv=\"Expires\"", // 5D
  202.     "-", // 5E
  203.     "-", // 5F
  204. };
  205.  
  206.  
  207. static char *attrVal[] = { 
  208.     ".com/", // 85
  209.     ".edu/", // 86
  210.     ".net/", // 87
  211.     ".org/", // 88
  212.     "accept", // 89
  213.     "bottom", // 8A
  214.     "clear", // 8B
  215.     "delete", // 8C
  216.     "help", // 8D
  217.     "http://", // 8E
  218.     "http://www.", // 8F
  219.  
  220.     "https://", // 90
  221.     "https://www.", // 91
  222.     "?", // 92
  223.     "middle", // 93
  224.     "nowrap", // 94
  225.     "onpick", // 95
  226.     "onenterbackward", // 96
  227.     "onenterforward", // 97
  228.     "ontimer", // 98
  229.     "options", // 99
  230.     "password", // 9A
  231.     "reset", // 9B
  232.     "?", // 9C
  233.     "text", // 9D
  234.     "top", // 9E
  235.     "unknown", // 9F
  236.     "wrap", // A0
  237.     "www.", // A1
  238. };
  239.  
  240. char *getAttributes(WMLDeckPtr wmldck, unsigned char attr, GlobalsType *g);
  241.  
  242. #ifdef __palmos__
  243. #define underline palmUnderline
  244. #define bold palmBold
  245. #define hyperLink palmHyperLink
  246. #define wmlInput palmWmlInput
  247. #define wmlInputValue palmWmlInputValue
  248. #define getPos palmGetPos
  249. #define wmlSelectOptionTxt palmWmlSelectOptionTxt
  250. #define wmlSelect palmWmlSelect 
  251. #define wmlSelectValue palmWmlSelectValue
  252. #define wmlSelectOption palmWmlSelectOption
  253. #define wmlSelectEnd palmWmlSelectEnd
  254. #endif __palmos__
  255.  
  256. int pushwmlstack( WMLDeckPtr wmldck)
  257. {
  258.     unsigned char *ptr;
  259.     int i;
  260.  
  261.     if (wmldck->stack == NULL) {
  262.         wmldck->maxstack = 10;
  263.         wmldck->stack=Malloc(wmldck->maxstack);
  264.         ErrFatalDisplayIf (!wmldck->stack, "Malloc(stack)");
  265.     }
  266.     if (wmldck->stackDepth >= wmldck->maxstack) {       
  267.         i = wmldck->maxstack;
  268.         wmldck->maxstack+=10;
  269.         ptr = wmldck->stack;
  270.         wmldck->stack=Malloc(wmldck->maxstack);
  271.         ErrFatalDisplayIf (!wmldck->stack, "Malloc(stack-resize)");
  272.         while (i>0)
  273.            wmldck->stack[--i]=ptr[i];
  274.         Free(ptr);
  275.     }
  276.     wmldck->stack[wmldck->stackDepth++] = wmldck->tag;
  277.  
  278.     return(0);    
  279. }
  280.  
  281. void  freewmlstack(WMLDeckPtr wmldck)
  282. {
  283.     wmldck->stackDepth=0;
  284.     if (wmldck->stack != NULL){
  285.         Free(wmldck->stack);
  286.         wmldck->stack = NULL;
  287.     }
  288.      
  289. }
  290.  
  291. unsigned char popwmlstack(WMLDeckPtr wmldck)
  292. {
  293.     unsigned char c;
  294.  
  295.     if (wmldck->stack == NULL)
  296.         return(-1);
  297.     wmldck->stackDepth--; 
  298.     c = wmldck->stack[wmldck->stackDepth];        
  299.     if (wmldck->stackDepth == 0) {
  300.         Free(wmldck->stack);
  301.         wmldck->stack = NULL;
  302.     }
  303.     return(c);    
  304. }
  305.  
  306. void renderLn(GlobalsType *g)
  307. {
  308. #ifndef __palmos__    
  309.     fprintf(stdout,"\n");
  310. #else
  311.     palmprintln(g);
  312. #endif __palmos__
  313.  
  314. }
  315.  
  316.  
  317. void renderString(WMLDeckPtr wmldck, char *string, GlobalsType *g)
  318. {
  319.     if (wmldck->action == ACTION_RENDER)
  320. #ifndef __palmos__    
  321.         fprintf(stdout,string);
  322. #else
  323.         palmprintf(string,g);
  324. #endif __palmos__
  325.  
  326. }
  327.  
  328. void renderImage(WMLDeckPtr wmldck, GlobalsType *g)
  329. {
  330.  char                       url[MAX_URL_LEN+1];
  331.  Int16                      len;
  332.  Int16                      sock;
  333.  unsigned char                *imgBuf= NULL;
  334.  UInt32                     maxTimer;
  335.  WSPPDU                       wsppdu;
  336.  char                       *wmlSrc;
  337.  
  338. //    FrmSetTitle(FrmGetActiveForm(),"Loading Image");
  339.     wmlSrc= getAttributes(wmldck,WML_src,g);
  340.     if(StrNCaselessCompare(wmlSrc,"MTCH:",5)==0)
  341.         return;
  342.     wapCreateUrlStr(wmlSrc,url,g);
  343.     imgBuf=Malloc(DEF_RECEIVE_BUF+1);       
  344.     ErrFatalDisplayIf (!imgBuf, "Malloc Failed");
  345.     sock = wapGetUrl(&(g->conn), url,false,g);
  346.     maxTimer = TimGetTicks() + (REPLY_TIMEOUT * SysTicksPerSecond());
  347.     do { //TODO: this is no good, just a quick hack to get it working: an active loop
  348.         len = WspGetReply(sock,imgBuf,DEF_RECEIVE_BUF,maxTimer,g);
  349.     }
  350.     while(len==0);
  351.     if (sock >= 0)
  352.         close (sock);
  353.     if (len > 0){ // looks like we've got at least a header
  354.         if (WspDecode(imgBuf,len, &wsppdu ) == 0) {
  355. #ifdef __palmos__    
  356.             palmDrawImage(&wsppdu,g);
  357. #endif __palmos__
  358.             WspFreePdu(&wsppdu);
  359.         }
  360.     }
  361.     if (imgBuf) {
  362.         Free(imgBuf);
  363.     }        
  364.        
  365. }
  366.  
  367. void srcString(WMLDeckPtr wmldck, char *string, GlobalsType *g)
  368. {
  369.     if (wmldck->action == ACTION_SRC)
  370. #ifndef __palmos__    
  371.         fprintf(stdout,string);
  372. #else
  373.         palmsrcprintf(string,g);
  374. #endif __palmos__
  375.  
  376. }
  377.  
  378. void srcIndent(WMLDeckPtr wmldck, GlobalsType *g)
  379. {
  380.     int i;
  381.  
  382.     if (wmldck->action == ACTION_SRC)
  383.         for (i=0;i<wmldck->stackDepth;i++)
  384.             srcString(wmldck," ",g);
  385.  
  386. }
  387.  
  388. void srcTag(WMLDeckPtr wmldck, GlobalsType *g)
  389. {
  390.     if ((wmldck->tag >=5) && (wmldck->tag <= 0x3F )) {
  391.         srcString(wmldck,"<",g);  
  392.         srcString(wmldck,wmltag[wmldck->tag-5],g);    
  393.     }
  394. }
  395.  
  396.  
  397. void srcAttr(WMLDeckPtr wmldck, unsigned char attr_id, char *val,GlobalsType *g)
  398. {
  399.     if ((attr_id >=5) && (attr_id <= 0x5F )) {
  400.         srcString(wmldck," ",g);  
  401.         srcString(wmldck,attrStart[attr_id-05],g);    
  402.         if (val[0]!=0) {
  403.             srcString(wmldck,val,g);
  404.             srcString(wmldck,"\"",g);
  405.         }
  406.  
  407.     }
  408. }
  409.  
  410.  
  411.  
  412. int checkCards(int startoffset, WMLDeckPtr wmldck, GlobalsType *g)
  413. {
  414. int off;
  415. CardPtr tmp,idx;
  416. Char *cptr;
  417.  
  418.     switch (wmldck->tag) {
  419.     case WML_card :
  420.         off = wmldck->offset;
  421.         tmp = Malloc(sizeof(CardType));
  422.         ErrFatalDisplayIf (!tmp, "Malloc Failed");
  423.         tmp->offset = wmldck->offset;
  424.         tmp->next = NULL;
  425.         cptr = getAttributes(wmldck,WML_id,g);
  426.         if (cptr){
  427.             tmp->card_id = Malloc(StrLen(cptr)+1);
  428.             ErrFatalDisplayIf (!tmp->card_id, "Malloc2 Failed");
  429.             StrCopy(tmp->card_id,cptr);
  430.         }else
  431.         {
  432.             tmp->card_id = NULL;
  433.         }
  434.         if ( wmldck->card == NULL)
  435.         {
  436.             wmldck->card = tmp;
  437.         }else
  438.         {
  439.            idx = wmldck->card;
  440.            while(idx->next != NULL){
  441.                    idx = idx->next;
  442.            }
  443.            idx->next = tmp;
  444.         }                        
  445.         wmldck->offset = off;
  446.         getAttributes(wmldck,END,g);
  447.         break;  
  448. /*
  449.     case WML_template : 
  450.         wmldck->template = startoffset; 
  451.         palmprintf("GOT Template:'");
  452.         palmprintf(getAttributes(wmldck,WML_id));
  453.         palmprintf("' ");
  454.         break;
  455. */
  456.     default:
  457.         getAttributes(wmldck,END,g);
  458.     }
  459.     return(0);      
  460. }
  461.  
  462.  
  463. int getAttributeValue(WMLDeckPtr wmldck,char attrstr[])
  464. {
  465.     unsigned char c;
  466.     int l,j;
  467.  
  468.             attrstr[0] = 0;
  469.             j=0;
  470.             c = wmldck->data[wmldck->offset++];
  471.             while ((c > 128) || (c==ENTITY) || (c == STR_I) || (c == STR_T)   
  472.                    || (c==SWITCH_PAGE) || (c==PI) 
  473.                    || ((c >= EXT_I_0) && (c <= EXT_I_2))
  474.                    || ((c >= EXT_T_0) && (c <= EXT_T_2))) {
  475.  
  476.                 switch (c) {
  477.                 case ENTITY:
  478.                     WspReadInt(wmldck->data,&(wmldck->offset)); 
  479.                     DisplayError("Unhandled WML ENTITY");
  480.                     attrstr[j++]='<';
  481.                     attrstr[j++]='!';
  482.                     attrstr[j++]='>';
  483.                     attrstr[j] = 0;
  484.                     break;
  485.  
  486.                 case STR_I:
  487.                 case EXT_I_0:
  488.                 case EXT_I_1:
  489.                 case EXT_I_2:     
  490.                     while (wmldck->data[wmldck->offset] != 0) {
  491.                         attrstr[j++]=wmldck->data[wmldck->offset++];
  492.                     }
  493.                     attrstr[j] = 0;
  494.                     wmldck->offset++;   
  495.                     break;
  496.  
  497.                 case PI: // processing instruction
  498.                     DisplayError("Unhandled WML PI");                
  499.                     break; 
  500.  
  501.                 case EXT_T_0:
  502.                 case EXT_T_1:
  503.                 case EXT_T_2: // 
  504.                     l = WspReadInt(wmldck->data,&(wmldck->offset));
  505.                     attrstr[j++]=c;
  506.                     while (wmldck->strTable[l] !=0)
  507.                         attrstr[j++] = wmldck->strTable[l++];                   
  508.                     attrstr[j++]=END;
  509.                     attrstr[j] = 0;
  510.                     // !! TODO : handle escape/noescape
  511.                     if (c==EXT_T_0)
  512.                         ;//escaped
  513.                     if (c==EXT_T_0)
  514.                         ;//unescaped
  515.                     break;
  516.                 case STR_T: 
  517.                     l = WspReadInt(wmldck->data,&(wmldck->offset));
  518.                     while (wmldck->strTable[l] !=0)
  519.                         attrstr[j++] = wmldck->strTable[l++];                   
  520.                     attrstr[j] = 0;
  521.                     break;  
  522.                 case EXT_0:
  523.                 case EXT_1:
  524.                 case EXT_2:
  525.                     //Single byte extension tokens        
  526.                     l = wmldck->data[wmldck->offset++];
  527.                     break;
  528.                 case OPAQUE: 
  529.                     DisplayError("UNHANDELD OPAQUE");
  530.                     break;
  531.  
  532.                 default:
  533.                     if ((c >=0x85) && (c <= 0xA1 )) {
  534.                         l=0;
  535.                         while (attrVal[c-0x85][l]!=0)
  536.                             attrstr[j++] = attrVal[c-0x85][l++];                    
  537.                         attrstr[j] = 0;
  538.                     } else
  539.                         DisplayError("UNKNOWN ATTRIBUTE"); 
  540.                 } //switch    
  541.                 c = wmldck->data[wmldck->offset++];
  542.             } //while
  543.         wmldck->offset--;
  544.         return(0);
  545. }
  546.  
  547. char *getAttributes(WMLDeckPtr wmldck, unsigned char attr, GlobalsType *g)
  548. {
  549. //    static Char attrstr[128];
  550. //    char tmpstr[128];
  551.     unsigned char c,attr_id;
  552.  
  553.     wmldck->attrstr[0]=0;
  554.     if (wmldck->data[wmldck->offset] & WBXML_has_attributes) {
  555.         wmldck->offset++;
  556.         c= wmldck->data[wmldck->offset++];
  557.         while (c != END) {
  558.             attr_id = c;
  559.             if (attr_id == attr){
  560.                   getAttributeValue(wmldck,wmldck->attrstr);
  561.                return(wmldck->attrstr);
  562.             }else{
  563.                   getAttributeValue(wmldck,wmldck->tmpstr);
  564.             }
  565.             if (wmldck->action == ACTION_SRC)
  566.                 srcAttr(wmldck, attr_id,wmldck->tmpstr,g);
  567.             c = wmldck->data[wmldck->offset++];
  568.         }//while
  569.         wmldck->offset--;
  570.     }
  571.     return(NULL);
  572. }
  573.  
  574. int readElement(WMLDeckPtr wmldck, GlobalsType *g)
  575. {
  576.     int startoffset;
  577.     unsigned char c;
  578.     Char *attr;
  579.  
  580.     startoffset = wmldck->offset;
  581.     wmldck->tag = wmldck->data[wmldck->offset] & WBXML_tag_id;
  582.     c = wmldck->data[wmldck->offset];
  583.  
  584.     if ((wmldck->tag >=5) && (wmldck->tag <= 0x3F )) {
  585.         switch (wmldck->action) {
  586.         case ACTION_RENDER :
  587.             switch(wmldck->tag) {
  588.             case WML_card :
  589.                 attr = getAttributes(wmldck,WML_title,g);
  590.                 if (attr)
  591.                     FrmSetTitle(FrmGetActiveForm(),attr);
  592.                 else
  593.                     FrmSetTitle(FrmGetActiveForm(),"Wapuniverse");                
  594.                 wmldck->offset=startoffset;
  595.                 attr = getAttributes(wmldck,WML_ontimer,g);
  596.                 if (attr){
  597.                     if (wmldck->ontimerUrl)
  598.                         free(wmldck->ontimerUrl);
  599.                     wmldck->ontimerUrl = Malloc(StrLen(attr)+1);
  600.                     ErrFatalDisplayIf (!wmldck->ontimerUrl, "Malloc Failed");
  601.                     StrCopy(wmldck->ontimerUrl,attr);                        
  602.                 }
  603.                 wmldck->offset=startoffset;
  604.                 attr = getAttributes(wmldck,END,g);
  605.                 break;
  606.             case WML_timer:
  607.                 attr = getAttributes(wmldck,WML_value,g);
  608.                 if (attr){
  609.                         wmldck->timerVal=StrAToI(attr);
  610.                 }else{
  611.                         DisplayError("Timer but no Value!");                 
  612.                 }
  613.                 wmldck->offset=startoffset;
  614.                 attr = getAttributes(wmldck,END,g);            
  615.             case WML_br:
  616.             case WML_p:
  617.                 renderLn(g);
  618.                 attr = getAttributes(wmldck,END,g);
  619.                 break;
  620.             case WML_img:
  621.                 renderImage(wmldck,g);
  622.                 wmldck->offset=startoffset;
  623.                 attr = getAttributes(wmldck,END,g);
  624.                 break;
  625.             case WML_u:
  626.                 underline(true);
  627.                 attr = getAttributes(wmldck,END,g);
  628.                 break;
  629.             case WML_b:
  630.             case WML_strong:
  631.                 bold(true);
  632.                 attr = getAttributes(wmldck,END,g);
  633.                 break;
  634.             case WML_prev:
  635. //                hyperLink(false,"","<PREV/>");
  636.                 break;
  637.             case WML_do:
  638.                 attr = getAttributes(wmldck,WML_type_accept,g);
  639.                 if (attr){
  640.                     hyperLink(true,NULL,NULL,g);
  641.                 }
  642.                 wmldck->offset=startoffset;
  643.                 attr = getAttributes(wmldck,END,g);                
  644.                 break;                
  645.             case WML_anchor:
  646.                 hyperLink(true,NULL,NULL,g);
  647.                 break;
  648.             case WML_go:
  649.                 if ( (attr = getAttributes(wmldck,WML_href_http,g))){
  650.                     hyperLink(false,"http://",attr,g);
  651.                 }else {
  652.                     wmldck->offset=startoffset;
  653.                      if ( (attr = getAttributes(wmldck,WML_href,g))){
  654.                         hyperLink(false,"",attr,g);                
  655.                     }else{
  656.                         wmldck->offset=startoffset;
  657.                          if ( (attr = getAttributes(wmldck,WML_href_https,g))){
  658.                             hyperLink(false,"https://",attr,g);                
  659.                         }
  660.                     }
  661.                 }
  662.                 attr = getAttributes(wmldck,END,g);
  663.                 break;
  664.             case WML_a:    
  665.                 if ( (attr = getAttributes(wmldck,WML_href_http,g))){
  666.                     hyperLink(true,"http://",attr,g);
  667.                 }else {
  668.                     wmldck->offset=startoffset;
  669.                      if ( (attr = getAttributes(wmldck,WML_href,g))){
  670.                         hyperLink(true,"",attr,g);                
  671.                     }else{
  672.                         wmldck->offset=startoffset;
  673.                          if ( (attr = getAttributes(wmldck,WML_href_https,g))){
  674.                             hyperLink(true,"https://",attr,g);                
  675.                         }
  676.                     }
  677.                 }
  678.                 attr = getAttributes(wmldck,END,g);
  679.                 break;
  680.             case WML_input:
  681.                 if ( (attr = getAttributes(wmldck,WML_name,g))){
  682.                     wmlInput(attr,g);
  683.                 }                             
  684.                 wmldck->offset=startoffset;
  685.                 if ( (attr = getAttributes(wmldck,WML_value,g))){
  686.                     wmlInputValue(attr,g);
  687.                 }                             
  688.                 wmldck->offset=startoffset;
  689.                 attr = getAttributes(wmldck,END,g);
  690.                 break;
  691.             case WML_select:
  692.                 if ( (attr = getAttributes(wmldck,WML_name,g))){
  693.                     wmlSelect(attr,g);
  694.                 }                             
  695.                 wmldck->offset=startoffset;
  696.                 if ( (attr = getAttributes(wmldck,WML_ivalue,g))){
  697.                     wmlSelectValue(attr,g);
  698.                 }                             
  699.                 wmldck->offset=startoffset;
  700.                 if ( (attr = getAttributes(wmldck,WML_value,g))){
  701.                     wmlSelectValue(attr,g);
  702.                 }                             
  703.                 wmldck->offset=startoffset;
  704.                 attr = getAttributes(wmldck,END,g);            
  705.                 break;
  706.             case WML_option:
  707.                 g->Render=false;
  708.                 if ( (attr = getAttributes(wmldck,WML_value,g))){
  709.                     wmlSelectOption(attr,g);
  710.                 }                             
  711.                 wmldck->offset=startoffset;
  712.                 attr = getAttributes(wmldck,END,g);                            
  713.                 break;
  714.             default:
  715.                 attr = getAttributes(wmldck,END,g);
  716.             }
  717.             break;
  718.  
  719.         case ACTION_SRC :
  720.             srcTag(wmldck,g);                   
  721.             getAttributes(wmldck,END,g);
  722.             break;
  723.         case ACTION_PARSE :
  724.             checkCards(startoffset,wmldck,g);
  725.             break;
  726.         default :
  727.             getAttributes(wmldck,END,g);
  728.  
  729.         }       
  730.     }
  731.     // check for content
  732.     if (c & WBXML_has_content) {
  733.         pushwmlstack(wmldck);
  734.         srcString(wmldck,">\n",g);
  735.         srcIndent(wmldck,g);
  736.     } else {
  737.         srcString(wmldck,"/>\n",g);
  738.         srcIndent(wmldck,g);
  739.     }
  740.     return(0);
  741. }
  742.  
  743.  
  744. int wbxml_parse_header(WSPPDUPtr wsppdu, WMLDeckPtr wmldck)
  745. {
  746.     int j;
  747.     int strTableSz;
  748.  
  749.     wmldck->stackDepth = 0;
  750.     wmldck->stack = NULL;
  751.     wmldck->offset = 0;
  752.     wmldck->data = wsppdu->data;
  753.     wmldck->version = wmldck->data[wmldck->offset++];
  754.     wmldck->publicID = wmldck->data[wmldck->offset++];
  755.     if (wmldck->publicID==0)
  756.         wmldck->offset++;
  757.     // get the CharSet
  758.     wmldck->charSet = wmldck->data[wmldck->offset++]; // not implemented yet ...
  759.     // get the StringTable size, allocate memory and load it.
  760.     strTableSz = WspReadInt(wmldck->data,&(wmldck->offset));
  761.     wmldck->strTable=Malloc(strTableSz+1);
  762.     wmldck->attrstr=Malloc(256);
  763.     wmldck->tmpstr=Malloc(256);
  764.     if ((!wmldck->strTable)||(!wmldck->attrstr) || (!wmldck->tmpstr) ) {
  765.         ErrDisplay("Malloc");
  766.         return(WML_ERR_MEM);
  767.     }
  768.     for (j=0;j<strTableSz;j++)
  769.         wmldck->strTable[j] = wmldck->data[wmldck->offset++];
  770.     wmldck->strTable[j]= 0;
  771.     wmldck->decksize = wsppdu->length - wmldck->offset;
  772.     wmldck->data = (wsppdu->data)+wmldck->offset;
  773.     wmldck->offset = 0;
  774.     return(0);
  775. }
  776.  
  777.  
  778. int wbxml_parse(WSPPDUPtr wsppdu, int action, WMLDeckPtr wmldck, int offset, GlobalsType *g)
  779. {
  780.     unsigned char *temp,c;
  781.     int j;
  782.  
  783.     if (wsppdu->data==NULL) {
  784.         return -1;
  785.     }
  786.     temp = Malloc (1024);
  787.     ErrFatalDisplayIf (!temp, "Malloc Failed");
  788.     wbxml_parse_header(wsppdu, wmldck);  
  789.     wmldck->action = action;
  790.     wmldck->offset = offset;
  791.     // Parse the WBXML bytecode
  792.     while (wmldck->offset < wmldck->decksize) {
  793.         switch (wmldck->data[wmldck->offset]) {
  794.         case SWITCH_PAGE :
  795.             DisplayError("SWITCH_PAGE WMLC");
  796.             break;
  797.         case END:
  798.             c= popwmlstack(wmldck);
  799.             if (wmldck->action== ACTION_SRC) {
  800.                 srcString(wmldck,"\n",g);
  801.                 srcIndent(wmldck,g);
  802.                 srcString(wmldck,"</",g);
  803.                 srcString(wmldck,wmltag[c-5],g);
  804.                 srcString(wmldck,">",g);
  805.             }
  806.             if (wmldck->action== ACTION_RENDER) {
  807.                 switch(c) {
  808.                 case WML_option:
  809.                     wmlSelectOptionTxt(temp,g);
  810.                     g->Render=true;
  811.                     break;
  812.                 case WML_select:
  813.                     wmlSelectEnd(g);
  814.                     break;
  815.                 case WML_u:
  816.                     underline(false);
  817.                     break;
  818.                 case WML_strong:
  819.                 case WML_b:
  820.                     bold(false);
  821.                     break;
  822.                 case WML_anchor:
  823.                 case WML_go:
  824.                 case WML_a:    
  825.                     hyperLink(false,NULL,NULL,g);
  826.                     break;
  827.                 }
  828.             }
  829.             if (wmldck->stackDepth == 0){  // end of <WML>, needed because angelOne seems to sent some trailing garbage.
  830.                 freewmlstack(wmldck);
  831.                 Free(temp);
  832.                 return(0);
  833.             }
  834.             break;
  835.         case ENTITY:  // 0x02
  836. //            DisplayError("ENTITY WMLC");
  837.             wmldck->offset++;
  838.             j = WspReadInt(wmldck->data,&(wmldck->offset)); // UCS-4 character code
  839.             temp[0]=j; temp[1]=0;
  840.             // TODO : should map UCS-4 to something printable ??                        
  841.             if (wmldck->action== ACTION_SRC)
  842.                 srcString(wmldck,temp,g);
  843.             if ((wmldck->action== ACTION_RENDER)&& (g->Render==true))
  844.                 renderString(wmldck,temp,g);
  845.             wmldck->offset--;
  846.             break;
  847.         case STR_I: //Inline String follows
  848.             wmldck->offset++;
  849.             j=0;
  850.             while (wmldck->data[wmldck->offset] != 0) {
  851.                 temp[j++]=wmldck->data[wmldck->offset++];   
  852.             }
  853.             temp[j] = 0;
  854.             if (wmldck->action== ACTION_SRC)
  855.                 srcString(wmldck,temp,g);
  856.             if ((wmldck->action== ACTION_RENDER)&& (g->Render==true))
  857.                 renderString(wmldck,temp,g);
  858.             break;
  859.         case EXT_I_0:
  860.         case EXT_I_1:
  861.         case EXT_I_2:
  862.         case EXT_T_0:
  863.         case EXT_T_1:
  864.         case EXT_T_2:
  865.         case EXT_0:
  866.         case EXT_1:
  867.         case EXT_2:
  868.         case OPAQUE:
  869.             DisplayError("WML OPAQUE Extension in WMLC");
  870.             break;
  871.         case PI:
  872.             DisplayError("PI not supported in WMLC");
  873.             break;
  874.         case STR_T: 
  875.             wmldck->offset++;
  876.             j = WspReadInt(wmldck->data,&(wmldck->offset));
  877.             StrCopy(temp,wmldck->strTable+j);
  878.             if (wmldck->action== ACTION_SRC)
  879.                 srcString(wmldck,temp,g);
  880.             if ((wmldck->action== ACTION_RENDER) && (g->Render==true))
  881.                 renderString(wmldck,temp,g);
  882.             wmldck->offset--;
  883.             break;
  884.         default:
  885.             readElement(wmldck,g);
  886.         }
  887.         wmldck->offset++;
  888.     }
  889.  
  890.     freewmlstack(wmldck);
  891.     Free(temp);
  892.     return(0);
  893. }
  894.  
  895. int wbxml_free_wmldck(WMLDeckPtr wmldck)
  896. {
  897. CardPtr tmp;
  898.  
  899.     if (wmldck->attrstr != NULL)
  900.         Free(wmldck->attrstr);
  901.     wmldck->attrstr = NULL;
  902.     if (wmldck->tmpstr != NULL)
  903.         Free(wmldck->tmpstr);
  904.     wmldck->tmpstr = NULL;
  905.     if (wmldck->strTable != NULL)
  906.         Free(wmldck->strTable);
  907.     wmldck->strTable = NULL;
  908.     if (wmldck->stack != NULL)
  909.         Free(wmldck->stack);
  910.     wmldck->stack = NULL;
  911.     while (wmldck->card != NULL){
  912.         tmp = wmldck->card;
  913.         wmldck->card = tmp->next;
  914.         if(tmp->card_id){
  915.             Free(tmp->card_id);
  916.         }
  917.         Free(tmp);
  918.     }
  919.     
  920.  
  921.     return(0);
  922. }
  923.  
  924.  
  925.