//Open a file and return a pointer to the file desc struct. EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) { if (espFsData == NULL) { httpd_printf("Call espFsInit first!\n"); return NULL; } char *p=espFsData; char *hpos; char namebuf[256]; EspFsHeader h; EspFsFile *r; //Strip initial slashes while(fileName[0]=='/') fileName++; //Go find that file! while(1) { hpos=p; //Grab the next file header. spi_flash_read((uint32)p, (uint32*)&h, sizeof(EspFsHeader)); if (h.magic!=ESPFS_MAGIC) { httpd_printf("Magic mismatch. EspFS image broken.\n"); return NULL; } if (h.flags&FLAG_LASTFILE) { httpd_printf("End of image.\n"); return NULL; } //Grab the name of the file. p+=sizeof(EspFsHeader); spi_flash_read((uint32)p, (uint32*)&namebuf, sizeof(namebuf)); // httpd_printf("Found file '%s'. Namelen=%x fileLenComp=%x, compr=%d flags=%d\n", // namebuf, (unsigned int)h.nameLen, (unsigned int)h.fileLenComp, h.compression, h.flags); if (strcmp(namebuf, fileName)==0) { //Yay, this is the file we need! p+=h.nameLen; //Skip to content. r=(EspFsFile *)malloc(sizeof(EspFsFile)); //Alloc file desc mem // httpd_printf("Alloc %p\n", r); if (r==NULL) return NULL; r->header=(EspFsHeader *)hpos; r->decompressor=h.compression; r->posComp=p; r->posStart=p; r->posDecomp=0; if (h.compression==COMPRESS_NONE) { r->decompData=NULL; #ifdef ESPFS_HEATSHRINK } else if (h.compression==COMPRESS_HEATSHRINK) { //File is compressed with Heatshrink. char parm; heatshrink_decoder *dec; //Decoder params are stored in 1st byte. readFlashUnaligned(&parm, r->posComp, 1); r->posComp++; httpd_printf("Heatshrink compressed file; decode parms = %x\n", parm); dec=heatshrink_decoder_alloc(16, (parm>>4)&0xf, parm&0xf); r->decompData=dec; #endif } else {
// Returns flags of opened file. int ICACHE_FLASH_ATTR espFsFlags(EspFsFile *fh) { if (fh == NULL) { httpd_printf("File handle not ready\n"); return -1; } int8_t flags; readFlashUnaligned((char*)&flags, (char*)&fh->header->flags, 1); return (int)flags; }
//Read len bytes from the given file into buff. Returns the actual amount of bytes read. int ICACHE_FLASH_ATTR espFsRead(EspFsFile *fh, char *buff, int len) { int flen; if (fh==NULL) return 0; readFlashUnaligned((char*)&flen, (char*)&fh->header->fileLenComp, 4); //Cache file length. //Do stuff depending on the way the file is compressed. if (fh->decompressor==COMPRESS_NONE) { int toRead; toRead=flen-(fh->posComp-fh->posStart); if (len>toRead) len=toRead; // os_printf("Reading %d bytes from %x\n", len, (unsigned int)fh->posComp); readFlashUnaligned(buff, fh->posComp, len); fh->posDecomp+=len; fh->posComp+=len; // os_printf("Done reading %d bytes, pos=%x\n", len, fh->posComp); return len; } return 0; }