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

📄 fat_layer.c

📁 MP3 Cyclone的source code 利用FPGGA實現MP3的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
 *  file_seek
 *  Purpose:  This function is used to reposition the read pointer in the
 *  file.
 *  Supported operations:
 *  
 *  API:
 *  -- file_handle = pointer to a valid file handle
 *  -- int index = offset from initial start of file in BYTES
 *
 *  -- int whence = other info about how to seek
 */

BOOL file_seek(FILE_HNDL_PTR file_handle, LONG index, LONG whence){
  LONG cluster_index=0;
  LONG sector_index=0;
  LONG byte_index=0;
  LONG bytes_per_cluster;

  int remainder;

#if FAT_DEBUG
  if(DEBUG_FILE_SEEK){
    printf("\nfile_handle: %x, ", file_handle);
    printf("index: %x,", index);
    printf("whence: %x\n", whence);
  }  
#endif

  bytes_per_cluster = file_handle->vol_ptr->bpb_fat_ptr->sec_per_clust * 
    file_handle->vol_ptr->bpb_fat_ptr->bytes_per_sec;

  if(whence == ABSOLUTE_SEEK){
    file_handle->byte_index = index;
  }else if (whence == RELATIVE_SEEK){
    file_handle->byte_index += index;
    file_handle->curr_sector_offset += index;
  }

  if(file_handle->byte_index >= file_handle->dir_entry->dir_file_size){
    return FALSE;
  }

#if FAT_DEBUG
  if(DEBUG_FILE_SEEK){
    printf("Cluster: %x, Sector: %x, Byte:%x\n", file_handle->curr_cluster, 
     file_handle->curr_sector_index,
     file_handle->curr_sector_offset);
  }
#endif


  if(whence == RELATIVE_SEEK){  
    if(file_handle->curr_sector_offset >= file_handle->vol_ptr->bpb_fat_ptr->bytes_per_sec){
      file_handle->curr_sector_index += (file_handle->curr_sector_offset / file_handle->vol_ptr->bpb_fat_ptr->bytes_per_sec);
      file_handle->curr_sector_offset %= file_handle->vol_ptr->bpb_fat_ptr->bytes_per_sec;
    }

    if(file_handle->curr_sector_index >= file_handle->vol_ptr->bpb_fat_ptr->sec_per_clust){
      cluster_index += (file_handle->curr_sector_index / file_handle->vol_ptr->bpb_fat_ptr->sec_per_clust);
      file_handle->curr_sector_index %= file_handle->vol_ptr->bpb_fat_ptr->sec_per_clust;
    }
  }

  if(whence == ABSOLUTE_SEEK){
    file_handle->curr_cluster = (file_handle->dir_entry->dir_clust_hi << sizeof(LONG) |
         file_handle->dir_entry->dir_clust_low);
  }

  while(cluster_index > 0){
    file_handle->vol_ptr->fat_op=FAT_GET;
    file_handle->vol_ptr->fat_num=file_handle->curr_cluster;
    doFatTableOp(file_handle->vol_ptr);
    /* finding the cluster number depends on the FAT type */
    if (file_handle->vol_ptr->fat_type == FAT12){
      if (file_handle->vol_ptr->fat_num & 0x0001)
        file_handle->curr_cluster = (file_handle->vol_ptr->fat_data) >> 4;
      else
        file_handle->curr_cluster = (file_handle->vol_ptr->fat_data) & 0x0FFF;
    }else
      file_handle->curr_cluster = file_handle->vol_ptr->fat_data;
    cluster_index-=1;
  }

#if FAT_DEBUG
  if(DEBUG_FILE_SEEK){
    printf("Cluster: %x, Sector: %x, Byte:%x\n", file_handle->curr_cluster, 
     file_handle->curr_sector_index,
     file_handle->curr_sector_offset);
  }
#endif


  return TRUE;
}










/* 
 *  fileOp
 *  Purpose: This function is called to perform an operation on a file's
 *  data area.
 *  Supported operations:
 *  -- read  : reads a sectors worth of data to the disk
 *  -- write : writes a sectors worth of data to the disk
 *
 *  API:
 *  -- file_handle->file_op = FILE_READ | FILE_WRITE
 *  -- file_handle->file_op_data1 = (LONG) number of bytes to read
 *  -- file_handle->file_op_data2 = (BYTE *) pointer to the receiving/sending buffer
 *
 *  Returns:
 */

