From 3b99af699baba3ddbec2fbe74af6392678fbe31d Mon Sep 17 00:00:00 2001 From: Jan Breuer <jan.breuer@jaybee.cz> Date: 周二, 10 11月 2015 01:04:30 +0800 Subject: [PATCH] Add array result functions --- libscpi/src/parser.c | 249 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 242 insertions(+), 7 deletions(-) diff --git a/libscpi/src/parser.c b/libscpi/src/parser.c index 62dc151..faaeb3f 100644 --- a/libscpi/src/parser.c +++ b/libscpi/src/parser.c @@ -129,6 +129,7 @@ context->cmd_error = FALSE; context->output_count = 0; context->input_count = 0; + context->arbitrary_reminding = 0; /* if callback exists - call command callback */ if (cmd->callback != NULL) { @@ -486,14 +487,12 @@ } /** - * Write arbitrary block program data to the result + * Write arbitrary block header with length * @param context - * @param data * @param len * @return */ -size_t SCPI_ResultArbitraryBlock(scpi_t * context, const char * data, size_t len) { - size_t result = 0; +size_t SCPI_ResultArbitraryBlockHeader(scpi_t * context, size_t len) { char block_header[12]; size_t header_len; block_header[0] = '#'; @@ -502,10 +501,44 @@ header_len = strlen(block_header + 2); block_header[1] = (char) (header_len + '0'); - result += writeData(context, block_header, header_len + 2); - result += writeData(context, data, len); + context->arbitrary_reminding = len; + return writeData(context, block_header, header_len + 2); +} - context->output_count++; +/** + * Add data to arbitrary block + * @param context + * @param data + * @param len + * @return + */ +size_t SCPI_ResultArbitraryBlockData(scpi_t * context, const void * data, size_t len) { + + if (context->arbitrary_reminding < len) { + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return 0; + } + + context->arbitrary_reminding -= len; + + if (context->arbitrary_reminding == 0) { + context->output_count++; + } + + return writeData(context, (const char *) data, len); +} + +/** + * Write arbitrary block program data to the result + * @param context + * @param data + * @param len + * @return + */ +size_t SCPI_ResultArbitraryBlock(scpi_t * context, const void * data, size_t len) { + size_t result = 0; + result += SCPI_ResultArbitraryBlockHeader(context, len); + result += SCPI_ResultArbitraryBlockData(context, data, len); return result; } @@ -1351,6 +1384,7 @@ } #if USE_COMMAND_TAGS + /** * Return the .tag field of the matching scpi_command_t * @param context @@ -1391,3 +1425,204 @@ scpi_bool_t SCPI_ParamErrorOccurred(scpi_t * context) { return context->cmd_error; } + +/** + * Result binary array and swap bytes if needed (native endiannes != required endiannes) + * @param context + * @param array + * @param count + * @param item_size + * @param format + * @return + */ +static size_t parserResultArrayBinary(scpi_t * context, const void * array, size_t count, size_t item_size, scpi_array_format_t format) { + + if (SCPI_GetNativeFormat() == format) { + switch (item_size) { + case 1: + case 2: + case 4: + case 8: + return SCPI_ResultArbitraryBlock(context, array, count * item_size); + default: + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return 0; + } + } else { + size_t result = 0; + size_t i; + switch (item_size) { + case 1: + case 2: + case 4: + case 8: + result += SCPI_ResultArbitraryBlockHeader(context, count * item_size); + default: + SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR); + return 0; + } + + switch (item_size) { + case 1: + result += SCPI_ResultArbitraryBlockData(context, array, count); + break; + case 2: + for (i = 0; i < count; i++) { + uint16_t val = SCPI_Swap16(((uint16_t*)array)[i]); + result += SCPI_ResultArbitraryBlockData(context, &val, item_size); + } + break; + case 4: + for (i = 0; i < count; i++) { + uint32_t val = SCPI_Swap32(((uint32_t*)array)[i]); + result += SCPI_ResultArbitraryBlockData(context, &val, item_size); + } + break; + case 8: + for (i = 0; i < count; i++) { + uint64_t val = SCPI_Swap64(((uint64_t*)array)[i]); + result += SCPI_ResultArbitraryBlockData(context, &val, item_size); + } + break; + } + + return result; + } +} + + +#define RESULT_ARRAY(func) do {\ + size_t result;\ + if (format == SCPI_FORMAT_ASCII) {\ + size_t i;\ + for (i = 0; i < count; i++) {\ + result += func(context, array[i]);\ + }\ + if (count > 0) {\ + result += count - 1; /* add length of commas */\ + }\ + } else {\ + result = parserResultArrayBinary(context, array, count, sizeof(*array), format);\ + }\ + return result;\ +} while(0) + +/** + * Result array of signed 8bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayInt8(scpi_t * context, const int8_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultInt8); +} + +/** + * Result array of unsigned 8bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayUInt8(scpi_t * context, const uint8_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultUInt8); +} + +/** + * Result array of signed 16bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayInt16(scpi_t * context, const int16_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultInt16); +} + +/** + * Result array of unsigned 16bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayUInt16(scpi_t * context, const uint16_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultUInt16); +} + +/** + * Result array of signed 32bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayInt32(scpi_t * context, const int32_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultInt32); +} + +/** + * Result array of unsigned 32bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayUInt32(scpi_t * context, const uint32_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultUInt32); +} + +/** + * Result array of signed 64bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayInt64(scpi_t * context, const int64_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultInt64); +} + +/** + * Result array of unsigned 64bit integers + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayUInt64(scpi_t * context, const uint64_t * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultUInt64); +} + +/** + * Result array of floats + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayFloat(scpi_t * context, const float * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultFloat); +} + +/** + * Result array of doubles + * @param context + * @param array + * @param count + * @param format + * @return + */ +size_t SCPI_ResultArrayDouble(scpi_t * context, const double * array, size_t count, scpi_array_format_t format) { + RESULT_ARRAY(SCPI_ResultDouble); +} -- Gitblit v1.9.1