/*
 * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
 * Copyright (C) 2015 Canon Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "SharedBuffer.h"

#include <algorithm>
#include <wtf/HexNumber.h>
#include <wtf/persistence/PersistentCoders.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/unicode/UTF8Conversion.h>

namespace WebCore {

SharedBuffer::SharedBuffer(const char* data, size_t size)
{
    append(data, size);
}

SharedBuffer::SharedBuffer(const unsigned char* data, size_t size)
{
    append(reinterpret_cast<const char*>(data), size);
}

SharedBuffer::SharedBuffer(FileSystem::MappedFileData&& fileData)
    : m_size(fileData.size())
{
    m_segments.append({0, DataSegment::create(WTFMove(fileData))});
}

SharedBuffer::SharedBuffer(Vector<char>&& data)
{
    append(WTFMove(data));
}

#if USE(GSTREAMER)
Ref<SharedBuffer> SharedBuffer::create(GstMappedBuffer& mappedBuffer)
{
    ASSERT(mappedBuffer.isSharable());
    return adoptRef(*new SharedBuffer(mappedBuffer));
}

SharedBuffer::SharedBuffer(GstMappedBuffer& mappedBuffer)
    : m_size(mappedBuffer.size())
{
    m_segments.append({0, DataSegment::create(&mappedBuffer)});
}
#endif

RefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePath)
{
    bool mappingSuccess;
    FileSystem::MappedFileData mappedFileData(filePath, FileSystem::MappedFileMode::Shared, mappingSuccess);

    if (!mappingSuccess)
        return SharedBuffer::createFromReadingFile(filePath);

    return adoptRef(new SharedBuffer(WTFMove(mappedFileData)));
}

Ref<SharedBuffer> SharedBuffer::create(Vector<char>&& vector)
{
    return adoptRef(*new SharedBuffer(WTFMove(vector)));
}

// FIXME: Move the whole class from Vector<char> to Vector<uint8_t> and make this efficient, replacing the Vector<char> version above.
Ref<SharedBuffer> SharedBuffer::create(Vector<uint8_t>&& vector)
{
    return adoptRef(*new SharedBuffer { vector.data(), vector.size() });
}

void SharedBuffer::combineIntoOneSegment() const
{
#if ASSERT_ENABLED
    // FIXME: We ought to be able to set this to true and have no assertions fire.
    // Remove all instances of appending after calling this, because they are all O(n^2) algorithms since r215686.
    // m_hasBeenCombinedIntoOneSegment = true;
#endif
    if (m_segments.size() <= 1)
        return;

    Vector<char> combinedData;
    combinedData.reserveInitialCapacity(m_size);
    for (const auto& segment : m_segments)
        combinedData.append(segment.segment->data(), segment.segment->size());
    ASSERT(combinedData.size() == m_size);
    m_segments.clear();
    m_segments.append({0, DataSegment::create(WTFMove(combinedData))});
    ASSERT(m_segments.size() == 1);
    ASSERT(internallyConsistent());
}

const char* SharedBuffer::data() const
{
    if (!m_segments.size())
        return nullptr;
    combineIntoOneSegment();
    ASSERT(internallyConsistent());
    return m_segments[0].segment->data();
}

SharedBufferDataView SharedBuffer::getSomeData(size_t position) const
{
    RELEASE_ASSERT(position < m_size);
    auto comparator = [](const size_t& position, const DataSegmentVectorEntry& entry) {
        return position < entry.beginPosition;
    };
    const DataSegmentVectorEntry* element = std::upper_bound(m_segments.begin(), m_segments.end(), position, comparator);
    element--; // std::upper_bound gives a pointer to the element that is greater than position. We want the element just before that.
    return { element->segment.copyRef(), position - element->beginPosition };
}

String SharedBuffer::toHexString() const
{
    StringBuilder stringBuilder;
    for (unsigned byteOffset = 0; byteOffset < size(); byteOffset++) {
        const uint8_t byte = data()[byteOffset];
        stringBuilder.append(pad('0', 2, hex(byte)));
    }
    return stringBuilder.toString();
}

RefPtr<ArrayBuffer> SharedBuffer::tryCreateArrayBuffer() const
{
    auto arrayBuffer = ArrayBuffer::tryCreateUninitialized(static_cast<unsigned>(size()), sizeof(char));
    if (!arrayBuffer) {
        WTFLogAlways("SharedBuffer::tryCreateArrayBuffer Unable to create buffer. Requested size was %zu\n", size());
        return nullptr;
    }

    size_t position = 0;
    for (const auto& segment : m_segments) {
        memcpy(static_cast<char*>(arrayBuffer->data()) + position, segment.segment->data(), segment.segment->size());
        position += segment.segment->size();
    }

    ASSERT(position == m_size);
    ASSERT(internallyConsistent());
    return arrayBuffer;
}

void SharedBuffer::append(const SharedBuffer& data)
{
    ASSERT(!m_hasBeenCombinedIntoOneSegment);
    m_segments.reserveCapacity(m_segments.size() + data.m_segments.size());
    for (const auto& element : data.m_segments) {
        m_segments.uncheckedAppend({m_size, element.segment.copyRef()});
        m_size += element.segment->size();
    }
    ASSERT(internallyConsistent());
}

void SharedBuffer::append(const char* data, size_t length)
{
    ASSERT(!m_hasBeenCombinedIntoOneSegment);
    Vector<char> vector;
    vector.append(data, length);
    m_segments.append({m_size, DataSegment::create(WTFMove(vector))});
    m_size += length;
    ASSERT(internallyConsistent());
}

void SharedBuffer::append(Vector<char>&& data)
{
    ASSERT(!m_hasBeenCombinedIntoOneSegment);
    auto dataSize = data.size();
    m_segments.append({m_size, DataSegment::create(WTFMove(data))});
    m_size += dataSize;
    ASSERT(internallyConsistent());
}

void SharedBuffer::clear()
{
    m_size = 0;
    m_segments.clear();
    ASSERT(internallyConsistent());
}

Ref<SharedBuffer> SharedBuffer::copy() const
{
    Ref<SharedBuffer> clone = adoptRef(*new SharedBuffer);
    clone->m_size = m_size;
    clone->m_segments.reserveInitialCapacity(m_segments.size());
    for (const auto& element : m_segments)
        clone->m_segments.uncheckedAppend({element.beginPosition, element.segment.copyRef()});
    ASSERT(clone->internallyConsistent());
    ASSERT(internallyConsistent());
    return clone;
}

#if ASSERT_ENABLED
bool SharedBuffer::internallyConsistent() const
{
    size_t position = 0;
    for (const auto& element : m_segments) {
        if (element.beginPosition != position)
            return false;
        position += element.segment->size();
    }
    return position == m_size;
}
#endif // ASSERT_ENABLED

const char* SharedBuffer::DataSegment::data() const
{
    auto visitor = WTF::makeVisitor(
        [](const Vector<char>& data) { return data.data(); },
#if USE(CF)
        [](const RetainPtr<CFDataRef>& data) { return reinterpret_cast<const char*>(CFDataGetBytePtr(data.get())); },
#endif
#if USE(SOUP)
        [](const GUniquePtr<SoupBuffer>& data) { return data->data; },
#endif
#if USE(GLIB)
        [](const GRefPtr<GBytes>& data) { return reinterpret_cast<const char*>(g_bytes_get_data(data.get(), nullptr)); },
#endif
#if USE(GSTREAMER)
        [](const RefPtr<GstMappedBuffer>& data) { return reinterpret_cast<const char*>(data->data()); },
#endif
        [](const FileSystem::MappedFileData& data) { return reinterpret_cast<const char*>(data.data()); }
    );
    return WTF::visit(visitor, m_immutableData);
}

#if !USE(CF)
void SharedBuffer::hintMemoryNotNeededSoon() const
{
}
#endif

WTF::Persistence::Decoder SharedBuffer::decoder() const
{
    return { reinterpret_cast<const uint8_t*>(data()), size() };
}

bool SharedBuffer::operator==(const SharedBuffer& other) const
{
    if (this == &other)
        return true;

    if (m_size != other.m_size)
        return false;

    auto thisIterator = begin();
    size_t thisOffset = 0;
    auto otherIterator = other.begin();
    size_t otherOffset = 0;

    while (thisIterator != end() && otherIterator != other.end()) {
        auto& thisSegment = thisIterator->segment.get();
        auto& otherSegment = otherIterator->segment.get();

        if (&thisSegment == &otherSegment && !thisOffset && !otherOffset) {
            ++thisIterator;
            ++otherIterator;
            continue;
        }

        ASSERT(thisOffset < thisSegment.size());
        ASSERT(otherOffset < otherSegment.size());

        size_t thisRemaining = thisSegment.size() - thisOffset;
        size_t otherRemaining = otherSegment.size() - otherOffset;
        size_t remaining = std::min(thisRemaining, otherRemaining);

        if (memcmp(thisSegment.data() + thisOffset, otherSegment.data() + otherOffset, remaining))
            return false;

        thisOffset += remaining;
        otherOffset += remaining;

        if (thisOffset == thisSegment.size()) {
            ++thisIterator;
            thisOffset = 0;
        }

        if (otherOffset == otherSegment.size()) {
            ++otherIterator;
            otherOffset = 0;
        }
    }
    return true;
}

size_t SharedBuffer::DataSegment::size() const
{
    auto visitor = WTF::makeVisitor(
        [](const Vector<char>& data) { return data.size(); },
#if USE(CF)
        [](const RetainPtr<CFDataRef>& data) { return CFDataGetLength(data.get()); },
#endif
#if USE(SOUP)
        [](const GUniquePtr<SoupBuffer>& data) { return static_cast<size_t>(data->length); },
#endif
#if USE(GLIB)
        [](const GRefPtr<GBytes>& data) { return g_bytes_get_size(data.get()); },
#endif
#if USE(GSTREAMER)
        [](const RefPtr<GstMappedBuffer>& data) { return data->size(); },
#endif
        [](const FileSystem::MappedFileData& data) { return data.size(); }
    );
    return WTF::visit(visitor, m_immutableData);
}

SharedBufferDataView::SharedBufferDataView(Ref<SharedBuffer::DataSegment>&& segment, size_t positionWithinSegment)
    : m_positionWithinSegment(positionWithinSegment)
    , m_segment(WTFMove(segment))
{
    ASSERT(positionWithinSegment < m_segment->size());
}

size_t SharedBufferDataView::size() const
{
    return m_segment->size() - m_positionWithinSegment;
}

const char* SharedBufferDataView::data() const
{
    return m_segment->data() + m_positionWithinSegment;
}

RefPtr<SharedBuffer> utf8Buffer(const String& string)
{
    // Allocate a buffer big enough to hold all the characters.
    const int length = string.length();
    Vector<char> buffer(length * 3);

    // Convert to runs of 8-bit characters.
    char* p = buffer.data();
    if (length) {
        if (string.is8Bit()) {
            const LChar* d = string.characters8();
            if (!WTF::Unicode::convertLatin1ToUTF8(&d, d + length, &p, p + buffer.size()))
                return nullptr;
        } else {
            const UChar* d = string.characters16();
            if (WTF::Unicode::convertUTF16ToUTF8(&d, d + length, &p, p + buffer.size()) != WTF::Unicode::ConversionOK)
                return nullptr;
        }
    }

    buffer.shrink(p - buffer.data());
    return SharedBuffer::create(WTFMove(buffer));
}

} // namespace WebCore
