Beispiel #1
0
void ChmDoc::FixPathCodepage(AutoFree& path, UINT& fileCP) {
    if (!path || HasData(path))
        return;

    AutoFree utf8Path(ToUtf8((unsigned char*)path.Get()));
    if (HasData(utf8Path)) {
        path.Set(utf8Path.StealData());
        fileCP = codepage;
    } else if (fileCP != codepage) {
        utf8Path.Set(ToUtf8((unsigned char*)path.Get(), fileCP));
        if (HasData(utf8Path)) {
            path.Set(utf8Path.StealData());
            codepage = fileCP;
        }
    }
}
void HtmlPrettyPrintTest() {
    size_t lenOut;
    AutoFree data;

    data.Set(PrettyPrintHtml("<p><b>Test</b></p>", (size_t)-1, lenOut));
    utassert(str::Len(data) == lenOut && str::Eq(data, "<p><b>Test</b></p>\n"));

    data.Set(PrettyPrintHtml("<p><b>Test</p>", (size_t)-1, lenOut));
    utassert(str::Len(data) == lenOut && str::Eq(data, "<p><b>Test</p>\n"));

    data.Set(PrettyPrintHtml("<html><body><p>Content</p></body></html>", (size_t)-1, lenOut));
    utassert(str::Len(data) == lenOut && str::Eq(data, "<html>\n\t<body>\n\t\t<p>Content</p>\n\t</body>\n</html>\n"));

    data.Set(PrettyPrintHtml("<html><body><p>Content</html></body>", (size_t)-1, lenOut));
    // TODO: add newline before non-matching </html> ?
    // TODO: insert missing closing tags (</p> and </body>)?
    utassert(str::Len(data) == lenOut && str::Eq(data, "<html>\n\t<body>\n\t\t<p>Content</html>\n</body>\n"));

    data.Set(PrettyPrintHtml("<p  attr=' value '><b> bold  text </b> </p>", (size_t)-1, lenOut));
    // TODO: normalize whitespace?
    utassert(str::Len(data) == lenOut && str::Eq(data, "<p  attr=' value '><b> bold  text </b></p>\n"));
}
Beispiel #3
0
bool ChmDoc::HasData(const char* fileName) {
    if (!fileName)
        return nullptr;

    AutoFree tmpName;
    if (!str::StartsWith(fileName, "/")) {
        tmpName.Set(str::Join("/", fileName));
        fileName = tmpName;
    } else if (str::StartsWith(fileName, "///"))
        fileName += 2;

    struct chmUnitInfo info;
    return chm_resolve_object(chmHandle, fileName, &info) == CHM_RESOLVE_SUCCESS;
}
Beispiel #4
0
unsigned char* ChmDoc::GetData(const char* fileName, size_t* lenOut) {
    AutoFree fileNameTmp;
    if (!str::StartsWith(fileName, "/")) {
        fileNameTmp.Set(str::Join("/", fileName));
        fileName = fileNameTmp;
    } else if (str::StartsWith(fileName, "///")) {
        fileName += 2;
    }

    struct chmUnitInfo info;
    int res = chm_resolve_object(chmHandle, fileName, &info);
    if (CHM_RESOLVE_SUCCESS != res && str::FindChar(fileName, '\\')) {
        // Microsoft's HTML Help CHM viewer tolerates backslashes in URLs
        fileNameTmp.SetCopy(fileName);
        str::TransChars(fileNameTmp, "\\", "/");
        fileName = fileNameTmp;
        res = chm_resolve_object(chmHandle, fileName, &info);
    }
    if (CHM_RESOLVE_SUCCESS != res)
        return nullptr;
    size_t len = (size_t)info.length;
    if (len > 128 * 1024 * 1024) {
        // don't allow anything above 128 MB
        return nullptr;
    }

    // +1 for 0 terminator for C string compatibility
    ScopedMem<unsigned char> data((unsigned char*)malloc(len + 1));
    if (!data)
        return nullptr;
    if (!chm_retrieve_object(chmHandle, &info, data.Get(), 0, len))
        return nullptr;
    data[len] = '\0';

    if (lenOut)
        *lenOut = len;
    return data.StealData();
}