
/*
 * Copyright (C) 2009 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.
 */

#ifndef ANDROID_RS_BUILD_FOR_HOST
#include "rsContext.h"
#else
#include "rsContextHostStub.h"
#endif

#include "rsStream.h"

using namespace android;
using namespace android::renderscript;

IStream::IStream(const uint8_t *buf, bool use64) {
    mData = buf;
    mPos = 0;
    mUse64 = use64;
}

void IStream::loadByteArray(void *dest, size_t numBytes) {
    memcpy(dest, mData + mPos, numBytes);
    mPos += numBytes;
}

uint64_t IStream::loadOffset() {
    uint64_t tmp;
    if (mUse64) {
        mPos = (mPos + 7) & (~7);
        tmp = reinterpret_cast<const uint64_t *>(&mData[mPos])[0];
        mPos += sizeof(uint64_t);
        return tmp;
    }
    return loadU32();
}

void IStream::loadString(String8 *s) {
    uint32_t len = loadU32();
    s->setTo((const char *)&mData[mPos], len);
    mPos += len;
}

// Output stream implementation
OStream::OStream(uint64_t len, bool use64) {
    mData = (uint8_t*)malloc(len);
    mLength = len;
    mPos = 0;
    mUse64 = use64;
}

OStream::~OStream() {
    free(mData);
}

void OStream::addByteArray(const void *src, size_t numBytes) {
    // We need to potentially grow more than once if the number of byes we write is substantial
    while (mPos + numBytes >= mLength) {
        growSize();
    }
    memcpy(mData + mPos, src, numBytes);
    mPos += numBytes;
}

void OStream::addOffset(uint64_t v) {
    if (mUse64) {
        mPos = (mPos + 7) & (~7);
        if (mPos + sizeof(v) >= mLength) {
            growSize();
        }
        mData[mPos++] = (uint8_t)(v & 0xff);
        mData[mPos++] = (uint8_t)((v >> 8) & 0xff);
        mData[mPos++] = (uint8_t)((v >> 16) & 0xff);
        mData[mPos++] = (uint8_t)((v >> 24) & 0xff);
        mData[mPos++] = (uint8_t)((v >> 32) & 0xff);
        mData[mPos++] = (uint8_t)((v >> 40) & 0xff);
        mData[mPos++] = (uint8_t)((v >> 48) & 0xff);
        mData[mPos++] = (uint8_t)((v >> 56) & 0xff);
    } else {
        addU32(v);
    }
}

void OStream::addString(String8 *s) {
    uint32_t len = s->size();
    addU32(len);
    if (mPos + len*sizeof(char) >= mLength) {
        growSize();
    }
    char *stringData = reinterpret_cast<char *>(&mData[mPos]);
    for (uint32_t i = 0; i < len; i ++) {
        stringData[i] = s->string()[i];
    }
    mPos += len*sizeof(char);
}

void OStream::growSize() {
    uint8_t *newData = (uint8_t*)malloc(mLength*2);
    memcpy(newData, mData, mLength*sizeof(uint8_t));
    mLength = mLength * 2;
    free(mData);
    mData = newData;
}


