/*
 * 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_STREAM_H
#define ANDROID_RS_STREAM_H

#include <stdio.h>
#include "rsUtils.h"

// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {

class IStream {
public:
    IStream(const uint8_t *, bool use64);

    float loadF() {
        mPos = (mPos + 3) & (~3);
        float tmp = reinterpret_cast<const float *>(&mData[mPos])[0];
        mPos += sizeof(float);
        return tmp;
    }
    int32_t loadI32() {
        mPos = (mPos + 3) & (~3);
        int32_t tmp = reinterpret_cast<const int32_t *>(&mData[mPos])[0];
        mPos += sizeof(int32_t);
        return tmp;
    }
    uint32_t loadU32() {
        mPos = (mPos + 3) & (~3);
        uint32_t tmp = reinterpret_cast<const uint32_t *>(&mData[mPos])[0];
        mPos += sizeof(uint32_t);
        return tmp;
    }
    uint16_t loadU16() {
        mPos = (mPos + 1) & (~1);
        uint16_t tmp = reinterpret_cast<const uint16_t *>(&mData[mPos])[0];
        mPos += sizeof(uint16_t);
        return tmp;
    }
    inline uint8_t loadU8() {
        uint8_t tmp = reinterpret_cast<const uint8_t *>(&mData[mPos])[0];
        mPos += sizeof(uint8_t);
        return tmp;
    }
    void loadByteArray(void *dest, size_t numBytes);
    uint64_t loadOffset();
    const char * loadString();
    uint64_t getPos() const {
        return mPos;
    }
    void reset(uint64_t pos) {
        mPos = pos;
    }
    void reset() {
        mPos = 0;
    }

    const uint8_t * getPtr() const {
        return mData;
    }
protected:
    const uint8_t * mData;
    uint64_t mPos;
    bool mUse64;
};

class OStream {
public:
    OStream(uint64_t length, bool use64);
    ~OStream();

    void align(uint32_t bytes) {
        mPos = (mPos + (bytes - 1)) & (~(bytes - 1));
        if (mPos >= mLength) {
            growSize();
        }
    }

    void addF(float v) {
        uint32_t uintV = *reinterpret_cast<uint32_t*> (&v);
        addU32(uintV);
    }
    void addI32(int32_t v) {
        mPos = (mPos + 3) & (~3);
        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);
    }
    void addU32(uint32_t v) {
        mPos = (mPos + 3) & (~3);
        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);
    }
    void addU16(uint16_t v) {
        mPos = (mPos + 1) & (~1);
        if (mPos + sizeof(v) >= mLength) {
            growSize();
        }
        mData[mPos++] = (uint8_t)(v & 0xff);
        mData[mPos++] = (uint8_t)(v >> 8);
    }
    inline void addU8(uint8_t v) {
        if (mPos + 1 >= mLength) {
            growSize();
        }
        reinterpret_cast<uint8_t *>(&mData[mPos])[0] = v;
        mPos ++;
    }
    void addByteArray(const void *src, size_t numBytes);
    void addOffset(uint64_t v);
    void addString(const char *name);
    void addString(const char *name, size_t len);
    uint64_t getPos() const {
        return mPos;
    }
    void reset(uint64_t pos) {
        mPos = pos;
    }
    void reset() {
        mPos = 0;
    }
    const uint8_t * getPtr() const {
        return mData;
    }
protected:
    void growSize();
    uint8_t * mData;
    uint64_t mLength;
    uint64_t mPos;
    bool mUse64;
};


} // renderscript
} // android
#endif //ANDROID_RS_STREAM_H


