#define SCPI_CORE_PRIVATE // access to 'scpi_core_private.h'
#include "app/scpi/scpi_core.h"
#include "app/scpi/scpi_core_private.h"
#include "app/scpi/scpi_parser.h"
#define SCPI_CORE_STATE__PROCESSDATA_GUARD
#include "app/scpi/CommandParserStates/process_data.h"

// @scpi_response_helper
// Helper function. Helps to implement correct data output from the QUERY.
// Copies the query data and updates the @sRead.nDataLength and @common_ctx->status
// to the appropriate values, also returns actual query data offset.
// @common_ctx - common context pointer passed to the handler;
// @idx - current data offset in the handler;
// @source - the data source pointer;
// @isdone - optional, if passed, specifies wheither to set DONE status or not;
// Returns: actual data offset for the handler after the data pushed into the output buffer
size_t scpi_response_helper( sProcessProgramDataCommonContext_t * common_ctx, size_t idx, void * source, size_t source_max, bool * isdone )
{
   sScpiParserContext_t * global_ctx = common_ctx->global_ctx;

   // @src - response string iterator
   const char * src = ((const char *)source) + idx;

   // @length - length of data to be copied
   size_t length = strnlen( (const char *)src, source_max ); 

   // @length - number of bytes actually written
   size_t written = scpi_WriteChunkOutput( src, length );

   // Check for end-condition:
   if( NULL != isdone )
   {
       // external controlled DONE status
       if( *isdone )
       {
          common_ctx->status = eProgramDataDone;
       }
       else
       {
          common_ctx->status = eProgramDataNeedRead;
       }
   }
   else
   {
       // internal controlled DONE status
       if( written == length )
       {
           common_ctx->status = eProgramDataDone;
       }
       else
       {
           common_ctx->status = eProgramDataNeedRead;
       }
   }

   return written;
}

// @scpi_response_done_helper
// Helper function. Helps to implement setting of the status
// @isdone - DONE status for handler
void scpi_response_done_helper( sProcessProgramDataCommonContext_t * common_ctx, bool isdone )
{
   // external controlled DONE status
   if( isdone )
   {
      common_ctx->status = eProgramDataDone;
   }
   else
   {
      common_ctx->status = eProgramDataNeedRead;
   }
   
}