File Browser

Recall that fopen returns a pointer to a FILE, which happens to be a struct. Within that struct are a number of fields that keep track of an opened fileā€™s state. The actual implementation is a bit complex! But consider the simplified definition of FILE below.

typedef struct
{
    bool read_only;      // True if file was opened only for reading (as with "r"), not writing
    char *first_byte;    // Pointer to the first byte of the file
    char *current_byte;  // Pointer to the current position in the file
    int size;            // Size of the file in bytes
}
FILE;

Assume that first_byte and current_byte point to memory that represents an opened file, in which case writing to those addresses, as via fwrite, will have the effect of updating the file on disk. And recall that files are read, as via fread, by default, from their first byte through their last. And, so, when a file is first opened, both first_byte and current_byte will point to that fileā€™s first byte. And each time a byte is read thereafter, current_byte will be incremented.

  1. (2 points.) It turns out thereā€™s a function called fgetpos that can tell you how many bytes away current_byte is from first_byte. For instance, if a file has been opened but no bytes have been read, fgetpos would return 0; if a file has been opened and one byte has been read, fgetpos would return 1. Complete the (simplified) implementation of fgetpos below, assuming the definition of FILE above.

     int fgetpos(FILE *stream)
     {
         // TODO
     }
    
  1. (4 points.) It turns out thereā€™s also a function called fsetpos that allows you to ā€œseekā€ (i.e., fast-forward or rewind) to any byte in a file, relative to its first byte. For instance, a call to fsetpos(file, 0), where file is pointer to a FILE, would have the effect of (re)setting current_byte to first_byte. Complete the (simplified) implementation of fsetpos below, assuming again the definition of FILE above. Your implementation should return false in cases of error, which we leave to you to identify; otherwise, it should return true.

     bool fsetpos(FILE *stream, int offset)
     {
         // TODO
     }
    
  1. (6 points.) Recall that fwrite is a function that writes data to a file if and only if that file has been opened for writing, as via "w". It turns out it also updates a FILE in the following ways:

    • The data stored in buffer is written to that file, starting at current_byte and continuing for size bytes.
    • When writing is complete, current_byte is updated to the byte immediately after the last byte written.
    • The size of the file, as stored in the struct, is adjusted as needed.

    Complete the (simplified) implementation of fwrite below, assuming again the definition of FILE above. Your implementation should return false in cases of error, which we leave to you to identify; otherwise, it should return true.

     typedef unsigned char BYTE;
     bool fwrite(BYTE *buffer, int size, FILE *stream)
     {
         // TODO
     }
    
  1. (2 points.) Recall that feof is a function that indicates whether a caller has read past the end of a file. Complete the (simplified) implementation of feof below, assuming again the definition of FILE above. Your implementation should return true if a caller has read past the end of a file; otherwise it should return false.

     bool feof(FILE *stream)
     {
         // TODO
     }