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

📄 rdcf2.c

📁 基于lpc2106和OV6620的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
      f->mode |= WRITTEN;      f->file.first_cluster = EMPTY_CLUSTER;      f->file.size = 0L;      update_directory_entry (f, 0);      flush_buffer (f);    }  } else if (!found) {    //    printf("!found, !O_CREAT\n");    // not found, not CREATE -> error    error_exit (f, ~ENOENT);  }  // mark APPEND  if (mode & O_APPEND) {    f->mode |= APPEND;  }  // now file is created or we have signalled an error  // decide the file mode  switch (mode & 0x3) {  case O_RDONLY:    //    printf("open for reading\n");    f->mode |= RDCF_READ;    break;  case O_RDWR:    //    printf("open for reading\n");    f->mode |= RDCF_READ;    // fallthrough to write  case O_WRONLY:    //    printf("open for writing\n");    check_write_access (f);    f->mode |= RDCF_WRITE;    break;  }  // do final setup  f->last_cluster = EMPTY_CLUSTER;  f->position = 0;  f->cluster = f->file.first_cluster;  // seek to end of file if O_WRONLY and O_APPEND  if ((mode & O_APPEND) && ((mode & 0x3) == O_WRONLY)) {    //    printf("O_APPEND seeking now\n");    int result;    if ((result = rdcf_seek (f, f->file.size)) != 0)      return result;  }  return 0;}/*************************************************************** * rdcf_read * *   fill buf with data from opened file. *   returns positive number on succes of bytes read. ****************************************************************/int rdcf_read (struct rdcf *f, void *buf, int count){  uint32_t size = f->file.size;  unsigned unread_bytes = count;  uint32_t position = f->position;  char *buffer = buf;  if ((f->result = setjmp (f->error)) != 0)    return f->result;  if ((f->mode & RDCF_READ) == 0)    error_exit (f, ~EBADFD);  f->buffer_status = EMPTY;  while (unread_bytes > 0) {    unsigned n = unread_bytes;    unsigned rest_of_sector = SECTOR_SIZE - position % SECTOR_SIZE;    unsigned sector;    if (size < position + n)      n = size - position;    if (n == 0)      break;    sector = first_sector_in_cluster (f, f->cluster) +      (position / SECTOR_SIZE) % f->sectors_per_cluster;    if (n > rest_of_sector)      n = rest_of_sector;    if (position % SECTOR_SIZE == 0 && n == SECTOR_SIZE)      read_sector (f, sector, buffer);    else {                      /* read a partial sector */      read_buffer (f, sector);      memcpy (buffer, &f->buffer.buf[position % SECTOR_SIZE], n);    }    buffer += n;    position += n;    unread_bytes -= n;    if (position % (f->sectors_per_cluster * SECTOR_SIZE) == 0        && position < size) {      unsigned next_cluster = FAT_entry (f, f->cluster);      if (next_cluster >= f->last_cluster_mark)        f->last_cluster = f->cluster;      f->cluster = next_cluster;    }  }  f->position = position;  return f->result = count - unread_bytes;}int rdcf_seek (struct rdcf *f, uint32_t offset){  unsigned i, cluster;  if ((f->result = setjmp (f->error)) != 0)    return f->result;  if (offset > f->file.size)    error_exit (f, ~EINVAL);  f->buffer_status = EMPTY;  cluster = f->file.first_cluster;  for (i = offset / (f->sectors_per_cluster * SECTOR_SIZE); i > 0; i--) {    unsigned new_cluster = FAT_entry (f, cluster);    if (new_cluster >= f->last_cluster_mark)      f->last_cluster = cluster;    cluster = new_cluster;  }  f->cluster = cluster;  f->position = offset;  return 0;}static int real_rdcf_write (struct rdcf *f, const uint8_t * buf, int count){  uint32_t size = f->file.size;  uint32_t position = f->position;  unsigned unwritten_bytes = count;  const uint8_t *buffer = buf;  if ((f->result = setjmp (f->error)) != 0)    return f->result;  f->buffer_status = EMPTY;  if ((f->mode & RDCF_WRITE) == 0)    error_exit (f, ~EBADFD);  if (f->mode & APPEND) {    //    printf("O_APPEND seeking now\n");    int result;    if ((result = rdcf_seek (f, size)) != 0)      return result;    position = f->position;  }  while (unwritten_bytes > 0) {    unsigned sector;    unsigned n = unwritten_bytes;    unsigned rest_of_sector = SECTOR_SIZE - position % SECTOR_SIZE;    if (n > rest_of_sector)      n = rest_of_sector;    if (f->cluster == EMPTY_CLUSTER || f->cluster >= f->last_cluster_mark) {      unsigned new_cluster =        add_new_cluster (f, f->last_cluster);      if (new_cluster == EMPTY_CLUSTER)        break;      DriveDesc.FirstPossiblyEmptyCluster = new_cluster + 1;      f->cluster = f->last_cluster = new_cluster;      if (f->file.first_cluster == EMPTY_CLUSTER)        f->file.first_cluster = new_cluster;    }    sector = first_sector_in_cluster (f, f->cluster) +      (position / SECTOR_SIZE) % f->sectors_per_cluster;    if (position % SECTOR_SIZE == 0 &&        (n == SECTOR_SIZE || position + n >= size)) {      write_sector (f, sector, buffer);    }    else {                      /* write a partial sector */      read_buffer (f, sector);      memcpy (&f->buffer.buf[position % SECTOR_SIZE], buffer, n);      f->buffer_status = DIRTY;    }    buffer += n;    position += n;    unwritten_bytes -= n;    if (position > size)      size = position;    if (position % (f->sectors_per_cluster * SECTOR_SIZE) == 0) {      unsigned next_cluster = FAT_entry (f, f->cluster);      if (next_cluster >= f->last_cluster_mark)        f->last_cluster = f->cluster;      f->cluster = next_cluster;    }  }  flush_buffer (f);  f->position = position;  f->file.size = size;  f->mode |= WRITTEN;#ifdef RDCF_FLUSH_DIR_AFTER_WRITE  rdcf_get_date_and_time (&f->file.date_and_time);  // do not allow empty files.  update_directory_entry (f, (f->file.size) ? 0 : 1);  flush_buffer (f);#endif  return f->result = count - unwritten_bytes;}int rdcf_write (struct rdcf *f, const void *buf, int count){                               // traps write() and ensures no dangling FAT chains.  int result;  result = real_rdcf_write (f, buf, count);  // uhoh, something really bad happened!  // flush buffer and close the handle.  if (result <= 0) {    rdcf_close (f);  }  return result;}int rdcf_flush_directory (struct rdcf *f){  if ((f->result = setjmp (f->error)) != 0)    return f->result;  rdcf_get_date_and_time (&f->file.date_and_time);  // do not allow empty files.  update_directory_entry (f, (f->file.size) ? 0 : 1);  flush_buffer (f);  return 0;}#if 0int rdcf_attribute (struct rdcf *f, const char *spec, unsigned attribute){  if ((f->result = setjmp (f->error)) != 0)    return f->result;  if (!find_file (f, initialize_fcb (f, spec)) ||      f->file.attribute & RDCF_DIRECTORY) {    error_exit (f, ~ENOENT);  }  f->file.attribute = (f->file.attribute & ~CHANGEABLE_ATTRIBUTES) |    (attribute & CHANGEABLE_ATTRIBUTES);  update_directory_entry (f, 0);  flush_buffer (f);  return 0;}int rdcf_date_and_time (struct rdcf *f, const char *spec,                        struct rdcf_date_and_time *p){  if ((f->result = setjmp (f->error)) != 0)    return f->result;  spec = initialize_fcb (f, spec);  if (*spec == 0) {    f->directory_cluster = 0;    if (!find_file_in_directory_or_find_volume (f, NULL))      error_exit (f, ~ENOENT);  }  else {    if (!find_file (f, spec))      error_exit (f, ~ENOENT);  }  f->file.date_and_time = *p;  if ((f->file.attribute & (RDCF_DIRECTORY + RDCF_VOLUME)) == 0) {    check_write_access (f);    f->file.attribute |= RDCF_ARCHIVE;  }  update_directory_entry (f, 0);  if (f->file.attribute & RDCF_DIRECTORY)    update_dot_and_dot_dot (f);  flush_buffer (f);  return 0;}int rdcf_directory (struct rdcf *f, const char *spec){  /* uint8_t name_extension[NAME_SIZE+EXTENSION_SIZE]; ??? */  if ((f->result = setjmp (f->error)) != 0)    return f->result;  if (find_file (f, initialize_fcb (f, spec)))    error_exit (f, ~EISDIR);  /* spec_to_name_extension(f, name_extension, f->file.spec); ??? */  /* name_extension_to_spec(f->file.spec, name_extension); ??? */  /* determine whether there is enough free space for directory */  {    unsigned cluster = 2;    unsigned required_clusters =      f->directory_index == NO_DIRECTORY_INDEX ? 2 : 1;    for (cluster = 2; required_clusters != 0; cluster++) {      if (cluster > f->maximum_cluster_number)        error_exit (f, ~ENOSPC);      if (FAT_entry (f, cluster) == EMPTY_CLUSTER)        required_clusters--;    }  }  lengthen_directory_if_necessary (f);  f->file.attribute = RDCF_DIRECTORY;  f->file.first_cluster = add_new_cluster (f, EMPTY_CLUSTER, 2);  clear_cluster (f, f->file.first_cluster);  f->file.size = 0L;  rdcf_get_date_and_time (&f->file.date_and_time);  update_directory_entry (f, 0);  update_dot_and_dot_dot (f);  flush_buffer (f);  return 0;}long int rdcf_free_space (struct rdcf *f#ifdef RDCF_MULTIPLE_DRIVE                          , char *spec#endif  ){  unsigned cluster;  unsigned number_of_empty_clusters = 0;  if ((f->result = setjmp (f->error)) != 0)    return (long) (f->result);#ifndef RDCF_MULTIPLE_DRIVE  initialize_fcb (f, NULL);#else  if (*initialize_fcb (f, spec) != 0)    error_exit (f, ~EINVAL);#endif  for (cluster = 2; cluster <= f->maximum_cluster_number; cluster++) {    if (FAT_entry (f, cluster) == EMPTY_CLUSTER)      number_of_empty_clusters++;  }  f->file.size = (uint32_t) number_of_empty_clusters *    (f->sectors_per_cluster * SECTOR_SIZE);  return (long) (f->file.size);}int rdcf_get_file_information (struct rdcf *f, const char *spec, unsigned idx){  if ((f->result = setjmp (f->error)) != 0)    return f->result;  find_entry (f, spec, idx);  read_directory_entry (f);  return f->result = f->file.spec[0] == DELETED_FILE ? ENOENT :    f->file.spec[0] == 0 ? ENOSPC : 0;}int rdcf_next_file_information (struct rdcf *f){  if ((f->result = setjmp (f->error)) != 0)    return f->result;  f->directory_index++;  if (f->directory_cluster == 0) {    if (f->directory_index >=        (f->first_data_sector -         f->first_directory_sector) * ENTRIES_PER_SECTOR) {      error_exit (f, ~ENOSPC);    }  }  else {    if (f->directory_index >= ENTRIES_PER_SECTOR * f->sectors_per_cluster) {      f->directory_cluster = FAT_entry (f, f->directory_cluster);      if (f->directory_cluster >= f->last_cluster_mark)        error_exit (f, ~ENOSPC);      f->directory_index = 0;    }  }  read_directory_entry (f);  return f->result = f->file.spec[0] == DELETED_FILE ? ENOENT :    f->file.spec[0] == 0 ? ENOSPC : 0;}/*-----------------------------------------------------------------------------When f represents a subdirectory, this function updates the . and .. entries atthe beginning of its first cluster.-----------------------------------------------------------------------------*/static void update_dot_and_dot_dot (struct rdcf *f){  f->directory_cluster = f->file.first_cluster;  f->directory_index = 0;  memset (f->file.spec, ' ', NAME_SIZE + EXTENSION_SIZE);  f->file.spec[0] = '.';  update_directory_entry (f, 0);  f->file.first_cluster = f->directory_first_cluster;  f->directory_index = 1;  f->file.spec[1] = '.';  update_directory_entry (f, 0);}/*-----------------------------------------------------------------------------This function contains the common code from rdcf_get_file_information() andrdcf_set_file_information().  It finds the directory entry specified by thespec and index, and puts its cluster and index into f->directory_cluster andf->directory_index.-----------------------------------------------------------------------------*/static void find_entry (struct rdcf *f, const char *spec, unsigned idx){  spec = initialize_fcb (f, spec);  if (*spec == 0) {    if (idx >=        (f->first_data_sector -         f->first_directory_sector) * ENTRIES_PER_SECTOR) {      error_exit (f, ~ENOSPC);    }    f->directory_first_cluster = f->directory_cluster = 0;  }  else {    if (!find_file (f, spec) || (f->file.attribute & RDCF_DIRECTORY) == 0)      error_exit (f, ~ENOENT);    f->directory_first_cluster = f->directory_cluster = f->file.first_cluster;    while (idx >= ENTRIES_PER_SECTOR * f->sectors_per_cluster) {      f->directory_cluster = FAT_entry (f, f->directory_cluster);      if (f->directory_cluster >= f->last_cluster_mark)        error_exit (f, ~ENOSPC);      idx -= ENTRIES_PER_SECTOR * f->sectors_per_cluster;    }  }  f->directory_index = idx;}#endif// vi:nowrap:

⌨️ 快捷键说明

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