/* libs/cutils/record_stream.c
**
** Copyright 2006, 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 <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <cutils/record_stream.h>
#include <string.h>
#include <stdint.h>
#ifdef HAVE_WINSOCK
#include <winsock2.h>   /* for ntohl */
#else
#include <netinet/in.h>
#endif

#define HEADER_SIZE 4

struct RecordStream {
    int fd;
    size_t maxRecordLen;

    unsigned char *buffer;

    unsigned char *unconsumed;
    unsigned char *read_end;
    unsigned char *buffer_end;
};


extern RecordStream *record_stream_new(int fd, size_t maxRecordLen)
{
    RecordStream *ret;

    assert (maxRecordLen <= 0xffff);

    ret = (RecordStream *)calloc(1, sizeof(RecordStream));

    ret->fd = fd;
    ret->maxRecordLen = maxRecordLen;
    ret->buffer = (unsigned char *)malloc (maxRecordLen + HEADER_SIZE);
    
    ret->unconsumed = ret->buffer;
    ret->read_end = ret->buffer;
    ret->buffer_end = ret->buffer + maxRecordLen + HEADER_SIZE;

    return ret;
}


extern void record_stream_free(RecordStream *rs)
{
    free(rs->buffer);
    free(rs);
}


/* returns NULL; if there isn't a full record in the buffer */
static unsigned char * getEndOfRecord (unsigned char *p_begin,
                                            unsigned char *p_end)
{
    size_t len;
    unsigned char * p_ret;

    if (p_end < p_begin + HEADER_SIZE) {
        return NULL;
    }

    //First four bytes are length
    len = ntohl(*((uint32_t *)p_begin));

    p_ret = p_begin + HEADER_SIZE + len;

    if (p_end < p_ret) {
        return NULL;
    }

    return p_ret;
}

static void *getNextRecord (RecordStream *p_rs, size_t *p_outRecordLen)
{
    unsigned char *record_start, *record_end;

    record_end = getEndOfRecord (p_rs->unconsumed, p_rs->read_end);

    if (record_end != NULL) {
        /* one full line in the buffer */
        record_start = p_rs->unconsumed + HEADER_SIZE;
        p_rs->unconsumed = record_end;

        *p_outRecordLen = record_end - record_start;

        return record_start;
    }

    return NULL;
}

/**
 * Reads the next record from stream fd
 * Records are prefixed by a 16-bit big endian length value
 * Records may not be larger than maxRecordLen
 *
 * Doesn't guard against EINTR
 *
 * p_outRecord and p_outRecordLen may not be NULL
 *
 * Return 0 on success, -1 on fail
 * Returns 0 with *p_outRecord set to NULL on end of stream
 * Returns -1 / errno = EAGAIN if it needs to read again
 */
int record_stream_get_next (RecordStream *p_rs, void ** p_outRecord, 
                                    size_t *p_outRecordLen)
{
    void *ret;

    ssize_t countRead;

    /* is there one record already in the buffer? */
    ret = getNextRecord (p_rs, p_outRecordLen);

    if (ret != NULL) {
        *p_outRecord = ret;
        return 0;
    }

    // if the buffer is full and we don't have a full record
    if (p_rs->unconsumed == p_rs->buffer 
        && p_rs->read_end == p_rs->buffer_end
    ) {
        // this should never happen
        //LOGE("max record length exceeded\n");
        assert (0);
        errno = EFBIG;
        return -1;
    }

    if (p_rs->unconsumed != p_rs->buffer) {
        // move remainder to the beginning of the buffer
        size_t toMove;

        toMove = p_rs->read_end - p_rs->unconsumed;
        if (toMove) {
            memmove(p_rs->buffer, p_rs->unconsumed, toMove);
        }

        p_rs->read_end = p_rs->buffer + toMove;
        p_rs->unconsumed = p_rs->buffer;
    }

    countRead = read (p_rs->fd, p_rs->read_end, p_rs->buffer_end - p_rs->read_end);

    if (countRead <= 0) {
        /* note: end-of-stream drops through here too */
        *p_outRecord = NULL;
        return countRead;
    }

    p_rs->read_end += countRead;

    ret = getNextRecord (p_rs, p_outRecordLen);

    if (ret == NULL) {
        /* not enough of a buffer to for a whole command */
        errno = EAGAIN;
        return -1;
    }

    *p_outRecord = ret;        
    return 0;
}
