<commit_before>/*****************************************************************************/
/*                                                  ###                      */
/*       #####          ###    ###                  ###  CREATE: 2010-01-29  */
/*     #######          ###    ###      [CORE]      ###  ~~~~~~~~~~~~~~~~~~  */
/*    ########          ###    ###                  ###  MODIFY: XXXX-XX-XX  */
/*    ####  ##          ###    ###                  ###  ~~~~~~~~~~~~~~~~~~  */
/*   ###       ### ###  ###    ###    ####    ####  ###   ##  +-----------+  */
/*  ####       ######## ##########  #######  ###### ###  ###  |  A NEW C  |  */
/*  ###        ######## ########## ########  ###### ### ###   | FRAMEWORK |  */
/*  ###     ## #### ### ########## ###  ### ###     ######    |  FOR ALL  |  */
/*  ####   ### ###  ### ###    ### ###  ### ###     ######    | PLATFORMS |  */
/*  ########## ###      ###    ### ######## ####### #######   |  AND ALL  |  */
/*   #######   ###      ###    ### ########  ###### ###  ###  | COMPILERS |  */
/*    #####    ###      ###    ###  #### ##   ####  ###   ##  +-----------+  */
/*  =======================================================================  */
/*  >>>>>>>>>>>>>>>>>>>>>>>> CrHack 文件格式函数库 <<<<<<<<<<<<<<<<<<<<<<<<  */
/*  =======================================================================  */
/*****************************************************************************/

#ifndef __CR_FMTLIB_C__
#define __CR_FMTLIB_C__ 0x84834BAFUL

#include "hash.h"
#include "safe.h"
#include "fmtint.h"
#include "strlib.h"

/*****************************************************************************/
/*                               插件功能封装                                */
/*****************************************************************************/

/*
---------------------------------------
    使用文件名的扩展名作为键A
---------------------------------------
*/
static uint_t
match_findA (
  __CR_IN__ const void_t*   key
    )
{
    leng_t  idx, len;

    /* 注意: 文件名必须都小写 */
    len = str_lenA((ansi_t*)key);
    for (idx = len; idx != 0; idx--) {
        if (((ansi_t*)key)[idx - 1] == CR_AC('.')) {
            key = (void_t*)(&(((ansi_t*)key)[idx - 1]));
            return (hash_str_djb2(key, (len - idx + 1) * sizeof(ansi_t)));
        }
    }
    return (hash_str_djb2(key, 0));     /* 无扩展名或不确定 */
}

/*
---------------------------------------
    使用文件名的扩展名作为键W
---------------------------------------
*/
static uint_t
match_findW (
  __CR_IN__ const void_t*   key
    )
{
    leng_t  idx, len;

    /* 注意: 文件名必须都小写 */
    len = str_lenW((wide_t*)key);
    for (idx = len; idx != 0; idx--) {
        if (((wide_t*)key)[idx - 1] == CR_WC('.')) {
            key = (void_t*)(&(((wide_t*)key)[idx - 1]));
            return (hash_str_djb2(key, (len - idx + 1) * sizeof(wide_t)));
        }
    }
    return (hash_str_djb2(key, 0));     /* 无扩展名或不确定 */
}

/*
=======================================
    释放引擎插件
=======================================
*/
CR_API void_t
engine_free (
  __CR_IN__ sENGINE*    engine
    )
{
    sENGINE_INT*    real;

    real = (sENGINE_INT*)engine;
    if (engine->engine_free != NULL)
        engine->engine_free(engine);
    curtain_freeT(&real->m_findw, sMATCHw);
    curtain_freeT(&real->m_finda, sMATCHa);
    if (engine->sbin != NULL)
        sbin_unload(engine->sbin);
    mem_free(engine);
}

