/*
* Copyright (C) 2011 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.
*/
#include "QemuPipeStream.h"
#include <hardware/qemu_pipe.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

QemuPipeStream::QemuPipeStream(size_t bufSize) :
    IOStream(bufSize),
    m_sock(-1),
    m_bufsize(bufSize),
    m_buf(NULL)
{
}

QemuPipeStream::QemuPipeStream(int sock, size_t bufSize) :
    IOStream(bufSize),
    m_sock(sock),
    m_bufsize(bufSize),
    m_buf(NULL)
{
}

QemuPipeStream::~QemuPipeStream()
{
    if (m_sock >= 0) {
        ::close(m_sock);
    }
    if (m_buf != NULL) {
        free(m_buf);
    }
}


int QemuPipeStream::connect(void)
{
    m_sock = qemu_pipe_open("opengles");
    if (!valid()) return -1;
    return 0;
}

void *QemuPipeStream::allocBuffer(size_t minSize)
{
    size_t allocSize = (m_bufsize < minSize ? minSize : m_bufsize);
    if (!m_buf) {
        m_buf = (unsigned char *)malloc(allocSize);
    }
    else if (m_bufsize < allocSize) {
        unsigned char *p = (unsigned char *)realloc(m_buf, allocSize);
        if (p != NULL) {
            m_buf = p;
            m_bufsize = allocSize;
        } else {
            ERR("realloc (%d) failed\n", allocSize);
            free(m_buf);
            m_buf = NULL;
            m_bufsize = 0;
        }
    }

    return m_buf;
};

int QemuPipeStream::commitBuffer(size_t size)
{
    return writeFully(m_buf, size);
}

int QemuPipeStream::writeFully(const void *buf, size_t len)
{
    //DBG(">> QemuPipeStream::writeFully %d\n", len);
    if (!valid()) return -1;

    size_t res = len;
    int retval = 0;

    while (res > 0) {
        ssize_t stat = ::write(m_sock, (const char *)(buf) + (len - res), res);
        if (stat > 0) {
            res -= stat;
            continue;
        }
        if (stat == 0) { /* EOF */
            ERR("QemuPipeStream::writeFully failed: premature EOF\n");
            retval = -1;
            break;
        }
        if (errno == EINTR) {
            continue;
        }
        retval =  stat;
        ERR("QemuPipeStream::writeFully failed: %s\n", strerror(errno));
        break;
    }
    //DBG("<< QemuPipeStream::writeFully %d\n", len );
    return retval;
}

const unsigned char *QemuPipeStream::readFully(void *buf, size_t len)
{
    //DBG(">> QemuPipeStream::readFully %d\n", len);
    if (!valid()) return NULL;
    if (!buf) {
        if (len>0) ERR("QemuPipeStream::readFully failed, buf=NULL, len %d", len);
        return NULL;  // do not allow NULL buf in that implementation
    }
    size_t res = len;
    while (res > 0) {
        ssize_t stat = ::read(m_sock, (char *)(buf) + len - res, len);
        if (stat == 0) {
            // client shutdown;
            return NULL;
        } else if (stat < 0) {
            if (errno == EINTR) {
                continue;
            } else {
                ERR("QemuPipeStream::readFully failed (buf %p): %s\n",
                    buf, strerror(errno));
                return NULL;
            }
        } else {
            res -= stat;
        }
    }
    //DBG("<< QemuPipeStream::readFully %d\n", len);
    return (const unsigned char *)buf;
}

const unsigned char *QemuPipeStream::read( void *buf, size_t *inout_len)
{
    //DBG(">> QemuPipeStream::read %d\n", *inout_len);
    if (!valid()) return NULL;
    if (!buf) {
      ERR("QemuPipeStream::read failed, buf=NULL");
      return NULL;  // do not allow NULL buf in that implementation
    }

    int n = recv(buf, *inout_len);

    if (n > 0) {
        *inout_len = n;
        return (const unsigned char *)buf;
    }

    //DBG("<< QemuPipeStream::read %d\n", *inout_len);
    return NULL;
}

int QemuPipeStream::recv(void *buf, size_t len)
{
    if (!valid()) return int(ERR_INVALID_SOCKET);
    char* p = (char *)buf;
    int ret = 0;
    while(len > 0) {
        int res = ::read(m_sock, p, len);
        if (res > 0) {
            p += res;
            ret += res;
            len -= res;
            continue;
        }
        if (res == 0) { /* EOF */
             break;
        }
        if (errno == EINTR)
            continue;

        /* A real error */
        if (ret == 0)
            ret = -1;
        break;
    }
    return ret;
}
