CascLib

repository·master·Indexed 19 days ago

https://github.com/ladislav-zezula/casclib

An open-source C++ library designed for reading Blizzard's CASC (Content Addressable Storage Container) storage formats. It provides tools for interacting with CASC-based data files, including classes for parsing CSV data (CASC_CSV), navigating file trees (CASC_FILE_TREE), parsing MIME data (CASC_MIME), and managing network connections via sockets.

Tokens
4.6K
Snippets
20
Records
21
Agent score
67%

What's inside CascLib

  1. Use CascLib as a DLL on Windows

    master

    To use CascLib as a Dynamic Link Library (DLL) in a Windows project:

    1. Clone the repository: git clone https://github.com/ladislav-zezula/CascLib.git.
    2. Open the appropriate solution file in Visual Studio.
    3. Perform a Build / Batch Build and select all CascLib_dll Release configurations. The resulting .dll and .lib files are located in:
      • .\bin\CascLib_dll\Win32\Release (32-bit)
      • .\bin\CascLib_dll\x64\Release (64-bit)
    4. Include CascLib.h in your project, add the corresponding CascLib.lib to your project settings, and build.
    git clone https://github.com/ladislav-zezula/CascLib.git
  2. Install CascLib as a shared library on Debian/Ubuntu

    master

    To install CascLib as a shared library on Debian or Ubuntu systems, build the Debian packages and then install them using dpkg.

    dpkg-buildpackage -us -uc
    cd ..
    sudo dpkg -i libcasc1_3.2_amd64.deb libcasc-dev_3.2_amd64.deb
  3. Use CascLib as a static library on Windows

    master

    To use CascLib as a static library in a Windows project using Visual Studio:

    1. Clone the repository: git clone https://github.com/ladislav-zezula/CascLib.git.
    2. Open the appropriate solution file (CascLib_vs17.sln for VS 2017, CascLib_vs15.sln for VS 2015, or CascLib_vs08.sln for VS 2008).
    3. Perform a Build / Batch Build for all CascLib configurations. The resulting .lib files are located in .\bin\CascLib\Win32 and .\bin\CascLib\x64.
    4. Organize the .lib files into architecture-specific directories (e.g., lib32 and lib64).
    5. Include CascLib.h in your project. This header automatically selects the correct .lib file based on your project settings.
    6. Build your project.
    git clone https://github.com/ladislav-zezula/CascLib.git
  4. Configure CASC_FILE_TREE extra data flags

    master

    When calling CASC_FILE_TREE::Create, you can specify flags to determine if the CASC_FILE_NODE structure should allocate space for extra metadata in its ExtraValues array. If these flags are not set during creation, attempting to use GetExtras or SetExtras for these fields may not work as expected.

    Tree Creation Flags

    • FTREE_FLAG_USE_DATA_ID: Enables storage of the FileDataId in the node.
    • FTREE_FLAG_USE_LOCALE_FLAGS: Enables storage of file locale flags in the node.
    • FTREE_FLAG_USE_CONTENT_FLAGS: Enables storage of content flags in the node.
    #define FTREE_FLAG_USE_DATA_ID        0x0001
    #define FTREE_FLAG_USE_LOCALE_FLAGS   0x0002
    #define FTREE_FLAG_USE_CONTENT_FLAGS  0x0004
    
    // Usage:
    // pTree->Create(FTREE_FLAG_USE_DATA_ID | FTREE_FLAG_USE_LOCALE_FLAGS);
  5. Reference: Windows Static Library Build Configurations

    master

    When building CascLib as a static library in Visual Studio, the following build configurations are available. Use the one that matches your project's character set (Ansi vs Unicode) and C Runtime (CRT) requirements (Dynamic vs Static).

    DebugAD\CascLibDAD.lib (Debug Ansi version with dynamic CRT library)
    DebugAS\CascLibDAS.lib (Debug Ansi version with static CRT library)
    DebugUD\CascLibDUD.lib (Debug Unicode version with dynamic CRT library)
    DebugUS\CascLibDUS.lib (Debug Unicode version with static CRT library)
    ReleaseAD\CascLibRAD.lib (Release Ansi version with dynamic CRT library)
    ReleaseAS\CascLibRAS.lib (Release Ansi version with static CRT library)
    ReleaseUD\CascLibRUD.lib (Release Unicode version with dynamic CRT library)
    ReleaseUS\CascLibRUS.lib (Release Unicode version with static CRT library)
  6. Configure socket caching with sockets_set_caching()

    master

    CascLib provides a mechanism to cache sockets to improve performance and reuse connections. You can enable or disable this global caching behavior using sockets_set_caching(bool caching).

    • sockets_set_caching(true): Enables socket caching.
    • sockets_set_caching(false): Disables socket caching.
    // Enable caching for all socket connections
    sockets_set_caching(true);
  7. Access data in CASC_CSV_LINE and CASC_CSV_COLUMN

    master

    When iterating through a CSV, you interact with two main structures:

    1. CASC_CSV_LINE: Represents a single row.

      • Use operator[](size_t nIndex) to get a column by its position.
      • Use operator[](const char* szColumnName) to get a column by its header name.
      • Use GetColumnCount() to find the number of columns in the row.
    2. CASC_CSV_COLUMN: Represents the data within a specific cell.

      • szValue: A pointer to the string content.
      • nLength: The length of the string content.
      • Empty(): Returns true if the column is null or has zero length.
    // Example of accessing column properties
    const CASC_CSV_COLUMN& col = line[0];
    if (!col.Empty()) {
        printf("Value: %s, Length: %zu\n", col.szValue, col.nLength);
    }
  8. Configure custom parsing via SetNextLineProc

    master

    You can provide custom logic for finding the next line or column by using SetNextLineProc. This is useful if your CSV data is stored in a non-standard way or requires custom delimiters/logic.

    • PfnNextLineProc: A callback to find the start of the next line. It must find the next line, place a zero terminator there, and return the beginning of the next line. If no next line exists, return NULL.
    • PfnNextColProc: A callback to find the next column within a line.
    • pvUserData: A pointer to user-defined data passed to the callbacks.

    The callback type is CASC_CSV_NEXTPROC: typedef char * (*CASC_CSV_NEXTPROC)(void * pvUserData, char * szLine);

    // Example callback signature
    char* MyNextLineProc(void* pvUserData, char* szLine) {
        // Custom logic to find next line
        return nextLinePtr;
    }
    
    // Registering the callback
    csv.SetNextLineProc(MyNextLineProc, MyNextColProc, myContext);
  9. Connect to a remote host using sockets_connect()

    master

    To establish a network connection to a specific host and port, use the sockets_connect function. This function returns a pointer to a CASC_SOCKET object (PCASC_SOCKET). The socket object manages the underlying connection and can be used to perform network operations.

    Note that CASC_SOCKET uses reference counting. You should manage the lifecycle of the returned pointer using AddRef() and Release() to ensure the socket is not deleted while still in use.

    // Example of connecting to a host
    PCASC_SOCKET pSocket = sockets_connect("example.com", 80);
    if (pSocket != NULL) {
        // Use the socket...
        
        // When finished, release the reference
        pSocket->Release();
    }
  10. Use CASC_CSV to parse CSV data

    master

    The CASC_CSV class is the primary interface for loading and navigating CSV data. You can initialize it by specifying the maximum number of lines and whether the file contains a header. Data can be loaded from a file path or a memory buffer.

    To navigate the data, you can use the [] operator on the CASC_CSV instance to access specific lines by index or by header name. Once you have a CASC_CSV_LINE, you can access individual columns using the [] operator with either a column name or a numeric index.

    // Initialize with max 1000 lines and a header
    CASC_CSV csv(1000, true);
    
    // Load from a file
    if (csv.Load("data.csv") == SUCCESS) {
        // Access the first data line (index 0)
        const CASC_CSV_LINE& line = csv[0];
        
        // Access a column by name
        const CASC_CSV_COLUMN& col = line["ColumnName"];
        if (!col.Empty()) {
            const char* value = col.szValue;
        }
    
        // Access a column by index
        const CASC_CSV_COLUMN& colByIndex = line[0];
    }
  11. Use the CASC_FILE_TREE class to navigate CASC storage structures

    master

    The CASC_FILE_TREE class provides a common implementation for representing and navigating file trees within various ROOt file formats. It manages a collection of CASC_FILE_NODE objects, allowing for insertion, searching, and path retrieval.

    Lifecycle

    • Initialization: Call Create(DWORD Flags) to initialize the tree. You can pass flags to enable storage of extra metadata.
    • Destruction: Call Free() to destroy the tree and release resources.

    Key Operations

    • Insertion: Add nodes using InsertByName, InsertByHash, or InsertById.
    • Searching: Locate nodes using Find (by path, ID, or CKey), FindById, or Find (by hash).
    • Path Retrieval: Use PathAt to get the full string path of a node.
    • Metadata: Use GetExtras and SetExtras to manage additional data like FileDataId, LocaleFlags, or ContentFlags if the tree was created with the appropriate flags.
    // Example usage pattern
    PCASC_FILE_TREE pTree = (PCASC_FILE_TREE)new CASC_FILE_TREE();
    // Create tree with support for FileDataId, LocaleFlags, and ContentFlags
    DWORD flags = FTREE_FLAG_USE_DATA_ID | FTREE_FLAG_USE_LOCALE_FLAGS | FTREE_FLAG_USE_CONTENT_FLAGS;
    pTree->Create(flags);
    
    // Insert a node
    PCASC_FILE_NODE pNode = pTree->InsertByName(pCKeyEntry, "example/path/file.txt", fileDataId);
    
    // Find a node by path
    PCASC_FILE_NODE pFound = pTree->Find("example/path/file.txt", CASC_INVALID_ID, nullptr);
    
    // Get the path string
    char szPath[MAX_PATH];
    pTree->PathAt(szPath, MAX_PATH, pFound);
    
    pTree->Free();
    delete pTree;