文档章节

Module for interfacing with file system

 成长的烦恼007
发布于 2016/10/17 13:17
字数 920
阅读 16
收藏 0
// Module for interfacing with file system

#include "module.h"
#include "lauxlib.h"
#include "platform.h"

#include "c_types.h"
#include "flash_fs.h"
#include "c_string.h"

static volatile int file_fd = FS_OPEN_OK - 1;

// Lua: open(filename, mode)
static int file_open( lua_State* L )
{
  size_t len;
  if((FS_OPEN_OK - 1)!=file_fd){
    fs_close(file_fd);
    file_fd = FS_OPEN_OK - 1;
  }

  const char *fname = luaL_checklstring( L, 1, &len );
  luaL_argcheck(L, len < FS_NAME_MAX_LENGTH && c_strlen(fname) == len, 1, "filename invalid");

  const char *mode = luaL_optstring(L, 2, "r");

  file_fd = fs_open(fname, fs_mode2flag(mode));

  if(file_fd < FS_OPEN_OK){
    file_fd = FS_OPEN_OK - 1;
    lua_pushnil(L);
  } else {
    lua_pushboolean(L, 1);
  }
  return 1; 
}

// Lua: close()
static int file_close( lua_State* L )
{
  if((FS_OPEN_OK - 1)!=file_fd){
    fs_close(file_fd);
    file_fd = FS_OPEN_OK - 1;
  }
  return 0;  
}

// Lua: format()
static int file_format( lua_State* L )
{
  size_t len;
  file_close(L);
  if( !fs_format() )
  {
    NODE_ERR( "\n*** ERROR ***: unable to format. FS might be compromised.\n" );
    NODE_ERR( "It is advised to re-flash the NodeMCU image.\n" );
    luaL_error(L, "Failed to format file system");
  }
  else{
    NODE_ERR( "format done.\n" );
  }
  return 0; 
}

#if defined(BUILD_SPIFFS)

extern spiffs fs;

// Lua: list()
static int file_list( lua_State* L )
{
  spiffs_DIR d;
  struct spiffs_dirent e;
  struct spiffs_dirent *pe = &e;

  lua_newtable( L );
  SPIFFS_opendir(&fs, "/", &d);
  while ((pe = SPIFFS_readdir(&d, pe))) {
    // NODE_ERR("  %s size:%i\n", pe->name, pe->size);
    lua_pushinteger(L, pe->size);
    lua_setfield( L, -2, pe->name );
  }
  SPIFFS_closedir(&d);
  return 1;
}

static int file_seek (lua_State *L) 
{
  static const int mode[] = {FS_SEEK_SET, FS_SEEK_CUR, FS_SEEK_END};
  static const char *const modenames[] = {"set", "cur", "end", NULL};
  if((FS_OPEN_OK - 1)==file_fd)
    return luaL_error(L, "open a file first");
  int op = luaL_checkoption(L, 1, "cur", modenames);
  long offset = luaL_optlong(L, 2, 0);
  op = fs_seek(file_fd, offset, mode[op]);
  if (op < 0)
    lua_pushnil(L);  /* error */
  else
    lua_pushinteger(L, fs_tell(file_fd));
  return 1;
}

// Lua: exists(filename)
static int file_exists( lua_State* L )
{
  size_t len;
  const char *fname = luaL_checklstring( L, 1, &len );    
  luaL_argcheck(L, len < FS_NAME_MAX_LENGTH && c_strlen(fname) == len, 1, "filename invalid");

  spiffs_stat stat;
  int rc = SPIFFS_stat(&fs, (char *)fname, &stat);

  lua_pushboolean(L, (rc == SPIFFS_OK ? 1 : 0));

  return 1;
}

// Lua: remove(filename)
static int file_remove( lua_State* L )
{
  size_t len;
  const char *fname = luaL_checklstring( L, 1, &len );    
  luaL_argcheck(L, len < FS_NAME_MAX_LENGTH && c_strlen(fname) == len, 1, "filename invalid");
  file_close(L);
  SPIFFS_remove(&fs, (char *)fname);
  return 0;  
}

// Lua: flush()
static int file_flush( lua_State* L )
{
  if((FS_OPEN_OK - 1)==file_fd)
    return luaL_error(L, "open a file first");
  if(fs_flush(file_fd) == 0)
    lua_pushboolean(L, 1);
  else
    lua_pushnil(L);
  return 1;
}
#if 0
// Lua: check()
static int file_check( lua_State* L )
{
  file_close(L);
  lua_pushinteger(L, fs_check());
  return 1;
}
#endif