#define DEBUG_FILEOP FALSE
int fileOp(FILE_HNDL_PTR file_handle){
  LONG num_bytes_to_process=0, fetch_this_num_bytes=0, bytes_left_in_sector=0;
  LONG bytes_done=0, index=0;

  /*
   * To do:
   * we could cache the last operation and location to determine the next cluster and 
   * sector to read/write
   */

  /*
   * process number of bytes to read.. let the ride begin
   * run through the sectors in the cluster
   */
  
  num_bytes_to_process = file_handle->file_op_data1;

  if((file_handle->byte_index + num_bytes_to_process) >= 
     file_handle->dir_entry->dir_file_size){
    num_bytes_to_process = file_handle->dir_entry->dir_file_size - 
      file_handle->byte_index;
  }
  bytes_done = num_bytes_to_process;

  /* 
   * We can simply jump in and start reading, as all of the nasty computation
   * regarding cluster, sector, and offet has been done by lseek
   */
#if FAT_DEBUG
  if(DEBUG_FILEOP){
  printf("fileOp-> file_op_data1 = %x, file_op_data2 = %x\n", 
   file_handle->file_op_data1, 
   file_handle->file_op_data2);
  }
#endif

  while(num_bytes_to_process > 0){
    /* if the operation was a partial write, read in the sector, and then write it out. */
    file_handle->cluster_op = CLUSTER_READ;
    file_handle->cluster_op_data1 = file_handle->curr_cluster;
    file_handle->cluster_op_data2 = file_handle->curr_sector_index;
    
    /* 
     * To do:
     * fix up reads and writes of sectors so that if a sector is in memory, it is 
     * not re-read.
     */

    if(file_handle->cluster_op == CLUSTER_READ){
#if FAT_DEBUG
      if(DEBUG_FILEOP){
  printf("calling fileop-> curr_cluster: %x, curr_sector_index: %x\n", 
         file_handle->curr_cluster,
         file_handle->curr_sector_index);
      }
#endif

      doClusterOp(file_handle); 
      
      /*
       * How many bytes left in this sector... 
       * we can only fetch the number left in the sector... at max
       */
      bytes_left_in_sector = file_handle->vol_ptr->fat_bytes_per_sec -
  file_handle->curr_sector_offset;

      if(num_bytes_to_process > bytes_left_in_sector){
  fetch_this_num_bytes = bytes_left_in_sector;
  num_bytes_to_process -= bytes_left_in_sector;
      }else{
  fetch_this_num_bytes = num_bytes_to_process;
  num_bytes_to_process=0;
      }

      /* Stop thrashing the index */
      memcpy(file_handle->file_op_data2 + index,
       file_handle->fat_file_buf + file_handle->curr_sector_offset,
       fetch_this_num_bytes);
      index+=fetch_this_num_bytes;

    }else if(file_handle->file_op == CLUSTER_WRITE){
      /* 
       * To do:
       * fix file writes
       */
      printf("ERROR: fileOp() - write not currently supported\n");
    }
    file_seek(file_handle, fetch_this_num_bytes, RELATIVE_SEEK);
  }
  file_handle->file_op_data1 = bytes_done;
  return 0;
}    
  
/* 
 * These are all the high level access functions
 */
BOOL kill_file_handle(FILE_HNDL_PTR file_handle){
  /* 
   * To do:
   * make this routine work
   */
  printf("ERROR: kill_file_handle() not yet supported\n");
  return FALSE;
}

BOOL close_file(FILE_HNDL_PTR file_handle){
  /* 
   * To do:
   * make this routine work
   */
  printf("ERROR: close_file() not yet supported\n");

  return FALSE;
}

LONG read_file(FILE_HNDL_PTR file_handle,
         BYTE *buffer, 
         LONG size){
  
  if(size > file_handle->dir_entry->dir_file_size){
    //printf("error: read_file: char_number > dir_file_size\n");
    //    return FALSE;
    size = file_handle->dir_entry->dir_file_size;
  }
  if(size >= (file_handle->dir_entry->dir_file_size-file_handle->byte_index))
    size = file_handle->dir_entry->dir_file_size-file_handle->byte_index;

  /* 
   * o.k., down to business... lets start readin'
   * calculate number of clusters to dive into
   * calculate the correct sector to get
   * read/write the sector
   */
  
  file_handle->file_op=FILE_READ;
  file_handle->file_op_data1=size;
  file_handle->file_op_data2=buffer;
  fileOp(file_handle);
  return(file_handle->file_op_data1);

};

//
//  fileByIndexOp
//
//  API:
//  -- file_handle->file_op = GET_NUM_FILES 
//  -- file_handle->file_op_data1 = index
//  -- file_handle->file_op_data2 = (BYTE *) name of entry to search for
//
//  Returns:
//  GET_NUM_FILES => file_handle->file_op_data1 = number of files in dir
//  GET_FILE_BY_INDEX 
//      =>file_handle->file_ptr = the necessary info to read the file
//      =>file_handle->file_op_data2 = the name of the file on the fat
//

