/*
 * The contents of this file are subject to the Mozilla Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 *
 * The Original Code is MPEG4IP.
 *
 * The Initial Developer of the Original Code is Cisco Systems Inc.
 * Portions created by Cisco Systems Inc. are
 * Copyright (C) Cisco Systems Inc. 2001.  All Rights Reserved.
 *
 * Contributor(s):
 *      Dave Mackie     dmackie@cisco.com
 */

#include "src/impl.h"

namespace mp4v2 {
namespace impl {

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

// MP4File low level IO support

uint64_t MP4File::GetPosition( File* file )
{
    if( m_memoryBuffer )
        return m_memoryBufferPosition;

    if( !file )
        file = m_file;

    ASSERT( file );
    return file->position - m_initialSeekOffset;
}

void MP4File::SetPosition( uint64_t pos, File* file )
{
    if( m_memoryBuffer ) {
        if( pos >= m_memoryBufferSize )
            throw new Exception( "position out of range", __FILE__, __LINE__, __FUNCTION__ );
        m_memoryBufferPosition = pos;
        return;
    }

    if( !file )
        file = m_file;

    ASSERT( file );
    if( file->seek( pos + m_initialSeekOffset))
        throw new PlatformException( "seek failed", sys::getLastError(), __FILE__, __LINE__, __FUNCTION__ );
}

uint64_t MP4File::GetSize( File* file )
{
    if( m_memoryBuffer )
        return m_memoryBufferSize;

    if( !file )
        file = m_file;

    ASSERT( file );
    return file->size - m_initialSeekOffset;
}

void MP4File::ReadBytes( uint8_t* buf, uint32_t bufsiz, File* file )
{
    if( bufsiz == 0 )
        return;

    ASSERT( buf );
    WARNING( m_numReadBits > 0 );

    if( m_memoryBuffer ) {
        if( m_memoryBufferPosition + bufsiz > m_memoryBufferSize )
            throw new Exception( "not enough bytes, reached end-of-memory", __FILE__, __LINE__, __FUNCTION__ );
        memcpy( buf, &m_memoryBuffer[m_memoryBufferPosition], bufsiz );
        m_memoryBufferPosition += bufsiz;
        return;
    }

    if( !file )
        file = m_file;

    ASSERT( file );
    File::Size nin;
    if( file->read( buf, bufsiz, nin ))
        throw new PlatformException( "read failed", sys::getLastError(), __FILE__, __LINE__, __FUNCTION__ );
    if( nin != bufsiz )
        throw new Exception( "not enough bytes, reached end-of-file", __FILE__, __LINE__, __FUNCTION__ );
}

void MP4File::PeekBytes( uint8_t* buf, uint32_t bufsiz, File* file )
{
    const uint64_t pos = GetPosition( file );
    ReadBytes( buf, bufsiz, file );
    SetPosition( pos, file );
}

void MP4File::EnableMemoryBuffer( uint8_t* pBytes, uint64_t numBytes )
{
    ASSERT( !m_memoryBuffer );

    if (pBytes) {
        m_memoryBuffer = pBytes;
        m_memoryBufferSize = numBytes;
    } else {
        if (numBytes) {
            m_memoryBufferSize = numBytes;
        } else {
            m_memoryBufferSize = 4096;
        }
        m_memoryBuffer = (uint8_t*)MP4Malloc(m_memoryBufferSize);
    }
    m_memoryBufferPosition = 0;
}

void MP4File::DisableMemoryBuffer( uint8_t** ppBytes, uint64_t* pNumBytes )
{
    ASSERT(m_memoryBuffer != NULL);

    if (ppBytes) {
        *ppBytes = m_memoryBuffer;
    }
    if (pNumBytes) {
        *pNumBytes = m_memoryBufferPosition;
    }

    m_memoryBuffer = NULL;
    m_memoryBufferSize = 0;
    m_memoryBufferPosition = 0;
}

void MP4File::WriteBytes( uint8_t* buf, uint32_t bufsiz, File* file )
{
    ASSERT( m_numWriteBits == 0 || m_numWriteBits >= 8 );

    if( !buf || bufsiz == 0 )
        return;

    if( m_memoryBuffer ) {
        if( m_memoryBufferPosition + bufsiz > m_memoryBufferSize ) {
            m_memoryBufferSize = 2 * (m_memoryBufferSize + bufsiz);
            m_memoryBuffer = (uint8_t*)MP4Realloc( m_memoryBuffer, m_memoryBufferSize );
        }
        memcpy( &m_memoryBuffer[m_memoryBufferPosition], buf, bufsiz );
        m_memoryBufferPosition += bufsiz;
        return;
    }

    if( !file )
        file = m_file;

    ASSERT( file );
    File::Size nout;
    if( file->write( buf, bufsiz, nout ))
        throw new PlatformException( "write failed", sys::getLastError(), __FILE__, __LINE__, __FUNCTION__ );
    if( nout != bufsiz )
        throw new Exception( "not all bytes written", __FILE__, __LINE__, __FUNCTION__ );
}

uint64_t MP4File::ReadUInt(uint8_t size)
{
    switch (size) {
    case 1:
        return ReadUInt8();
    case 2:
        return ReadUInt16();
    case 3:
        return ReadUInt24();
    case 4:
        return ReadUInt32();
    case 8:
        return ReadUInt64();
    default:
        ASSERT(false);
        return 0;
    }
}

uint8_t MP4File::ReadUInt8()
{
    uint8_t data;
    ReadBytes(&data, 1);
    return data;
}

void MP4File::WriteUInt8(uint8_t value)
{
    WriteBytes(&value, 1);
}

uint16_t MP4File::ReadUInt16()
{
    uint8_t data[2];
    ReadBytes(&data[0], 2);
    return ((data[0] << 8) | data[1]);
}

void MP4File::WriteUInt16(uint16_t value)
{
    uint8_t data[2];
    data[0] = (value >> 8) & 0xFF;
    data[1] = value & 0xFF;
    WriteBytes(data, 2);
}

uint32_t MP4File::ReadUInt24()
{
    uint8_t data[3];
    ReadBytes(&data[0], 3);
    return ((data[0] << 16) | (data[1] << 8) | data[2]);
}

void MP4File::WriteUInt24(uint32_t value)
{
    uint8_t data[3];
    data[0] = (value >> 16) & 0xFF;
    data[1] = (value >> 8) & 0xFF;
    data[2] = value & 0xFF;
    WriteBytes(data, 3);
}

uint32_t MP4File::ReadUInt32()
{
    uint8_t data[4];
    ReadBytes(&data[0], 4);
    return ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]);
}

