⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vfsfiles.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 4 页
字号:
/* FUNCTION: vfread()
 * 
 * vfread() - fread for vfs. if vfd parm is a vfs handle, this gets 
 * data from the virtual file system, doing uncompression on the fly. 
 * If vfd is not in vfs, this can be ifdefed to fall to a native 
 * fread() call. Parameters and returns are identical to fread(); 
 *
 * PARAM1: char * buf
 * PARAM2: unsigned size
 * PARAM3: unsigned items
 * PARAM4: VFILE * vfd
 *
 * RETURNS: 
 */

int 
vfread(char * buf, unsigned size, unsigned items, VFILE * vfd)
{
   unsigned bcount;  /* number of bytes put in caller's buffer */

   IN_PROFILER(PF_FS, PF_ENTRY);

   /* lock the VFS */
   vfs_lock();

   /* if the file is in our list of open files */
   if (isvfile_locked(vfd))
   {

#ifdef HT_RWVFS
      /* the caller is trying to read a handle to a file that's been
         deleted, so he gets 0 data back */
      if (vfd->file == NULL)
      {
         vfs_unlock();
         IN_PROFILER(PF_FS, PF_EXIT);
         return 0;
      }
#endif   /* HT_RWVFS */

#ifdef HT_EXTDEV
      /* if the file was created by an external file system */
      if (vfd->file->method)
      {
         struct vfroutines *  vfs   =  (struct  vfroutines*)   (vfd->file->method);
         int   rc;

         /* call that system's fread() */
         rc = vfs->r_fread(buf,size,items,vfd);
         vfs_unlock();
         IN_PROFILER(PF_FS, PF_EXIT);
         return rc;
      }
#endif   /* HT_EXTDEV */

#ifdef HT_RWVFS
      /* the data pointer can be NULL if somebody tries to read from 
       * a freshly created file, in which case there is no data in 
       * the file, so return 0
       */
      if (!(vfd->file->data))
      {
         vfs_unlock();
         IN_PROFILER(PF_FS, PF_EXIT);
         return 0;
      }
#endif   /* HT_RWVFS */

      bcount = items * size;  /* number of bytes to transfer */

#ifdef HTML_COMPRESSION
      if (vfd->file->flags & VF_HTMLCOMPRESSED)
      {
         int   chr;  /* next char to process */

         while (bcount)
         {
            chr = vgetc_locked(vfd);
            if (chr == EOF)
            {
               vfs_unlock();
               IN_PROFILER(PF_FS, PF_EXIT);
               return(((items*size)-bcount)/size);
            }

            *buf++ = (char)chr;
            bcount--;
         }
         vfs_unlock();
         IN_PROFILER(PF_FS, PF_EXIT);
         return(items); /* filled user buffer, return # items copied */
      }
      else  /* else fall to faster non-compression code */
#endif   /* HTML_COMPRESSION */
      {  /* get here to do simple uncompressed data read */
         unsigned location = vfd->cmploc - vfd->file->data;

         if (((unsigned long)location + bcount) > vfd->file->comp_size)
            bcount = (unsigned)(vfd->file->comp_size - location);
         MEMCPY(buf, vfd->cmploc, bcount);
         vfd->cmploc += bcount;
      }
      vfs_unlock();
      IN_PROFILER(PF_FS, PF_EXIT);
      return (bcount/size);
   }

   vfs_unlock();
   IN_PROFILER(PF_FS, PF_EXIT);

#ifdef HT_LOCALFS
   /* default to call on local system */
   return(fread(buf, size, items, (FILE*)vfd));
#else
   return 0;
#endif   /* HT_LOCALFS */
}

/* VFS_WRITE_BUF_INC defines how much the size of the buffer used to
   store file system data is increased at a time */
#define  VFS_WRITE_BUF_INC 8192
#define VFS_ROUND_UP(x) \
   (((((x) - 1) / VFS_WRITE_BUF_INC) + 1) * VFS_WRITE_BUF_INC)



/* FUNCTION: vfwrite_locked()
 * 
 * PARAM1: char * buf
 * PARAM2: unsigned size
 * PARAM3: unsigned items
 * PARAM4: VFILE *vfd
 *
 * RETURNS: 
 */

