// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../include/fxcrt/fx_basic.h"
FX_STRSIZE FX_ftoa(FX_FLOAT f, FX_LPSTR buf);
CFX_BinaryBuf::CFX_BinaryBuf(IFX_Allocator* pAllocator)
    : m_pAllocator(pAllocator)
    , m_AllocStep(0)
    , m_pBuffer(NULL)
    , m_DataSize(0)
    , m_AllocSize(0)
{
}
CFX_BinaryBuf::CFX_BinaryBuf(FX_STRSIZE size, IFX_Allocator* pAllocator)
    : m_pAllocator(pAllocator)
    , m_AllocStep(0)
    , m_DataSize(size)
    , m_AllocSize(size)
{
    m_pBuffer = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, size);
}
CFX_BinaryBuf::~CFX_BinaryBuf()
{
    if (m_pBuffer) {
        FX_Allocator_Free(m_pAllocator, m_pBuffer);
    }
}
void CFX_BinaryBuf::Delete(int start_index, int count)
{
    if (!m_pBuffer || start_index < 0 || start_index + count > m_DataSize) {
        return;
    }
    FXSYS_memmove32(m_pBuffer + start_index, m_pBuffer + start_index + count, m_DataSize - start_index - count);
    m_DataSize -= count;
}
void CFX_BinaryBuf::Clear()
{
    m_DataSize = 0;
}
void CFX_BinaryBuf::DetachBuffer()
{
    m_DataSize = 0;
    m_pBuffer = NULL;
    m_AllocSize = 0;
}
void CFX_BinaryBuf::AttachData(void* buffer, FX_STRSIZE size)
{
    if (m_pBuffer) {
        FX_Allocator_Free(m_pAllocator, m_pBuffer);
    }
    m_DataSize = size;
    m_pBuffer = (FX_LPBYTE)buffer;
    m_AllocSize = size;
}
void CFX_BinaryBuf::TakeOver(CFX_BinaryBuf& other)
{
    AttachData(other.GetBuffer(), other.GetSize());
    other.DetachBuffer();
}
void CFX_BinaryBuf::EstimateSize(FX_STRSIZE size, FX_STRSIZE step)
{
    m_AllocStep = step;
    if (m_AllocSize >= size) {
        return;
    }
    ExpandBuf(size - m_DataSize);
}
void CFX_BinaryBuf::ExpandBuf(FX_STRSIZE add_size)
{
    FX_STRSIZE new_size = add_size + m_DataSize;
    if (m_AllocSize >= new_size) {
        return;
    }
    int alloc_step;
    if (m_AllocStep == 0) {
        alloc_step = m_AllocSize / 4;
        if (alloc_step < 128 ) {
            alloc_step = 128;
        }
    } else {
        alloc_step = m_AllocStep;
    }
    new_size = (new_size + alloc_step - 1) / alloc_step * alloc_step;
    FX_LPBYTE pNewBuffer = m_pBuffer;
    if (pNewBuffer) {
        pNewBuffer = FX_Allocator_Realloc(m_pAllocator, FX_BYTE, m_pBuffer, new_size);
    } else {
        pNewBuffer = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, new_size);
    }
    if (pNewBuffer) {
        m_pBuffer = pNewBuffer;
        m_AllocSize = new_size;
    }
}
void CFX_BinaryBuf::CopyData(const void* pStr, FX_STRSIZE size)
{
    if (size == 0) {
        m_DataSize = 0;
        return;
    }
    if (m_AllocSize < size) {
        ExpandBuf(size - m_DataSize);
    }
    if (!m_pBuffer) {
        return;
    }
    FXSYS_memcpy32(m_pBuffer, pStr, size);
    m_DataSize = size;
}
void CFX_BinaryBuf::AppendBlock(const void* pBuf, FX_STRSIZE size)
{
    ExpandBuf(size);
    if (pBuf && m_pBuffer) {
        FXSYS_memcpy32(m_pBuffer + m_DataSize, pBuf, size);
    }
    m_DataSize += size;
}
void CFX_BinaryBuf::InsertBlock(FX_STRSIZE pos, const void* pBuf, FX_STRSIZE size)
{
    ExpandBuf(size);
    if (!m_pBuffer) {
        return;
    }
    FXSYS_memmove32(m_pBuffer + pos + size, m_pBuffer + pos, m_DataSize - pos);
    if (pBuf) {
        FXSYS_memcpy32(m_pBuffer + pos, pBuf, size);
    }
    m_DataSize += size;
}
void CFX_BinaryBuf::AppendFill(FX_BYTE byte, FX_STRSIZE count)
{
    ExpandBuf(count);
    if (!m_pBuffer) {
        return;
    }
    FXSYS_memset8(m_pBuffer + m_DataSize, byte, count);
    m_DataSize += count;
}
CFX_ByteStringC CFX_BinaryBuf::GetByteString() const
{
    return CFX_ByteStringC(m_pBuffer, m_DataSize);
}
void CFX_BinaryBuf::GetByteStringL(CFX_ByteStringL &str) const
{
    str.Set(CFX_ByteStringC(m_pBuffer, m_DataSize), m_pAllocator);
}
CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_BSTR lpsz)
{
    AppendBlock((FX_LPCBYTE)lpsz, lpsz.GetLength());
    return *this;
}
CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (int i)
{
    char buf[32];
    FXSYS_itoa(i, buf, 10);
    AppendBlock(buf, (FX_STRSIZE)FXSYS_strlen(buf));
    return *this;
}
CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_DWORD i)
{
    char buf[32];
    FXSYS_itoa(i, buf, 10);
    AppendBlock(buf, (FX_STRSIZE)FXSYS_strlen(buf));
    return *this;
}
CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (double f)
{
    char buf[32];
    FX_STRSIZE len = FX_ftoa((FX_FLOAT)f, buf);
    AppendBlock(buf, len);
    return *this;
}
CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (const CFX_ByteTextBuf& buf)
{
    AppendBlock(buf.m_pBuffer, buf.m_DataSize);
    return *this;
}
void CFX_ByteTextBuf::operator =(const CFX_ByteStringC& str)
{
    CopyData((FX_LPCBYTE)str, str.GetLength());
}
void CFX_WideTextBuf::AppendChar(FX_WCHAR ch)
{
    if (m_AllocSize < m_DataSize + (FX_STRSIZE)sizeof(FX_WCHAR)) {
        ExpandBuf(sizeof(FX_WCHAR));
    }
    ASSERT(m_pBuffer != NULL);
    *(FX_WCHAR*)(m_pBuffer + m_DataSize) = ch;
    m_DataSize += sizeof(FX_WCHAR);
}
CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_WSTR str)
{
    AppendBlock(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR));
    return *this;
}
CFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideString &str)
{
    AppendBlock((FX_LPCWSTR)str, str.GetLength() * sizeof(FX_WCHAR));
    return *this;
}
CFX_WideTextBuf& CFX_WideTextBuf::operator << (int i)
{
    char buf[32];
    FXSYS_itoa(i, buf, 10);
    FX_STRSIZE len = (FX_STRSIZE)FXSYS_strlen(buf);
    if (m_AllocSize < m_DataSize + (FX_STRSIZE)(len * sizeof(FX_WCHAR))) {
        ExpandBuf(len * sizeof(FX_WCHAR));
    }
    ASSERT(m_pBuffer != NULL);
    FX_LPWSTR str = (FX_WCHAR*)(m_pBuffer + m_DataSize);
    for (FX_STRSIZE j = 0; j < len; j ++) {
        *str ++ = buf[j];
    }
    m_DataSize += len * sizeof(FX_WCHAR);
    return *this;
}
CFX_WideTextBuf& CFX_WideTextBuf::operator << (double f)
{
    char buf[32];
    FX_STRSIZE len = FX_ftoa((FX_FLOAT)f, buf);
    if (m_AllocSize < m_DataSize + (FX_STRSIZE)(len * sizeof(FX_WCHAR))) {
        ExpandBuf(len * sizeof(FX_WCHAR));
    }
    ASSERT(m_pBuffer != NULL);
    FX_LPWSTR str = (FX_WCHAR*)(m_pBuffer + m_DataSize);
    for (FX_STRSIZE i = 0; i < len; i ++) {
        *str ++ = buf[i];
    }
    m_DataSize += len * sizeof(FX_WCHAR);
    return *this;
}
CFX_WideTextBuf& CFX_WideTextBuf::operator << (FX_LPCWSTR lpsz)
{
    AppendBlock(lpsz, (FX_STRSIZE)FXSYS_wcslen(lpsz)*sizeof(FX_WCHAR));
    return *this;
}
CFX_WideTextBuf& CFX_WideTextBuf::operator << (const CFX_WideTextBuf& buf)
{
    AppendBlock(buf.m_pBuffer, buf.m_DataSize);
    return *this;
}
void CFX_WideTextBuf::operator =(FX_WSTR str)
{
    CopyData(str.GetPtr(), str.GetLength() * sizeof(FX_WCHAR));
}
CFX_WideStringC CFX_WideTextBuf::GetWideString() const
{
    return CFX_WideStringC((FX_LPCWSTR)m_pBuffer, m_DataSize / sizeof(FX_WCHAR));
}
void CFX_WideTextBuf::GetWideStringL(CFX_WideStringL& wideText) const
{
    wideText.Set(CFX_WideStringC((FX_LPCWSTR)m_pBuffer, m_DataSize / sizeof(FX_WCHAR)), m_pAllocator);
}
CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_BYTE i)
{
    if (m_pStream) {
        m_pStream->WriteBlock(&i, 1);
    } else {
        m_SavingBuf.AppendByte(i);
    }
    return *this;
}
CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (int i)
{
    if (m_pStream) {
        m_pStream->WriteBlock(&i, sizeof(int));
    } else {
        m_SavingBuf.AppendBlock(&i, sizeof(int));
    }
    return *this;
}
CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_DWORD i)
{
    if (m_pStream) {
        m_pStream->WriteBlock(&i, sizeof(FX_DWORD));
    } else {
        m_SavingBuf.AppendBlock(&i, sizeof(FX_DWORD));
    }
    return *this;
}
CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_FLOAT f)
{
    if (m_pStream) {
        m_pStream->WriteBlock(&f, sizeof(FX_FLOAT));
    } else {
        m_SavingBuf.AppendBlock(&f, sizeof(FX_FLOAT));
    }
    return *this;
}
CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_BSTR bstr)
{
    int len = bstr.GetLength();
    if (m_pStream) {
        m_pStream->WriteBlock(&len, sizeof(int));
        m_pStream->WriteBlock(bstr, len);
    } else {
        m_SavingBuf.AppendBlock(&len, sizeof(int));
        m_SavingBuf.AppendBlock(bstr, len);
    }
    return *this;
}
CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_LPCWSTR wstr)
{
    FX_STRSIZE len = (FX_STRSIZE)FXSYS_wcslen(wstr);
    if (m_pStream) {
        m_pStream->WriteBlock(&len, sizeof(int));
        m_pStream->WriteBlock(wstr, len);
    } else {
        m_SavingBuf.AppendBlock(&len, sizeof(int));
        m_SavingBuf.AppendBlock(wstr, len);
    }
    return *this;
}
CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (const CFX_WideString& wstr)
{
    CFX_ByteString encoded = wstr.UTF16LE_Encode();
    return operator << (encoded);
}
void CFX_ArchiveSaver::Write(const void* pData, FX_STRSIZE dwSize)
{
    if (m_pStream) {
        m_pStream->WriteBlock(pData, dwSize);
    } else {
        m_SavingBuf.AppendBlock(pData, dwSize);
    }
}
CFX_ArchiveLoader::CFX_ArchiveLoader(FX_LPCBYTE pData, FX_DWORD dwSize)
{
    m_pLoadingBuf = pData;
    m_LoadingPos = 0;
    m_LoadingSize = dwSize;
}
FX_BOOL CFX_ArchiveLoader::IsEOF()
{
    return m_LoadingPos >= m_LoadingSize;
}
CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_BYTE& i)
{
    if (m_LoadingPos >= m_LoadingSize) {
        return *this;
    }
    i = m_pLoadingBuf[m_LoadingPos++];
    return *this;
}
CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (int& i)
{
    Read(&i, sizeof(int));
    return *this;
}
CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_DWORD& i)
{
    Read(&i, sizeof(FX_DWORD));
    return *this;
}
CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (FX_FLOAT& i)
{
    Read(&i, sizeof(FX_FLOAT));
    return *this;
}
CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (CFX_ByteString& str)
{
    if (m_LoadingPos + 4 > m_LoadingSize) {
        return *this;
    }
    int len;
    operator >> (len);
    str.Empty();
    if (len <= 0 || m_LoadingPos + len > m_LoadingSize) {
        return *this;
    }
    FX_LPSTR buffer = str.GetBuffer(len);
    FXSYS_memcpy32(buffer, m_pLoadingBuf + m_LoadingPos, len);
    str.ReleaseBuffer(len);
    m_LoadingPos += len;
    return *this;
}
CFX_ArchiveLoader& CFX_ArchiveLoader::operator >> (CFX_WideString& str)
{
    CFX_ByteString encoded;
    operator >> (encoded);
    str = CFX_WideString::FromUTF16LE((const unsigned short*)(FX_LPCSTR)encoded, encoded.GetLength());
    return *this;
}
FX_BOOL CFX_ArchiveLoader::Read(void* pBuf, FX_DWORD dwSize)
{
    if (m_LoadingPos + dwSize > m_LoadingSize) {
        return FALSE;
    }
    FXSYS_memcpy32(pBuf, m_pLoadingBuf + m_LoadingPos, dwSize);
    m_LoadingPos += dwSize;
    return TRUE;
}
void CFX_BitStream::Init(FX_LPCBYTE pData, FX_DWORD dwSize)
{
    m_pData = pData;
    m_BitSize = dwSize * 8;
    m_BitPos = 0;
}
void CFX_BitStream::ByteAlign()
{
    int mod = m_BitPos % 8;
    if (mod == 0) {
        return;
    }
    m_BitPos += 8 - mod;
}
FX_DWORD CFX_BitStream::GetBits(FX_DWORD nBits)
{
    if (nBits > m_BitSize || m_BitPos + nBits > m_BitSize) {
        return 0;
    }
    if (nBits == 1) {
        int bit = (m_pData[m_BitPos / 8] & (1 << (7 - m_BitPos % 8))) ? 1 : 0;
        m_BitPos ++;
        return bit;
    }
    FX_DWORD byte_pos = m_BitPos / 8;
    FX_DWORD bit_pos = m_BitPos % 8, bit_left = nBits;
    FX_DWORD result = 0;
    if (bit_pos) {
        if (8 - bit_pos >= bit_left) {
            result = (m_pData[byte_pos] & (0xff >> bit_pos)) >> (8 - bit_pos - bit_left);
            m_BitPos += bit_left;
            return result;
        }
        bit_left -= 8 - bit_pos;
        result = (m_pData[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left;
    }
    while (bit_left >= 8) {
        bit_left -= 8;
        result |= m_pData[byte_pos++] << bit_left;
    }
    if (bit_left) {
        result |= m_pData[byte_pos] >> (8 - bit_left);
    }
    m_BitPos += nBits;
    return result;
}
IFX_BufferArchive::IFX_BufferArchive(FX_STRSIZE size, IFX_Allocator* pAllocator)
    : m_pAllocator(pAllocator)
    , m_BufSize(size)
    , m_pBuffer(NULL)
    , m_Length(0)
{
}
void IFX_BufferArchive::Clear()
{
    m_Length = 0;
    if (m_pBuffer) {
        FX_Allocator_Free(m_pAllocator, m_pBuffer);
        m_pBuffer = NULL;
    }
}
FX_BOOL IFX_BufferArchive::Flush()
{
    FX_BOOL bRet = DoWork(m_pBuffer, m_Length);
    m_Length = 0;
    return bRet;
}
FX_INT32 IFX_BufferArchive::AppendBlock(const void* pBuf, size_t size)
{
    if (!pBuf || size < 1) {
        return 0;
    }
    if (!m_pBuffer) {
        m_pBuffer = FX_Allocator_Alloc(m_pAllocator, FX_BYTE, m_BufSize);
        if (!m_pBuffer) {
            return -1;
        }
    }
    FX_LPBYTE buffer = (FX_LPBYTE)pBuf;
    FX_STRSIZE temp_size = (FX_STRSIZE)size;
    while (temp_size > 0) {
        FX_STRSIZE buf_size = FX_MIN(m_BufSize - m_Length, (FX_STRSIZE)temp_size);
        FXSYS_memcpy32(m_pBuffer + m_Length, buffer, buf_size);
        m_Length += buf_size;
        if (m_Length == m_BufSize) {
            if (!Flush()) {
                return -1;
            }
        }
        temp_size -= buf_size;
        buffer += buf_size;
    }
    return (FX_INT32)size;
}
FX_INT32 IFX_BufferArchive::AppendByte(FX_BYTE byte)
{
    return AppendBlock(&byte, 1);
}
FX_INT32 IFX_BufferArchive::AppendDWord(FX_DWORD i)
{
    char buf[32];
    FXSYS_itoa(i, buf, 10);
    return AppendBlock(buf, (size_t)FXSYS_strlen(buf));
}
FX_INT32 IFX_BufferArchive::AppendString(FX_BSTR lpsz)
{
    return AppendBlock((FX_LPCBYTE)lpsz, lpsz.GetLength());
}
CFX_FileBufferArchive::CFX_FileBufferArchive(FX_STRSIZE size, IFX_Allocator* pAllocator)
    : IFX_BufferArchive(size, pAllocator)
    , m_pFile(NULL)
    , m_bTakeover(FALSE)
{
}
CFX_FileBufferArchive::~CFX_FileBufferArchive()
{
    Clear();
}
void CFX_FileBufferArchive::Clear()
{
    if (m_pFile && m_bTakeover) {
        m_pFile->Release();
    }
    m_pFile = NULL;
    m_bTakeover = FALSE;
    IFX_BufferArchive::Clear();
}
FX_BOOL CFX_FileBufferArchive::AttachFile(IFX_StreamWrite *pFile, FX_BOOL bTakeover )
{
    if (!pFile) {
        return FALSE;
    }
    if (m_pFile && m_bTakeover) {
        m_pFile->Release();
    }
    m_pFile = pFile;
    m_bTakeover = bTakeover;
    return TRUE;
}
FX_BOOL CFX_FileBufferArchive::AttachFile(FX_LPCWSTR filename)
{
    if (!filename) {
        return FALSE;
    }
    if (m_pFile && m_bTakeover) {
        m_pFile->Release();
    }
    m_pFile = FX_CreateFileWrite(filename);
    if (!m_pFile) {
        return FALSE;
    }
    m_bTakeover = TRUE;
    return TRUE;
}
FX_BOOL CFX_FileBufferArchive::AttachFile(FX_LPCSTR filename)
{
    if (!filename) {
        return FALSE;
    }
    if (m_pFile && m_bTakeover) {
        m_pFile->Release();
    }
    m_pFile = FX_CreateFileWrite(filename);
    if (!m_pFile) {
        return FALSE;
    }
    m_bTakeover = TRUE;
    return TRUE;
}
FX_BOOL CFX_FileBufferArchive::DoWork(const void* pBuf, size_t size)
{
    if (!m_pFile) {
        return FALSE;
    }
    if (!pBuf || size < 1) {
        return TRUE;
    }
    return m_pFile->WriteBlock(pBuf, size);
}
