1
0
minibtx-acn/pc-software/btxasm/cept.c
2018-06-01 10:49:06 +02:00

636 lines
19 KiB
C

/*
####################################################################################
# #
# Bildschirmtricks MikroPAD V2.0.0 #
# http client layer #
# #
# Copyright (C) 2008 Philipp Fabian Benedikt Maier (aka. Dexter) #
# #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation; either version 2 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, write to the Free Software #
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #
# #
#################################################################################### */
/* ## HEADER ########################################################################## */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h" /* Include btx configuration */
#include "cept.h" /* include own header file */
#define HEAD_PARSER_MODE 1 /* Parser control constants */
#define HYPERTEXT_PARSER_MODE 2
/* #################################################################################### */
/* ## CEPT PARSER ##################################################################### */
/* Trigger on a specified tag (Note: tag should be null terminated e.g. "<body>\0" ) */
static int applicationBtxCeptTriggerTag(char *data, char *tag)
{
char *dataPointer = data;
char *tagPointer = tag;
while(*tagPointer != '\0')
{
if((*tagPointer != *dataPointer)||(*dataPointer == '\0'))
return -1; /* Not that tag what we are looking for */
dataPointer++;
tagPointer++;
}
return 0; /* All chars match, this is the tag what we ar looking for */
}
/* Translate a cept tag to its binary pendant */
static int applicationBtxCeptTranslateTag(char *data, char *code, int *size)
{
*size = 1;
int sizecount = 0;
char *dataPointer = data;
char *tagPointer = data;
char hexCode = 0;
if(*dataPointer == '<')
{
dataPointer++;
/* Calculate tag size */
while(*dataPointer != '>')
{
if((sizecount >= BTX_CEPT_TAG_MAXSIZE)||(*dataPointer == '\0'))
{
*code = *data;
*size = 1;
return -1; /* Invalid tag */
}
dataPointer++;
sizecount++;
}
*size = sizecount + 2; /* Tag + 2 chars for <> */
/* Examine tag */
if(applicationBtxCeptTriggerTag(tagPointer,"<0x\0") == 0)
{
tagPointer++;
tagPointer++;
tagPointer++;
/* Note: I know this is not very witty but i was tired to code a
more sophisticated piece of code... */
if(*tagPointer == '0')
hexCode = 0;
else if(*tagPointer == '1')
hexCode = 16;
else if(*tagPointer == '2')
hexCode = 32;
else if(*tagPointer == '3')
hexCode = 48;
else if(*tagPointer == '4')
hexCode = 64;
else if(*tagPointer == '5')
hexCode = 80;
else if(*tagPointer == '6')
hexCode = 96;
else if(*tagPointer == '7')
hexCode = 112;
else if(*tagPointer == '8')
hexCode = 128;
else if(*tagPointer == '9')
hexCode = 144;
else if(*tagPointer == 'a')
hexCode = 160;
else if(*tagPointer == 'b')
hexCode = 176;
else if(*tagPointer == 'c')
hexCode = 192;
else if(*tagPointer == 'd')
hexCode = 208;
else if(*tagPointer == 'e')
hexCode = 224;
else if(*tagPointer == 'f')
hexCode = 240;
tagPointer++;
if(*tagPointer == '1')
hexCode += 1;
else if(*tagPointer == '2')
hexCode += 2;
else if(*tagPointer == '3')
hexCode += 3;
else if(*tagPointer == '4')
hexCode += 4;
else if(*tagPointer == '5')
hexCode += 5;
else if(*tagPointer == '6')
hexCode += 6;
else if(*tagPointer == '7')
hexCode += 7;
else if(*tagPointer == '8')
hexCode += 8;
else if(*tagPointer == '9')
hexCode += 9;
else if(*tagPointer == 'a')
hexCode += 10;
else if(*tagPointer == 'b')
hexCode += 11;
else if(*tagPointer == 'c')
hexCode += 12;
else if(*tagPointer == 'd')
hexCode += 13;
else if(*tagPointer == 'e')
hexCode += 14;
else if(*tagPointer == 'f')
hexCode += 15;
*code = hexCode;
}
else if(applicationBtxCeptTriggerTag(tagPointer,"<sp>\0") == 0)
*code = ' ';
else if(applicationBtxCeptTriggerTag(tagPointer,"<apb>\0") == 0)
*code = CEPT_APB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<apf>\0") == 0)
*code = CEPT_APF;
else if(applicationBtxCeptTriggerTag(tagPointer,"<apd>\0") == 0)
*code = CEPT_APD;
else if(applicationBtxCeptTriggerTag(tagPointer,"<apu>\0") == 0)
*code = CEPT_APU;
else if(applicationBtxCeptTriggerTag(tagPointer,"<cs>\0") == 0)
*code = CEPT_CS;
else if(applicationBtxCeptTriggerTag(tagPointer,"<apr>\0") == 0)
*code = CEPT_APR;
else if(applicationBtxCeptTriggerTag(tagPointer,"<si>\0") == 0)
*code = CEPT_SI;
else if(applicationBtxCeptTriggerTag(tagPointer,"<so>\0") == 0)
*code = CEPT_SO;
else if(applicationBtxCeptTriggerTag(tagPointer,"<con>\0") == 0)
*code = CEPT_CON;
else if(applicationBtxCeptTriggerTag(tagPointer,"<rpt>\0") == 0)
*code = CEPT_RPT;
else if(applicationBtxCeptTriggerTag(tagPointer,"<cof>\0") == 0)
*code = CEPT_COF;
else if(applicationBtxCeptTriggerTag(tagPointer,"<can>\0") == 0)
*code = CEPT_CAN;
else if(applicationBtxCeptTriggerTag(tagPointer,"<ss2>\0") == 0)
*code = CEPT_SS2;
else if(applicationBtxCeptTriggerTag(tagPointer,"<esc>\0") == 0)
*code = CEPT_ESC;
else if(applicationBtxCeptTriggerTag(tagPointer,"<ss3>\0") == 0)
*code = CEPT_SS3;
else if(applicationBtxCeptTriggerTag(tagPointer,"<aph>\0") == 0)
*code = CEPT_APH;
else if(applicationBtxCeptTriggerTag(tagPointer,"<us>\0") == 0)
*code = CEPT_US;
else if(applicationBtxCeptTriggerTag(tagPointer,"<nul>\0") == 0)
*code = CEPT_NUL;
else if(applicationBtxCeptTriggerTag(tagPointer,"<soh>\0") == 0)
*code = CEPT_SOH;
else if(applicationBtxCeptTriggerTag(tagPointer,"<stx>\0") == 0)
*code = CEPT_STX;
else if(applicationBtxCeptTriggerTag(tagPointer,"<etx>\0") == 0)
*code = CEPT_ETX;
else if(applicationBtxCeptTriggerTag(tagPointer,"<eot>\0") == 0)
*code = CEPT_EOT;
else if(applicationBtxCeptTriggerTag(tagPointer,"<enq>\0") == 0)
*code = CEPT_ENQ;
else if(applicationBtxCeptTriggerTag(tagPointer,"<ack>\0") == 0)
*code = CEPT_ACK;
else if(applicationBtxCeptTriggerTag(tagPointer,"<itb>\0") == 0)
*code = CEPT_ITB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<dle>\0") == 0)
*code = CEPT_DLE;
else if(applicationBtxCeptTriggerTag(tagPointer,"<nak>\0") == 0)
*code = CEPT_NAK;
else if(applicationBtxCeptTriggerTag(tagPointer,"<syn>\0") == 0)
*code = CEPT_SYN;
else if(applicationBtxCeptTriggerTag(tagPointer,"<etb>\0") == 0)
*code = CEPT_ETB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<ini>\0") == 0)
*code = CEPT_INI;
else if(applicationBtxCeptTriggerTag(tagPointer,"<ter>\0") == 0)
*code = CEPT_TER;
else if(applicationBtxCeptTriggerTag(tagPointer,"<dct>\0") == 0)
*code = CEPT_DCT;
else if(applicationBtxCeptTriggerTag(tagPointer,"<fsh>\0") == 0)
*code = CEPT_FSH;
else if(applicationBtxCeptTriggerTag(tagPointer,"<std>\0") == 0)
*code = CEPT_STD;
else if(applicationBtxCeptTriggerTag(tagPointer,"<ebx>\0") == 0)
*code = CEPT_EBX;
else if(applicationBtxCeptTriggerTag(tagPointer,"<sbx>\0") == 0)
*code = CEPT_SBX;
else if(applicationBtxCeptTriggerTag(tagPointer,"<nsz>\0") == 0)
*code = CEPT_NSZ;
else if(applicationBtxCeptTriggerTag(tagPointer,"<dbh>\0") == 0)
*code = CEPT_DBH;
else if(applicationBtxCeptTriggerTag(tagPointer,"<dbw>\0") == 0)
*code = CEPT_DBW;
else if(applicationBtxCeptTriggerTag(tagPointer,"<dbs>\0") == 0)
*code = CEPT_DBS;
else if(applicationBtxCeptTriggerTag(tagPointer,"<cdy>\0") == 0)
*code = CEPT_CDY;
else if(applicationBtxCeptTriggerTag(tagPointer,"<spl>\0") == 0)
*code = CEPT_SPL;
else if(applicationBtxCeptTriggerTag(tagPointer,"<stl>\0") == 0)
*code = CEPT_STL;
else if(applicationBtxCeptTriggerTag(tagPointer,"<csi>\0") == 0)
*code = CEPT_CSI;
else if(applicationBtxCeptTriggerTag(tagPointer,"<abk>\0") == 0)
*code = CEPT_ABK;
else if(applicationBtxCeptTriggerTag(tagPointer,"<anr>\0") == 0)
*code = CEPT_ANR;
else if(applicationBtxCeptTriggerTag(tagPointer,"<ang>\0") == 0)
*code = CEPT_ANG;
else if(applicationBtxCeptTriggerTag(tagPointer,"<any>\0") == 0)
*code = CEPT_ANY;
else if(applicationBtxCeptTriggerTag(tagPointer,"<anb>\0") == 0)
*code = CEPT_ANB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<anm>\0") == 0)
*code = CEPT_ANM;
else if(applicationBtxCeptTriggerTag(tagPointer,"<anc>\0") == 0)
*code = CEPT_ANC;
else if(applicationBtxCeptTriggerTag(tagPointer,"<anw>\0") == 0)
*code = CEPT_ANW;
else if(applicationBtxCeptTriggerTag(tagPointer,"<mbk>\0") == 0)
*code = CEPT_MBK;
else if(applicationBtxCeptTriggerTag(tagPointer,"<msr>\0") == 0)
*code = CEPT_MSR;
else if(applicationBtxCeptTriggerTag(tagPointer,"<msg>\0") == 0)
*code = CEPT_MSG;
else if(applicationBtxCeptTriggerTag(tagPointer,"<msy>\0") == 0)
*code = CEPT_MSY;
else if(applicationBtxCeptTriggerTag(tagPointer,"<msb>\0") == 0)
*code = CEPT_MSB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<msm>\0") == 0)
*code = CEPT_MSM;
else if(applicationBtxCeptTriggerTag(tagPointer,"<msc>\0") == 0)
*code = CEPT_MSC;
else if(applicationBtxCeptTriggerTag(tagPointer,"<msw>\0") == 0)
*code = CEPT_MSW;
else if(applicationBtxCeptTriggerTag(tagPointer,"<bbd>\0") == 0)
*code = CEPT_BBD;
else if(applicationBtxCeptTriggerTag(tagPointer,"<nbd>\0") == 0)
*code = CEPT_NBD;
else if(applicationBtxCeptTriggerTag(tagPointer,"<hms>\0") == 0)
*code = CEPT_HMS;
else if(applicationBtxCeptTriggerTag(tagPointer,"<rms>\0") == 0)
*code = CEPT_RMS;
else if(applicationBtxCeptTriggerTag(tagPointer,"<bkf>\0") == 0)
*code = CEPT_BKF;
else if(applicationBtxCeptTriggerTag(tagPointer,"<rdf>\0") == 0)
*code = CEPT_RDF;
else if(applicationBtxCeptTriggerTag(tagPointer,"<grf>\0") == 0)
*code = CEPT_GRF;
else if(applicationBtxCeptTriggerTag(tagPointer,"<ylf>\0") == 0)
*code = CEPT_YLF;
else if(applicationBtxCeptTriggerTag(tagPointer,"<blf>\0") == 0)
*code = CEPT_BLF;
else if(applicationBtxCeptTriggerTag(tagPointer,"<mgf>\0") == 0)
*code = CEPT_MGF;
else if(applicationBtxCeptTriggerTag(tagPointer,"<cnf>\0") == 0)
*code = CEPT_CNF;
else if(applicationBtxCeptTriggerTag(tagPointer,"<whf>\0") == 0)
*code = CEPT_WHF;
else if(applicationBtxCeptTriggerTag(tagPointer,"<bkb>\0") == 0)
*code = CEPT_BKB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<rdb>\0") == 0)
*code = CEPT_RDB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<grb>\0") == 0)
*code = CEPT_GRB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<ylb>\0") == 0)
*code = CEPT_YLB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<blb>\0") == 0)
*code = CEPT_BLB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<mgb>\0") == 0)
*code = CEPT_MGB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<cnb>\0") == 0)
*code = CEPT_CNB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<whb>\0") == 0)
*code = CEPT_WHB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<npo>\0") == 0)
*code = CEPT_NPO;
else if(applicationBtxCeptTriggerTag(tagPointer,"<ipo>\0") == 0)
*code = CEPT_IPO;
else if(applicationBtxCeptTriggerTag(tagPointer,"<trb>\0") == 0)
*code = CEPT_TRB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<stc>\0") == 0)
*code = CEPT_STC;
else if(applicationBtxCeptTriggerTag(tagPointer,"<fbkb>\0") == 0)
*code = CEPT_FBKB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<frdb>\0") == 0)
*code = CEPT_FRDB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<fgrb>\0") == 0)
*code = CEPT_FGRB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<fylb>\0") == 0)
*code = CEPT_FYLB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<fblb>\0") == 0)
*code = CEPT_FBLB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<fmgb>\0") == 0)
*code = CEPT_FMGB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<fcnb>\0") == 0)
*code = CEPT_FCNB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<fwhb>\0") == 0)
*code = CEPT_FWHB;
else if(applicationBtxCeptTriggerTag(tagPointer,"<ftrb>\0") == 0)
*code = CEPT_FTRB;
else
{
*size = 1;
*code = *data;
return -1; /* Invalid tag! */
}
return 0;
}
else
{
*size = 1;
*code = *data;
return -1; /* Invalid tag! */
}
}
/* Strip everthing that is encapsulated by <!-- --> */
static int applicationBtxCeptStripComments(char *data)
{
int ignoreData = 0;
char *dataPointer = data;
char *dataAheadPointer = data;
while(*dataAheadPointer != '\0')
{
if(applicationBtxCeptTriggerTag(dataAheadPointer, "<!--\0") == 0)
ignoreData = 1;
if(applicationBtxCeptTriggerTag(dataAheadPointer, "-->\0") == 0)
{
ignoreData = 0;
dataAheadPointer += 3;
}
*dataPointer = *dataAheadPointer;
if(ignoreData == 0)
dataPointer++;
dataAheadPointer++;
}
*dataPointer = '\0';
return 0;
}
/* Chech if the character is non pintable. Return 0 when printable and -1 when non printable */
static int applicationBtxCeptCheckPrintable(char *data)
{
if(*data == ' ') /* In our case a space is a non printable char (We have <sp> for that) */
return -1;
else if ((*data >= 0x20)&&(*data <= 0x7E)) /* Printable char */
return 0;
else if(*data == '\0') /* Do not destroy \0 terminator */
return 0;
else /* All other chars are threated as non printable */
return -1;
}
/* Strip non printable characters */
static int applicationBtxCeptStripNonPrintable(char *data)
{
char *dataPointer = data;
char *dataAheadPointer = data;
while(*dataAheadPointer != '\0')
{
if(applicationBtxCeptCheckPrintable(dataAheadPointer) == -1)
dataAheadPointer++;
else
{
*dataPointer = *dataAheadPointer;
dataPointer++;
dataAheadPointer++;
}
}
*dataPointer = '\0';
return 0;
}
/* Extract content and name from a meta tag string */
static int applicationBtxParseMetaTag(char *data, char *name, char *content)
{
char *dataPointer = data;
char *namePointer = name;
char *contentPointer = content;
int copyControl = 0;
int nameSizeCount = 0; /* Size counter to prevent buffer overflow */
int contentSizeCount = 0;
while(*dataPointer != '>')
{
if(*dataPointer == '\0')
return -1; /* Something has gone completely wrong */
if(*dataPointer == '\"') /* Switch off copy control when delimeter character passes by */
copyControl = 0;
if(copyControl == 1)
{
if(nameSizeCount < (BTX_CEPT_META_TAG_NAME_BUFFERSIZE -1))
{
*namePointer = *dataPointer;
namePointer++;
nameSizeCount++;
}
else
return -1;
}
else if(copyControl == 2)
{
if(contentSizeCount < (BTX_CEPT_META_TAG_CONTENT_BUFFERSIZE -1))
{
*contentPointer = *dataPointer;
contentPointer++;
contentSizeCount++;
}
else
return -1;
}
else
{
if((applicationBtxCeptTriggerTag(dataPointer,"name=\"\0") == 0))
{
dataPointer += 5;
copyControl = 1;
}
else if((applicationBtxCeptTriggerTag(dataPointer,"content=\"\0") == 0))
{
dataPointer += 8;
copyControl = 2;
}
}
dataPointer++;
}
*namePointer = '\0';
*contentPointer = '\0';
if(copyControl != 0) /* If copy control flag is not zero something gone wrong ! */
return -1;
else
return 0;
}
/* Parse the raw data that was received via http to a btx-cept-page */
int applicationBtxCeptParse(char *dataIn, btxCeptPageData *page)
{
char *dataInPointer = dataIn;
char *dataOutPointer = page->ceptPage;
int tagSize;
char binaryCode;
int parserMode = 0; /* Parser control flags */
int parserActive = 0;
int tagHistory = 0;
page->ceptPageLength = 0; /* Initalize data in the page structure */
page->metaTagCount = 0;
applicationBtxCeptStripComments(dataInPointer); /* strip comments */
applicationBtxCeptStripNonPrintable(dataInPointer); /* strip non printable chars (and whitespaces) */
while(*dataInPointer != '\0')
{
/* Handle parser control */
if((applicationBtxCeptTriggerTag(dataInPointer,"<cept>\0") == 0))
{
if(tagHistory == 0)
{
tagHistory = 1;
parserActive = 1;
}
else
return -1;
}
if((applicationBtxCeptTriggerTag(dataInPointer,"<head>\0") == 0))
{
if(tagHistory == 1)
{
tagHistory = 2;
parserMode = HEAD_PARSER_MODE;
}
else
return -1;
}
if((applicationBtxCeptTriggerTag(dataInPointer,"</head>\0") == 0))
{
if(tagHistory == 2)
{
tagHistory = 3;
parserMode = 0;
}
else
return -1;
}
if((applicationBtxCeptTriggerTag(dataInPointer,"<body>\0") == 0))
{
if(tagHistory == 3)
{
tagHistory = 4;
parserMode = HYPERTEXT_PARSER_MODE;
dataInPointer += 6; /* Override the body tag */
}
else
return -1;
}
if((applicationBtxCeptTriggerTag(dataInPointer,"</body>\0") == 0))
{
if(tagHistory == 4)
{
tagHistory = 5;
parserMode = 0;
}
else
return -1;
}
if((applicationBtxCeptTriggerTag(dataInPointer,"</cept>\0") == 0))
{
if(tagHistory == 5)
{
tagHistory = 6;
parserActive = 0;
}
else
return -1;
}
/* Head parser mode */
if((parserMode == HEAD_PARSER_MODE)&&(parserActive == 1))
{
if((applicationBtxCeptTriggerTag(dataInPointer,"<meta\0") == 0))
{
if(page->metaTagCount<BTX_CEPT_META_TAG_MAXCOUNT)
{
if(applicationBtxParseMetaTag(dataInPointer,page->metaName[page->metaTagCount],page->metaContent[page->metaTagCount]) == -1)
return -1;
page->metaTagCount++;
}
else
return -1;
}
dataInPointer++;
}
/* Hypertect parser mode */
else if((parserMode == HYPERTEXT_PARSER_MODE)&&(parserActive == 1))
{
if(page->ceptPageLength < BTX_CEPT_BINARY_BUFFERSIZE)
{
applicationBtxCeptTranslateTag(dataInPointer,&binaryCode,&tagSize); /* Translate hypertext to binary */
dataInPointer += tagSize;
*dataOutPointer = binaryCode;
dataOutPointer++;
page->ceptPageLength++;
}
else
return 0;
}
/* Parser off */
else
dataInPointer++;
}
*dataOutPointer = '\0';
/* Do final check, every flack must be set! */
if((tagHistory == 6)&&(parserActive == 0)&&(parserMode == 0))
return 0;
else
return -1;
}
/* #################################################################################### */