int 
vfwrite_locked(char * buf, unsigned size, unsigned items, VFILE * vfd)
{
#ifndef HT_RWVFS
#ifndef HT_LOCALFS
#ifndef HT_EXTDEV

   /* if the file is in our list of files */
   if (isvfile_locked(vfd))
   {
      vfd->error = ENP_LOGIC;
      return 0;
   }

   /* I know this is ugly but its the simplist way I can figure to 
    * suppress those annoying "parameter not used" compiler warnings. 
    * its a damned shame given that it results in the 
    * generation of superfluous code
    */
   USE_ARG(buf);
   USE_ARG(size);
   USE_ARG(items);

   return EBADF;

#endif   /* HT_EXTDEV */
#endif   /* HT_LOCALFS */
#endif   /* HT_RWVFS */

#ifdef HT_RWVFS
   unsigned int bcount; /* number of bytes to write */
   unsigned long current_offset;
   struct vfs_file * vfp;
#endif   /* HT_RWVFS */

   /* if the file is not in our list of files */
   if (!isvfile_locked(vfd))
   {
#ifdef HT_LOCALFS
      /* default to call on local system */
      return(fwrite(buf, size, items, (FILE*)vfd));
#else
      return EBADF;
#endif   /* HT_LOCALFS */

   }
   /* this file is in our list of files */

#ifdef HT_EXTDEV
   /* if the file was created by an external file system */
   if (vfd->file->method)
   {
      struct vfroutines *  vfs   =  (struct  vfroutines*)   (vfd->file->method);
      int   rc;

      /* call that system's fwrite() */
      rc = vfs->r_fwrite(buf,size,items,vfd);
      return rc;
   }
#endif

   /* if we don't support writes, set an error */
#ifndef HT_RWVFS

   vfd->error = ENP_LOGIC;
   return 0;

#else    /* HT_RWVFS */

   /* the caller is trying to write to a file that's been deleted,
      so he writes 0 data */
   if (vfd->file == NULL)
   {
      return 0;
   }

   vfp = vfd->file;

   /* if the file is not writable, return error condition */
   if (!(vfp->flags & VF_WRITE))
   {
      vfd->error = ENP_FILEIO;
      return 0;
   }

   /* compute number of bytes to write */
   bcount = size * items;

   /* get rid of this degenerate case up front */
   if (bcount == 0)
   {
      return 0;
   }

   /* if the file currently has no data buffer */
   if (vfp->data == NULL)
   {
      /* compute the size of the buffer to be created */
      /* we round up the size of the data to be written so we dont have
         the overhead of a memory allocation on every write */
      unsigned long buf_size = VFS_ROUND_UP((unsigned long)bcount);

      /* allocate a buffer of that size */
      vfp->data = vf_alloc_buffer(buf_size);

      /* if the allocation failed */
      if (!(vfp->data))
      {
         vfd->error = ENP_NOMEM;
         return 0;
      }

      /* store the size of the allocated buffer */
      vfp->buf_size = buf_size;

      /* store the number of bytes written in the real and compressed
         file sizes */
      vfp->real_size = bcount;
      vfp->comp_size = bcount;

      /* set the file pointer to the first byte following the last
         byte written */
      vfd->cmploc = vfp->data + bcount;

      /* turn off the compression flag */
      vfp->flags &= ~VF_HTMLCOMPRESSED;

      /* the data in the file is stale */
      vfp->flags |= VF_STALE;

      /* the buffer data was dynamically allocated */
      vfp->flags |= VF_DYNAMICDATA;

      /* copy the data to be written to the file buffer */
      MEMCPY(vfp->data,buf,bcount);

      /* return the number of "items" written */
      return items;
   }

   /* compute the current offset into the file */
   current_offset = vfd->cmploc - vfp->data;

   /* if the data to be written wont fit into the file buffer */
   if ((current_offset + bcount) > vfp->buf_size)
   {
      /* compute the size of a new buffer to hold the data */
      unsigned long new_buf_size = VFS_ROUND_UP(current_offset + bcount);
      unsigned char *new_buffer;

      /* allocate a new buffer */
      new_buffer = vf_alloc_buffer(new_buf_size);

      /* check for allocation failure */
      if (!new_buffer)
      {
         vfd->error = ENP_NOMEM;
         return 0;
      }

      /* copy the old buffer contents to the new buffer */
      MEMCPY(new_buffer,vfp->data,(unsigned int) (vfp->comp_size));

      /* if the old buffer had been dynamically allocated */
      if (vfp->flags & VF_DYNAMICDATA)
      {
         /* free it */
         vf_free_buffer(vfp->data,vfp->buf_size);
      }

      /* store the new buffer in the file structure */
      vfp->data = new_buffer;

      /* store the new buffer size in the file structure */
      vfp->buf_size = new_buf_size;

      /* the new buffer was dynamically allocated */
      vfp->flags |= VF_DYNAMICDATA;

      /* set the current file pointer to point into the new data 
       * buffer note that this means the VFS does not support 
       * simultaneous opens of the same file, since for that to work, 
       * all the other cmploc's that point to this file would 
       * have to be updated also 
       */
      vfd->cmploc = vfp->data + current_offset;
   }

   /* copy the data to the current file pointer */
   MEMCPY(vfd->cmploc,buf,bcount);

   /* update the current file pointer */
   vfd->cmploc += bcount;

   /* if the resulting current offset is greater than the file size */
   if (current_offset + bcount > vfp->comp_size)
   {
      /* update the "compressed" file size */
      vfp->comp_size = current_offset + bcount;
   }

   /* since we turn off the compression bit below, the "real" size and
      the compressed size must be the same */
   vfp->real_size = vfp->comp_size;

   /* turn off the compression flag */
   vfp->flags &= ~VF_HTMLCOMPRESSED;

   /* the data in the file is stale */
   vfp->flags |= VF_STALE;

   /* return the number of "items" written */
   return items;

#endif   /* HT_RWVFS */
}



