/*
 * 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 MtpStringBuffer& src)
    :   mCharCount(src.mCharCount),
        mByteCount(src.mByteCount)
{
    memcpy(mBuffer, src.mBuffer, mByteCount);
}


MtpStringBuffer::~MtpStringBuffer() {
}

void MtpStringBuffer::set(const char* src) {
    int length = strlen(src);
    if (length >= sizeof(mBuffer))
        length = sizeof(mBuffer) - 1;
    memcpy(mBuffer, src, length);

    // count the characters
    int count = 0;
    char ch;
    while ((ch = *src++) != 0) {
        if ((ch & 0x80) == 0) {
            // single byte character
        } else if ((ch & 0xE0) == 0xC0) {
            // two byte character
            if (! *src++) {
                // last character was truncated, so ignore last byte
                length--;
                break;
            }
        } else if ((ch & 0xF0) == 0xE0) {
            // 3 byte char
            if (! *src++) {
                // last character was truncated, so ignore last byte
                length--;
                break;
            }
            if (! *src++) {
                // last character was truncated, so ignore last two bytes
                length -= 2;
                break;
            }
        }
        count++;
    }

    mByteCount = length + 1;
    mBuffer[length] = 0;
    mCharCount = count;
}

void MtpStringBuffer::readFromPacket(MtpDataPacket* packet) {
    int count = packet->getUInt8();
    uint8_t* dest = mBuffer;
    for (int i = 0; i < count; i++) {
        uint16_t ch = packet->getUInt16();
        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;
}

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
