Handler et parseur simple pour un fichier XML pour le projet télécommande par iPhone ou iPod, remplace un tag par la valeur de la variable entière. Très perfectible.

Committer:
jfpautex
Date:
Fri Oct 29 21:48:27 2010 +0000
Revision:
0:2b2fce21fd82
versin #1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jfpautex 0:2b2fce21fd82 1
jfpautex 0:2b2fce21fd82 2 /*
jfpautex 0:2b2fce21fd82 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
jfpautex 0:2b2fce21fd82 4
jfpautex 0:2b2fce21fd82 5 Permission is hereby granted, free of charge, to any person obtaining a copy
jfpautex 0:2b2fce21fd82 6 of this software and associated documentation files (the "Software"), to deal
jfpautex 0:2b2fce21fd82 7 in the Software without restriction, including without limitation the rights
jfpautex 0:2b2fce21fd82 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
jfpautex 0:2b2fce21fd82 9 copies of the Software, and to permit persons to whom the Software is
jfpautex 0:2b2fce21fd82 10 furnished to do so, subject to the following conditions:
jfpautex 0:2b2fce21fd82 11
jfpautex 0:2b2fce21fd82 12 The above copyright notice and this permission notice shall be included in
jfpautex 0:2b2fce21fd82 13 all copies or substantial portions of the Software.
jfpautex 0:2b2fce21fd82 14
jfpautex 0:2b2fce21fd82 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
jfpautex 0:2b2fce21fd82 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
jfpautex 0:2b2fce21fd82 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
jfpautex 0:2b2fce21fd82 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
jfpautex 0:2b2fce21fd82 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
jfpautex 0:2b2fce21fd82 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
jfpautex 0:2b2fce21fd82 21 THE SOFTWARE.
jfpautex 0:2b2fce21fd82 22
jfpautex 0:2b2fce21fd82 23 Copyright (c) 2010 Pautex Jean-Francois
jfpautex 0:2b2fce21fd82 24 Realise l'interface wagoml de style d'appel : http://ip/wagoml/fichier.xml
jfpautex 0:2b2fce21fd82 25 Remplace le texte dans les balises de type : "@MnREAD" par une valeur numerique
jfpautex 0:2b2fce21fd82 26 ## PREMIERE PUBLICATION
jfpautex 0:2b2fce21fd82 27 - la longueur de fichier xml n'est pas modifiable.
jfpautex 0:2b2fce21fd82 28 - les variables sont limités a M1, M2, M3, M4, et M5
jfpautex 0:2b2fce21fd82 29
jfpautex 0:2b2fce21fd82 30 */
jfpautex 0:2b2fce21fd82 31
jfpautex 0:2b2fce21fd82 32 #include "FSWagoHandler.h"
jfpautex 0:2b2fce21fd82 33
jfpautex 0:2b2fce21fd82 34 // #define __DEBUG
jfpautex 0:2b2fce21fd82 35 #include "dbg/dbg.h"
jfpautex 0:2b2fce21fd82 36
jfpautex 0:2b2fce21fd82 37 #define CHUNK_SIZE 1024
jfpautex 0:2b2fce21fd82 38
jfpautex 0:2b2fce21fd82 39 #define DEFAULT_PAGE "/index.xml"
jfpautex 0:2b2fce21fd82 40 extern int M0,M1,M2,M3,M4,M5; // val de variable en Entier 0.. 32768
jfpautex 0:2b2fce21fd82 41
jfpautex 0:2b2fce21fd82 42 FSWagoHandler::FSWagoHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) : HTTPRequestHandler(rootPath, path, pTCPSocket), m_err404(false) {}
jfpautex 0:2b2fce21fd82 43
jfpautex 0:2b2fce21fd82 44 FSWagoHandler::~FSWagoHandler() {
jfpautex 0:2b2fce21fd82 45 if (m_fp)
jfpautex 0:2b2fce21fd82 46 fclose(m_fp);
jfpautex 0:2b2fce21fd82 47 DBG("\r\nHandler destroyed\r\n");
jfpautex 0:2b2fce21fd82 48 }
jfpautex 0:2b2fce21fd82 49
jfpautex 0:2b2fce21fd82 50 //static init
jfpautex 0:2b2fce21fd82 51 map<string,string> FSWagoHandler::m_lFsPath = map<string,string>();
jfpautex 0:2b2fce21fd82 52
jfpautex 0:2b2fce21fd82 53 void FSWagoHandler::mount(const string& fsPath, const string& rootPath) {
jfpautex 0:2b2fce21fd82 54 m_lFsPath[rootPath]=fsPath;
jfpautex 0:2b2fce21fd82 55 }
jfpautex 0:2b2fce21fd82 56
jfpautex 0:2b2fce21fd82 57 void FSWagoHandler::doGet() {
jfpautex 0:2b2fce21fd82 58 DBG("\r\nIn FSWagoHandler::doGet() - rootPath=%s, path=%s\r\n", rootPath().c_str(), path().c_str());
jfpautex 0:2b2fce21fd82 59 //FIXME: Translate path to local/path
jfpautex 0:2b2fce21fd82 60 string checkedRootPath = rootPath();
jfpautex 0:2b2fce21fd82 61 if (checkedRootPath.empty())
jfpautex 0:2b2fce21fd82 62 checkedRootPath="/";
jfpautex 0:2b2fce21fd82 63 string filePath = m_lFsPath[checkedRootPath];
jfpautex 0:2b2fce21fd82 64 if (path().size() > 1) {
jfpautex 0:2b2fce21fd82 65 filePath += path();
jfpautex 0:2b2fce21fd82 66 // filePath += DEFAULT_PAGE; // test
jfpautex 0:2b2fce21fd82 67 } else {
jfpautex 0:2b2fce21fd82 68 filePath += DEFAULT_PAGE;
jfpautex 0:2b2fce21fd82 69 }
jfpautex 0:2b2fce21fd82 70
jfpautex 0:2b2fce21fd82 71 DBG("Trying to open %s\r\n", filePath.c_str());
jfpautex 0:2b2fce21fd82 72
jfpautex 0:2b2fce21fd82 73 m_fp = fopen(filePath.c_str(), "r"); //FIXME: if null, error 404
jfpautex 0:2b2fce21fd82 74
jfpautex 0:2b2fce21fd82 75
jfpautex 0:2b2fce21fd82 76
jfpautex 0:2b2fce21fd82 77 if (!m_fp) { // all not ok erre lecture
jfpautex 0:2b2fce21fd82 78 m_err404 = true;
jfpautex 0:2b2fce21fd82 79 setErrCode(404);
jfpautex 0:2b2fce21fd82 80 const char* msg = "File not found.";
jfpautex 0:2b2fce21fd82 81 setContentLen(strlen(msg));
jfpautex 0:2b2fce21fd82 82 respHeaders()["Content-Type"] = "text/xml";
jfpautex 0:2b2fce21fd82 83 respHeaders()["Connection"] = "close";
jfpautex 0:2b2fce21fd82 84 writeData(msg,strlen(msg)); //Only send header
jfpautex 0:2b2fce21fd82 85 DBG("\r\nExit FSWagoHandler::doGet() w Error 404\r\n");
jfpautex 0:2b2fce21fd82 86 return;
jfpautex 0:2b2fce21fd82 87 }
jfpautex 0:2b2fce21fd82 88
jfpautex 0:2b2fce21fd82 89 //Seek EOF to get length
jfpautex 0:2b2fce21fd82 90 fseek(m_fp, 0, SEEK_END);
jfpautex 0:2b2fce21fd82 91 setContentLen( ftell(m_fp) );
jfpautex 0:2b2fce21fd82 92 fseek(m_fp, 0, SEEK_SET); //Goto SOF
jfpautex 0:2b2fce21fd82 93
jfpautex 0:2b2fce21fd82 94 respHeaders()["Connection"] = "close";
jfpautex 0:2b2fce21fd82 95 onWriteable();
jfpautex 0:2b2fce21fd82 96 DBG("\r\nExit SimpleHandler::doGet()\r\n");
jfpautex 0:2b2fce21fd82 97 }
jfpautex 0:2b2fce21fd82 98
jfpautex 0:2b2fce21fd82 99 void FSWagoHandler::doPost() {
jfpautex 0:2b2fce21fd82 100
jfpautex 0:2b2fce21fd82 101 }
jfpautex 0:2b2fce21fd82 102
jfpautex 0:2b2fce21fd82 103 void FSWagoHandler::doHead() {
jfpautex 0:2b2fce21fd82 104
jfpautex 0:2b2fce21fd82 105 }
jfpautex 0:2b2fce21fd82 106
jfpautex 0:2b2fce21fd82 107 void FSWagoHandler::onReadable() { //Data has been read
jfpautex 0:2b2fce21fd82 108
jfpautex 0:2b2fce21fd82 109 }
jfpautex 0:2b2fce21fd82 110
jfpautex 0:2b2fce21fd82 111 void FSWagoHandler::onWriteable() { //Data has been written & buf is free
jfpautex 0:2b2fce21fd82 112 DBG("\r\nFSHandler::onWriteable() event\r\n");
jfpautex 0:2b2fce21fd82 113 if (m_err404) {
jfpautex 0:2b2fce21fd82 114 //Error has been served, now exit
jfpautex 0:2b2fce21fd82 115 close();
jfpautex 0:2b2fce21fd82 116 return;
jfpautex 0:2b2fce21fd82 117 }
jfpautex 0:2b2fce21fd82 118
jfpautex 0:2b2fce21fd82 119 // buffer de 1024 bytes
jfpautex 0:2b2fce21fd82 120 static char rBuf[CHUNK_SIZE]; // vuffer allong&#65533; on va en ajouter
jfpautex 0:2b2fce21fd82 121
jfpautex 0:2b2fce21fd82 122 while (true) {
jfpautex 0:2b2fce21fd82 123 int len = fread(rBuf, 1, CHUNK_SIZE, m_fp);
jfpautex 0:2b2fce21fd82 124 len = decode(rBuf,len);
jfpautex 0:2b2fce21fd82 125
jfpautex 0:2b2fce21fd82 126 if (len>0) {
jfpautex 0:2b2fce21fd82 127 int writtenLen = writeData(rBuf, len); // sortie du packet 128 byt
jfpautex 0:2b2fce21fd82 128 if (writtenLen < 0) { //Socket error
jfpautex 0:2b2fce21fd82 129 DBG("FSWagoHandler: Socket error %d\n", writtenLen);
jfpautex 0:2b2fce21fd82 130 if (writtenLen == TCPSOCKET_MEM) {
jfpautex 0:2b2fce21fd82 131 fseek(m_fp, -len, SEEK_CUR);
jfpautex 0:2b2fce21fd82 132 return; //Wait for the queued TCP segments to be transmitted
jfpautex 0:2b2fce21fd82 133 } else {
jfpautex 0:2b2fce21fd82 134 //This is a critical error
jfpautex 0:2b2fce21fd82 135 close();
jfpautex 0:2b2fce21fd82 136 return;
jfpautex 0:2b2fce21fd82 137 }
jfpautex 0:2b2fce21fd82 138 } else if (writtenLen < len) { //Short write, socket's buffer is full
jfpautex 0:2b2fce21fd82 139 fseek(m_fp, writtenLen - len, SEEK_CUR);
jfpautex 0:2b2fce21fd82 140 return;
jfpautex 0:2b2fce21fd82 141 }
jfpautex 0:2b2fce21fd82 142 } else {
jfpautex 0:2b2fce21fd82 143 close(); //Data written, we can close the connection
jfpautex 0:2b2fce21fd82 144 return;
jfpautex 0:2b2fce21fd82 145 }
jfpautex 0:2b2fce21fd82 146 }
jfpautex 0:2b2fce21fd82 147 }
jfpautex 0:2b2fce21fd82 148
jfpautex 0:2b2fce21fd82 149 void FSWagoHandler::onClose() { //Connection is closing
jfpautex 0:2b2fce21fd82 150 if (m_fp)
jfpautex 0:2b2fce21fd82 151 fclose(m_fp);
jfpautex 0:2b2fce21fd82 152 }
jfpautex 0:2b2fce21fd82 153 // ---------------------------------------------------------------------------
jfpautex 0:2b2fce21fd82 154 // dans le fichier xml cible recherche et remplacementt simple -----------
jfpautex 0:2b2fce21fd82 155 //
jfpautex 0:2b2fce21fd82 156 // cherche variable @M0READ @M1READ etc et remplace par la valeur de M0, M1 etc...
jfpautex 0:2b2fce21fd82 157 // on est dans la balise <IW>@M0READ</IW> du fichier wagoml en general, len est inutilisé
jfpautex 0:2b2fce21fd82 158 // car il n'est pas modifié.
jfpautex 0:2b2fce21fd82 159 int FSWagoHandler::decode(char* rBuf, int len) {
jfpautex 0:2b2fce21fd82 160 // DBG("\r\nFSWagoHandler: decode %d\r\n", len);
jfpautex 0:2b2fce21fd82 161 int index;
jfpautex 0:2b2fce21fd82 162 char str[16];
jfpautex 0:2b2fce21fd82 163
jfpautex 0:2b2fce21fd82 164 index = indexOfChar(rBuf,len,'@'); // trouve @ debut de la memoire reference @M0READ par exemple
jfpautex 0:2b2fce21fd82 165
jfpautex 0:2b2fce21fd82 166 while ( (index = indexOfChar(rBuf,len,'@')) > 0 ) {
jfpautex 0:2b2fce21fd82 167 if ( rBuf[index+6] == 'D') { // operation de lecture de valeur
jfpautex 0:2b2fce21fd82 168 // retrouve data pour <IW>
jfpautex 0:2b2fce21fd82 169 int valeur;
jfpautex 0:2b2fce21fd82 170 char indchar = rBuf[index+2];
jfpautex 0:2b2fce21fd82 171 switch (indchar) {
jfpautex 0:2b2fce21fd82 172 case '0' :
jfpautex 0:2b2fce21fd82 173 valeur = M0;
jfpautex 0:2b2fce21fd82 174 break;
jfpautex 0:2b2fce21fd82 175 case '1' :
jfpautex 0:2b2fce21fd82 176 valeur = M1;
jfpautex 0:2b2fce21fd82 177 break;
jfpautex 0:2b2fce21fd82 178 case '2' :
jfpautex 0:2b2fce21fd82 179 valeur = M2;
jfpautex 0:2b2fce21fd82 180 break;
jfpautex 0:2b2fce21fd82 181 case '3' :
jfpautex 0:2b2fce21fd82 182 valeur = M3;
jfpautex 0:2b2fce21fd82 183 break;
jfpautex 0:2b2fce21fd82 184 case '4' :
jfpautex 0:2b2fce21fd82 185 valeur = M4;
jfpautex 0:2b2fce21fd82 186 break;
jfpautex 0:2b2fce21fd82 187 case '5' :
jfpautex 0:2b2fce21fd82 188 valeur = M5;
jfpautex 0:2b2fce21fd82 189 break;
jfpautex 0:2b2fce21fd82 190 default :
jfpautex 0:2b2fce21fd82 191 valeur = 0;
jfpautex 0:2b2fce21fd82 192 }
jfpautex 0:2b2fce21fd82 193
jfpautex 0:2b2fce21fd82 194 // lecture de quel valeur ici il est complet
jfpautex 0:2b2fce21fd82 195 rBuf[index] = '+'; // ajoute + optionnel pour test
jfpautex 0:2b2fce21fd82 196 rBuf[index+6] = ' '; // efface le "D"
jfpautex 0:2b2fce21fd82 197
jfpautex 0:2b2fce21fd82 198 // copie la valeur a la place de MXREAD
jfpautex 0:2b2fce21fd82 199 sprintf(str,"%d", valeur );
jfpautex 0:2b2fce21fd82 200 rBuf[index+1] = str[0];
jfpautex 0:2b2fce21fd82 201
jfpautex 0:2b2fce21fd82 202 if ( valeur >= 10) rBuf[index+2] = str[1];
jfpautex 0:2b2fce21fd82 203 else rBuf[index+2] = ' ';
jfpautex 0:2b2fce21fd82 204 if ( valeur >= 100) rBuf[index+3] = str[2];
jfpautex 0:2b2fce21fd82 205 else rBuf[index+3] = ' ';
jfpautex 0:2b2fce21fd82 206 if ( valeur >= 1000) rBuf[index+4] = str[3];
jfpautex 0:2b2fce21fd82 207 else rBuf[index+4] = ' ';
jfpautex 0:2b2fce21fd82 208 if ( valeur >= 10000) rBuf[index+5] = str[4];
jfpautex 0:2b2fce21fd82 209 else rBuf[index+5] = ' ';
jfpautex 0:2b2fce21fd82 210 }
jfpautex 0:2b2fce21fd82 211 }
jfpautex 0:2b2fce21fd82 212 return len;
jfpautex 0:2b2fce21fd82 213 }
jfpautex 0:2b2fce21fd82 214
jfpautex 0:2b2fce21fd82 215 // index de caractere ds buf trouve x, redonne la position du premier trouve
jfpautex 0:2b2fce21fd82 216 int FSWagoHandler::indexOfChar(char* rBuf, int len, char x) {
jfpautex 0:2b2fce21fd82 217 int pos = -1, i;
jfpautex 0:2b2fce21fd82 218 for (i=0; i<len; i++) {
jfpautex 0:2b2fce21fd82 219 if ( rBuf[i] == x ) {
jfpautex 0:2b2fce21fd82 220 pos = i;
jfpautex 0:2b2fce21fd82 221 break;
jfpautex 0:2b2fce21fd82 222 }
jfpautex 0:2b2fce21fd82 223 }
jfpautex 0:2b2fce21fd82 224 return pos;
jfpautex 0:2b2fce21fd82 225 }
jfpautex 0:2b2fce21fd82 226
jfpautex 0:2b2fce21fd82 227 // remplace une chaine - inutilisé
jfpautex 0:2b2fce21fd82 228 int FSWagoHandler::remplaceCharAtIndex(char* rBuf, int len, int index, char x) {
jfpautex 0:2b2fce21fd82 229 rBuf[index] = x;
jfpautex 0:2b2fce21fd82 230 return len;
jfpautex 0:2b2fce21fd82 231 }
jfpautex 0:2b2fce21fd82 232
jfpautex 0:2b2fce21fd82 233 // remplace une chaine (non utilise pour le moment)
jfpautex 0:2b2fce21fd82 234 int FSWagoHandler::insertCharsAtIndex(char* rBuf, int len, int index, char* x, int lenx) {
jfpautex 0:2b2fce21fd82 235 int i;
jfpautex 0:2b2fce21fd82 236 // fait une place en partant de la fin
jfpautex 0:2b2fce21fd82 237 for (i=len+lenx-1; i >= index+lenx; i--) {
jfpautex 0:2b2fce21fd82 238 rBuf[i] = rBuf[i-lenx];
jfpautex 0:2b2fce21fd82 239 }
jfpautex 0:2b2fce21fd82 240 // recopie chaine entrante ds le etrou
jfpautex 0:2b2fce21fd82 241 for (i=0; i<lenx; i++) {
jfpautex 0:2b2fce21fd82 242 rBuf[index+i] = x[i];
jfpautex 0:2b2fce21fd82 243 }
jfpautex 0:2b2fce21fd82 244 return len + lenx;
jfpautex 0:2b2fce21fd82 245 }
jfpautex 0:2b2fce21fd82 246
jfpautex 0:2b2fce21fd82 247
jfpautex 0:2b2fce21fd82 248 // --------------------------------