Esempio n. 1
0
static void
ClipboardInitReadHistory(FcitxClipboard *clipboard)
{
    FILE *fp;
    if (!clipboard->config.save_history)
        return;
    fp = FcitxXDGGetFileUserWithPrefix("clipboard", "history.dat", "r", NULL);
    if (!fp)
        return;
    uint32_t len;
    if (!fcitx_utils_read_uint32(fp, &len))
        goto out;
    fcitx_utils_read_uint32(fp, &clipboard->primary.len);
    if (len > (uint32_t)clipboard->config.history_len) {
        clipboard->clp_hist_len = clipboard->config.history_len;
    } else {
        clipboard->clp_hist_len = len;
    }
    ClipboardSelectionStr *clp_hist_lst = clipboard->clp_hist_lst;
    unsigned int i;
    for (i = 0;i < clipboard->clp_hist_len;i++) {
        fcitx_utils_read_uint32(fp, &clp_hist_lst[i].len);
    }
    if (fseek(fp, (len + 2) * sizeof(uint32_t), SEEK_SET) < 0) {
        clipboard->clp_hist_len = 0;
        clipboard->primary.len = 0;
        goto out;
    }
    clipboard->primary.str = malloc(clipboard->primary.len + 1);
    fread(clipboard->primary.str, 1, clipboard->primary.len, fp);
    clipboard->primary.str[clipboard->primary.len] = '\0';
    for (i = 0;i < clipboard->clp_hist_len;i++) {
        clp_hist_lst[i].str = malloc(clp_hist_lst[i].len + 1);
        fread(clp_hist_lst[i].str, 1, clp_hist_lst[i].len, fp);
        clp_hist_lst[i].str[clp_hist_lst[i].len] = '\0';
    }
out:
    fclose(fp);
}
Esempio n. 2
0
boolean LoadTableDict(TableMetaData* tableMetaData)
{
    char            strCode[MAX_CODE_LENGTH + 1];
    char           *strHZ = 0;
    FILE           *fpDict;
    RECORD         *recTemp;
    unsigned int    i = 0;
    uint32_t        iTemp, iTempCount;
    char            cChar = 0, cTemp;
    int8_t          iVersion = 1;
    int             iRecordIndex;
    TableDict      *tableDict;

    //读入码表
    FcitxLog(DEBUG, _("Loading Table Dict"));

    int reload = 0;
    do {
        boolean error = false;
        if (!reload) {
            /**
             * kcm saves a absolute path here but it is then interpreted as
             * a relative path?
             **/
            fpDict = FcitxXDGGetFileWithPrefix("table", tableMetaData->strPath,
                                               "r", NULL);
        } else {
            char *tablepath;
            char *path = fcitx_utils_get_fcitx_path("pkgdatadir");
            fcitx_utils_alloc_cat_str(tablepath, path, "/table/",
                                      tableMetaData->strPath);
            fpDict = fopen(tablepath, "r");
            free(tablepath);
        }
        if (!fpDict)
            return false;

        tableMetaData->tableDict = fcitx_utils_new(TableDict);

        tableDict = tableMetaData->tableDict;
        tableDict->pool = fcitx_memory_pool_create();
#define CHECK_LOAD_TABLE_ERROR(SIZE) if (size < (SIZE)) { error = true; goto table_load_error; }

        //先读取码表的信息
        //判断版本信息
        size_t size;
        size = fcitx_utils_read_uint32(fpDict, &iTemp);
        CHECK_LOAD_TABLE_ERROR(1);

        if (!iTemp) {
            size = fread(&iVersion, sizeof(int8_t), 1, fpDict);
            CHECK_LOAD_TABLE_ERROR(1);
            iVersion = (iVersion < INTERNAL_VERSION);
            size = fcitx_utils_read_uint32(fpDict, &iTemp);
            CHECK_LOAD_TABLE_ERROR(1);
        }

        tableDict->strInputCode = (char*)realloc(tableDict->strInputCode, sizeof(char) * (iTemp + 1));
        size = fread(tableDict->strInputCode, sizeof(char), iTemp + 1, fpDict);
        CHECK_LOAD_TABLE_ERROR(iTemp + 1);
        /*
         * 建立索引,加26是为了为拼音编码预留空间
         */
        size_t tmp_len = strlen(tableDict->strInputCode) + 26;
        tableDict->recordIndex = (RECORD_INDEX*)fcitx_memory_pool_alloc(tableDict->pool, tmp_len * sizeof(RECORD_INDEX));
        for (iTemp = 0; iTemp < tmp_len; iTemp++) {
            tableDict->recordIndex[iTemp].cCode = 0;
            tableDict->recordIndex[iTemp].record = NULL;
        }
        /********************************************************************/

        size = fread(&(tableDict->iCodeLength), sizeof(uint8_t), 1, fpDict);
        CHECK_LOAD_TABLE_ERROR(1);
        UpdateTableMetaData(tableMetaData);

        if (!iVersion) {
            size = fread(&(tableDict->iPYCodeLength), sizeof(uint8_t), 1, fpDict);
            CHECK_LOAD_TABLE_ERROR(1);
        }
        else
            tableDict->iPYCodeLength = tableDict->iCodeLength;

        size = fcitx_utils_read_uint32(fpDict, &iTemp);
        CHECK_LOAD_TABLE_ERROR(1);
        tableDict->strIgnoreChars = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (iTemp + 1));
        size = fread(tableDict->strIgnoreChars, sizeof(char), iTemp + 1, fpDict);
        CHECK_LOAD_TABLE_ERROR(iTemp + 1);

        size = fread(&(tableDict->bRule), sizeof(unsigned char), 1, fpDict);
        CHECK_LOAD_TABLE_ERROR(1);

        if (tableDict->bRule) { //表示有组词规则
            tableDict->rule = (RULE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RULE) * (tableDict->iCodeLength - 1));
            for (i = 0; i < tableDict->iCodeLength - 1; i++) {
                size = fread(&(tableDict->rule[i].iFlag), sizeof(unsigned char), 1, fpDict);
                CHECK_LOAD_TABLE_ERROR(1);
                size = fread(&(tableDict->rule[i].iWords), sizeof(unsigned char), 1, fpDict);
                CHECK_LOAD_TABLE_ERROR(1);
                tableDict->rule[i].rule = (RULE_RULE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RULE_RULE) * tableDict->iCodeLength);
                for (iTemp = 0; iTemp < tableDict->iCodeLength; iTemp++) {
                    size = fread(&(tableDict->rule[i].rule[iTemp].iFlag), sizeof(unsigned char), 1, fpDict);
                    CHECK_LOAD_TABLE_ERROR(1);
                    size = fread(&(tableDict->rule[i].rule[iTemp].iWhich), sizeof(unsigned char), 1, fpDict);
                    CHECK_LOAD_TABLE_ERROR(1);
                    size = fread(&(tableDict->rule[i].rule[iTemp].iIndex), sizeof(unsigned char), 1, fpDict);
                    CHECK_LOAD_TABLE_ERROR(1);
                }
            }
        }

        tableDict->recordHead = (RECORD*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RECORD));
        tableDict->currentRecord = tableDict->recordHead;

        size = fcitx_utils_read_uint32(fpDict, &tableDict->iRecordCount);
        CHECK_LOAD_TABLE_ERROR(1);

        for (i = 0; i < SINGLE_HZ_COUNT; i++) {
            tableDict->tableSingleHZ[i] = (RECORD*)NULL;
            tableDict->tableSingleHZCons[i] = (RECORD*)NULL;
        }

        iRecordIndex = 0;
        size_t bufSize = 0;
        for (i = 0; i < tableDict->iRecordCount; i++) {
            size = fread(strCode, sizeof(int8_t), tableDict->iPYCodeLength + 1, fpDict);
            CHECK_LOAD_TABLE_ERROR(tableDict->iPYCodeLength + 1);
            size = fcitx_utils_read_uint32(fpDict, &iTemp);
            CHECK_LOAD_TABLE_ERROR(1);
            /* we don't actually have such limit, but sometimes, broken table
             * may break this, so we need to give a limitation.
             */
            if (iTemp > UTF8_MAX_LENGTH * 30) {
                error = true;
                goto table_load_error;
            }
            if (iTemp > bufSize) {
                bufSize = iTemp;
                strHZ = realloc(strHZ, bufSize);
            }
            size = fread(strHZ, sizeof(int8_t), iTemp, fpDict);
            CHECK_LOAD_TABLE_ERROR(iTemp);
            recTemp = (RECORD*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(RECORD));
            recTemp->strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iPYCodeLength + 1));
            memset(recTemp->strCode, 0, sizeof(char) * (tableDict->iPYCodeLength + 1));
            strcpy(recTemp->strCode, strCode);
            recTemp->strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * iTemp);
            strcpy(recTemp->strHZ, strHZ);

            if (!iVersion) {
                size = fread(&cTemp, sizeof(int8_t), 1, fpDict);
                CHECK_LOAD_TABLE_ERROR(1);
                recTemp->type = cTemp;
            }

            size = fcitx_utils_read_uint32(fpDict, &recTemp->iHit);
            CHECK_LOAD_TABLE_ERROR(1);
            size = fcitx_utils_read_uint32(fpDict, &recTemp->iIndex);
            CHECK_LOAD_TABLE_ERROR(1);
            if (recTemp->iIndex > tableDict->iTableIndex)
                tableDict->iTableIndex = recTemp->iIndex;

            /* 建立索引 */
            if (cChar != recTemp->strCode[0]) {
                cChar = recTemp->strCode[0];
                tableDict->recordIndex[iRecordIndex].cCode = cChar;
                tableDict->recordIndex[iRecordIndex].record = recTemp;
                iRecordIndex++;
            }
            /******************************************************************/
            /** 为单字生成一个表   */
            if (fcitx_utf8_strlen(recTemp->strHZ) == 1 && !IsIgnoreChar(tableDict, strCode[0]))
            {
                RECORD** tableSingleHZ = NULL;
                if (recTemp->type == RECORDTYPE_NORMAL)
                    tableSingleHZ = tableDict->tableSingleHZ;
                else if (recTemp->type == RECORDTYPE_CONSTRUCT)
                    tableSingleHZ = tableDict->tableSingleHZCons;

                if (tableSingleHZ) {
                    iTemp = CalHZIndex(recTemp->strHZ);
                    if (iTemp < SINGLE_HZ_COUNT) {
                        if (tableSingleHZ[iTemp]) {
                            if (strlen(strCode) > strlen(tableDict->tableSingleHZ[iTemp]->strCode))
                                tableSingleHZ[iTemp] = recTemp;
                        } else
                            tableSingleHZ[iTemp] = recTemp;
                    }
                }
            }

            if (recTemp->type == RECORDTYPE_PINYIN)
                tableDict->bHasPinyin = true;

            if (recTemp->type == RECORDTYPE_PROMPT && strlen(recTemp->strCode) == 1)
                tableDict->promptCode[(uint8_t) recTemp->strCode[0]] = recTemp;

            tableDict->currentRecord->next = recTemp;
            recTemp->prev = tableDict->currentRecord;
            tableDict->currentRecord = recTemp;
        }
        if (strHZ) {
            free(strHZ);
            strHZ = NULL;
        }

        tableDict->currentRecord->next = tableDict->recordHead;
        tableDict->recordHead->prev = tableDict->currentRecord;

