/*
 * Copyright (C) 2008 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.
 */
/*
 * Implementation of an expandable byte buffer.  Designed for serializing
 * primitive values, e.g. JDWP replies.
 */
#include "jdwp/ExpandBuf.h"
#include "Bits.h"
#include "Common.h"

#include <stdlib.h>
#include <string.h>

/*
 * Data structure used to track buffer use.
 */
struct ExpandBuf {
    u1*     storage;
    int     curLen;
    int     maxLen;
};

#define kInitialStorage 64

/*
 * Allocate a JdwpBuf and some initial storage.
 */
ExpandBuf* expandBufAlloc(void)
{
    ExpandBuf* newBuf;

    newBuf = (ExpandBuf*) malloc(sizeof(*newBuf));
    newBuf->storage = (u1*) malloc(kInitialStorage);
    newBuf->curLen = 0;
    newBuf->maxLen = kInitialStorage;

    return newBuf;
}

/*
 * Free a JdwpBuf and associated storage.
 */
void expandBufFree(ExpandBuf* pBuf)
{
    if (pBuf == NULL)
        return;

    free(pBuf->storage);
    free(pBuf);
}

/*
 * Get a pointer to the start of the buffer.
 */
u1* expandBufGetBuffer(ExpandBuf* pBuf)
{
    return pBuf->storage;
}

/*
 * Get the amount of data currently in the buffer.
 */
size_t expandBufGetLength(ExpandBuf* pBuf)
{
    return pBuf->curLen;
}


/*
 * Ensure that the buffer has enough space to hold incoming data.  If it
 * doesn't, resize the buffer.
 */
static void ensureSpace(ExpandBuf* pBuf, int newCount)
{
    u1* newPtr;

    if (pBuf->curLen + newCount <= pBuf->maxLen)
        return;

    while (pBuf->curLen + newCount > pBuf->maxLen)
        pBuf->maxLen *= 2;

    newPtr = realloc(pBuf->storage, pBuf->maxLen);
    if (newPtr == NULL) {
        LOGE("realloc(%d) failed\n", pBuf->maxLen);
        abort();
    }

    pBuf->storage = newPtr;
}

/*
 * Allocate some space in the buffer.
 */
u1* expandBufAddSpace(ExpandBuf* pBuf, int gapSize)
{
    u1* gapStart;

    ensureSpace(pBuf, gapSize);
    gapStart = pBuf->storage + pBuf->curLen;
    /* do we want to garbage-fill the gap for debugging? */
    pBuf->curLen += gapSize;

    return gapStart;
}

/*
 * Append a byte.
 */
void expandBufAdd1(ExpandBuf* pBuf, u1 val)
{
    ensureSpace(pBuf, sizeof(val));
    *(pBuf->storage + pBuf->curLen) = val;
    pBuf->curLen++;
}

/*
 * Append two big-endian bytes.
 */
void expandBufAdd2BE(ExpandBuf* pBuf, u2 val)
{
    ensureSpace(pBuf, sizeof(val));
    set2BE(pBuf->storage + pBuf->curLen, val);
    pBuf->curLen += sizeof(val);
}

/*
 * Append four big-endian bytes.
 */
void expandBufAdd4BE(ExpandBuf* pBuf, u4 val)
{
    ensureSpace(pBuf, sizeof(val));
    set4BE(pBuf->storage + pBuf->curLen, val);
    pBuf->curLen += sizeof(val);
}

/*
 * Append eight big-endian bytes.
 */
void expandBufAdd8BE(ExpandBuf* pBuf, u8 val)
{
    ensureSpace(pBuf, sizeof(val));
    set8BE(pBuf->storage + pBuf->curLen, val);
    pBuf->curLen += sizeof(val);
}

/*
 * Add a UTF8 string as a 4-byte length followed by a non-NULL-terminated
 * string.
 *
 * Because these strings are coming out of the VM, it's safe to assume that
 * they can be null-terminated (either they don't have null bytes or they
 * have stored null bytes in a multi-byte encoding).
 */
void expandBufAddUtf8String(ExpandBuf* pBuf, const u1* str)
{
    int strLen = strlen((const char*)str);

    ensureSpace(pBuf, sizeof(u4) + strLen);
    setUtf8String(pBuf->storage + pBuf->curLen, str);
    pBuf->curLen += sizeof(u4) + strLen;
}
