Skip to content

Commit

Permalink
Various polishing (mostly with pack)
Browse files Browse the repository at this point in the history
* update documentation to note a confusion with get_file_offset vs. offset parameter in read_file
* add extensive test case for the basic functionality of pack
* fixed a bug in pack::add_memory discovered by the aformentioned test
* label the pack method arguments in Angelscript registration
* test runner now aborts when run from compiled, testts should be run from source for now
* update readme to include example paths for extracting windev, new contributor guideline about API changes
  • Loading branch information
samtupy committed Sep 13, 2024
1 parent c6dd16b commit bab0c9a
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ Get the offset of a file in your pack.

## Returns:
uint: the offset of the file (in bytes).

## Remarks:
Do not confuse this with the offset parameter in the pack::read_file method. This function is provided encase you wish to re-open the pack file with your own file object and seek to a file's data within that external object. The offset_in_file parameter in the read_file method is relative to the file being read.
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
# read_file
Get the contents of a file contained in a pack.

`string pack::read_file(string pack_filename, uint offset, uint size);`
`string pack::read_file(string pack_filename, uint offset_in_file, uint size);`

## Arguments:
* string pack_filename: the name of the file to be read.
* uint offset: the file's offset in the pack (see `pack::get_file_offset`).
* uint size: the size of the file (see `pack::get_file_size`).
* uint offset: the offset within the file to begin reading data from (do not confuse this with pack::get_file_offset)
* uint size: the number of bytes to read (see `pack::get_file_size` to read the entire file).

## Returns:
string: the contents of the file.

## Remarks:
This function allows you to read chunks of data from a file, as well as an entire file in one call. To facilitate this, the offset and size parameters are provided. offset is relative to the file being read E. 0 for the beginning of it. So to read a file in one chunk, you could execute:
```
string file_contents = my_pack.read_file("filename", 0, my_pack.get_file_size("filename"));
```
7 changes: 4 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ If you want to build all plugins, you will also need the curl and libgit2 librar
For Linux and MacOS, scripts with build commands are in build/build_Linux.sh and build/build_macos.sh.