table_load_error:
        fclose(fpDict);
        if (error) {
            fcitx_memory_pool_destroy(tableDict->pool);
            tableDict->pool = NULL;
            reload++;
        } else {
            break;
        }
    } while(reload < 2);

    if (!tableDict->pool)
        return false;

    FcitxLog(DEBUG, _("Load Table Dict OK"));

    //读取相应的特殊符号表
    fpDict = FcitxXDGGetFileWithPrefix("table", tableMetaData->strSymbolFile, "r", NULL);

    if (fpDict) {
        tableDict->iFH = fcitx_utils_calculate_record_number(fpDict);
        tableDict->fh = (FH*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(FH) * tableDict->iFH);

        char* strBuf = NULL;
        size_t bufLen = 0;
        for (i = 0; i < tableDict->iFH; i++) {
            if (getline(&strBuf, &bufLen, fpDict) == -1)
                break;

            if (!fcitx_utf8_check_string(strBuf))
                break;

            if (fcitx_utf8_strlen(strBuf) > FH_MAX_LENGTH)
                break;

            strcpy(tableDict->fh[i].strFH, strBuf);
        }
        fcitx_utils_free(strBuf);
        tableDict->iFH = i;

        fclose(fpDict);
    }

    tableDict->strNewPhraseCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1));
    tableDict->strNewPhraseCode[tableDict->iCodeLength] = '\0';

    tableDict->iAutoPhrase = 0;
    if (tableMetaData->bAutoPhrase) {
        tableDict->autoPhrase = (AUTOPHRASE*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(AUTOPHRASE) * AUTO_PHRASE_COUNT);

        //读取上次保存的自动词组信息
        FcitxLog(DEBUG, _("Loading Autophrase."));

        char *temppath;
        fcitx_utils_alloc_cat_str(temppath, tableMetaData->uniqueName,
                                  "_LastAutoPhrase.tmp");
        fpDict = FcitxXDGGetFileWithPrefix("table", temppath, "r", NULL);
        free(temppath);
        i = 0;
        if (fpDict) {
            size_t size = fcitx_utils_read_int32(fpDict, &tableDict->iAutoPhrase);
            if (size == 1) {
                for (; i < tableDict->iAutoPhrase; i++) {
                    tableDict->autoPhrase[i].strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1));
                    tableDict->autoPhrase[i].strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1));
                    size = fread(tableDict->autoPhrase[i].strCode, tableDict->iCodeLength + 1, 1, fpDict);
                    if (size != 1) {
                        tableDict->iAutoPhrase = i;
                        break;
                    }
                    size = fread(tableDict->autoPhrase[i].strHZ, PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1, 1, fpDict);
                    tableDict->autoPhrase[i].strHZ[PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH] = 0;
                    if (size != 1 || !fcitx_utf8_check_string(tableDict->autoPhrase[i].strHZ)) {
                        tableDict->iAutoPhrase = i;
                        break;
                    }
                    size = fcitx_utils_read_uint32(fpDict, &iTempCount);
                    if (size != 1) {
                        tableDict->iAutoPhrase = i;
                        break;
                    }

                    tableDict->autoPhrase[i].iSelected = iTempCount;
                    if (i == AUTO_PHRASE_COUNT - 1)
                        tableDict->autoPhrase[i].next = &tableDict->autoPhrase[0];
                    else
                        tableDict->autoPhrase[i].next = &tableDict->autoPhrase[i + 1];
                }
            }
            fclose(fpDict);
        }

        for (; i < AUTO_PHRASE_COUNT; i++) {
            tableDict->autoPhrase[i].strCode = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (tableDict->iCodeLength + 1));
            tableDict->autoPhrase[i].strHZ = (char*)fcitx_memory_pool_alloc(tableDict->pool, sizeof(char) * (PHRASE_MAX_LENGTH * UTF8_MAX_LENGTH + 1));
            tableDict->autoPhrase[i].iSelected = 0;
            if (i == AUTO_PHRASE_COUNT - 1)
                tableDict->autoPhrase[i].next = &tableDict->autoPhrase[0];
            else
                tableDict->autoPhrase[i].next = &tableDict->autoPhrase[i + 1];
        }

        if (i == AUTO_PHRASE_COUNT)
            tableDict->insertPoint = &tableDict->autoPhrase[0];
        else
            tableDict->insertPoint = &tableDict->autoPhrase[i - 1];

        FcitxLog(DEBUG, _("Load Autophrase OK"));
    } else
        tableDict->autoPhrase = (AUTOPHRASE *) NULL;

    return true;
}
Esempio n. 3
0
int main(int argc, char *argv[])
{
    char            strCode[100];
    char            strHZ[UTF8_MAX_LENGTH * 31];
    FILE           *fpDict;
    unsigned int    i = 0;
    uint32_t        iTemp;
    uint32_t        j;
    unsigned char   iLen;
    unsigned char   iRule;
    unsigned char   iPYLen;
    char            iVersion = 0;
    boolean         old = false;
    const char**          templ = NULL;

    int c;
    while ((c = getopt(argc, argv, "oh")) != -1) {
        switch (c) {
        case 'o':
            old = true;
            break;
        case 'h':

        default:
            usage();
        }
    }

    templ = old ? templateOld : templateNew;

    if (optind + 1 != argc) {
        usage();
    }

    fpDict = fopen(argv[optind], "r");

    if (!fpDict) {
        printf("\nCannot read source file!\n\n");
        exit(2);
    }

    //先读取码表的信息
    fcitx_utils_read_uint32(fpDict, &iTemp);

    if (iTemp == 0) {
        fread(&iVersion, sizeof(char), 1, fpDict);
        printf(templ[TEMPL_VERNEW], iVersion);
        fcitx_utils_read_uint32(fpDict, &iTemp);
    } else
        printf("%s", templ[TEMPL_VEROLD]);

    fread(strCode, sizeof(char), iTemp + 1, fpDict);

    printf(templ[TEMPL_KEYCODE], strCode);
    char cPinyin = '\0';

    fread(&iLen, sizeof(unsigned char), 1, fpDict);

    printf(templ[TEMPL_LEN], iLen);

    if (iVersion) {
        fread(&iPYLen, sizeof(unsigned char), 1, fpDict);

        if (iPYLen) {
            cPinyin = guessValidChar('@', strCode);
            printf(templ[TEMPL_PY], cPinyin);
            printf(templ[TEMPL_PYLEN], iPYLen);
        }
    }
    char* temp = malloc(strlen(strCode) * sizeof(char) + 3);
    strcpy(temp, strCode);
    char pyStr[] = {cPinyin, '\0'};
    strcat(temp, pyStr);
    char cPrompt = guessValidChar('&', temp);
    char prStr[] = {cPrompt, '\0'};
    strcat(temp, prStr);
    char cPhrase = guessValidChar('^', temp);
    free(temp);
    if (cPrompt == 0) {
        printf("%s", templ[TEMPL_PROMPT2]);
    }
    else {
        printf(templ[TEMPL_PROMPT], cPrompt);
    }
    if (cPhrase == 0) {
        printf("%s", templ[TEMPL_CONSTRUCTPHRASE2]);
    }
    else {
        printf(templ[TEMPL_CONSTRUCTPHRASE], cPhrase);
    }

    fcitx_utils_read_uint32(fpDict, &iTemp);

    fread(strCode, sizeof(char), iTemp + 1, fpDict);

    if (iTemp)
        printf(templ[TEMPL_INVALIDCHAR], strCode);

    fread(&iRule, sizeof(unsigned char), 1, fpDict);

    if (iRule) {
        //表示有组词规则
        printf("%s", templ[TEMPL_RULE]);

        for (i = 0; i < iLen - 1; i++) {
            fread(&iRule, sizeof(unsigned char), 1, fpDict);
            printf("%c", (iRule) ? 'a' : 'e');
            fread(&iRule, sizeof(unsigned char), 1, fpDict);
            printf("%d=", iRule);

            for (iTemp = 0; iTemp < iLen; iTemp++) {
                fread(&iRule, sizeof(unsigned char), 1, fpDict);
                printf("%c", (iRule) ? 'p' : 'n');
                fread(&iRule, sizeof(unsigned char), 1, fpDict);
                printf("%d", iRule);
                fread(&iRule, sizeof(unsigned char), 1, fpDict);
                printf("%d", iRule);

                if (iTemp != (iLen - 1))
                    printf("+");
            }

            printf("\n");
        }
    }

    printf("%s", templ[TEMPL_DATA]);

    fcitx_utils_read_uint32(fpDict, &j);

    if (iVersion)
        iLen = iPYLen;

    for (i = 0; i < j; i++) {
        fread(strCode, sizeof(char), iLen + 1, fpDict);
        fcitx_utils_read_uint32(fpDict, &iTemp);
        if (iTemp > UTF8_MAX_LENGTH * 30)
            break;
        fread(strHZ, sizeof(unsigned char), iTemp, fpDict);

        if (iVersion) {
            fread(&iRule, sizeof(unsigned char), 1, fpDict);

            if (iRule == RECORDTYPE_PINYIN)
                printf("%c%s %s\n", cPinyin, strCode, strHZ);
            else if (iRule == RECORDTYPE_CONSTRUCT) {
                if (cPhrase == 0) {
                    fprintf(stderr, "Could not find a valid char for construct phrase\n");
                    exit(1);
                }
                else
                    printf("%c%s %s\n", cPhrase, strCode, strHZ);
            }
            else if (iRule == RECORDTYPE_PROMPT)
                if (cPrompt == 0) {
                    fprintf(stderr, "Could not find a valid char for prompt\n");
                    exit(1);
                }
                else
                    printf("%c%s %s\n", cPrompt, strCode, strHZ);
            else
                printf("%s %s\n", strCode, strHZ);
        }

        fcitx_utils_read_uint32(fpDict, &iTemp);
        fcitx_utils_read_uint32(fpDict, &iTemp);
    }

    fclose(fpDict);

    return 0;
}