#define DEBUG_FILECOUNT FALSE
int get_file_count(FILE_HNDL_PTR file_handle){
  char /*file_name[11],*/ search_name[11];
  LONG cluster_to_search;
  int dir_entry_offset;
  BYTE *dir_entry;
  LONG sec_num=0, sectors_per_cluster=0;
  LONG cluster_num;
  int index=0;
  BOOL done=FALSE;
  //int char_count;
  unsigned int fileCount = 0;
  FAT_FILE_PTR tmp_dir_entry_ptr;


  /*
   * Non - Root directories that need to be searched
   * We'll handle this later................
   */
  if(0 ) {

    /* op + cluster number */
    file_handle->cluster_op = CLUSTER_READ;
    file_handle->cluster_op_data1 = file_handle->curr_cluster;
    sectors_per_cluster = file_handle->vol_ptr->bpb_fat_ptr->sec_per_clust;

#if FAT_DEBUG
    if(DEBUG_FILECOUNT){

    }
#endif

    /* Just in case you need to root around in the root directory. */
  }else if((file_handle->file_op == GET_NUM_FILES)||
     (file_handle->file_op == GET_FILE_BY_INDEX)){

    file_handle->cluster_op = ROOT_READ;
    sectors_per_cluster = file_handle->vol_ptr->root_sectors;

#if FAT_DEBUG
    if(DEBUG_FILECOUNT){
          printf("root_file_op\n");
    printf("op: %x, spc: %x\n",
     file_handle->cluster_op,
     sectors_per_cluster);
    }
#endif

  }
     
  /*
   * Loop over all entries in the clusters for this directory
   * Lookin' for the file...
   */
  while(!done){
    /* 
     * In the case of the root directory under FAT 16, we don't 
     * need to go beyond the size of our root directory in 
     * terms of sectors...
     */
      done=TRUE;

    for(sec_num=0;(sec_num < sectors_per_cluster);sec_num++){ 

      file_handle->cluster_op_data2=sec_num;
      doClusterOp(file_handle);
      
      /* Read done, now iterate over entries in the sector */
      for(dir_entry_offset=0;
        dir_entry_offset < file_handle->vol_ptr->bpb_fat_ptr->bytes_per_sec;
        dir_entry_offset += sizeof(FAT_FILE))
      {
        // file_handle->dir_entry = (FAT_FILE_PTR)(file_handle->fat_file_buf + dir_entry_offset);
        tmp_dir_entry_ptr = (FAT_FILE_PTR)(file_handle->fat_file_buf + dir_entry_offset);
  
#if FAT_DEBUG
        if(DEBUG_FILECOUNT) 
        {
          printf("Entry: "); 
          debug_print((BYTE *)tmp_dir_entry_ptr->dir_name, 11);
          printf("\n");
        }
#endif

        /* No more files in the directory... go home! */
        if(tmp_dir_entry_ptr->dir_name[0] == 0x00)
        {
          file_handle->file_op_data1=fileCount;
          if(file_handle->file_op == GET_FILE_BY_INDEX)
            return FALSE;
          else
            return TRUE;
        }
        else
        {
          if(!(*(tmp_dir_entry_ptr->dir_attr) & (ATTR_READ_ONLY | 
               ATTR_HIDDEN | 
               ATTR_SYSTEM | 
               ATTR_VOLUME_ID)))
          {
            if(!(*(tmp_dir_entry_ptr->dir_attr) & ATTR_DIRECTORY)){
              if(tmp_dir_entry_ptr->dir_name[0] != 0xE5)
                fileCount++;
#if FAT_DEBUG
              if(DEBUG_FILECOUNT)
                printf("File Count: %d\n", fileCount);
#endif
            }
          }
          if((file_handle->file_op == GET_FILE_BY_INDEX) && 
            (fileCount == (file_handle->file_op_data1+1)))
          {
            memcpy((BYTE*)file_handle->dir_entry, (BYTE*)tmp_dir_entry_ptr, sizeof(FAT_FILE));
            file_handle->curr_cluster=(file_handle->dir_entry->dir_clust_hi << sizeof(LONG) |
               file_handle->dir_entry->dir_clust_low);
            file_handle->curr_sector_index = 0;
            file_handle->curr_sector_offset = 0;
            file_handle->byte_index = 0;
#if FAT_DEBUG
            if(DEBUG_FILECOUNT) 
            {
              printf("Curr cluster: %x\n", file_handle->curr_cluster);
            }
#endif
            file_handle->file_op_data1=(fileCount-1);
            return(TRUE);
          } 
        }
      }
    }
    return(FALSE);
  }
  return 0;
}


int FAT_GetNumFiles(FILE_HNDL_PTR file_handle){
  file_handle->file_op = GET_NUM_FILES;
  if(get_file_count(file_handle))
    return(file_handle->file_op_data1);
  else
    return 0;
}

BOOL FAT_GetFileByIndex(FILE_HNDL_PTR file_handle, int index){
  file_handle->file_op = GET_FILE_BY_INDEX;
  file_handle->file_op_data1 = index;
  if(get_file_count(file_handle))
    return(TRUE);
  else 
    return(FALSE);
}

void FAT_GetShortName(FILE_HNDL_PTR file_handle, char *buf){
  memcpy((char*)buf, (char*)file_handle->dir_entry->dir_name, 11);
  buf[11]=0;
}

⌨️ 快捷键说明

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