void MP4File::WriteUInt32(uint32_t value)
{
    uint8_t data[4];
    data[0] = (value >> 24) & 0xFF;
    data[1] = (value >> 16) & 0xFF;
    data[2] = (value >> 8) & 0xFF;
    data[3] = value & 0xFF;
    WriteBytes(data, 4);
}

uint64_t MP4File::ReadUInt64()
{
    uint8_t data[8];
    uint64_t result = 0;
    uint64_t temp;

    ReadBytes(&data[0], 8);

    for (int i = 0; i < 8; i++) {
        temp = data[i];
        result |= temp << ((7 - i) * 8);
    }
    return result;
}

void MP4File::WriteUInt64(uint64_t value)
{
    uint8_t data[8];

    for (int i = 7; i >= 0; i--) {
        data[i] = value & 0xFF;
        value >>= 8;
    }
    WriteBytes(data, 8);
}

float MP4File::ReadFixed16()
{
    uint8_t iPart = ReadUInt8();
    uint8_t fPart = ReadUInt8();

    return iPart + (((float)fPart) / 0x100);
}

void MP4File::WriteFixed16(float value)
{
    if (value >= 0x100) {
        ostringstream msg;
        msg << value << " out of range";
        throw new PlatformException(msg.str().c_str(), ERANGE, __FILE__, __LINE__, __FUNCTION__);
    }

    uint8_t iPart = (uint8_t)value;
    uint8_t fPart = (uint8_t)((value - iPart) * 0x100);

    WriteUInt8(iPart);
    WriteUInt8(fPart);
}

