Code: Alles auswählen
#GRF_REPACK_FAST = 1
#GRF_REPACK_DECRYPT = 2
#GRF_REPACK_RECOMPRESS = 3
#GRF_FLAG_FILE = 1
#GRF_FLAG_MIXCRYPT = 2
#GRF_FLAG_DES = 4
#GRF_FLAG_DELETE = 8
#GRF_REPACK_FAST = 1
#GRF_REPACK_DECRYPT = 2
#GRF_REPACK_RECOMPRESS = 3
Prototype.l PB_grf_version(void.l)
Prototype.l PB_grf_versionstring(void.l)
Prototype.l PB_grf_versionstring_r(char.s, size.l)
Prototype.l PB_grf_new(char.s, flag.l)
Prototype.l PB_grf_new_by_fd(int.l, flag.l)
Prototype.l PB_grf_load(char.s, flag.l)
Prototype.l PB_grf_load_from_new(grf_handle.l)
Prototype.l PB_grf_save(grf_handle.l)
Prototype.l PB_grf_free(grf_handle.l)
Prototype.l PB_grf_set_callback(grf_handle.l, callback.l, callback_param.l)
Prototype.l PB_grf_set_compression_level(grf_handle.l, level.l)
Prototype.l PB_grf_filecount(grf_handle.l)
Prototype.l PB_grf_wasted_space(grf_handle.l)
Prototype.l PB_grf_file_add(grf_handle.l, file.s, buffer.l, size.l)
Prototype.l PB_grf_file_add_fd(grf_handle.l, file.s, fd.l)
Prototype.l PB_grf_file_add_path(grf_handle.l, name.s, file.s)
Prototype.l PB_grf_get_file(grf_handle.l, file.s)
Prototype.l PB_grf_file_get_filename(grf_node.l)
Prototype.l PB_grf_file_get_basename(grf_node.l)
Prototype.l PB_grf_file_get_size(grf_node.l)
Prototype.l PB_grf_file_get_storage_pos(grf_node.l)
Prototype.l PB_grf_file_get_storage_size(grf_node.l)
Prototype.l PB_grf_file_get_storage_flags(grf_node.l)
Prototype.l PB_grf_file_get_contents(grf_node.l, void.l)
Prototype.l PB_grf_file_put_contents_to_fd(grf_node.l, int.l)
Prototype.l PB_grf_put_contents_to_file(grf_node.l, file.s)
Prototype.l PB_grf_file_rename(grf_node.l, file.s)
Prototype.l PB_grf_file_delete(grf_node.l)
Prototype.l PB_grf_create_tree(grf_handle.l)
Prototype.l PB_grf_tree_get_root(grf_handle.l)
Prototype.l PB_grf_tree_list_node(grf_treenode.l)
Prototype.l PB_grf_tree_is_dir(grf_treenode.l)
Prototype.l PB_grf_tree_get_name(grf_treenode.l)
Prototype.l PB_grf_tree_get_file(grf_treenode.l)
Prototype.l PB_grf_tree_get_parent(grf_treenode.l)
Prototype.l PB_grf_file_get_tree(grf_node.l)
Prototype.l PB_grf_tree_dir_count_files(grf_treenode.l)
Prototype.l PB_grf_get_file_list(grf_handle.l)
Prototype.l PB_grf_get_file_first(grf_handle.l)
Prototype.l PB_grf_get_file_next(grf_node.l)
Prototype.l PB_grf_get_file_prev(grf_node.l)
Prototype.l PB_grf_get_file_id_list(grf_handle.l)
Prototype.l PB_grf_update_id_list(grf_handle.l)
Prototype.l PB_grf_file_get_id(grf_node.l)
Prototype.l PB_grf_get_file_by_id(grf_handle.l, uint32.l)
Prototype.l PB_grf_repack(grf_handle.l, flag.l)
Prototype.l PB_grf_merge(grf_handle1.l, grf_handle2.l, flag.l)
Prototype.l PB_euc_kr_to_utf8(string.s)
Prototype.l PB_euc_kr_to_utf8_r(string.s, flag.l)
Prototype.l PB_utf8_to_euc_kr(string.s)
Prototype.l PB_utf8_to_euc_kr_r(string.s, flag.l)
GRFLibrary.l = OpenLibrary(#PB_Any, "grf.dll")
If GRFLibrary
;{ BASE FUNCTIONS
;* (int) grf_version()
;* Returns the current GRF version As an integer.
;* You can get major/minor/revision values With the following math:
;* major = (version >> 16) & 0xff
;* minor = (version >> 8) & 0xff
;* revision = version & 0xff
Global grf_version.PB_grf_version = GetFunction(GRFLibrary, "grf_version")
;* (char *) grf_versionstring()
;* (char *) grf_versionstring_r(char *buffer, size_t len)
;* Returns the version As a string, which includes a linebreak (For the version
;* of zlib)
;* You can use the reentrant version of this function For thread-safe usage.
Global grf_versionstring.PB_grf_versionstring = GetFunction(GRFLibrary, "grf_versionstring")
Global grf_versionstring_r.PB_grf_versionstring_r = GetFunction(GRFLibrary, "grf_versionstring_r")
;* (grf_handle) grf_new(const char *filename, bool allow_write)
;* (grf_handle) grf_new_by_fd(int fd, bool allow_write)
;* Creates a new GRF file called filename. You will usually want To set
;* allow_write To true, As creating a new grf For Read-only use isn't really
;* useful, however no write happens Until you call grf_save(), so you can
;* use grf_new(), assign a callback, then call grf_load_from_new() To have
;* a callback While the loading happens.
;* grf_new_by_fd() is useful on windows For example, As grf_new() does Not
;* support unicode names, you can open the file yourself, then pass it To
;* grf_new_by_fd().
Global grf_new.PB_grf_new = GetFunction(GRFLibrary, "grf_new")
Global grf_new_by_fd.PB_grf_new_by_fd = GetFunction(GRFLibrary, "grf_new_by_fd")
;* (grf_handle) grf_load(const char filename, bool allow_write)
;* Well ... This just loads file filename, And returns a handle To the GRF.
Global grf_load.PB_grf_load = GetFunction(GRFLibrary, "grf_load")
;* (grf_handle) grf_load_from_new(grf_handle handle)
;* Loads GRF Data from an handle returned by grf_new() Or grf_new_by_fd()
;* If a problem happens, the grf is free()d And the function returns NULL.
Global grf_load_from_new.PB_grf_load_from_new = GetFunction(GRFLibrary, "grf_load_from_new")
;* (bool) grf_save(grf_handle handle)
;* Write the grf's files table to disk.
Global grf_save.PB_grf_save = GetFunction(GRFLibrary, "grf_save")
;* grf_free(grf_handle handle)
;* Free a GRF file And all the memory used by it, And closes the grf's fd.
;* If any change was made To the grf, grf_free() will call grf_save() just
;* before freeing everything. If grf_save() fails, the failure is ignored
;* And the ressources freeing happens anyway. If you need To check For result
;* of save, call grf_save() before grf_free().
Global grf_free.PB_grf_free = GetFunction(GRFLibrary, "grf_free")
;* grf_set_callback(grf_handle handle, callback, callback_param)
;* Callback: bool callback(void *param, grf_handle handle, int position,
;* int max, const char *filename)
;* Defines a callback function For all the long operations. This includes
;* loading, repack, merge, etc...
Global grf_set_callback.PB_grf_set_callback = GetFunction(GRFLibrary, "grf_set_callback")
;* grf_set_compression_level(grf_handle handle, int level)
;* Sets the compression level used on this GRF file. This affects newly added
;* files, repack/merge when using GRF_REPACK_RECOMPRESS mode, And files table.
;* The level is directly passed To zlib, And should be between 0 (no
;* compression) And 9.
Global grf_set_compression_level.PB_grf_set_compression_level = GetFunction(GRFLibrary, "grf_set_compression_level")
;* (unsigned int) grf_filecount(grf_handle handle)
;* Returns the number of files currently in the GRF. Directory entries are
;* excluded from this count.
Global grf_filecount.PB_grf_filecount = GetFunction(GRFLibrary, "grf_filecount")
;* (unsigned int) grf_wasted_space(void *handle)
;* Returns the amount of Data (in bytes) that would be theorically saved If the
;* file gets repacked.
;* A good application would be To check this value each time the patch client is
;* run, And ask the user about repacking If the value is over 20MB.
Global grf_wasted_space.PB_grf_wasted_space = GetFunction(GRFLibrary, "grf_wasted_space")
;}
;{ FILES FUNCTIONS
;* (grf_node) grf_file_add(grf_handle, const char *name, void *buffer, size_t size)
;* (grf_node) grf_file_add_fd(grf_handle, const char *name, int fd)
;* (grf_node) grf_file_add_path(grf_handle, const char *name, const char *file)
;* Add a file To the specified GRF file (opened For writing) And Return the
;* pointer To the created file.
Global grf_file_add.PB_grf_file_add = GetFunction(GRFLibrary, "grf_file_add")
Global grf_file_add_fd.PB_grf_file_add_fd = GetFunction(GRFLibrary, "grf_file_add_fd")
Global grf_file_add_path.PB_grf_file_add_path = GetFunction(GRFLibrary, "grf_file_add_path")
;* (grf_node) grf_get_file(grf_handle handle, const char *filename)
;* Returns a node handle To the specified file inside the GRF file. If the
;* function fails, NULL is returned.
Global grf_get_file.PB_grf_get_file = GetFunction(GRFLibrary, "grf_get_file")
;* (const char *) grf_file_get_filename(grf_node)
;* Returns the full filename of a file.
Global grf_file_get_filename.PB_grf_file_get_filename = GetFunction(GRFLibrary, "grf_file_get_filename")
;* (const char *) grf_file_get_basename(grf_node)
;* Returns only the filename (no path info)
Global grf_file_get_basename.PB_grf_file_get_basename = GetFunction(GRFLibrary, "grf_file_get_basename")
;* (unsigned int) grf_file_get_size(grf_node)
;* Returns the (real) size of the file.
Global grf_file_get_size.PB_grf_file_get_size = GetFunction(GRFLibrary, "grf_file_get_size")
;* (unsigned int) grf_file_get_storage_pos(grf_node)
;* Returns the position of the file in the archive.
Global grf_file_get_storage_pos.PB_grf_file_get_storage_pos = GetFunction(GRFLibrary, "grf_file_get_storage_pos")
;* (unsigned int) grf_file_get_storage_size(grf_node)
;* Returns the real (compressed) size of the file.
Global grf_file_get_storage_size.PB_grf_file_get_storage_size = GetFunction(GRFLibrary, "grf_file_get_storage_size")
;* (unsigned int) grf_file_get_storage_flags(grf_node)
;* Test If the first bit is set To know If a node is a file, Or Not.
Global grf_file_get_storage_flags.PB_grf_file_get_storage_flags = GetFunction(GRFLibrary, "grf_file_get_storage_flags")
;* (unsigned int) grf_file_get_contents(grf_node, void *ptr)
;* Extracts the file To the provided pointer And returns the number of bytes
;* successfully extracted. The system assumes that you pre-allocated enough
;* memory in ptr by calling grf_file_get_size().
Global grf_file_get_contents.PB_grf_file_get_contents = GetFunction(GRFLibrary, "grf_file_get_contents")
;* (unsigned int) grf_file_put_contents_to_fd(grf_node, int)
;* Extracts a file To the specified file descriptor. This can be a socket Or
;* a regular file, no seeks are used.
Global grf_file_put_contents_to_fd.PB_grf_file_put_contents_to_fd = GetFunction(GRFLibrary, "grf_file_put_contents_to_fd")
;* (bool) grf_put_contents_to_file(grf_node, const char *filename)
;* Write the contents of the compressed file To the filesystem.
Global grf_put_contents_to_file.PB_grf_put_contents_to_file = GetFunction(GRFLibrary, "grf_put_contents_to_file")
;* (bool) grf_file_rename(grf_node, const char *new_name)
;* Rename the given file To new_name. NB: You must provide a FULL filename,
;* including the full path of the file, eg: Data\some_file.txt
;* Renaming To an already existing file will delete it. Renaming To a
;* directory name will give unexpected results.
Global grf_file_rename.PB_grf_file_rename = GetFunction(GRFLibrary, "grf_file_rename")
;* (bool) grf_file_delete(grf_node)
;* Removes a file from the GRF.
;* NB: This will Not immediatly reduce the size of the resulting GRF file,
;* you will have To repack the GRF To see a reduction in its size. However If
;* you add a file which is exactly the same size As the deleted file, no repack
;* will be needed.
Global grf_file_delete.PB_grf_file_delete = GetFunction(GRFLibrary, "grf_file_delete")
;}
;{ TREE FUNCTIONS
;* Trees are a good way To display the content of a GRF file in a hierarchized
;* way. Basically, GRF files just contain a list of file, And each file has
;* its full path information attached To it. Using grf_create_tree(), you can
;* ask libgrf To build a Global directories/files-based tree For the GRF,
;* allowing things such As listing the content of a directory directly,
;* without having To parse the whole files list yourself.
;* grf_create_tree(grf_handle)
;* Create a tree For the specified GRF file.
Global grf_create_tree.PB_grf_create_tree = GetFunction(GRFLibrary, "grf_create_tree")
;* (grf_treenode) grf_tree_get_root(grf_handle)
;* Returns the root node of the tree.
Global grf_tree_get_root.PB_grf_tree_get_root = GetFunction(GRFLibrary, "grf_tree_get_root")
;* (grf_treenode *)grf_tree_list_node(grf_treenode)
;* Returns the list of files/directories found in a specific node.
;* NB: You will have To free() this result after use.
Global grf_tree_list_node.PB_grf_tree_list_node = GetFunction(GRFLibrary, "grf_tree_list_node")
;* (bool) grf_tree_is_dir(grf_treenode)
;* Return true If this node is a tree. Return false If it's a regular file.
;* There's no other possible type for a node.
Global grf_tree_is_dir.PB_grf_tree_is_dir = GetFunction(GRFLibrary, "grf_tree_is_dir")
;* (const char *) grf_tree_get_name(grf_treenode)
;* Returns the name of a node (no path info will be added)
Global grf_tree_get_name.PB_grf_tree_get_name = GetFunction(GRFLibrary, "grf_tree_get_name")
;* (grf_node) grf_tree_get_file(grf_treenode)
;* Return the node of the file attached To the current treenode. Will Return
;* NULL For directories. (but do Not rely on that, you have a function named
;* grf_tree_is_dir() To determine If a node is a dir, Or Not)
Global grf_tree_get_file.PB_grf_tree_get_file = GetFunction(GRFLibrary, "grf_tree_get_file")
;* (grf_treenode) grf_tree_get_parent(grf_treenode)
;* Returns the parent node, Or NULL If you call that on the root node.
Global grf_tree_get_parent.PB_grf_tree_get_parent = GetFunction(GRFLibrary, "grf_tree_get_parent")
;* (grf_treenode) grf_file_get_tree(grf_node)
;* Returns the grf_treenode entry corresponding To a file. Will Return NULL
;* If the treenode wasn't created previously.
Global grf_file_get_tree.PB_grf_file_get_tree = GetFunction(GRFLibrary, "grf_file_get_tree")
;* (unsigned int) grf_tree_dir_count_files(grf_treenode)
;* Returns the number of files contained in a treenode dir.
Global grf_tree_dir_count_files.PB_grf_tree_dir_count_files = GetFunction(GRFLibrary, "grf_tree_dir_count_files")
;}
;{ FILE LISTING FUNCTIONS
;* (grf_node*) grf_get_file_list(grf_handle)
;* Returns all the nodes contained in the GRF files. The order is totally
;* random And files may be inserted anyway in this list, so don't rely too
;* much on that, 'kay?
;* NB: Remember To free() it after use too, m'kay?
;*
;* DEPRECATED: Please use grf_get_file_id_list() instead. This is the same
;* As grf_get_file_list(), but you don't have to free the list after, and
;* it's less cpu-intensive (just return a pointer instead of building a list).
Global grf_get_file_list.PB_grf_get_file_list = GetFunction(GRFLibrary, "grf_get_file_list")
;* (grf_node) grf_get_file_first(grf_handle)
;* Returns the first file's node pointer in the GRF, or NULL if no file were
;* found.
Global grf_get_file_first.PB_grf_get_file_first = GetFunction(GRFLibrary, "grf_get_file_first")
;* (grf_node) grf_get_file_next(grf_node)
;* Returns Next file, Or NULL If file was last file.
Global grf_get_file_next.PB_grf_get_file_next = GetFunction(GRFLibrary, "grf_get_file_next")
;* (grf_node) grf_get_file_prev(grf_node)
;* Returns previous file, Or NULL If file is already the first one.
Global grf_get_file_prev.PB_grf_get_file_prev = GetFunction(GRFLibrary, "grf_get_file_prev")
;}
;{ FILE ID FUNCTIONS
;* (grf_node*) grf_get_file_id_list(grf_handle)
;* Returns the Global list of files. The order may change each time you call
;* grf_update_id_list().
Global grf_get_file_id_list.PB_grf_get_file_id_list = GetFunction(GRFLibrary, "grf_get_file_id_list")
;* grf_update_id_list(grf_handle)
;* Recompute the ID list (needed after add/remove)
Global grf_update_id_list.PB_grf_update_id_list = GetFunction(GRFLibrary, "grf_update_id_list")
;* (unsigned int) grf_file_get_id(grf_node)
;* Returns ID (index position in the list) of a file.
Global grf_file_get_id.PB_grf_file_get_id = GetFunction(GRFLibrary, "grf_file_get_id")
;* (grf_node) grf_get_file_by_id(grf_handle, unsigned int id)
;* Returns the file corresponding To the given ID.
Global grf_get_file_by_id.PB_grf_get_file_by_id = GetFunction(GRFLibrary, "grf_get_file_by_id")
;}
;{ GRF MASS OPERATIONS
;* (bool) grf_repack(grf_handle, char options)
;* Repack given GRF file, To save wasted_bytes And maybe more (If using the
;* recompress option).
;* Valid options :
;* - GRF_REPACK_FAST (just move files)
;* - GRF_REPACK_DECRYPT (move files, And decrypt files If any was found
;* encrypted)
;* - GRF_REPACK_RECOMPRESS (recompress all files, And replace If newly
;* compressed file is smaller than the one previously stored)
Global grf_repack.PB_grf_repack = GetFunction(GRFLibrary, "grf_repack")
;* (bool) grf_merge(grf_handle dest, grf_handle src, char options)
;* Copy files from "src" grf_handle (can be opened Read-only) To "dest"
;* grf_handle (must be opened Read/write). Takes the same options As
;* grf_repack With one exception : GRF_REPACK_RECOMPRESS will recompress all
;* files, even If the new one is larger than the Not-recompressed one.
Global grf_merge.PB_grf_merge = GetFunction(GRFLibrary, "grf_merge")
;}
;{ CHARSET FUNCTIONS
;* (char *) euc_kr_to_utf8(const char *text)
;* (char *) euc_kr_to_utf8_r(const char *text, unsigned char *ptr)
;* "Translates" EUC-KR text As encoded in GRF files To UTF-8. Available also
;* in reentrant version.
Global euc_kr_to_utf8.PB_euc_kr_to_utf8 = GetFunction(GRFLibrary, "euc_kr_to_utf8")
Global euc_kr_to_utf8_r.PB_euc_kr_to_utf8_r = GetFunction(GRFLibrary, "euc_kr_to_utf8_r")
;* (char *) utf8_to_euc_kr(const char *text)
;* (char *) utf8_to_euc_kr_r(const char *text, unsigned char *ptr)
;* "Translates" UTF-8 text To EUC-KR As used To encode filenames in GRF files
;* Of course you need To input KOREAN/ASCII text Or it'll return NULL.
Global utf8_to_euc_kr.PB_utf8_to_euc_kr = GetFunction(GRFLibrary, "utf8_to_euc_kr")
Global utf8_to_euc_kr_r.PB_utf8_to_euc_kr_r = GetFunction(GRFLibrary, "utf8_to_euc_kr_r")
;}
Else
MessageRequester("Grf Wrapper","Unable to open Grf Library")
EndIf
Code: Alles auswählen
IncludeFile "grf.pbi"
Debug "Grf.dll Version:"
Debug PeekS(grf_versionstring(0))
Debug "----------------------------------------------------"
grf.l = grf_new("test.grf", #GRF_FLAG_FILE)
grf_set_compression_level(grf,9)
Debug "GRF File ID = "+Str(grf)
Debug "Und das compression level ist 9"
Debug "----------------------------------------------------"
Debug "Create File in der GRF Datei mit dem Inhalt Test"
string.s = "Test"
grf_file_add(grf, "Test.txt", @string, Len(string))
Debug "----------------------------------------------------"
Debug "Grf File Schliessen"
grf_free(grf)
grf = 0
Debug "----------------------------------------------------"
grf = grf_load("test.grf", #GRF_FLAG_FILE)
Debug "GRF File ID = "+Str(grf)
Debug "----------------------------------------------------"
pos.l = grf_get_file(grf, "Test.txt")
Debug "Finde Test.txt in der Grf Datei"
Debug "Test.txt ist an Position = "+Str(pos)
Debug "----------------------------------------------------"
size.l = grf_file_get_size(pos)
Debug "Die Test.txt Datei ist = "+Str(size)+" Bytes groß"
Debug "----------------------------------------------------"
string = Space(size)
grf_file_get_contents(pos, @string)
Debug "Inhalt der Test.txt ist = "+string
Debug "----------------------------------------------------"
Debug "Grf File Schliessen"
grf_free(grf)
End
Sie ist beim GrfBuilder (Ist ein Grf Ent\Packer) und libgrf (beispiele für die grf.dll) bei.
Für Linux giebts auch eine Version.
Ich benutzte ihn als Packer für mein Project.
Vergleichs Beispiel:
Code: Alles auswählen
IncludeFile "grf.pbi"
file.s = OpenFileRequester("Choose a file to compress", "", "*.*", 0)
ReadFile(0, file)
FileLength = Lof(0)
*Source = AllocateMemory(FileLength)
*Target = AllocateMemory(FileLength+8)
ReadData(0, *Source, FileLength)
CloseFile(0)
CompressedLength = PackMemory(*Source, *Target, FileLength,9)
CreateFile(0,"test.pack")
WriteData(0, *Target, CompressedLength)
CloseFile(0)
grf.l = grf_new("test1.grf", #GRF_FLAG_FILE)
grf_set_compression_level(grf,9)
grf_file_add(grf, GetFilePart(file), *Source, FileLength)
grf_free(grf)
grf.l = grf_new("test2.grf", #GRF_FLAG_FILE)
grf_set_compression_level(grf,9)
grf_file_add(grf, GetFilePart(file), *Target, CompressedLength)
grf_free(grf)
FreeMemory(*Source)
FreeMemory(*Target)
Message.s = Str(FileSize(file)) + " Orginal Größe"
Message+ #LF$+Str(FileSize("test.pack")) + " PureBasic Packer"
Message+ #LF$+Str(FileSize("test1.grf")) + " GRF Packer"
Message+ #LF$+Str(FileSize("test2.grf")) + " PureBasic Packer nochmal mit GRF Gepackt"
MessageRequester("Info", Message)
DeleteFile("test.pack")
DeleteFile("test1.grf")
DeleteFile("test2.grf")
End