For now only on windows, the option exists to make the process of dealing with dependencies much simpler than hunting them down manually and setting up include/library paths. For those who want them, I've decided to provide my own build artifacts. This is a bin/include/lib directory structure that contains organized header files, link libraries (static when possible), and dlls for distribution like bass and phonon which makes building nvgt as simple as pointing to this directory structure and running the build command. This download contains more than the libraries specifically required to build NVGT as A, it includes the libraries required to build plugins and B, it may include libraries that I use in other projects. If it gets giant, I'll provide a download just containing nvgt libraries. For now, you can
[download windev.zip here](https://nvgt.gg/windev.zip) and place an extracted version of it in the root of the nvgt repository, that is a folder called windev containing bin, include, lib, misc should exist in the root of the nvgt repo.
[download windev.zip here](https://nvgt.gg/windev.zip) and place an extracted version of it in the root of the nvgt repository, that is a folder called windev containing bin, include, lib, misc should exist in the root of the nvgt repo, as in nvgt/windev/bin, nvgt/windev/include etc.

Though unlike the windev.zip file these only contain binaries for the bass and steam audio versions we are using at present, you can also [download macosdev.tar.gz](https://nvgt.gg/macosdev.tar.gz) for MacOS or [download lindev.tar.gz](https://nvgt.gg/lindev.tar.gz) for Linux to ease at least some of the dependency hunt.

Expand Down Expand Up @@ -80,7 +80,8 @@ Pull requests are also very welcome and are generally the quickest path to getti
3. Though it is not absolutely required, it is usually a good idea to open a discussion or issue before a pull request that introduces any kind of very significant change is created. This should absolutely be done before any sort of dependency addition or change. Pull requests that do not adhere to this may be delayed or denied.
4. Please check the blog and the todo list before opening a pull request, encase we have noted a certain way we wish to do something that your pull request might go against.
5. If you modify the c++ code, please try making sure it builds on as many platforms that we support as you have access to. For example you can build NVGT on Linux using wsl on windows. You only need to worry about this within reason, but any work you can do here is seriously appreciated.
6. If you contribute to the documentation, please try to run the docgen.py script and make sure your changes basically compile, and then open the html version of the compiled documentation and make sure it looks OK before committing. Please follow the existing documentation source structure to the best of your ability when writing topics.
7. Understand that any contributions to the project are to be put under the same license that NVGT is released under, which is zlib. It is OK to add a credit to yourself for large portions of source code you contribute, but the general copyright notice is to remain the same.
6. Regardless of whether you modify c++ code or nvgt includes, please be very careful that you do not change the existing API in any waythat would cause existing nvgt code to stop running without a discussion first. Even if a discussion aproves such compatibility breaking changes, they are to be clearly documented.
7. If you contribute to the documentation, please try to run the docgen.py script and make sure your changes basically compile, and then open the html version of the compiled documentation and make sure it looks OK before committing. Please follow the existing documentation source structure to the best of your ability when writing topics.
8. Understand that any contributions to the project are to be put under the same license that NVGT is released under, which is zlib. It is OK to add a credit to yourself for large portions of source code you contribute, but the general copyright notice is to remain the same.

Please note that these guidelines may be updated at any time. Thanks for your interest in contributing!
32 changes: 16 additions & 16 deletions src/pack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ bool pack::add_memory(const string& pack_filename, unsigned char* data, unsigned
for (uint64_t p = 0; p < size; p += bufsize) {
if (p + bufsize >= size) bufsize = size - p;
for (unsigned int j = 0; j < bufsize; j++)
tmp[j] = pack_char_encrypt(data[(p * bufsize) + j], (p * bufsize) + j, i.namelen);
tmp[j] = pack_char_encrypt(data[p + j], p + j, i.namelen);
if (fwrite(tmp, 1, bufsize, fptr) != bufsize) {
fseek(fptr, cur_pos, SEEK_SET);
return false;
Expand Down Expand Up @@ -633,22 +633,22 @@ void RegisterScriptPack(asIScriptEngine* engine) {
engine->RegisterObjectMethod(_O("pack"), _O("bool set_pack_identifier(const string&in)"), asMETHOD(pack, set_pack_identifier), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool open(const string &in, uint = PACK_OPEN_MODE_READ, bool = false)"), asMETHOD(pack, open), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool close()"), asMETHOD(pack, close), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool add_file(const string &in, const string& in, bool = false)"), asMETHOD(pack, add_file), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool add_memory(const string &in, const string& in, bool = false)"), asMETHODPR(pack, add_memory, (const string&, const string&, bool), bool), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool delete_file(const string &in)"), asMETHOD(pack, delete_file), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool file_exists(const string &in) const"), asMETHOD(pack, file_exists), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("string get_file_name(int) const"), asMETHODPR(pack, get_file_name, (int), string), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool add_file(const string &in disc_filename, const string& in pack_filename, bool allow_replace = false)"), asMETHOD(pack, add_file), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool add_memory(const string &in pack_filename, const string& in data, bool allow_replace = false)"), asMETHODPR(pack, add_memory, (const string&, const string&, bool), bool), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool delete_file(const string &in pack_filename)"), asMETHOD(pack, delete_file), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool file_exists(const string &in pack_filename) const"), asMETHOD(pack, file_exists), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("string get_file_name(int index) const"), asMETHODPR(pack, get_file_name, (int), string), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("string[]@ list_files() const"), asMETHODPR(pack, list_files, (), CScriptArray*), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("uint get_file_size(const string &in) const"), asMETHOD(pack, get_file_size), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("uint get_file_offset(const string &in) const"), asMETHOD(pack, get_file_offset), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("string read_file(const string &in, uint, uint) const"), asMETHOD(pack, read_file_string), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool raw_seek(int)"), asMETHOD(pack, raw_seek), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool stream_close(uint)"), asMETHOD(pack, stream_close_script), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("uint stream_open(const string &in, uint) const"), asMETHOD(pack, stream_open_script), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("string stream_read(uint, uint) const"), asMETHOD(pack, stream_read), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("uint stream_pos(uint) const"), asMETHOD(pack, stream_pos_script), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("uint stream_seek(uint, uint, int) const"), asMETHOD(pack, stream_seek_script), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("uint stream_size(uint) const"), asMETHOD(pack, stream_size_script), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("uint get_file_size(const string &in pack_filename) const"), asMETHOD(pack, get_file_size), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("uint get_file_offset(const string &in pack_filename) const"), asMETHOD(pack, get_file_offset), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("string read_file(const string &in pack_filename, uint offset_in_file, uint read_byte_count) const"), asMETHOD(pack, read_file_string), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool raw_seek(int offset)"), asMETHOD(pack, raw_seek), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool stream_close(uint index)"), asMETHOD(pack, stream_close_script), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("uint stream_open(const string &in pack_filename, uint offset_in_file) const"), asMETHOD(pack, stream_open_script), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("string stream_read(uint index, uint read_byte_count) const"), asMETHOD(pack, stream_read), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("uint stream_pos(uint index) const"), asMETHOD(pack, stream_pos_script), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("uint stream_seek(uint index, uint offset, int origin) const"), asMETHOD(pack, stream_seek_script), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("uint stream_size(uint index) const"), asMETHOD(pack, stream_size_script), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("bool get_active() const property"), asMETHOD(pack, is_active), asCALL_THISCALL);
engine->RegisterObjectMethod(_O("pack"), _O("uint get_size() const property"), asMETHOD(pack, size), asCALL_THISCALL);
}
38 changes: 38 additions & 0 deletions test/case/pack.nvgt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "file_contents.nvgt"

void test_pack() {
put_file_contents("tmp/pack.dat", "test overwrite: lets start with bogus data");
dictionary cases;
pack p;
assert(p.open("tmp/pack.dat", PACK_OPEN_MODE_CREATE));
string[]@ case_list = find_files("case/*.nvgt");
for (uint i = 0; i < case_list.length(); i++) {
string case_data = get_file_contents("case/" + case_list[i]);
if (case_data.empty()) {
case_list.remove_at(i);
i--;
continue;
}
assert(p.add_file("case/" + case_list[i], case_list[i]));
assert(!case_data.empty());
assert(p.add_memory("mem/" + case_list[i], case_data));
cases.set(case_list[i], case_data);
}
p.close();
assert(p.open("tmp/pack.dat", PACK_OPEN_MODE_READ));
assert(p.size == cases.get_size() * 2);
@case_list = p.list_files();
assert(case_list.length() == p.size);
for (uint i = 0; i < case_list.length(); i++) {
int size = p.get_file_size(case_list[i]);
string pack_content = p.read_file(case_list[i], 0, size);
string case_name = case_list[i];
if (case_name.starts_with("mem/")) case_name.erase(0, 4);
string disc_content;
assert(cases.get(case_name, disc_content));
assert(!disc_content.empty() and !pack_content.empty());
assert(disc_content == pack_content);
}
p.close();
file_delete("tmp/pack.dat");
}
4 changes: 4 additions & 0 deletions test/tests.nvgt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ void help() {
exit();
}
void main() {
if (SCRIPT_COMPILED) {
println("sorry, currently tests must be run from source");
exit(64);
}
timer timetracker;
// Very oversimplified command line parsing.
for (uint i = 1; i < ARGS.length(); i++) {
Expand Down

0 comments on commit bab0c9a

Please sign in to comment.