float MP4File::ReadFixed32()
{
    uint16_t iPart = ReadUInt16();
    uint16_t fPart = ReadUInt16();

    return iPart + (((float)fPart) / 0x10000);
}

void MP4File::WriteFixed32(float value)
{
    if (value >= 0x10000) {
        ostringstream msg;
        msg << value << " out of range";
        throw new PlatformException(msg.str().c_str(), ERANGE, __FILE__, __LINE__, __FUNCTION__);
    }

    uint16_t iPart = (uint16_t)value;
    uint16_t fPart = (uint16_t)((value - iPart) * 0x10000);

    WriteUInt16(iPart);
    WriteUInt16(fPart);
}

float MP4File::ReadFloat()
{
    union {
        float f;
        uint32_t i;
    } u;

    u.i = ReadUInt32();
    return u.f;
}

void MP4File::WriteFloat(float value)
{
    union {
        float f;
        uint32_t i;
    } u;

    u.f = value;
    WriteUInt32(u.i);
}

char* MP4File::ReadString()
{
    uint32_t length = 0;
    uint32_t alloced = 64;
    char* data = (char*)MP4Malloc(alloced);

    do {
        if (length == alloced) {
            data = (char*)MP4Realloc(data, alloced * 2);
            if (data == NULL) return NULL;
            alloced *= 2;
        }
        ReadBytes((uint8_t*)&data[length], 1);
        length++;
    } while (data[length - 1] != 0);

    data = (char*)MP4Realloc(data, length);
    return data;
}

void MP4File::WriteString(char* string)
{
    if (string == NULL) {
        uint8_t zero = 0;
        WriteBytes(&zero, 1);
    } else {
        WriteBytes((uint8_t*)string, (uint32_t)strlen(string) + 1);
    }
}

char* MP4File::ReadCountedString(uint8_t charSize, bool allowExpandedCount, uint8_t fixedLength)
{
    uint32_t charLength;
    if (allowExpandedCount) {
        uint8_t b;
        uint32_t ix = 0;
        charLength = 0;
        do {
            b = ReadUInt8();
            charLength += b;
            ix++;
            if (ix > 25)
                throw new PlatformException("Counted string too long 25 * 255",ERANGE,
                                            __FILE__, __LINE__, __FUNCTION__);
        } while (b == 255);
    } else {
        charLength = ReadUInt8();
    }
    
    if (fixedLength && (charLength > fixedLength - 1)) {
        /*
         * The counted length of this string is greater than the
         * maxiumum fixed length, so truncate the string to the
         * maximum fixed length amount (take 1 byte away from the
         * fixedlength since we've already sacrificed one byte for
         * reading the counted length, and there has been a bug where
         * a non counted string has been used in the place of a
         * counted string).
         */  
        WARNING(charLength > fixedLength - 1);
        charLength = fixedLength - 1U;
    }

    uint32_t byteLength = charLength * charSize;
    char* data = (char*)MP4Malloc(byteLength + 1);
    if (byteLength > 0) {
        ReadBytes((uint8_t*)data, byteLength);
    }
    data[byteLength] = '\0';

    // read padding
    if (fixedLength) {
        const uint8_t padsize = fixedLength - byteLength -1U;
        if( padsize ) {
            uint8_t* padbuf = (uint8_t*)malloc( padsize );
            ReadBytes( padbuf, padsize );
            free( padbuf );
        }
    }

    return data;
}

