/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkPDFConvertType1FontStream.h"

#include "SkTemplates.h"
#include "SkTo.h"

#include <ctype.h>

static bool parsePFBSection(const uint8_t** src, size_t* len, int sectionType,
                            size_t* size) {
    // PFB sections have a two or six bytes header. 0x80 and a one byte
    // section type followed by a four byte section length.  Type one is
    // an ASCII section (includes a length), type two is a binary section
    // (includes a length) and type three is an EOF marker with no length.
    const uint8_t* buf = *src;
    if (*len < 2 || buf[0] != 0x80 || buf[1] != sectionType) {
        return false;
    } else if (buf[1] == 3) {
        return true;
    } else if (*len < 6) {
        return false;
    }

    *size = (size_t)buf[2] | ((size_t)buf[3] << 8) | ((size_t)buf[4] << 16) |
            ((size_t)buf[5] << 24);
    size_t consumed = *size + 6;
    if (consumed > *len) {
        return false;
    }
    *src = *src + consumed;
    *len = *len - consumed;
    return true;
}

static bool parsePFB(const uint8_t* src, size_t size, size_t* headerLen,
                     size_t* dataLen, size_t* trailerLen) {
    const uint8_t* srcPtr = src;
    size_t remaining = size;

    return parsePFBSection(&srcPtr, &remaining, 1, headerLen) &&
           parsePFBSection(&srcPtr, &remaining, 2, dataLen) &&
           parsePFBSection(&srcPtr, &remaining, 1, trailerLen) &&
           parsePFBSection(&srcPtr, &remaining, 3, nullptr);
}

/* The sections of a PFA file are implicitly defined.  The body starts
 * after the line containing "eexec," and the trailer starts with 512
 * literal 0's followed by "cleartomark" (plus arbitrary white space).
 *
 * This function assumes that src is NUL terminated, but the NUL
 * termination is not included in size.
 *
 */
static bool parsePFA(const char* src, size_t size, size_t* headerLen,
                     size_t* hexDataLen, size_t* dataLen, size_t* trailerLen) {
    const char* end = src + size;

    const char* dataPos = strstr(src, "eexec");
    if (!dataPos) {
        return false;
    }
    dataPos += strlen("eexec");
    while ((*dataPos == '\n' || *dataPos == '\r' || *dataPos == ' ') &&
            dataPos < end) {
        dataPos++;
    }
    *headerLen = dataPos - src;

    const char* trailerPos = strstr(dataPos, "cleartomark");
    if (!trailerPos) {
        return false;
    }
    int zeroCount = 0;
    for (trailerPos--; trailerPos > dataPos && zeroCount < 512; trailerPos--) {
        if (*trailerPos == '\n' || *trailerPos == '\r' || *trailerPos == ' ') {
            continue;
        } else if (*trailerPos == '0') {
            zeroCount++;
        } else {
            return false;
        }
    }
    if (zeroCount != 512) {
        return false;
    }

    *hexDataLen = trailerPos - src - *headerLen;
    *trailerLen = size - *headerLen - *hexDataLen;

    // Verify that the data section is hex encoded and count the bytes.
    int nibbles = 0;
    for (; dataPos < trailerPos; dataPos++) {
        if (isspace(*dataPos)) {
            continue;
        }
        // isxdigit() is locale-sensitive https://bugs.skia.org/8285
        if (nullptr == strchr("0123456789abcdefABCDEF", *dataPos)) {
            return false;
        }
        nibbles++;
    }
    *dataLen = (nibbles + 1) / 2;

    return true;
}

static int8_t hexToBin(uint8_t c) {
    if (!isxdigit(c)) {
        return -1;
    } else if (c <= '9') {
        return c - '0';
    } else if (c <= 'F') {
        return c - 'A' + 10;
    } else if (c <= 'f') {
        return c - 'a' + 10;
    }
    return -1;
}

sk_sp<SkData> SkPDFConvertType1FontStream(
        std::unique_ptr<SkStreamAsset> srcStream, size_t* headerLen,
        size_t* dataLen, size_t* trailerLen) {
    size_t srcLen = srcStream ? srcStream->getLength() : 0;
    SkASSERT(srcLen);
    if (!srcLen) {
        return nullptr;
    }
    // Flatten and Nul-terminate the source stream so that we can use
    // strstr() to search it.
    SkAutoTMalloc<uint8_t> sourceBuffer(SkToInt(srcLen + 1));
    (void)srcStream->read(sourceBuffer.get(), srcLen);
    sourceBuffer[SkToInt(srcLen)] = 0;
    const uint8_t* src = sourceBuffer.get();

    if (parsePFB(src, srcLen, headerLen, dataLen, trailerLen)) {
        static const int kPFBSectionHeaderLength = 6;
        const size_t length = *headerLen + *dataLen + *trailerLen;
        SkASSERT(length > 0);
        SkASSERT(length + (2 * kPFBSectionHeaderLength) <= srcLen);

        sk_sp<SkData> data(SkData::MakeUninitialized(length));

        const uint8_t* const srcHeader = src + kPFBSectionHeaderLength;
        // There is a six-byte section header before header and data
        // (but not trailer) that we're not going to copy.
        const uint8_t* const srcData = srcHeader + *headerLen + kPFBSectionHeaderLength;
        const uint8_t* const srcTrailer = srcData + *headerLen;

        uint8_t* const resultHeader = (uint8_t*)data->writable_data();
        uint8_t* const resultData = resultHeader + *headerLen;
        uint8_t* const resultTrailer = resultData + *dataLen;

        SkASSERT(resultTrailer + *trailerLen == resultHeader + length);

        memcpy(resultHeader,  srcHeader,  *headerLen);
        memcpy(resultData,    srcData,    *dataLen);
        memcpy(resultTrailer, srcTrailer, *trailerLen);

        return data;
    }

    // A PFA has to be converted for PDF.
    size_t hexDataLen;
    if (!parsePFA((const char*)src, srcLen, headerLen, &hexDataLen, dataLen,
                 trailerLen)) {
        return nullptr;
    }
    const size_t length = *headerLen + *dataLen + *trailerLen;
    SkASSERT(length > 0);
    auto data = SkData::MakeUninitialized(length);
    uint8_t* buffer = (uint8_t*)data->writable_data();

    memcpy(buffer, src, *headerLen);
    uint8_t* const resultData = &(buffer[*headerLen]);

    const uint8_t* hexData = src + *headerLen;
    const uint8_t* trailer = hexData + hexDataLen;
    size_t outputOffset = 0;
    uint8_t dataByte = 0;  // To hush compiler.
    bool highNibble = true;
    for (; hexData < trailer; hexData++) {
        int8_t curNibble = hexToBin(*hexData);
        if (curNibble < 0) {
            continue;
        }
        if (highNibble) {
            dataByte = curNibble << 4;
            highNibble = false;
        } else {
            dataByte |= curNibble;
            highNibble = true;
            resultData[outputOffset++] = dataByte;
        }
    }
    if (!highNibble) {
        resultData[outputOffset++] = dataByte;
    }
    SkASSERT(outputOffset == *dataLen);

    uint8_t* const resultTrailer = &(buffer[SkToInt(*headerLen + outputOffset)]);
    memcpy(resultTrailer, src + *headerLen + hexDataLen, *trailerLen);
    return data;
}