/*
=======================================
    初始化引擎插件
=======================================
*/
CR_API sENGINE*
engine_init (
  __CR_IN__ const sMATCHa*      finda,
  __CR_IN__ const sMATCHw*      findw,
  __CR_IN__ const sTRY_LDRa*    loada,
  __CR_IN__ const sTRY_LDRw*    loadw
    )
{
    sENGINE_INT*    engine;

    engine = struct_new(sENGINE_INT);
    if (engine == NULL) {
        err_set(__CR_FMTLIB_C__, CR_NULL,
                "engine_init()", "struct_new() failure");
        return (NULL);
    }
    struct_zero(engine, sENGINE_INT);

    /* 生成两个哈希表并注册文件类型匹配 */
    if (finda != NULL) {
        if (!curtain_initT(&engine->m_finda, sMATCHa, 0, 0)) {
            err_set(__CR_FMTLIB_C__, FALSE,
                    "engine_init()", "curtain_initT() failure");
            goto _failure1;
        }
        engine->m_finda.find = match_findA;

        while (finda->loader != NULL) {
            if (curtain_insertT(&engine->m_finda, sMATCHa,
                                finda->filext, finda) == NULL) {
                err_set(__CR_FMTLIB_C__, CR_NULL,
                        "engine_init()", "curtain_insertT() failure");
                goto _failure2;
            }
            finda++;
        }
    }
    if (findw != NULL) {
        if (!curtain_initT(&engine->m_findw, sMATCHw, 0, 0)) {
            err_set(__CR_FMTLIB_C__, FALSE,
                    "engine_init()", "curtain_initT() failure");
            goto _failure2;
        }
        engine->m_findw.find = match_findW;

        while (findw->loader != NULL) {
            if (curtain_insertT(&engine->m_findw, sMATCHw,
                                findw->filext, findw) == NULL) {
                err_set(__CR_FMTLIB_C__, CR_NULL,
                        "engine_init()", "curtain_insertT() failure");
                goto _failure3;
            }
            findw++;
        }
    }
    engine->m_loada = loada;
    engine->m_loadw = loadw;
    engine->engine.mask = CR_FMTZ_MASK_ALL;
    return ((sENGINE*)engine);

_failure3:
    curtain_freeT(&engine->m_findw, sMATCHw);
_failure2:
    curtain_freeT(&engine->m_finda, sMATCHa);
_failure1:
    mem_free(engine);
    return (NULL);
}

/*
=======================================<commit_msg>LIB: 减少文件匹配哈希表占用内存的大小<commit_after>/*****************************************************************************/
/*                                                  ###                      */
/*       #####          ###    ###                  ###  CREATE: 2010-01-29  */
/*     #######          ###    ###      [CORE]      ###  ~~~~~~~~~~~~~~~~~~  */
/*    ########          ###    ###                  ###  MODIFY: XXXX-XX-XX  */
/*    ####  ##          ###    ###                  ###  ~~~~~~~~~~~~~~~~~~  */
/*   ###       ### ###  ###    ###    ####    ####  ###   ##  +-----------+  */
/*  ####       ######## ##########  #######  ###### ###  ###  |  A NEW C  |  */
/*  ###        ######## ########## ########  ###### ### ###   | FRAMEWORK |  */
/*  ###     ## #### ### ########## ###  ### ###     ######    |  FOR ALL  |  */
/*  ####   ### ###  ### ###    ### ###  ### ###     ######    | PLATFORMS |  */
/*  ########## ###      ###    ### ######## ####### #######   |  AND ALL  |  */
/*   #######   ###      ###    ### ########  ###### ###  ###  | COMPILERS |  */
/*    #####    ###      ###    ###  #### ##   ####  ###   ##  +-----------+  */
/*  =======================================================================  */
/*  >>>>>>>>>>>>>>>>>>>>>>>> CrHack 文件格式函数库 <<<<<<<<<<<<<<<<<<<<<<<<  */
/*  =======================================================================  */
/*****************************************************************************/

#ifndef __CR_FMTLIB_C__
#define __CR_FMTLIB_C__ 0x84834BAFUL

#include "hash.h"
#include "safe.h"
#include "fmtint.h"
#include "strlib.h"

/*****************************************************************************/
/*                               插件功能封装                                */
/*****************************************************************************/

/*
---------------------------------------
    使用文件名的扩展名作为键A
---------------------------------------
*/
static uint_t
match_findA (
  __CR_IN__ const void_t*   key
    )
{
    leng_t  idx, len;

    /* 注意: 文件名必须都小写 */
    len = str_lenA((ansi_t*)key);
    for (idx = len; idx != 0; idx--) {
        if (((ansi_t*)key)[idx - 1] == CR_AC('.')) {
            key = (void_t*)(&(((ansi_t*)key)[idx - 1]));
            return (hash_str_djb2(key, (len - idx + 1) * sizeof(ansi_t)));
        }
    }
    return (hash_str_djb2(key, 0));     /* 无扩展名或不确定 */
}