void MP4File::WriteCountedString(char* string,
                                 uint8_t charSize, bool allowExpandedCount,
                                 uint32_t fixedLength)
{
    uint32_t byteLength;
    uint8_t zero[1];

    if (string) {
        byteLength = (uint32_t)strlen(string);
        if (fixedLength && (byteLength >= fixedLength)) {
            byteLength = fixedLength-1;
        }
    }
    else {
        byteLength = 0;
    }
    uint32_t charLength = byteLength / charSize;

    if (allowExpandedCount) {
        while (charLength >= 0xFF) {
            WriteUInt8(0xFF);
            charLength -= 0xFF;
        }
        // Write the count
        WriteUInt8(charLength);
    } else {
        if (charLength > 255) {
            ostringstream msg;
            msg << "Length is " << charLength;
            throw new PlatformException(msg.str().c_str(), ERANGE, __FILE__, __LINE__, __FUNCTION__);
        }
        // Write the count
        WriteUInt8(charLength);
    }

    if (byteLength > 0) {
        // Write the string (or the portion that we want to write)
        WriteBytes((uint8_t*)string, byteLength);
    }

    // Write any padding if this is a fixed length counted string
    if (fixedLength) {
        zero[0] = 0;
        while (byteLength < fixedLength-1U) {
            WriteBytes(zero, 1);
            byteLength++;
        }
    }
}

uint64_t MP4File::ReadBits(uint8_t numBits)
{
    ASSERT(numBits > 0);
    ASSERT(numBits <= 64);

    uint64_t bits = 0;

    for (uint8_t i = numBits; i > 0; i--) {
        if (m_numReadBits == 0) {
            ReadBytes(&m_bufReadBits, 1);
            m_numReadBits = 8;
        }
        bits = (bits << 1) | ((m_bufReadBits >> (--m_numReadBits)) & 1);
    }

    return bits;
}

void MP4File::FlushReadBits()
{
    // eat any remaining bits in the read buffer
    m_numReadBits = 0;
}

void MP4File::WriteBits(uint64_t bits, uint8_t numBits)
{
    ASSERT(numBits <= 64);

    for (uint8_t i = numBits; i > 0; i--) {
        m_bufWriteBits |=
            (((bits >> (i - 1)) & 1) << (8 - ++m_numWriteBits));

        if (m_numWriteBits == 8) {
            FlushWriteBits();
        }
    }
}

void MP4File::PadWriteBits(uint8_t pad)
{
    if (m_numWriteBits) {
        WriteBits(pad ? 0xFF : 0x00, 8 - m_numWriteBits);
    }
}

void MP4File::FlushWriteBits()
{
    if (m_numWriteBits > 0) {
        WriteBytes(&m_bufWriteBits, 1);
        m_numWriteBits = 0;
        m_bufWriteBits = 0;
    }
}

uint32_t MP4File::ReadMpegLength()
{
    uint32_t length = 0;
    uint8_t numBytes = 0;
    uint8_t b;

    do {
        b = ReadUInt8();
        length = (length << 7) | (b & 0x7F);
        numBytes++;
    } while ((b & 0x80) && numBytes < 4);

    return length;
}

void MP4File::WriteMpegLength(uint32_t value, bool compact)
{
    if (value > 0x0FFFFFFF) {
        ostringstream msg;
        msg << "out of range: " << value;
        throw new PlatformException(msg.str().c_str(), ERANGE, __FILE__, __LINE__, __FUNCTION__ ); 
    }

    int8_t numBytes;

    if (compact) {
        if (value <= 0x7F) {
            numBytes = 1;
        } else if (value <= 0x3FFF) {
            numBytes = 2;
        } else if (value <= 0x1FFFFF) {
            numBytes = 3;
        } else {
            numBytes = 4;
        }
    } else {
        numBytes = 4;
    }

    int8_t i = numBytes;
    do {
        i--;
        uint8_t b = (value >> (i * 7)) & 0x7F;
        if (i > 0) {
            b |= 0x80;
        }
        WriteUInt8(b);
    } while (i > 0);
}

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

}
} // namespace mp4v2::impl
