/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "MtpStringBuffer"

#include <string.h>

#include "MtpDataPacket.h"
#include "MtpStringBuffer.h"

namespace android {

MtpStringBuffer::MtpStringBuffer()
    :   mCharCount(0),
        mByteCount(1)
{
    mBuffer[0] = 0;
}

MtpStringBuffer::MtpStringBuffer(const char* src)
    :   mCharCount(0),
        mByteCount(1)
{
    set(src);
}

MtpStringBuffer::MtpStringBuffer(const uint16_t* src)
    :   mCharCount(0),
        mByteCount(1)
{
    set(src);
}

MtpStringBuffer::MtpStringBuffer(const MtpStringBuffer& src)
    :   mCharCount(src.mCharCount),
        mByteCount(src.mByteCount)
{
    memcpy(mBuffer, src.mBuffer, mByteCount);
}


MtpStringBuffer::~MtpStringBuffer() {
}

void MtpStringBuffer::set(const char* src) {
    // count the characters
    int count = 0;
    char ch;
    char* dest = (char*)mBuffer;

    while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) {
        if ((ch & 0x80) == 0) {
            // single byte character
            *dest++ = ch;
        } else if ((ch & 0xE0) == 0xC0) {
            // two byte character
            char ch1 = *src++;
            if (! ch1) {
                // last character was truncated, so ignore last byte
                break;
            }

            *dest++ = ch;
            *dest++ = ch1;
        } else if ((ch & 0xF0) == 0xE0) {
            // 3 byte char
            char ch1 = *src++;
            if (! ch1) {
                // last character was truncated, so ignore last byte
                break;
            }
            char ch2 = *src++;
            if (! ch2) {
                // last character was truncated, so ignore last byte
                break;
            }

            *dest++ = ch;
            *dest++ = ch1;
            *dest++ = ch2;
        }
        count++;
    }

    *dest++ = 0;
    mByteCount = dest - (char*)mBuffer;
    mCharCount = count;
}

void MtpStringBuffer::set(const uint16_t* src) {
    int count = 0;
    uint16_t ch;
    uint8_t* dest = mBuffer;

    while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) {
        if (ch >= 0x0800) {
            *dest++ = (uint8_t)(0xE0 | (ch >> 12));
            *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F));
            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
        } else if (ch >= 0x80) {
            *dest++ = (uint8_t)(0xC0 | (ch >> 6));
            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
        } else {
            *dest++ = ch;
        }
        count++;
    }
    *dest++ = 0;
    mCharCount = count;
    mByteCount = dest - mBuffer;
}

bool MtpStringBuffer::readFromPacket(MtpDataPacket* packet) {
    uint8_t count;
    if (!packet->getUInt8(count))
        return false;

    uint8_t* dest = mBuffer;
    for (int i = 0; i < count; i++) {
        uint16_t ch;

        if (!packet->getUInt16(ch))
            return false;
        if (ch >= 0x0800) {
            *dest++ = (uint8_t)(0xE0 | (ch >> 12));
            *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F));
            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
        } else if (ch >= 0x80) {
            *dest++ = (uint8_t)(0xC0 | (ch >> 6));
            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
        } else {
            *dest++ = ch;
        }
    }
    *dest++ = 0;
    mCharCount = count;
    mByteCount = dest - mBuffer;
    return true;
}

void MtpStringBuffer::writeToPacket(MtpDataPacket* packet) const {
    int count = mCharCount;
    const uint8_t* src = mBuffer;
    packet->putUInt8(count > 0 ? count + 1 : 0);

    // expand utf8 to 16 bit chars
    for (int i = 0; i < count; i++) {
        uint16_t ch;
        uint16_t ch1 = *src++;
        if ((ch1 & 0x80) == 0) {
            // single byte character
            ch = ch1;
        } else if ((ch1 & 0xE0) == 0xC0) {
            // two byte character
            uint16_t ch2 = *src++;
            ch = ((ch1 & 0x1F) << 6) | (ch2 & 0x3F);
        } else {
            // three byte character
            uint16_t ch2 = *src++;
            uint16_t ch3 = *src++;
            ch = ((ch1 & 0x0F) << 12) | ((ch2 & 0x3F) << 6) | (ch3 & 0x3F);
        }
        packet->putUInt16(ch);
    }
    // only terminate with zero if string is not empty
    if (count > 0)
        packet->putUInt16(0);
}

}  // namespace android
