Skip to content

Commit

Permalink
Bug 1806394 r=nalexander
Browse files Browse the repository at this point in the history
  • Loading branch information
bytesized committed Feb 16, 2023
1 parent 7d98300 commit 7182ee6
Show file tree
Hide file tree
Showing 6 changed files with 325 additions and 159 deletions.
63 changes: 60 additions & 3 deletions modules/libmar/src/mar.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ typedef struct SeenIndex_ {
* Mozilla ARchive (MAR) file data structure
*/
struct MarFile_ {
FILE* fp; /* file pointer to the archive */
unsigned char* buffer; /* file buffer containing the entire MAR */
size_t data_len; /* byte count of the data in the buffer */
MarItem* item_table[TABLESIZE]; /* hash table of files in the archive */
SeenIndex* index_list; /* file indexes processed */
int item_table_is_valid; /* header and index validation flag */
Expand All @@ -72,16 +73,29 @@ typedef struct MarFile_ MarFile;
*/
typedef int (*MarItemCallback)(MarFile* mar, const MarItem* item, void* data);

enum MarReadResult_ {
MAR_READ_SUCCESS,
MAR_IO_ERROR,
MAR_MEM_ERROR,
MAR_FILE_TOO_BIG_ERROR,
};

typedef enum MarReadResult_ MarReadResult;

/**
* Open a MAR file for reading.
* @param path Specifies the path to the MAR file to open. This path must
* be compatible with fopen.
* @param out_mar Out-parameter through which the created MarFile structure is
* returned. Guaranteed to be a valid structure if
* MAR_READ_SUCCESS is returned. Otherwise NULL will be
* assigned.
* @return NULL if an error occurs.
*/
MarFile* mar_open(const char* path);
MarReadResult mar_open(const char* path, MarFile** out_mar);

#ifdef XP_WIN
MarFile* mar_wopen(const wchar_t* path);
MarReadResult mar_wopen(const wchar_t* path, MarFile** out_mar);
#endif

/**
Expand All @@ -90,6 +104,49 @@ MarFile* mar_wopen(const wchar_t* path);
*/
void mar_close(MarFile* mar);

/**
* Reads the specified amount of data from the buffer in MarFile that contains
* the entirety of the MAR file data.
* @param mar The MAR file to read from.
* @param dest The buffer to read into.
* @param position The byte index to start reading from the MAR at.
* On success, position will be incremented by size.
* @param size The number of bytes to read.
* @return 0 If the specified amount of data was read.
* -1 If the buffer MAR is not large enough to read the
* specified amount of data at the specified position.
*/
int mar_read_buffer(MarFile* mar, void* dest, size_t* position, size_t size);

/**
* Reads the specified amount of data from the buffer in MarFile that contains
* the entirety of the MAR file data. If there isn't that much data remaining,
* reads as much as possible.
* @param mar The MAR file to read from.
* @param dest The buffer to read into.
* @param position The byte index to start reading from the MAR at.
* This function will increment position by the number of bytes
* copied.
* @param size The maximum number of bytes to read.
* @return The number of bytes copied into dest.
*/
int mar_read_buffer_max(MarFile* mar, void* dest, size_t* position,
size_t size);

/**
* Increments position by distance. Checks that the resulting position is still
* within the bounds of the buffer. Much like fseek, this will allow position to
* be successfully placed just after the end of the buffer.
* @param mar The MAR file to read from.
* @param position The byte index to start reading from the MAR at.
* On success, position will be incremented by size.
* @param distance The number of bytes to move forward by.
* @return 0 If position was successfully moved.
* -1 If moving position by distance would move it outside the
* bounds of the buffer.
*/
int mar_buffer_seek(MarFile* mar, size_t* position, size_t distance);

/**
* Find an item in the MAR file by name.
* @param mar The MarFile object to query.
Expand Down
4 changes: 2 additions & 2 deletions modules/libmar/src/mar_extract.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ int mar_extract(const char* path) {
MarFile* mar;
int rv;

mar = mar_open(path);
if (!mar) {
MarReadResult result = mar_open(path, &mar);
if (result != MAR_READ_SUCCESS) {
return -1;
}

Expand Down

0 comments on commit 7182ee6

Please sign in to comment.