// Lua: rename("oldname", "newname")
static int file_rename( lua_State* L )
{
  size_t len;
  if((FS_OPEN_OK - 1)!=file_fd){
    fs_close(file_fd);
    file_fd = FS_OPEN_OK - 1;
  }

  const char *oldname = luaL_checklstring( L, 1, &len );
  luaL_argcheck(L, len < FS_NAME_MAX_LENGTH && c_strlen(oldname) == len, 1, "filename invalid");
  
  const char *newname = luaL_checklstring( L, 2, &len );  
  luaL_argcheck(L, len < FS_NAME_MAX_LENGTH && c_strlen(newname) == len, 2, "filename invalid");

  if(SPIFFS_OK==myspiffs_rename( oldname, newname )){
    lua_pushboolean(L, 1);
  } else {
    lua_pushboolean(L, 0);
  }
  return 1;
}

// Lua: fsinfo()
static int file_fsinfo( lua_State* L )
{
  u32_t total, used;
  if (SPIFFS_info(&fs, &total, &used)) {
    return luaL_error(L, "file system failed");
  }
  NODE_DBG("total: %d, used:%d\n", total, used);
  if(total>0x7FFFFFFF || used>0x7FFFFFFF || used > total)
  {
    return luaL_error(L, "file system error");
  }
  lua_pushinteger(L, total-used);
  lua_pushinteger(L, used);
  lua_pushinteger(L, total);
  return 3;
}

#endif

// g_read()
static int file_g_read( lua_State* L, int n, int16_t end_char )
{
  if(n <= 0 || n > LUAL_BUFFERSIZE)
    n = LUAL_BUFFERSIZE;
  if(end_char < 0 || end_char >255)
    end_char = EOF;
  
  luaL_Buffer b;
  if((FS_OPEN_OK - 1)==file_fd)
    return luaL_error(L, "open a file first");

  luaL_buffinit(L, &b);
  char *p = luaL_prepbuffer(&b);
  int i;

  n = fs_read(file_fd, p, n);
  for (i = 0; i < n; ++i)
    if (p[i] == end_char)
    {
      ++i;
      break;
    }

  if(i==0){
    luaL_pushresult(&b);  /* close buffer */
    return (lua_objlen(L, -1) > 0);  /* check whether read something */
  }

  fs_seek(file_fd, -(n - i), SEEK_CUR);
  luaL_addsize(&b, i);
  luaL_pushresult(&b);  /* close buffer */
  return 1;  /* read at least an `eol' */ 
}

// Lua: read()
// file.read() will read all byte in file
// file.read(10) will read 10 byte from file, or EOF is reached.
// file.read('q') will read until 'q' or EOF is reached. 
static int file_read( lua_State* L )
{
  unsigned need_len = LUAL_BUFFERSIZE;
  int16_t end_char = EOF;
  size_t el;
  if( lua_type( L, 1 ) == LUA_TNUMBER )
  {
    need_len = ( unsigned )luaL_checkinteger( L, 1 );
    if( need_len > LUAL_BUFFERSIZE ){
      need_len = LUAL_BUFFERSIZE;
    }
  }
  else if(lua_isstring(L, 1))
  {
    const char *end = luaL_checklstring( L, 1, &el );
    if(el!=1){
      return luaL_error( L, "wrong arg range" );
    }
    end_char = (int16_t)end[0];
  }

  return file_g_read(L, need_len, end_char);
}

// Lua: readline()
static int file_readline( lua_State* L )
{
  return file_g_read(L, LUAL_BUFFERSIZE, '\n');
}

// Lua: write("string")
static int file_write( lua_State* L )
{
  if((FS_OPEN_OK - 1)==file_fd)
    return luaL_error(L, "open a file first");
  size_t l, rl;
  const char *s = luaL_checklstring(L, 1, &l);
  rl = fs_write(file_fd, s, l);
  if(rl==l)
    lua_pushboolean(L, 1);
  else
    lua_pushnil(L);
  return 1;
}

// Lua: writeline("string")
static int file_writeline( lua_State* L )
{
  if((FS_OPEN_OK - 1)==file_fd)
    return luaL_error(L, "open a file first");
  size_t l, rl;
  const char *s = luaL_checklstring(L, 1, &l);
  rl = fs_write(file_fd, s, l);
  if(rl==l){
    rl = fs_write(file_fd, "\n", 1);
    if(rl==1)
      lua_pushboolean(L, 1);
    else
      lua_pushnil(L);
  }
  else{
    lua_pushnil(L);
  }
  return 1;
}

static int file_fscfg (lua_State *L)
{
  lua_pushinteger (L, fs.cfg.phys_addr);
  lua_pushinteger (L, fs.cfg.phys_size);
  return 2;
}

