Beispiel #1
0
//database functions
void dbsave()
{
    dprintf("Saving database...");
    DWORD ticks = GetTickCount();
    JSON root = json_object();
    CommentCacheSave(root);
    LabelCacheSave(root);
    BookmarkCacheSave(root);
    FunctionCacheSave(root);
    LoopCacheSave(root);
    BpCacheSave(root);
    WString wdbpath = StringUtils::Utf8ToUtf16(dbpath);
    if(json_object_size(root))
    {
        Handle hFile = CreateFileW(wdbpath.c_str(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
        if(!hFile)
        {
            dputs("\nFailed to open database for writing!");
            json_decref(root); //free root
            return;
        }
        SetEndOfFile(hFile);
        char* jsonText = json_dumps(root, JSON_INDENT(4));
        DWORD written = 0;
        if(!WriteFile(hFile, jsonText, (DWORD)strlen(jsonText), &written, 0))
        {
            json_free(jsonText);
            dputs("\nFailed to write database file!");
            json_decref(root); //free root
            return;
        }
        hFile.Close();
        json_free(jsonText);
        if(!settingboolget("Engine", "DisableDatabaseCompression"))
            LZ4_compress_fileW(wdbpath.c_str(), wdbpath.c_str());
    }
    else //remove database when nothing is in there
        DeleteFileW(wdbpath.c_str());
    dprintf("%ums\n", GetTickCount() - ticks);
    json_decref(root); //free root
}
Beispiel #2
0
static bool scriptcreatelinemap(const char* filename)
{
    Handle hFile = CreateFileW(StringUtils::Utf8ToUtf16(filename).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
    if(hFile == INVALID_HANDLE_VALUE)
    {
        GuiScriptError(0, "CreateFile failed...");
        return false;
    }
    unsigned int filesize = GetFileSize(hFile, 0);
    if(!filesize)
    {
        GuiScriptError(0, "Empty script...");
        return false;
    }
    Memory<char*> filedata(filesize + 1, "createlinemap:filedata");
    DWORD read = 0;
    if(!ReadFile(hFile, filedata(), filesize, &read, 0))
    {
        GuiScriptError(0, "ReadFile failed...");
        return false;
    }
    hFile.Close();
    int len = (int)strlen(filedata());
    char temp[256] = "";
    LINEMAPENTRY entry;
    memset(&entry, 0, sizeof(entry));
    std::vector<LINEMAPENTRY>().swap(linemap);
    for(int i = 0, j = 0; i < len; i++) //make raw line map
    {
        if(filedata()[i] == '\r' && filedata()[i + 1] == '\n') //windows file
        {
            memset(&entry, 0, sizeof(entry));
            int add = 0;
            while(temp[add] == ' ')
                add++;
            strcpy_s(entry.raw, temp + add);
            *temp = 0;
            j = 0;
            i++;
            linemap.push_back(entry);
        }
        else if(filedata()[i] == '\n') //other file
        {
            memset(&entry, 0, sizeof(entry));
            int add = 0;
            while(temp[add] == ' ')
                add++;
            strcpy_s(entry.raw, temp + add);
            *temp = 0;
            j = 0;
            linemap.push_back(entry);
        }
        else if(j >= 254)
        {
            memset(&entry, 0, sizeof(entry));
            int add = 0;
            while(temp[add] == ' ')
                add++;
            strcpy_s(entry.raw, temp + add);
            *temp = 0;
            j = 0;
            linemap.push_back(entry);
        }
        else
            j += sprintf(temp + j, "%c", filedata()[i]);
    }
    if(*temp)
    {
        memset(&entry, 0, sizeof(entry));
        strcpy_s(entry.raw, temp);
        linemap.push_back(entry);
    }
    int linemapsize = (int)linemap.size();
    while(!*linemap.at(linemapsize - 1).raw) //remove empty lines from the end
    {
        linemapsize--;
        linemap.pop_back();
    }
    for(int i = 0; i < linemapsize; i++)
    {
        LINEMAPENTRY cur = linemap.at(i);

        //temp. remove comments from the raw line
        char line_comment[256] = "";
        char* comment = strstr(&cur.raw[0], "//");
        if(comment && comment != cur.raw) //only when the line doesnt start with a comment
        {
            if(*(comment - 1) == ' ') //space before comment
            {
                strcpy_s(line_comment, comment);
                *(comment - 1) = '\0';
            }
            else //no space before comment
            {
                strcpy_s(line_comment, comment);
                *comment = 0;
            }
        }

        int rawlen = (int)strlen(cur.raw);
        if(!rawlen) //empty
        {
            cur.type = lineempty;
        }
        else if(!strncmp(cur.raw, "//", 2)) //comment
        {
            cur.type = linecomment;
            strcpy_s(cur.u.comment, cur.raw);
        }
        else if(cur.raw[rawlen - 1] == ':') //label
        {
            cur.type = linelabel;
            sprintf(cur.u.label, "l %.*s", rawlen - 1, cur.raw); //create a fake command for formatting
            strcpy_s(cur.u.label, StringUtils::Trim(cur.u.label).c_str());
            char temp[256] = "";
            strcpy_s(temp, cur.u.label + 2);
            strcpy_s(cur.u.label, temp); //remove fake command
            if(!*cur.u.label || !strcmp(cur.u.label, "\"\"")) //no label text
            {
                char message[256] = "";
                sprintf(message, "Empty label detected on line %d!", i + 1);
                GuiScriptError(0, message);
                std::vector<LINEMAPENTRY>().swap(linemap);
                return false;
            }
            int foundlabel = scriptlabelfind(cur.u.label);
            if(foundlabel) //label defined twice
            {
                char message[256] = "";
                sprintf(message, "Duplicate label \"%s\" detected on lines %d and %d!", cur.u.label, foundlabel, i + 1);
                GuiScriptError(0, message);
                std::vector<LINEMAPENTRY>().swap(linemap);
                return false;
            }
        }
        else if(scriptgetbranchtype(cur.raw) != scriptnobranch) //branch
        {
            cur.type = linebranch;
            cur.u.branch.type = scriptgetbranchtype(cur.raw);
            char newraw[MAX_SCRIPT_LINE_SIZE] = "";
            strcpy_s(newraw, StringUtils::Trim(cur.raw).c_str());
            int len = (int)strlen(newraw);
            for(int i = 0; i < len; i++)
                if(newraw[i] == ' ')
                {
                    strcpy_s(cur.u.branch.branchlabel, newraw + i + 1);
                    break;
                }
        }
        else
        {
            cur.type = linecommand;
            strcpy_s(cur.u.command, cur.raw);
        }

        //append the comment to the raw line again
        if(*line_comment)
            sprintf(cur.raw + rawlen, " %s", line_comment);
        linemap.at(i) = cur;
    }
    linemapsize = (int)linemap.size();
    for(int i = 0; i < linemapsize; i++)
    {
        auto & currentLine = linemap.at(i);
        if(currentLine.type == linebranch)  //invalid branch label
        {
            int labelline = scriptlabelfind(currentLine.u.branch.branchlabel);
            if(!labelline) //invalid branch label
            {
                char message[256] = "";
                sprintf(message, "Invalid branch label \"%s\" detected on line %d!", currentLine.u.branch.branchlabel, i + 1);
                GuiScriptError(0, message);
                std::vector<LINEMAPENTRY>().swap(linemap);
                return false;
            }
            else //set the branch destination line
                currentLine.u.branch.dest = scriptinternalstep(labelline);
        }
    }
    if(linemap.at(linemapsize - 1).type == linecomment || linemap.at(linemapsize - 1).type == linelabel) //label/comment on the end
    {
        memset(&entry, 0, sizeof(entry));
        entry.type = linecommand;
        strcpy_s(entry.raw, "ret");
        strcpy_s(entry.u.command, "ret");
        linemap.push_back(entry);
    }
    return true;
}
Beispiel #3
0
void dbload()
{
    // If the file doesn't exist, there is no DB to load
    if(!FileExists(dbpath))
        return;

    dprintf("Loading database...");
    DWORD ticks = GetTickCount();

    // Multi-byte (UTF8) file path converted to UTF16
    WString databasePathW = StringUtils::Utf8ToUtf16(dbpath);

    // Decompress the file if compression was enabled
    bool useCompression = !settingboolget("Engine", "DisableDatabaseCompression");
    LZ4_STATUS lzmaStatus = LZ4_INVALID_ARCHIVE;
    {
        lzmaStatus = LZ4_decompress_fileW(databasePathW.c_str(), databasePathW.c_str());

        // Check return code
        if(useCompression && lzmaStatus != LZ4_SUCCESS && lzmaStatus != LZ4_INVALID_ARCHIVE)
        {
            dputs("\nInvalid database file!");
            return;
        }
    }

    // Read the database file
    Handle hFile = CreateFileW(databasePathW.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
    if(!hFile)
    {
        dputs("\nFailed to open database file!");
        return;
    }

    unsigned int jsonFileSize = GetFileSize(hFile, 0);
    if(!jsonFileSize)
    {
        dputs("\nEmpty database file!");
        return;
    }

    Memory<char*> jsonText(jsonFileSize + 1);
    DWORD read = 0;
    if(!ReadFile(hFile, jsonText(), jsonFileSize, &read, 0))
    {
        dputs("\nFailed to read database file!");
        return;
    }
    hFile.Close();

    // Deserialize JSON
    JSON root = json_loads(jsonText(), 0, 0);

    if(lzmaStatus != LZ4_INVALID_ARCHIVE && useCompression)
        LZ4_compress_fileW(databasePathW.c_str(), databasePathW.c_str());

    // Validate JSON load status
    if(!root)
    {
        dputs("\nInvalid database file (JSON)!");
        return;
    }

    // Finally load all structures
    CommentCacheLoad(root);
    LabelCacheLoad(root);
    BookmarkCacheLoad(root);
    FunctionCacheLoad(root);
    LoopCacheLoad(root);
    BpCacheLoad(root);

    // Free root
    json_decref(root);
    dprintf("%ums\n", GetTickCount() - ticks);
}