/*
---------------------------------------
    使用文件名的扩展名作为键W
---------------------------------------
*/
static uint_t
match_findW (
  __CR_IN__ const void_t*   key
    )
{
    leng_t  idx, len;

    /* 注意: 文件名必须都小写 */
    len = str_lenW((wide_t*)key);
    for (idx = len; idx != 0; idx--) {
        if (((wide_t*)key)[idx - 1] == CR_WC('.')) {
            key = (void_t*)(&(((wide_t*)key)[idx - 1]));
            return (hash_str_djb2(key, (len - idx + 1) * sizeof(wide_t)));
        }
    }
    return (hash_str_djb2(key, 0));     /* 无扩展名或不确定 */
}

/*
=======================================
    释放引擎插件
=======================================
*/
CR_API void_t
engine_free (
  __CR_IN__ sENGINE*    engine
    )
{
    sENGINE_INT*    real;

    real = (sENGINE_INT*)engine;
    if (engine->engine_free != NULL)
        engine->engine_free(engine);
    curtain_freeT(&real->m_findw, sMATCHw);
    curtain_freeT(&real->m_finda, sMATCHa);
    if (engine->sbin != NULL)
        sbin_unload(engine->sbin);
    mem_free(engine);
}

/*
=======================================
    初始化引擎插件
=======================================
*/
CR_API sENGINE*
engine_init (
  __CR_IN__ const sMATCHa*      finda,
  __CR_IN__ const sMATCHw*      findw,
  __CR_IN__ const sTRY_LDRa*    loada,
  __CR_IN__ const sTRY_LDRw*    loadw
    )
{
    leng_t          count;
    sENGINE_INT*    engine;

    engine = struct_new(sENGINE_INT);
    if (engine == NULL) {
        err_set(__CR_FMTLIB_C__, CR_NULL,
                "engine_init()", "struct_new() failure");
        return (NULL);
    }
    struct_zero(engine, sENGINE_INT);

    /* 生成两个哈希表并注册文件类型匹配 */
    if (finda != NULL) {
        for (count = 0; ; count++) {
            if (finda[count].loader == NULL)
                break;
        }
        if (count != 0) {
            if (!curtain_initT(&engine->m_finda, sMATCHa, count, 0)) {
                err_set(__CR_FMTLIB_C__, FALSE,
                        "engine_init()", "curtain_initT() failure");
                goto _failure1;
            }
            engine->m_finda.find = match_findA;

            while (finda->loader != NULL) {
                if (curtain_insertT(&engine->m_finda, sMATCHa,
                                    finda->filext, finda) == NULL) {
                    err_set(__CR_FMTLIB_C__, CR_NULL,
                            "engine_init()", "curtain_insertT() failure");
                    goto _failure2;
                }
                finda++;
            }
        }
    }
    if (findw != NULL) {
        for (count = 0; ; count++) {
            if (findw[count].loader == NULL)
                break;
        }
        if (count != 0) {
            if (!curtain_initT(&engine->m_findw, sMATCHw, count, 0)) {
                err_set(__CR_FMTLIB_C__, FALSE,
                        "engine_init()", "curtain_initT() failure");
                goto _failure2;
            }
            engine->m_findw.find = match_findW;

            while (findw->loader != NULL) {
                if (curtain_insertT(&engine->m_findw, sMATCHw,
                                    findw->filext, findw) == NULL) {
                    err_set(__CR_FMTLIB_C__, CR_NULL,
                            "engine_init()", "curtain_insertT() failure");
                    goto _failure3;
                }
                findw++;
            }
        }
    }
    engine->m_loada = loada;
    engine->m_loadw = loadw;
    engine->engine.mask = CR_FMTZ_MASK_ALL;
    return ((sENGINE*)engine);

_failure3:
    curtain_freeT(&engine->m_findw, sMATCHw);
_failure2:
    curtain_freeT(&engine->m_finda, sMATCHa);
_failure1:
    mem_free(engine);
    return (NULL);
}

/*
=======================================
{'fraction_non_alphanumeric': 0.3250618231431739, 'fraction_numerical': 0.0068218640743583185, 'mean_word_length': 1.7536980511857243, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 93, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4401490', 'n_tokens_mistral': 3952, 'n_tokens_neox': 3797, 'n_words': 535}