/****************************************************************************
 * This file is part of the project AqHome.
 * AqHome (c) by 2023 Martin Preuss, all rights reserved.
 *
 * The license for this file can be found in the file COPYING which you
 * should have received along with this file.
 ****************************************************************************/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif



#include "./hexfilerecord_p.h"

#include <gwenhywfar/debug.h>
#include <gwenhywfar/misc.h>



GWEN_LIST_FUNCTIONS(AQH_HEXFILERECORD, AQH_HexfileRecord)




AQH_HEXFILERECORD *AQH_HexfileRecord_new()
{
  AQH_HEXFILERECORD *hr;

  GWEN_NEW_OBJECT(AQH_HEXFILERECORD, hr);
  GWEN_LIST_INIT(AQH_HEXFILERECORD, hr);
  return hr;
}



void AQH_HexfileRecord_free(AQH_HEXFILERECORD *hr)
{
  if (hr) {
    GWEN_LIST_FINI(AQH_HEXFILERECORD, hr);
    if (hr->dataPointer)
      free(hr->dataPointer);
    GWEN_FREE_OBJECT(hr);
  }
}



uint8_t AQH_HexfileRecord_GetByteCount(const AQH_HEXFILERECORD *hr)
{
  if (hr)
    return hr->byteCount;
  return 0;
}



void AQH_HexfileRecord_SetByteCount(AQH_HEXFILERECORD *hr, uint8_t b)
{
  if (hr)
    hr->byteCount=b;
}



uint16_t AQH_HexfileRecord_GetAddress(const AQH_HEXFILERECORD *hr)
{
  if (hr)
    return hr->address;
  return 0;
}



void AQH_HexfileRecord_SetAddress(AQH_HEXFILERECORD *hr, uint16_t a)
{
  if (hr)
    hr->address=a;
}



uint8_t AQH_HexfileRecord_GetRecordType(const AQH_HEXFILERECORD *hr)
{
  if (hr)
    return hr->recordType;
  return 0;
}



void AQH_HexfileRecord_SetRecordType(AQH_HEXFILERECORD *hr, uint8_t t)
{
  if (hr)
    hr->recordType=t;
}



const uint8_t *AQH_HexfileRecord_GetDataPointer(const AQH_HEXFILERECORD *hr)
{
  if (hr)
    return hr->dataPointer;
  return NULL;
}



void AQH_HexfileRecord_SetDataPointer(AQH_HEXFILERECORD *hr, uint8_t *ptr)
{
  if (hr) {
    if (hr->dataPointer)
      free(hr->dataPointer);
    hr->dataPointer=ptr;
  }
}



void AQH_HexfileRecord_SetData(AQH_HEXFILERECORD *hr, const uint8_t *ptr, uint8_t len)
{
  if (hr) {
    if (hr->dataPointer)
      free(hr->dataPointer);
    if (ptr && len) {
      hr->dataPointer=(uint8_t*) malloc(len);
      if (hr->dataPointer) {
        memmove(hr->dataPointer, ptr, len);
        hr->byteCount=len;
      }
      else {
        hr->dataPointer=NULL;
        hr->byteCount=0;
      }
    }
    else {
      hr->dataPointer=NULL;
      hr->byteCount=0;
    }
  }
}



const AQH_HEXFILERECORD *AQH_HexfileRecord_List_FindNonAdjacentDataRecord(const AQH_HEXFILERECORD *hr)
{
  uint16_t expectedAddr;
  int cnt=0;

  expectedAddr=AQH_HexfileRecord_GetAddress(hr)+AQH_HexfileRecord_GetByteCount(hr);
  hr=AQH_HexfileRecord_List_Next(hr);
  while(hr && AQH_HexfileRecord_GetRecordType(hr)==AQH_HEXFILERECORD_TYPE_DATA) {
    uint16_t addr;

    addr=AQH_HexfileRecord_GetAddress(hr);
    if (addr!=expectedAddr)
      break;
    expectedAddr=addr+AQH_HexfileRecord_GetByteCount(hr);
    cnt++;
    hr=AQH_HexfileRecord_List_Next(hr);
  }

  DBG_INFO(AQH_LOGDOMAIN, "- num of continuous records: %d", cnt);
  return hr;
}