// Module function map
static const LUA_REG_TYPE file_map[] = {
  { LSTRKEY( "list" ),      LFUNCVAL( file_list ) },
  { LSTRKEY( "open" ),      LFUNCVAL( file_open ) },
  { LSTRKEY( "close" ),     LFUNCVAL( file_close ) },
  { LSTRKEY( "write" ),     LFUNCVAL( file_write ) },
  { LSTRKEY( "writeline" ), LFUNCVAL( file_writeline ) },
  { LSTRKEY( "read" ),      LFUNCVAL( file_read ) },
  { LSTRKEY( "readline" ),  LFUNCVAL( file_readline ) },
  { LSTRKEY( "format" ),    LFUNCVAL( file_format ) },
#if defined(BUILD_SPIFFS)
  { LSTRKEY( "remove" ),    LFUNCVAL( file_remove ) },
  { LSTRKEY( "seek" ),      LFUNCVAL( file_seek ) },
  { LSTRKEY( "flush" ),     LFUNCVAL( file_flush ) },
  { LSTRKEY( "rename" ),    LFUNCVAL( file_rename ) },
  { LSTRKEY( "fsinfo" ),    LFUNCVAL( file_fsinfo ) },
  { LSTRKEY( "fscfg" ),     LFUNCVAL( file_fscfg ) },
  { LSTRKEY( "exists" ),    LFUNCVAL( file_exists ) },  
#endif
  { LNILKEY, LNILVAL }
};

NODEMCU_MODULE(FILE, "file", file_map, NULL);

 

© 著作权归作者所有

下一篇: LUA初始化
粉丝 0
博文 4
码字总数 4267
作品 0
台州
私信 提问
PX4 Software-In-The-Loop(SITL) Simulation on Gazebo

原文链接: PX4 Software-In-The-Loop(SITL) Simulation on Gazebo cd ~/srcgit clone https://github.com/PX4/Firmware.gitcd Firmwaregit submodule update --init --recursivecd .. make ......

CSDNhuaong
2017/10/26
0
0
ubuntu 1204安装nginx的编译配置参数

安装依赖库: sudo apt-get install libxml2-dev sudo apt-get install libxslt1-dev sudo apt-get install libpcre3-dev libssl-dev openssl sudo apt-get install libatomic-ops-dev sudo ......

活的自由
2013/07/23
111
0
Mac系统的openresty编译安装

[toc] 依赖软件包安装 pcre安装完成会提示如下 openssl安装完成会提示默认安装路径LDFLAGS 、CPPFLAGS 编译安装 编译参数 具体编译参数 编译结果汇总 安装...

秦牧羊
2016/04/29
143
0
perl脚本实现mtk项目差异化

makeMtk.perl #!/usr/bin/perl my $DEBUG = 0; # enable/disable script debugging message setBuildEnvVars("./mbldenv.sh"); # End $myCmd = "makeMtk"; #$0 #space check for build path ......

poineer_1
2013/09/17
2.2K
0
Centos6.5 安装淘宝 tengine

一、下载 http://tengine.taobao.org/ http://tengine.taobao.org/download/tengine-2.0.2.tar.gz 二、解压 tar -zxvf tengine-2.0.2.tar.gz ./configure 出现错误: ./configure: error: th......

Cennac
2014/04/02
769
0

没有更多内容

加载失败,请刷新页面

加载更多

mysql-connector-java升级到8.0后保存时间到数据库出现了时差

在一个新项目中用到了新版的mysql jdbc 驱动 <dependency>     <groupId>mysql</groupId>     <artifactId>mysql-connector-java</artifactId>     <version>8.0.18</version> ......

ValSong
今天
5
0
Spring Boot 如何部署到 Linux 中的服务

打包完成后的 Spring Boot 程序如何部署到 Linux 上的服务? 你可以参考官方的有关部署 Spring Boot 为 Linux 服务的文档。 文档链接如下: https://docs.ossez.com/spring-boot-docs/docs/r...

honeymoose
今天
6
0
Spring Boot 2 实战:使用 Spring Boot Admin 监控你的应用

1. 前言 生产上对 Web 应用 的监控是十分必要的。我们可以近乎实时来对应用的健康、性能等其他指标进行监控来及时应对一些突发情况。避免一些故障的发生。对于 Spring Boot 应用来说我们可以...

码农小胖哥
今天
6
0
ZetCode 教程翻译计划正式启动 | ApacheCN

原文:ZetCode 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远。 ApacheCN 学习资源 贡献指南 本项目需要校对,欢迎大家提交 Pull Request。 ...

ApacheCN_飞龙
今天
4
0
CSS定位

CSS定位 relative相对定位 absolute绝对定位 fixed和sticky及zIndex relative相对定位 position特性:css position属性用于指定一个元素在文档中的定位方式。top、right、bottom、left属性则...

studywin
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部