/* FUNCTION: vfwrite()
 * 
 * vfwrite() - This is included to support integration with native 
 * file systems. Parameters and returns are identical to fwrite(); 
 * except that on some error conditions EBADF is returned instead of 
 * 0 
 *
 * PARAM1: char * buf
 * PARAM2: unsigned size
 * PARAM3: unsigned items
 * PARAM4: VFILE *vfd
 *
 * RETURNS: 
 */

int
vfwrite(char * buf, unsigned size, unsigned items, VFILE * vfd)
{
   int   rc;

   IN_PROFILER(PF_FS, PF_ENTRY);

   /* lock the VFS */
   vfs_lock();

   /* do the write */
   rc = vfwrite_locked(buf, size, items, vfd);

   /* unlock the VFS */
   vfs_unlock();

   IN_PROFILER(PF_FS, PF_EXIT);

   return rc;
}




/* FUNCTION: vfseek()
 * 
 * vfseek : Returns 0 on success. Otherwise returns a nonzero value.
 *
 * PARAM1: VFILE * vfd
 * PARAM2: long offset
 * PARAM3: int mode
 *
 * RETURNS: 
 */

int 
vfseek(VFILE * vfd, long offset, int mode)
{
   /* lock the VFS */
   vfs_lock();

   if (isvfile_locked(vfd))
   {
#ifdef HT_RWVFS
      /* the caller is trying to seek a file that's been deleted,
         so return an error indication */
      if (vfd->file == NULL)
      {
         vfs_unlock();
         return -1;
      }
#endif   /* HT_RWVFS */

#ifdef HT_EXTDEV
      if (vfd->file->method)
      {
         struct vfroutines *  vfp   =  (struct  vfroutines*)   (vfd->file->method);
         int   rc;

         rc = vfp->r_fseek(vfd,offset,mode);
         vfs_unlock();
         return rc;
      }
#endif   /* HT_EXTDEV */
      /* this vfseek() currently only supports seek to exact
         end or begining of file */
      switch (mode)
      {
      case SEEK_SET:
         vfd->cmploc = vfd->file->data + offset;
         break;
      case SEEK_CUR:
         /* If the file is compressed, then the following
          * adjustment is inaccurate. Currently we don't have
          * any scenario where this happens. - handle later */
         vfd->cmploc += offset; 
         break;
      case SEEK_END:
         vfd->cmploc = vfd->file->data + vfd->file->comp_size + offset;
         break;
      }
      vfs_unlock();
      return(0);
   }

   vfs_unlock();

#ifdef HT_LOCALFS
   /* default to call on local system */
   return(fseek((FILE*)vfd, offset, mode));
#else
   return -1;
#endif   /* HT_LOCALFS */
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -