Jun Furutani / libMiMic

Fork of libMiMic by Ryo Iizuka

mbed/ModLocalFileSystem.cpp

Committer:
nyatla
Date:
2013-04-26
Revision:
17:f29e1ca90e3d
Child:
18:1970fec78229

File content as of revision 17:f29e1ca90e3d:

#include "ModLocalFileSystem.h"
#include "HttpdConnection.h"
#include "NyLPC_net.h"
#include "UrlReader.h"
#include <stdio.h>
#include <stdlib.h>
#include <typeinfo>
#include "mbed.h"
#include "FATDirHandle.h"
#define ModLocalFile_SIZE_OF_BUF 256
static char buf[ModLocalFile_SIZE_OF_BUF];


namespace MiMic
{
    ModLocalFileSystem::ModLocalFileSystem(const char* i_path):ModBaseClass(i_path)
    {
    }
    ModLocalFileSystem::ModLocalFileSystem():ModBaseClass()
    {
    }
    ModLocalFileSystem::~ModLocalFileSystem()
    {
    }
    void ModLocalFileSystem::setParam(const char* i_path)
    {
        ModBaseClass::setParam(i_path);
    }

   
    bool ModLocalFileSystem::execute(HttpdConnection& i_connection)
    {
        //check platform
        //<write here! />
        
        //check prefix
        if(!this->canHandle(i_connection)){
            return false;
        }
        //Httpd lock
        i_connection.lockHttpd();            

        //set file path
        {
            //call ModUrl
            NyLPC_TcModUrl_t mod;
            NyLPC_cModUrl_initialize(&mod);
            if(!NyLPC_cModUrl_execute2(&mod,i_connection._ref_inst,buf,ModLocalFile_SIZE_OF_BUF,0)){
                NyLPC_cModUrl_finalize(&mod);
                i_connection.releaseHttpd();
                return true;
            }
            NyLPC_cModUrl_finalize(&mod);
        }
        // if path has '/?list' query key,return directory information
        //otherwise FILE.
        UrlReader url(buf);
        if(url.hasQueryKey("list")){
            //directory-list
            const char* t;
            int l;
            url.getPath(t,l);
            buf[l]='\0';//split path
            //remove '/'
            if(buf[l-1]=='/'){
                buf[l-1]='\0';
            }

            DIR* d=opendir(buf);
            if(NyLPC_cHttpdUtils_sendJsonHeader((i_connection._ref_inst))){
                if ( d != NULL )
                {
                    bool is_fatfs=(typeid(*d) == typeid(FATDirHandle));
                    struct dirent *p;
                    p = readdir(d);
                    i_connection.sendBodyF("{\"dir\":\"%s\",\"status\":200,\"list\":[",buf);
                    for(;;)
                    {
                        if(is_fatfs){
                            bool isdir=(((struct direntFAT*)(p))->fattrib & AM_DIR)!=0;
                            i_connection.sendBodyF("{\"name\":\"%s\",\"mtype\":\"%s\",\"size\":%u}",
                            p->d_name,isdir?"directory":NyLPC_cMiMeType_getFileName2MimeType(p->d_name),
                            isdir?0:((struct direntFAT*)(p))->fsize);
                        }else{
                            i_connection.sendBodyF("{\"name\":\"%s\",\"mtype\":\"%s\",\"size\":undefined}",
                            p->d_name,NyLPC_cMiMeType_getFileName2MimeType(p->d_name));
                        }
                        p = readdir(d);
                        if(p==NULL){
                            break;
                        }
                        i_connection.sendBodyF(",");                        
                    }
                    closedir(d);
                    i_connection.sendBodyF("]}");
                }else{
                    i_connection.sendBodyF("{\"dir\":\"%s\",\"status\":404,\"list\":[]}",buf);
                }
            }
        }else{
            {//split URL path and query
                const char* t;
                int l;
                url.getPath(t,l);
                buf[l]='\0';
            }
            //return content
            FILE *fp;
            size_t sz;
            //size
            fp = fopen(buf, "r"); 
            if(fp!=NULL){
                fseek(fp, 0, SEEK_END); // seek to end of file
                sz = ftell(fp);       // get current file pointer
                fseek(fp, 0, SEEK_SET); // seek back to beginning of file
                if(i_connection.sendHeader(200,NyLPC_cMiMeType_getFileName2MimeType(buf),NULL,sz)){
                    for(;;){
                        sz=fread(buf,1,ModLocalFile_SIZE_OF_BUF,fp);
                        if(sz<1){
                            break;
                        }
                        if(!i_connection.sendBody(buf,sz)){
                            break;
                        }
//                        //switch transport thread
/*                        i_connection.releaseHttpd();
                        NyLPC_cThread_yield();
                        i_connection.lockHttpd();                        
*/                    }
                }
                fclose(fp);
            }else{
                i_connection.sendHeader(404,"text/html",NULL);
                i_connection.sendBodyF("<html><body>'%s' not found.</body></html>",buf);
            }            
        }
        //Httpd unlock
        i_connection.releaseHttpd();
        return true;
        
    }
}