
/*
 * 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 "SkPDFTypes.h"
#include "SkPDFUtils.h"
#include "SkStream.h"

#ifdef SK_BUILD_FOR_WIN
    #define SNPRINTF    _snprintf
#else
    #define SNPRINTF    snprintf
#endif

////////////////////////////////////////////////////////////////////////////////

SkString* pun(char* x) { return reinterpret_cast<SkString*>(x); }
const SkString* pun(const char* x) {
    return reinterpret_cast<const SkString*>(x);
}

SkPDFUnion::SkPDFUnion(Type t) : fType(t) {}

SkPDFUnion::~SkPDFUnion() {
    switch (fType) {
        case Type::kNameSkS:
        case Type::kStringSkS:
            pun(fSkString)->~SkString();
            return;
        case Type::kObjRef:
        case Type::kObject:
            SkSafeUnref(fObject);
            return;
        default:
            return;
    }
}

SkPDFUnion& SkPDFUnion::operator=(SkPDFUnion&& other) {
    if (this != &other) {
        this->~SkPDFUnion();
        SkNEW_PLACEMENT_ARGS(this, SkPDFUnion, (other.move()));
    }
    return *this;
}

SkPDFUnion::SkPDFUnion(SkPDFUnion&& other) {
    SkASSERT(this != &other);
    memcpy(this, &other, sizeof(*this));
    other.fType = Type::kDestroyed;
}

#if 0
SkPDFUnion SkPDFUnion::copy() const {
    SkPDFUnion u(fType);
    memcpy(&u, this, sizeof(u));
    switch (fType) {
        case Type::kNameSkS:
        case Type::kStringSkS:
            SkNEW_PLACEMENT_ARGS(pun(u.fSkString), SkString,
                                 (*pun(fSkString)));
            return u.move();
        case Type::kObjRef:
        case Type::kObject:
            SkRef(u.fObject);
            return u.move();
        default:
            return u.move();
    }
}
SkPDFUnion& SkPDFUnion::operator=(const SkPDFUnion& other) {
    return *this = other.copy();
}
SkPDFUnion::SkPDFUnion(const SkPDFUnion& other) {
    *this = other.copy();
}
#endif

bool SkPDFUnion::isName() const {
    return Type::kName == fType || Type::kNameSkS == fType;
}

#ifdef SK_DEBUG
// Most names need no escaping.  Such names are handled as static
// const strings.
bool is_valid_name(const char* n) {
    static const char kControlChars[] = "/%()<>[]{}";
    while (*n) {
        if (*n < '!' || *n > '~' || strchr(kControlChars, *n)) {
            return false;
        }
        ++n;
    }
    return true;
}
#endif  // SK_DEBUG

// Given an arbitrary string, convert it to a valid name.
static SkString escape_name(const char* name, size_t len) {
    static const char kToEscape[] = "#/%()<>[]{}";
    int count = 0;
    const char* const end = &name[len];
    for (const char* n = name; n != end; ++n) {
        if (*n < '!' || *n > '~' || strchr(kToEscape, *n)) {
            count += 2;
        }
        ++count;
    }
    SkString result(count);
    char* s = result.writable_str();
    static const char kHex[] = "0123456789ABCDEF";
    for (const char* n = name; n != end; ++n) {
        if (*n < '!' || *n > '~' || strchr(kToEscape, *n)) {
            *s++ = '#';
            *s++ = kHex[(*n >> 4) & 0xF];
            *s++ = kHex[*n & 0xF];
        } else {
            *s++ = *n;
        }
    }
    SkASSERT(&result.writable_str()[count] == s);  // don't over-write
    return result;                                 // allocated space
}

static SkString escape_name(const SkString& name) {
    return escape_name(name.c_str(), name.size());
}

static void write_string(SkWStream* o, const SkString& s) {
    o->write(s.c_str(), s.size());
}

static SkString format_string(const SkString& s) {
    return SkPDFUtils::FormatString(s.c_str(), s.size());
}

static SkString format_string(const char* s) {
    return SkPDFUtils::FormatString(s, strlen(s));
}

void SkPDFUnion::emitObject(SkWStream* stream,
                            const SkPDFObjNumMap& objNumMap,
                            const SkPDFSubstituteMap& substitutes) const {
    switch (fType) {
        case Type::kInt:
            stream->writeDecAsText(fIntValue);
            return;
        case Type::kBool:
            stream->writeText(fBoolValue ? "true" : "false");
            return;
        case Type::kScalar:
            SkPDFUtils::AppendScalar(fScalarValue, stream);
            return;
        case Type::kName:
            stream->writeText("/");
            SkASSERT(is_valid_name(fStaticString));
            stream->writeText(fStaticString);
            return;
        case Type::kString:
            SkASSERT(fStaticString);
            write_string(stream, format_string(fStaticString));
            return;
        case Type::kNameSkS:
            stream->writeText("/");
            write_string(stream, escape_name(*pun(fSkString)));
            return;
        case Type::kStringSkS:
            write_string(stream, format_string(*pun(fSkString)));
            return;
        case Type::kObjRef:
            stream->writeDecAsText(objNumMap.getObjectNumber(
                    substitutes.getSubstitute(fObject)));
            stream->writeText(" 0 R");  // Generation number is always 0.
            return;
        case Type::kObject:
            fObject->emitObject(stream, objNumMap, substitutes);
            return;
        default:
            SkDEBUGFAIL("SkPDFUnion::emitObject with bad type");
    }
}

void SkPDFUnion::addResources(SkPDFObjNumMap* objNumMap,
                              const SkPDFSubstituteMap& substituteMap) const {
    switch (fType) {
        case Type::kInt:
        case Type::kBool:
        case Type::kScalar:
        case Type::kName:
        case Type::kString:
        case Type::kNameSkS:
        case Type::kStringSkS:
            return;  // These have no resources.
        case Type::kObjRef: {
            SkPDFObject* obj = substituteMap.getSubstitute(fObject);
            if (objNumMap->addObject(obj)) {
                obj->addResources(objNumMap, substituteMap);
            }
            return;
        }
        case Type::kObject:
            fObject->addResources(objNumMap, substituteMap);
            return;
        default:
            SkDEBUGFAIL("SkPDFUnion::addResources with bad type");
    }
}

SkPDFUnion SkPDFUnion::Int(int32_t value) {
    SkPDFUnion u(Type::kInt);
    u.fIntValue = value;
    return u.move();
}

SkPDFUnion SkPDFUnion::Bool(bool value) {
    SkPDFUnion u(Type::kBool);
    u.fBoolValue = value;
    return u.move();
}

SkPDFUnion SkPDFUnion::Scalar(SkScalar value) {
    SkPDFUnion u(Type::kScalar);
    u.fScalarValue = value;
    return u.move();
}

SkPDFUnion SkPDFUnion::Name(const char* value) {
    SkPDFUnion u(Type::kName);
    SkASSERT(value);
    SkASSERT(is_valid_name(value));
    u.fStaticString = value;
    return u.move();
}

SkPDFUnion SkPDFUnion::String(const char* value) {
    SkPDFUnion u(Type::kString);
    SkASSERT(value);
    u.fStaticString = value;
    return u.move();
}

SkPDFUnion SkPDFUnion::Name(const SkString& s) {
    SkPDFUnion u(Type::kNameSkS);
    SkNEW_PLACEMENT_ARGS(pun(u.fSkString), SkString, (s));
    return u.move();
}

SkPDFUnion SkPDFUnion::String(const SkString& s) {
    SkPDFUnion u(Type::kStringSkS);
    SkNEW_PLACEMENT_ARGS(pun(u.fSkString), SkString, (s));
    return u.move();
}

SkPDFUnion SkPDFUnion::ObjRef(SkPDFObject* ptr) {
    SkPDFUnion u(Type::kObjRef);
    SkASSERT(ptr);
    u.fObject = ptr;
    return u.move();
}

SkPDFUnion SkPDFUnion::Object(SkPDFObject* ptr) {
    SkPDFUnion u(Type::kObject);
    SkASSERT(ptr);
    u.fObject = ptr;
    return u.move();
}

////////////////////////////////////////////////////////////////////////////////

#if 0  // Enable if needed.
void SkPDFAtom::emitObject(SkWStream* stream,
                           const SkPDFObjNumMap& objNumMap,
                           const SkPDFSubstituteMap& substitutes) {
    fValue.emitObject(stream, objNumMap, substitutes);
}
void SkPDFAtom::addResources(SkPDFObjNumMap* map,
                             const SkPDFSubstituteMap& substitutes) const {
    fValue.addResources(map, substitutes);
}
#endif  // 0

////////////////////////////////////////////////////////////////////////////////

SkPDFArray::SkPDFArray() {}
SkPDFArray::~SkPDFArray() {
    for (SkPDFUnion& value : fValues) {
        value.~SkPDFUnion();
    }
    fValues.reset();
}

int SkPDFArray::size() const { return fValues.count(); }

void SkPDFArray::reserve(int length) { fValues.setReserve(length); }

void SkPDFArray::emitObject(SkWStream* stream,
                             const SkPDFObjNumMap& objNumMap,
                             const SkPDFSubstituteMap& substitutes) {
    stream->writeText("[");
    for (int i = 0; i < fValues.count(); i++) {
        fValues[i].emitObject(stream, objNumMap, substitutes);
        if (i + 1 < fValues.count()) {
            stream->writeText(" ");
        }
    }
    stream->writeText("]");
}

void SkPDFArray::addResources(SkPDFObjNumMap* catalog,
                              const SkPDFSubstituteMap& substitutes) const {
    for (const SkPDFUnion& value : fValues) {
        value.addResources(catalog, substitutes);
    }
}

void SkPDFArray::append(SkPDFUnion&& value) {
    SkNEW_PLACEMENT_ARGS(fValues.append(), SkPDFUnion, (value.move()));
}

void SkPDFArray::appendInt(int32_t value) {
    this->append(SkPDFUnion::Int(value));
}

void SkPDFArray::appendBool(bool value) {
    this->append(SkPDFUnion::Bool(value));
}

void SkPDFArray::appendScalar(SkScalar value) {
    this->append(SkPDFUnion::Scalar(value));
}

void SkPDFArray::appendName(const char name[]) {
    this->append(SkPDFUnion::Name(SkString(name)));
}

void SkPDFArray::appendName(const SkString& name) {
    this->append(SkPDFUnion::Name(name));
}

void SkPDFArray::appendString(const SkString& value) {
    this->append(SkPDFUnion::String(value));
}

void SkPDFArray::appendString(const char value[]) {
    this->append(SkPDFUnion::String(value));
}

void SkPDFArray::appendObject(SkPDFObject* value) {
    this->append(SkPDFUnion::Object(value));
}

void SkPDFArray::appendObjRef(SkPDFObject* value) {
    this->append(SkPDFUnion::ObjRef(value));
}

///////////////////////////////////////////////////////////////////////////////

SkPDFDict::SkPDFDict() {}

SkPDFDict::~SkPDFDict() { this->clear(); }

SkPDFDict::SkPDFDict(const char type[]) { this->insertName("Type", type); }

void SkPDFDict::emitObject(SkWStream* stream,
                           const SkPDFObjNumMap& objNumMap,
                           const SkPDFSubstituteMap& substitutes) {
    stream->writeText("<<");
    for (int i = 0; i < fRecords.count(); i++) {
        fRecords[i].fKey.emitObject(stream, objNumMap, substitutes);
        stream->writeText(" ");
        fRecords[i].fValue.emitObject(stream, objNumMap, substitutes);
        if (i + 1 < fRecords.count()) {
            stream->writeText("\n");
        }
    }
    stream->writeText(">>");
}

void SkPDFDict::addResources(SkPDFObjNumMap* catalog,
                             const SkPDFSubstituteMap& substitutes) const {
    for (int i = 0; i < fRecords.count(); i++) {
        fRecords[i].fKey.addResources(catalog, substitutes);
        fRecords[i].fValue.addResources(catalog, substitutes);
    }
}

void SkPDFDict::set(SkPDFUnion&& name, SkPDFUnion&& value) {
    Record* rec = fRecords.append();
    SkASSERT(name.isName());
    SkNEW_PLACEMENT_ARGS(&rec->fKey, SkPDFUnion, (name.move()));
    SkNEW_PLACEMENT_ARGS(&rec->fValue, SkPDFUnion, (value.move()));
}

int SkPDFDict::size() const { return fRecords.count(); }

void SkPDFDict::insertObjRef(const char key[], SkPDFObject* value) {
    this->set(SkPDFUnion::Name(key), SkPDFUnion::ObjRef(value));
}
void SkPDFDict::insertObjRef(const SkString& key, SkPDFObject* value) {
    this->set(SkPDFUnion::Name(key), SkPDFUnion::ObjRef(value));
}

void SkPDFDict::insertObject(const char key[], SkPDFObject* value) {
    this->set(SkPDFUnion::Name(key), SkPDFUnion::Object(value));
}
void SkPDFDict::insertObject(const SkString& key, SkPDFObject* value) {
    this->set(SkPDFUnion::Name(key), SkPDFUnion::Object(value));
}

void SkPDFDict::insertBool(const char key[], bool value) {
    this->set(SkPDFUnion::Name(key), SkPDFUnion::Bool(value));
}

void SkPDFDict::insertInt(const char key[], int32_t value) {
    this->set(SkPDFUnion::Name(key), SkPDFUnion::Int(value));
}

void SkPDFDict::insertInt(const char key[], size_t value) {
    this->insertInt(key, SkToS32(value));
}

void SkPDFDict::insertScalar(const char key[], SkScalar value) {
    this->set(SkPDFUnion::Name(key), SkPDFUnion::Scalar(value));
}

void SkPDFDict::insertName(const char key[], const char name[]) {
    this->set(SkPDFUnion::Name(key), SkPDFUnion::Name(name));
}

void SkPDFDict::insertName(const char key[], const SkString& name) {
    this->set(SkPDFUnion::Name(key), SkPDFUnion::Name(name));
}

void SkPDFDict::insertString(const char key[], const char value[]) {
    this->set(SkPDFUnion::Name(key), SkPDFUnion::String(value));
}

void SkPDFDict::insertString(const char key[], const SkString& value) {
    this->set(SkPDFUnion::Name(key), SkPDFUnion::String(value));
}

void SkPDFDict::clear() {
    for (Record& rec : fRecords) {
        rec.fKey.~SkPDFUnion();
        rec.fValue.~SkPDFUnion();
    }
    fRecords.reset();
}

////////////////////////////////////////////////////////////////////////////////

SkPDFSubstituteMap::~SkPDFSubstituteMap() {
    fSubstituteMap.foreach(
            [](SkPDFObject*, SkPDFObject** v) { (*v)->unref(); });
}

void SkPDFSubstituteMap::setSubstitute(SkPDFObject* original,
                                       SkPDFObject* substitute) {
    SkASSERT(original != substitute);
    SkASSERT(!fSubstituteMap.find(original));
    fSubstituteMap.set(original, SkRef(substitute));
}

SkPDFObject* SkPDFSubstituteMap::getSubstitute(SkPDFObject* object) const {
    SkPDFObject** found = fSubstituteMap.find(object);
    return found ? *found : object;
}

////////////////////////////////////////////////////////////////////////////////

bool SkPDFObjNumMap::addObject(SkPDFObject* obj) {
    if (fObjectNumbers.find(obj)) {
        return false;
    }
    fObjectNumbers.set(obj, fObjectNumbers.count() + 1);
    fObjects.push(obj);
    return true;
}

int32_t SkPDFObjNumMap::getObjectNumber(SkPDFObject* obj) const {
    int32_t* objectNumberFound = fObjectNumbers.find(obj);
    SkASSERT(objectNumberFound);
    return *objectNumberFound;
}

