/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include "android/cbuffer.h"
#include "android/utils/stralloc.h"
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>

#define  DEBUG  0

#if DEBUG
#  define  ASSERT(cond,fmt,...)  ({ if (!(cond)) { fprintf(stderr, fmt, __VA_ARGS__); assert(cond); } })
#else
#  define  ASSERT(cond,fmt,...)  ((void)0)
#endif

#if DEBUG
void
cbuffer_assert( CBuffer*  cb, const char*  file, long  lineno )
{
    const char*  reason = NULL;

    if (cb->rpos < 0 || cb->rpos >= cb->size) {
        reason = "rpos is out of bounds";
    }
    else if (cb->count < 0 || cb->count > cb->size) {
        reason = "count is incorrect";
    }
    if (!reason)
        return;

    fprintf(stderr, "assert:%s:%ld: assertion failed: %s (pos=%d count=%d size=%d)\n",
            file, lineno, reason, cb->rpos, cb->count, cb->size);
    assert(0);
}
#  define  CBUFFER_ASSERT(cb)  cbuffer_assert(cb,__FUNCTION__,__LINE__)
#else
#  define  CBUFFER_ASSERT(cb)  ((void)0)
#endif

int
cbuffer_write_peek( CBuffer*  cb, uint8_t*  *pbase )
{
    int  wpos  = cb->rpos + cb->count;
    int  avail = cb->size - cb->count;

    CBUFFER_ASSERT(cb);

    if (wpos >= cb->size)
        wpos -= cb->size;

    if (wpos + avail > cb->size)
        avail = cb->size - wpos;

    *pbase = cb->buff + wpos;
    return avail;
}

void
cbuffer_write_step( CBuffer*  cb, int  len )
{
    CBUFFER_ASSERT(cb);

    cb->count += len;
    if (cb->count > cb->size)
        cb->count = cb->size;
}


int
cbuffer_write( CBuffer*  cb, const void*  from, int  len )
{
    int  len2 = len;

    CBUFFER_ASSERT(cb);

    while (len2 > 0) {
        int  avail = cb->size - cb->count;
        int  wpos  = cb->rpos + cb->count;

        ASSERT(avail >= 0, "avail is negative: %d", avail);

        if (avail == 0)
            break;

        if (wpos >= cb->size)
            wpos -= cb->size;

        ASSERT( wpos >= 0 && wpos < cb->size, "wpos is out-of-bounds: %d (rpos=%d)", wpos, cb->rpos);

        if (wpos + avail > cb->size)
            avail = cb->size - wpos;

        if (avail > len2)
            avail = len2;

        memcpy( cb->buff + wpos, (const char*)from, avail );

        from  = (char*)from + avail;
        len2 -= avail;
        cb->count += avail;
    }
    return len - len2;
}

int
cbuffer_read( CBuffer*  cb, void*  to, int  len )
{
    int   len2 = len;

    CBUFFER_ASSERT(cb);

    while (len2 > 0) {
        int  avail = cb->count;
        int  rpos = cb->rpos;

        ASSERT(avail >= 0, "avail is negative: %d", avail);

        if (avail == 0)
            break;

        ASSERT((rpos >= 0 && rpos < cb->size), "rpos is out-of-bounds: %d", rpos);

        if (rpos+avail > cb->size)
            avail = cb->size - rpos;

        if (avail > len2)
            avail = len2;

        memcpy( (char*)to, (const char*)cb->buff + rpos, avail );
        to    = (char*)to + avail;
        len2 -= avail;
        cb->count -= avail;
        cb->rpos  += avail;
        if (cb->rpos >= cb->size)
            cb->rpos -= cb->size;
    }
    return len - len2;
}

int
cbuffer_read_peek( CBuffer*  cb, uint8_t*  *pbase )
{
    int   rpos  = cb->rpos;
    int   avail = cb->count;

    CBUFFER_ASSERT(cb);

    if (rpos + avail > cb->size)
        avail = cb->size - rpos;

    *pbase = cb->buff + rpos;
    return avail;
}


void
cbuffer_read_step( CBuffer*  cb, int  len )
{
    CBUFFER_ASSERT(cb);

    if (len > cb->count)
        len = cb->count;

    cb->rpos  += len;
    if (cb->rpos >= cb->size)
        cb->rpos -= cb->size;

    cb->count -= len;
}

const char*
cbuffer_quote( CBuffer*  cb )
{
    STRALLOC_DEFINE(s);
    char* q;

    stralloc_format( s, "cbuffer %p (pos=%d count=%d size=%d)",
                     cb, cb->rpos, cb->count, cb->size );

    q = stralloc_to_tempstr( s );
    stralloc_reset(s);

    return q;
}

const char*
cbuffer_quote_data( CBuffer*  cb )
{
    STRALLOC_DEFINE(s);
    int   len  = cb->count;
    int   rpos = cb->rpos;
    char* result;

    while (len > 0) {
        int  avail = len;

        if (rpos >= cb->size)
            rpos -= cb->size;

        if (rpos + avail > cb->size)
            avail = cb->size - rpos;

        stralloc_add_quote_bytes( s, cb->buff + rpos, avail );
        rpos += avail;
        len  -= avail;
    }

    result = stralloc_to_tempstr(s);
    stralloc_reset(s);

    return result;
}

void
cbuffer_print( CBuffer*  cb )
{
    /* print the content of a cbuffer */
    printf( "%s: %s", cbuffer_quote(cb), cbuffer_quote_data(cb) );
}

