Advertisement
Guest User

Untitled

a guest
Jun 23rd, 2017
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.62 KB | None | 0 0
  1. #include <string>
  2. #include <vector>
  3. #include <stdio.h>
  4. using namespace std;
  5. struct fsHeader
  6. {
  7.     int numFiles;
  8. };
  9. struct fsEntry
  10. {
  11.     char fileName[512];
  12.     unsigned int filePtr;
  13. };
  14. struct fsFile
  15. {
  16.     char fileName[512];
  17.     char *data;
  18.     unsigned int size;
  19. };
  20.  
  21. class SimpleArchive
  22. {
  23. public:
  24.     SimpleArchive(string fileName, bool readFile)
  25.     {
  26.         this->fileName = fileName;
  27.        
  28.         if(readFile) readFromFile();
  29.     }
  30.  
  31.     void addFile(string fileName, char *data, int size)
  32.     {
  33.         fsFile file = {0};
  34.  
  35.         // Convert string to char[512] safely
  36.         strncpy(file.fileName, fileName.c_str(), 512);
  37.         file.fileName[512-1] = '\0';
  38.  
  39.         // Make a copy of data.
  40.         file.data = (char *)malloc(size);
  41.         memcpy(file.data, data, size);
  42.  
  43.         // Set the size.
  44.         file.size = size;
  45.  
  46.         files.push_back(file);
  47.     }
  48.  
  49.     bool removeFile(string fileName)
  50.     {
  51.         int fileID = getFileID(fileName);
  52.         if(fileID == -1) return false;
  53.        
  54.         files.erase(files.begin()+fileID);
  55.         return true;
  56.     }
  57.  
  58.     bool writeToFile()
  59.     {
  60.         int filePtr = 0;
  61.         fsHeader header;
  62.         header.numFiles = files.size();
  63.  
  64.         fsEntry *entries = (fsEntry *)malloc(sizeof(fsEntry) * header.numFiles);
  65.  
  66.         // Offset so filePtr is the first byte after the header and all entries.
  67.         filePtr += sizeof(fsHeader) + sizeof(fsEntry) * header.numFiles;
  68.  
  69.         // Calculate entries
  70.         for(int i=0; i<header.numFiles; ++i)
  71.         {
  72.             // Copy filename
  73.             memcpy(entries[i].fileName, files[i].fileName, 512);
  74.  
  75.             // Set fileptr, then adjust fileptr.
  76.             entries[i].filePtr = filePtr;
  77.             filePtr += files[i].size;
  78.         }
  79.        
  80.         // Open file
  81.         FILE *file = fopen(fileName.c_str(), "wb");
  82.         if(file == NULL) return false;
  83.  
  84.         // Write header+entries
  85.         fwrite(&header, sizeof(fsHeader), 1, file);
  86.         fwrite(entries, sizeof(fsEntry), header.numFiles, file);
  87.  
  88.         // Write files
  89.         for(int i=0; i<header.numFiles; ++i)
  90.         {
  91.             fwrite(files[i].data, files[i].size, 1, file);
  92.         }
  93.  
  94.         free(entries);
  95.  
  96.         return true;
  97.     }
  98.  
  99.     bool readFromFile()
  100.     {
  101.         int fileSize = -1;
  102.         FILE *file = fopen(fileName.c_str(), "rb"); // Read file as binary.
  103.  
  104.         if(file == NULL) return false;
  105.  
  106.         // Trick: Get filesize.
  107.         fseek(file, 0L, SEEK_END);
  108.         fileSize = ftell(file);
  109.         fseek(file, 0L, SEEK_SET);
  110.  
  111.         fsHeader header;
  112.         fread(&header, sizeof(fsHeader), 1, file);
  113.        
  114.         fsEntry *entries = (fsEntry *)malloc(sizeof(fsEntry) * header.numFiles);
  115.  
  116.         // Get all of the file entries.
  117.         for(int i=0; i<header.numFiles; ++i)
  118.         {
  119.             fread(&entries[i], sizeof(fsEntry), 1, file);
  120.         }
  121.  
  122.         // Get all of the actual files.
  123.         for(int i=0; i<header.numFiles-1; ++i)
  124.         {
  125.             int size = -1;
  126.             // Special case for last file: use container filesize to calculate filesize.
  127.             if(i != header.numFiles-1)
  128.             {
  129.                 // Calculate size.
  130.                 size = entries[i+1].filePtr - entries[i].filePtr;
  131.             }
  132.             else
  133.             {
  134.                 // Calculate size.
  135.                 size = fileSize - entries[header.numFiles-1].filePtr;
  136.             }
  137.  
  138.             // Allocate data.
  139.             char *data = (char *)malloc(size);
  140.            
  141.             // Read actual data.
  142.             fread(data, size, 1, file);
  143.  
  144.             // Create file entry for memory storage.
  145.             fsFile f = {0};
  146.             memcpy(f.fileName, entries[i].fileName, 512);
  147.             f.data = data;
  148.             f.size = size;
  149.            
  150.             // Push file.
  151.             files.push_back(f);
  152.         }
  153.        
  154.         fclose(file);
  155.  
  156.         free(entries);
  157.  
  158.         return true;
  159.     }
  160.  
  161.     fsFile *getFile(string fileName)
  162.     {
  163.         int fileID = getFileID(fileName);
  164.         if(fileID == -1) return NULL;
  165.        
  166.         return &files[fileID];
  167.     }
  168.  
  169. private:
  170.     int getFileID(string fileName)
  171.     {
  172.         for(int i=files.size()-1; i>=0; --i)
  173.         {
  174.             if(fileName == files[i].fileName)
  175.             {
  176.                 return i;
  177.             }
  178.         }
  179.         return -1;
  180.     }
  181.  
  182.     vector<fsFile> files;
  183.     string fileName;
  184. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement