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.

Revision:
0:2b2fce21fd82
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FSWagoHandler.cpp	Fri Oct 29 21:48:27 2010 +0000
@@ -0,0 +1,248 @@
+
+/*
+Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+Copyright (c) 2010 Pautex Jean-Francois
+Realise l'interface wagoml de style d'appel : http://ip/wagoml/fichier.xml
+Remplace le texte dans les balises de type : "@MnREAD" par une valeur numerique
+## PREMIERE PUBLICATION
+- la longueur de fichier xml n'est pas modifiable.
+- les variables sont limités a M1, M2, M3, M4, et M5
+
+*/
+
+#include "FSWagoHandler.h"
+
+// #define __DEBUG
+#include "dbg/dbg.h"
+
+#define CHUNK_SIZE 1024
+
+#define DEFAULT_PAGE "/index.xml"
+extern int M0,M1,M2,M3,M4,M5;                 // val de variable en Entier 0.. 32768
+
+FSWagoHandler::FSWagoHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) : HTTPRequestHandler(rootPath, path, pTCPSocket), m_err404(false) {}
+
+FSWagoHandler::~FSWagoHandler() {
+    if (m_fp)
+        fclose(m_fp);
+    DBG("\r\nHandler destroyed\r\n");
+}
+
+//static init
+map<string,string> FSWagoHandler::m_lFsPath = map<string,string>();
+
+void FSWagoHandler::mount(const string& fsPath, const string& rootPath) {
+    m_lFsPath[rootPath]=fsPath;
+}
+
+void FSWagoHandler::doGet() {
+    DBG("\r\nIn FSWagoHandler::doGet() - rootPath=%s, path=%s\r\n", rootPath().c_str(), path().c_str());
+    //FIXME: Translate path to local/path
+    string checkedRootPath = rootPath();
+    if (checkedRootPath.empty())
+        checkedRootPath="/";
+    string filePath = m_lFsPath[checkedRootPath];
+    if (path().size() > 1) {
+        filePath += path();
+        // filePath += DEFAULT_PAGE; // test
+    } else {
+        filePath += DEFAULT_PAGE;
+    }
+
+    DBG("Trying to open %s\r\n", filePath.c_str());
+
+    m_fp = fopen(filePath.c_str(), "r"); //FIXME: if null, error 404
+
+
+
+    if (!m_fp) { // all not ok erre lecture
+        m_err404 = true;
+        setErrCode(404);
+        const char* msg = "File not found.";
+        setContentLen(strlen(msg));
+        respHeaders()["Content-Type"] = "text/xml";
+        respHeaders()["Connection"] = "close";
+        writeData(msg,strlen(msg)); //Only send header
+        DBG("\r\nExit FSWagoHandler::doGet() w Error 404\r\n");
+        return;
+    }
+
+    //Seek EOF to get length
+    fseek(m_fp, 0, SEEK_END);
+    setContentLen( ftell(m_fp) );
+    fseek(m_fp, 0, SEEK_SET); //Goto SOF
+
+    respHeaders()["Connection"] = "close";
+    onWriteable();
+    DBG("\r\nExit SimpleHandler::doGet()\r\n");
+}
+
+void FSWagoHandler::doPost() {
+
+}
+
+void FSWagoHandler::doHead() {
+
+}
+
+void FSWagoHandler::onReadable() { //Data has been read
+
+}
+
+void FSWagoHandler::onWriteable() { //Data has been written & buf is free
+    DBG("\r\nFSHandler::onWriteable() event\r\n");
+    if (m_err404) {
+        //Error has been served, now exit
+        close();
+        return;
+    }
+
+    // buffer de 1024 bytes
+    static char rBuf[CHUNK_SIZE];   // vuffer allong&#65533; on va en ajouter
+
+    while (true) {
+        int len = fread(rBuf, 1, CHUNK_SIZE, m_fp);
+        len     = decode(rBuf,len);
+
+        if (len>0) {
+            int writtenLen = writeData(rBuf, len);      // sortie du packet 128 byt
+            if (writtenLen < 0) { //Socket error
+                DBG("FSWagoHandler: Socket error %d\n", writtenLen);
+                if (writtenLen == TCPSOCKET_MEM) {
+                    fseek(m_fp, -len, SEEK_CUR);
+                    return; //Wait for the queued TCP segments to be transmitted
+                } else {
+                    //This is a critical error
+                    close();
+                    return;
+                }
+            } else if (writtenLen < len) { //Short write, socket's buffer is full
+                fseek(m_fp, writtenLen - len, SEEK_CUR);
+                return;
+            }
+        } else {
+            close(); //Data written, we can close the connection
+            return;
+        }
+    }
+}
+
+void FSWagoHandler::onClose() { //Connection is closing
+    if (m_fp)
+        fclose(m_fp);
+}
+// ---------------------------------------------------------------------------
+// dans le fichier xml cible recherche et remplacementt simple     -----------
+//
+// cherche variable @M0READ @M1READ etc et remplace par la valeur de M0, M1 etc...
+// on est dans la balise <IW>@M0READ</IW>  du fichier wagoml en general, len est inutilisé
+// car il n'est pas modifié.
+int FSWagoHandler::decode(char* rBuf, int len) {
+    // DBG("\r\nFSWagoHandler: decode %d\r\n", len);
+    int  index;
+    char str[16];
+
+    index = indexOfChar(rBuf,len,'@');    // trouve @ debut de la memoire reference @M0READ par exemple
+
+    while ( (index = indexOfChar(rBuf,len,'@')) > 0 ) {
+        if ( rBuf[index+6] == 'D') {           // operation de lecture de valeur
+            // retrouve data pour <IW>
+            int valeur;
+            char indchar =  rBuf[index+2];
+            switch (indchar) {
+                case '0' :
+                    valeur = M0;
+                    break;
+                case '1' :
+                    valeur = M1;
+                    break;
+                case '2' :
+                    valeur = M2;
+                    break;
+                case '3' :
+                    valeur = M3;
+                    break;
+                case '4' :
+                    valeur = M4;
+                    break;
+                case '5' :
+                    valeur = M5;
+                    break;
+                default  :
+                    valeur  = 0;
+            }
+
+            // lecture de quel valeur ici il est complet
+            rBuf[index] = '+';      // ajoute + optionnel pour test
+            rBuf[index+6] = ' ';    // efface le "D"
+
+            // copie la valeur a la place de MXREAD
+            sprintf(str,"%d", valeur );
+            rBuf[index+1] = str[0];
+
+            if ( valeur >= 10)    rBuf[index+2] = str[1];
+            else                  rBuf[index+2] = ' ';
+            if ( valeur >= 100)   rBuf[index+3] = str[2];
+            else                  rBuf[index+3] = ' ';
+            if ( valeur >= 1000)  rBuf[index+4] = str[3];
+            else                  rBuf[index+4] = ' ';
+            if ( valeur >= 10000) rBuf[index+5] = str[4];
+            else                  rBuf[index+5] = ' ';
+        }
+    }
+    return len;
+}
+
+// index de caractere ds buf trouve x, redonne la position du premier trouve
+int FSWagoHandler::indexOfChar(char* rBuf, int len, char x) {
+    int pos = -1, i;
+    for (i=0; i<len; i++) {
+        if ( rBuf[i] == x ) {
+            pos = i;
+            break;
+        }
+    }
+    return pos;
+}
+
+// remplace une chaine - inutilisé
+int FSWagoHandler::remplaceCharAtIndex(char* rBuf, int len, int index, char x) {
+    rBuf[index] = x;
+    return len;
+}
+
+// remplace une chaine (non utilise pour le moment)
+int FSWagoHandler::insertCharsAtIndex(char* rBuf, int len, int index, char* x, int lenx) {
+    int i;
+    // fait une place en partant de la fin
+    for (i=len+lenx-1; i >= index+lenx; i--) {
+        rBuf[i] = rBuf[i-lenx];
+    }
+    // recopie chaine entrante ds le etrou
+    for (i=0; i<lenx; i++) {
+        rBuf[index+i] = x[i];
+    }
+    return len + lenx;
+}
+
+
+// --------------------------------
\ No newline at end of file