#ifndef __RTL__
 
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <stdarg.h>
#include <string.h>

#else /*__RTL__*/

#include <rtl.h>
#include <string.h>
#include <signal.h>
#include <posix/unistd.h>

#endif /*__RTL__*/
/*
#include "sui_event.h"
#include "sui_dinfo.h"
#include "ul_evcbase.h"
#include "ul_utmalloc.h"
*/
//#include "can_vca.h"
#include "sui_dinfo_dbuff.h"

// -------------- log levels ------------------
/*
#define LOG_FATAL   0
#define LOG_ERR     1
#define LOG_MSG     2
#define LOG_INF     3
#define LOG_DEB     4

//------------- LOG SUPPORT -----------------
static int log_is_cont = 0;
static void myvlog(int level, const char *format, va_list ap)
{
    if(log_is_cont) level |= VCA_LOGL_CONT;
    vca_vlog("vca_dinfo_dbuff", level, format, ap);
}

static void mylog(int level, const char *format, ...)
{
    va_list ap; 
    va_start(ap, format); 
    myvlog(level, format, ap);
    va_end(ap);
}
*/
//-------------------------------------------

//==================================================================
//               Data connection processing 
//==================================================================
static int sui_dbuff_rdval(sui_dinfo_t *di, long idx, void *buf)
{
    ul_dbuff_t *dbuf = (ul_dbuff_t*)buf;
    ul_dbuff_t *db = (ul_dbuff_t*)di->ptr;
    if(di->idxsize && (idx >= di->idxsize)) return SUDI_DATA_EINDX;
    ul_dbuff_cpy(dbuf, db->data, db->len);
    return SUDI_DATA_OK;
}

static int sui_dbuff_wrval(sui_dinfo_t *di, long idx, const void *buf)
{
    ul_dbuff_t *dbuf = (ul_dbuff_t*)buf;
    ul_dbuff_t *db = (ul_dbuff_t*)di->ptr;
    if(di->idxsize && (idx >= di->idxsize)) return SUDI_DATA_EINDX;
    ul_dbuff_cpy(db, dbuf->data, dbuf->len);
    sui_dinfo_changed(di);
    return SUDI_DATA_OK;
} 
//------------------------------------------------------------------------
int sui_dinfo_dbuff_rd_dbuff(sui_dinfo_t *di, long idx, ul_dbuff_t *dbuf) 
{
  if(!di->rdval) return SUDI_DATA_EPERM;
  if(!(di->tinfo & SUDI_TINFO_DBUFF)) return SUDI_DATA_EPERM;
  return di->rdval(di, idx, dbuf);
  //    mylog(LOG_INF, "Reading unknown data to dbuff of length 8.\n");
}

//------------------------------------------------------------------------

int sui_dinfo_dbuff_wr_dbuff( sui_dinfo_t *di, long idx, const ul_dbuff_t *dbuf) 
{
  if(!di->wrval) return SUDI_DATA_EPERM;
  if(!(di->tinfo & SUDI_TINFO_DBUFF)) return SUDI_DATA_EPERM;
  return di->wrval(di, idx, dbuf);
  //    mylog(LOG_INF, "Skipping writing dbuff to unknown data structure.\n");
}
//------------------------------------------------------------------------

int sui_dinfo_dbuff_rd_long(sui_dinfo_t *di, long idx, long *buf)
{
    int l, s = sizeof(*buf);
    int ret;
    ul_dbuff_t db;
    ul_dbuff_init(&db, UL_DBUFF_IS_STATIC);
    if(!di->rdval) return SUDI_DATA_EPERM;
    if(!(di->tinfo & SUDI_TINFO_DBUFF)) return SUDI_DATA_EPERM;
    ret = di->rdval(di, idx, &db);
    if(ret != SUDI_DATA_OK) return ret;
    l = db.len;
    l = (l > s)? s: l;
    memset(buf, 0, s);
    memcpy(buf, db.data, l);
    return SUDI_DATA_OK;
}
//------------------------------------------------------------------------

int sui_dinfo_dbuff_wr_long(sui_dinfo_t *di, long idx, const long *buf)
{
    int s = sizeof(*buf);
    int ret;
    ul_dbuff_t db;
    ul_dbuff_init(&db, UL_DBUFF_IS_STATIC);
    if(!di->wrval) return SUDI_DATA_EPERM;
    if(!(di->tinfo & SUDI_TINFO_DBUFF)) return SUDI_DATA_EPERM;
    ul_dbuff_set_len(&db, s);
    if(db.len != s) return SUDI_DATA_EPERM;
    memcpy(db.data, buf, s);
    ret = di->wrval(di, idx, &db);
    return SUDI_DATA_OK;
}
//==================================================================

sui_dinfo_t *sui_dinfo_dbuff_create(ul_dbuff_t *db, long aidxsize) 
{  
    sui_datai_rdfnc_t *ard = sui_dbuff_rdval; 
    sui_datai_wrfnc_t *awr = sui_dbuff_wrval;
    sui_dinfo_t *dinfo;
    
    dinfo = sui_create_dinfo(db, 0, 0, 0, 0, ard, awr);
    if(dinfo) {
        dinfo->idxsize = aidxsize;
        dinfo->tinfo = SUDI_TINFO_DBUFF;
    }
    return dinfo;
}

