summaryrefslogtreecommitdiffstats
path: root/otherservice/rpc_library/library/src/rpc_marshall.c
diff options
context:
space:
mode:
Diffstat (limited to 'otherservice/rpc_library/library/src/rpc_marshall.c')
-rw-r--r--otherservice/rpc_library/library/src/rpc_marshall.c740
1 files changed, 740 insertions, 0 deletions
diff --git a/otherservice/rpc_library/library/src/rpc_marshall.c b/otherservice/rpc_library/library/src/rpc_marshall.c
new file mode 100644
index 00000000..e4a085c0
--- /dev/null
+++ b/otherservice/rpc_library/library/src/rpc_marshall.c
@@ -0,0 +1,740 @@
+/*
+ * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file rpc_marshall.c
+ * @brief RPC Library Internal Implementation--Argument Conversion During API Calls
+ *
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <math.h>
+
+#include <other_service/rpc.h>
+#include "rpc_internal.h"
+
+#include "apidef.tab.h"
+#include "apidef.h"
+
+/** @addtogroup RPClib_in
+ * @{
+ */
+/** Structures for String Add Operations */
+typedef struct {
+ char *start;
+ char *wp;
+ unsigned int units;
+ unsigned int remain;
+} RpcString;
+
+#ifdef STRETCH_STRING
+#define _STRING_ALLOC_UNIT 512
+#else
+/*
+ * Batch allocate total bytes of arguments + data to be added internally
+ * (maximal 6 bytes per argument)
+ */
+#define _STRING_ALLOC_UNIT \
+ (RPC_MAX_API_ARG_TOTAL_SIZE + RPC_MAX_API_ARG_NUM * (2 + 4))
+#endif
+
+#define _ENOUGH_SPACE_FOR_ALL_TYPES \
+ (sizeof(UINT64) > sizeof(double) ? sizeof(UINT64) : sizeof(double))
+
+static RpcString* NewRpcString(void);
+#ifdef STRETCH_STRING
+static int StretchString(RpcString *str, UINT16 bytes);
+#endif
+static char *CopyString(RpcString *str, unsigned int *size);
+static void DestroyString(RpcString *str);
+static inline int AppendString(RpcString *str,
+ const UINT8 *append, UINT16 applen);
+static inline int MarshallUINT8(RpcString *str, UINT8 uc);
+static inline int MarshallUINT16(RpcString *str, UINT16 uh);
+static inline int MarshallUINT32(RpcString *str, UINT32 ui);
+static inline int MarshallUINT64(RpcString *str, UINT64 ul);
+static inline int Marshallfloat(RpcString *str, float f);
+static inline int Marshalldouble(RpcString *str, double d);
+static inline int MarshallUINT8Stream(RpcString *str, const UINT8 *buf,
+ UINT16 bytes);
+static inline int MarshallString(RpcString *str, char *buf,
+ UINT16 bytes);
+static inline int MarshallNullPointer(RpcString *str);
+static inline int MarshallPointer(RpcString *str);
+
+static RpcString *
+NewRpcString(void) {
+ RpcString *str;
+
+ str = rpc_malloc(sizeof(RpcString));
+ if (str == NULL) { // LCOV_EXCL_START 5: fail safe for libc malloc
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return NULL;
+ } // LCOV_EXCL_STOP
+
+ str->start = rpc_malloc(_STRING_ALLOC_UNIT);
+ if (str->start == NULL) { // LCOV_EXCL_START 5: fail safe for libc malloc
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ rpc_free(str);
+ return NULL;
+ } // LCOV_EXCL_STOP
+ str->start[0] = '\0';
+ str->wp = str->start;
+ str->units = 1;
+ str->remain = _STRING_ALLOC_UNIT - 1;
+
+ return str;
+}
+
+#ifdef STRETCH_STRING
+static int
+StretchString(RpcString *str, UINT16 bytes) {
+ unsigned int oldunits = str->units;
+ unsigned int units = 1 + (bytes / _STRING_ALLOC_UNIT) + oldunits;
+ if (units == oldunits) {
+ return 0;
+ }
+ unsigned int length = str->wp - str->start;
+ char *newp = rpc_malloc(units * _STRING_ALLOC_UNIT);
+ if (newp == NULL) {
+ return -1;
+ }
+ memcpy(newp, str->start, length);
+ rpc_free(str->start);
+ str->start = newp;
+ str->wp = str->start + length;
+ *(str->wp) = '\0';
+ str->units = units;
+ str->remain += (units - oldunits) * _STRING_ALLOC_UNIT;
+ return 0;
+}
+#endif /* STRETCH_STRING */
+
+static inline int
+AppendString(RpcString *str, const UINT8 *append, UINT16 applen) {
+ rpc_assert(append != NULL); // LCOV_EXCL_BR_LINE 6: double check
+#ifdef STRETCH_STRING
+ if (applen > str->remain) {
+ if (StretchString(str, applen - str->remain) < 0) {
+ return -1;
+ }
+ }
+#else
+ rpc_assert(applen <= str->remain); // LCOV_EXCL_BR_LINE 6: double check
+#endif
+ memcpy(str->wp, append, applen);
+ str->wp += applen;
+ str->remain -= applen;
+ return 0;
+}
+
+static char *
+CopyString(RpcString *str, unsigned int *size) {
+ unsigned int length = (unsigned int)(str->wp - str->start);
+ char *ret = rpc_malloc(length);
+ // LCOV_EXCL_BR_START 5: fail safe for libc malloc
+ if (ret == NULL) {
+ return NULL;
+ }
+ // LCOV_EXCL_BR_STOP
+ memcpy(ret, str->start, length);
+ if (size != NULL) {
+ *size = length;
+ }
+
+ return ret;
+}
+
+static void
+DestroyString(RpcString *str) {
+ rpc_free(str->start);
+ rpc_free(str);
+}
+
+static inline int
+MarshallUINT8(RpcString *str, UINT8 c) {
+ UINT8 buf[1 + sizeof(c)];
+ buf[0] = 'C';
+ buf[1] = c;
+ return AppendString(str, buf, sizeof(buf));
+}
+
+static inline int
+MarshallUINT8Stream(RpcString *str, const UINT8 *buf, UINT16 bytes) {
+ int ret = AppendString(str, (const UINT8 *)"B", 1);
+ if (ret < 0) { // LCOV_EXCL_BR_LINE 15: inline func rpc_marshall.c
+ return -1;
+ }
+ return AppendString(str, buf, bytes);
+}
+
+static inline int
+MarshallVararrayStream(RpcString *str, const UINT8 *buf, UINT16 bytes) {
+ char head_str[1+4+1+1]; /* Area where symbol "V" + size is stored */
+ sprintf(head_str, "V%03d ", bytes);
+ head_str[1+4+1] = '\0';
+
+ if (AppendString(str, (const UINT8 *)head_str, (UINT16)strlen(head_str)) < 0) { // LCOV_EXCL_BR_LINE 15: inline func rpc_marshall.c
+ return -1;
+ }
+
+ if (AppendString(str, buf, bytes) < 0) { // LCOV_EXCL_BR_LINE 15: inline func rpc_marshall.c
+ return -1;
+ }
+ return 0;
+}
+
+static inline int
+MarshallString(RpcString *str, char *buf, UINT16 bytes) {
+ char *p = buf;
+ UINT16 count = 0;
+ /* count the number of bytes in the argument */
+ while(*p != '\0' && count < (UINT16)(bytes - 1)) {
+ count++;
+ p++;
+ }
+
+ char count_str[1+strlen("1024")+1+1];
+ sprintf(count_str, "S%d ", count);
+
+ if (AppendString(str, (const UINT8 *)count_str, (UINT16)strlen(count_str)) < 0 || AppendString(str, (const UINT8 *)buf, count) < 0) { // LCOV_EXCL_BR_LINE 11: Unexpected branch // NOLINT(readability/nolint)
+ return -1;
+ }
+ return 0;
+}
+
+static int
+MarshallUINT16(RpcString *str, UINT16 uh) {
+ UINT8 buf[1 + sizeof(uh)];
+ buf[0] = 'H';
+ memcpy(buf + 1, &uh, sizeof(uh));
+ return AppendString(str, buf, sizeof(buf));
+}
+
+static inline int
+MarshallUINT32(RpcString *str, UINT32 ui) {
+ UINT8 buf[1 + sizeof(ui)];
+ buf[0] = 'I';
+ memcpy(buf + 1, &ui, sizeof(ui));
+ return AppendString(str, buf, sizeof(buf));
+}
+
+static inline int
+Marshallint(RpcString *str, int i) {
+ return MarshallUINT32(str, (UINT32)i);
+}
+
+static inline int
+MarshallUINT64(RpcString *str, UINT64 ul) {
+ UINT8 buf[1 + sizeof(ul)];
+ buf[0] = 'L';
+ memcpy(buf + 1, &ul, sizeof(ul));
+ return AppendString(str, buf, sizeof(buf));
+}
+
+static inline int
+Marshallfloat(RpcString *str, float f) {
+ UINT8 buf[1 + sizeof(f)];
+ buf[0] = 'F';
+ memcpy(buf + 1, &f, sizeof(f));
+ return AppendString(str, buf, sizeof(buf));
+}
+
+static inline int
+Marshalldouble(RpcString *str, double d) {
+ UINT8 buf[1 + sizeof(d)];
+ buf[0] = 'D';
+ memcpy(buf + 1, &d, sizeof(d));
+ return AppendString(str, buf, sizeof(buf));
+}
+
+static inline int
+MarshallPointer(RpcString *str) {
+ /* only to specify that a non-NULL pointer was delivered */
+ return AppendString(str, (const UINT8 *)"P", 1);
+}
+
+static inline int
+MarshallNullPointer(RpcString *str /*, int code*/) {
+ return AppendString(str, (const UINT8 *)"N", 1);
+}
+
+/** @ingroup RPClib_in
+ */
+
+#define MACROMarshallPointer(TYPE) \
+ do { \
+ TYPE *p = (TYPE *)temp; \
+ error = Marshall##TYPE(str, *p); \
+ } while(0)
+
+#define MACROMarshallValue(TYPE, STACK_TYPE) \
+ do { \
+ TYPE value = (TYPE)va_arg(ap, STACK_TYPE); \
+ error = Marshall##TYPE(str, value); \
+ } while(0)
+
+char *
+RPC_marshall_arguments(unsigned int *size, int dont_marshall_out_pointer,
+ int num_args, ...) {
+ rpc_assert(num_args <= RPC_MAX_API_ARG_NUM); // LCOV_EXCL_BR_LINE 6: double check
+ va_list ap;
+
+ RpcString *str;
+ str = NewRpcString();
+ if (str == NULL) { // LCOV_EXCL_BR_LINE 5: fail safe for libc malloc
+ AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
+ return NULL; // LCOV_EXCL_LINE 5: fail safe for libc malloc
+ }
+
+ va_start(ap, num_args);
+
+ int ii, error;
+ error = 0;
+
+ for(ii = 0 ; ii < num_args && error == 0 ; ii++) {
+ unsigned int code, is_vararray, is_pointer, in_out, out_only;
+ UINT16 bytes;
+ unsigned int val = va_arg(ap, unsigned int);
+
+ RPC_marshall_flag flag;
+ flag.all = ntohl(val);
+ code = flag.bits.code;
+ is_vararray = flag.bits.is_vararray;
+ is_pointer = flag.bits.is_pointer;
+ in_out = flag.bits.in_out;
+ bytes = flag.bits.bytes;
+ rpc_assert(bytes <= RPC_MAX_API_ARG_SIZE); // LCOV_EXCL_BR_LINE 6: double check
+
+
+ out_only = 0;
+ if (in_out == RPC_OUT_ARG) { /* OUT only argument */
+ out_only = 1;
+ }
+
+ if (is_pointer) { /* Argument passed by pointer */
+
+ void *temp = (void *)va_arg(ap, void *);
+ if (temp == NULL) {
+ /* NULL pointer */
+ error = MarshallNullPointer(str);
+ } else if (dont_marshall_out_pointer && out_only) {
+ /* Not refer to the contents of a pointer */
+ error = MarshallPointer(str);
+ } else {/* Marshall the contents of pointers */
+ if (is_vararray) {
+ /* Variable-length array */
+ error = MarshallVararrayStream(str, temp, bytes);
+ } else {
+ switch(code) {
+ case rpc_CHAR:
+ case rpc_INT8:
+ case rpc_UINT8:
+ MACROMarshallPointer(UINT8);
+ break;
+ case rpc_INT16:
+ case rpc_UINT16:
+ MACROMarshallPointer(UINT16);
+ break;
+ case rpc_INT:
+ case rpc_SINT:
+ case rpc_UINT:
+ MACROMarshallPointer(int);
+ break;
+ case rpc_INT32:
+ case rpc_UINT32:
+ MACROMarshallPointer(UINT32);
+ break;
+ case rpc_INT64:
+ case rpc_UINT64:
+ MACROMarshallPointer(UINT64);
+ break;
+ case rpc_FLOAT:
+ MACROMarshallPointer(float);
+ break;
+ case rpc_DOUBLE:
+ MACROMarshallPointer(double);
+ break;
+ case rpc_STRING:
+ error = MarshallString(str, temp, bytes);
+ break;
+ case rpc_USER_DEFINED:
+ error = MarshallUINT8Stream(str, temp, bytes);
+ break;
+ default:
+ error = -1;
+ break;
+ }
+ }
+ }
+ } else {/* Argument passed by value */
+
+ /* Note: In this area, the code depends on the CPU architecture */
+
+ switch(code) {
+ case rpc_CHAR:
+ case rpc_INT8:
+ case rpc_UINT8:
+ MACROMarshallValue(UINT8, unsigned int);
+ break;
+ case rpc_INT16:
+ case rpc_UINT16:
+ MACROMarshallValue(UINT16, unsigned int);
+ break;
+ case rpc_INT:
+ case rpc_SINT:
+ case rpc_UINT:
+ MACROMarshallValue(int, int); // LCOV_EXCL_BR_LINE 15: marco defined in rpc_marshall.c
+ break;
+ case rpc_INT32:
+ case rpc_UINT32:
+ MACROMarshallValue(UINT32, UINT32); // LCOV_EXCL_BR_LINE 15: marco defined in rpc_marshall.c
+ break;
+ case rpc_INT64:
+ case rpc_UINT64:
+ MACROMarshallValue(UINT64, UINT64); // LCOV_EXCL_BR_LINE 15: marco defined in rpc_marshall.c
+ break;
+ case rpc_FLOAT:
+ MACROMarshallValue(float, double); // LCOV_EXCL_BR_LINE 15: marco defined in rpc_marshall.c
+ break;
+ case rpc_DOUBLE:
+ MACROMarshallValue(double, double); // LCOV_EXCL_BR_LINE 15: marco defined in rpc_marshall.c
+ break;
+ case rpc_USER_DEFINED:
+ rpc_assert(bytes <= sizeof(UINT64));
+ /* This area is very architecture-dependent! */
+ if (bytes <= sizeof(UINT32)) {
+ UINT32 value = (UINT32)va_arg(ap, UINT32); // LCOV_EXCL_BR_LINE 15: macro defined in stdarg.h
+ error = MarshallUINT8Stream(str, (UINT8 *)&value, bytes);
+ } else if (bytes <= sizeof(UINT64)) { // LCOV_EXCL_BR_LINE 6: double check
+ UINT64 value = (UINT64)va_arg(ap, UINT64); // LCOV_EXCL_BR_LINE 15: macro defined in stdarg.h
+ error = MarshallUINT8Stream(str, (UINT8 *)&value, bytes);
+ }
+ break;
+ default:
+ error = -1;
+ break;
+ }
+ }
+ }
+ va_end(ap);
+
+ if (error != 0) {
+ DestroyString(str);
+ return NULL;
+ }
+
+ char *ret = CopyString(str, size);
+ DestroyString(str);
+ return ret;
+}
+
+static inline int DeMarshallUINT8(const char *from, UINT8 *ucp);
+static inline int DeMarshallUINT16(const char *from, UINT16 *uhp);
+static inline int DeMarshallUINT32(const char *from, UINT32 *uip);
+static inline int DeMarshallUINT64(const char *from, UINT64 *ulp);
+static inline int DeMarshallfloat(const char *from, float *fp);
+static inline int DeMarshalldouble(const char *from, double *dp);
+static inline int DeMarshallUINT8Stream(const char *from, UINT8 *buffer,
+ UINT16 bytes);
+static inline int DeMarshallString(const char *from, char *buffer,
+ UINT16 bytes);
+
+static inline int
+DeMarshallUINT8(const char *from, UINT8 *ucp) {
+ if (*from == 'C') {
+ *ucp = *(UINT8 *)(from + 1);
+ return 1 + sizeof(*ucp);
+ } else {
+ return -1;
+ }
+}
+
+static inline int
+DeMarshallUINT16(const char *from, UINT16 *uhp) {
+ if (*from == 'H') {
+ memcpy(uhp, from + 1, sizeof(*uhp));
+ return 1 + sizeof(*uhp);
+ } else {
+ return -1;
+ }
+}
+
+static inline int
+DeMarshallUINT32(const char *from, UINT32 *uip) {
+ if (*from == 'I') {
+ memcpy(uip, from + 1, sizeof(*uip));
+ return 1 + sizeof(*uip);
+ } else {
+ return -1;
+ }
+}
+
+static inline int
+DeMarshallint(const char *from, int *ip) {
+ return DeMarshallUINT32(from, (UINT32 *)ip);
+}
+
+static inline int
+DeMarshallUINT64(const char *from, UINT64 *ulp) {
+ if (*from == 'L') {
+ memcpy(ulp, from + 1, sizeof(*ulp));
+ return 1 + sizeof(*ulp);
+ } else {
+ return -1;
+ }
+}
+
+static inline int
+DeMarshallfloat(const char *from, float *fp) {
+ if (*from == 'F') {
+ memcpy(fp, from + 1, sizeof(*fp));
+ return 1 + sizeof(*fp);
+ } else {
+ return -1;
+ }
+}
+
+static inline int
+DeMarshalldouble(const char *from, double *dp) {
+ if (*from == 'D') {
+ memcpy(dp, from + 1, sizeof(*dp));
+
+ return 1 + sizeof(*dp);
+ } else {
+ return -1;
+ }
+}
+
+static inline int
+DeMarshallUINT8Stream(const char *from, UINT8 *buffer, UINT16 bytes) {
+ if (*from == 'B') {
+ memcpy(buffer, from + 1, bytes);
+ return (int)(1 + bytes);
+ } else {
+ return -1;
+ }
+}
+
+static inline int
+DeMarshallString(const char *from, char *buffer, UINT16 bytes) {
+ if (*from == 'S') {
+ char *start;
+ long len = strtol(from + 1, &start, 10);
+ if (len < 0 || len >= bytes) { // LCOV_EXCL_BR_LINE 5: fail safe for libc strtol
+ return -1;
+ }
+ start++; /* skip ' ' */
+ int skip = (int)(start - from);
+ memcpy(buffer, start, (size_t)len);
+ buffer[len] = '\0';
+ return skip + (int)len;
+ } else {
+ return -1;
+ }
+}
+
+/* Variable-length array data */
+static inline int
+DemarshallVararrayInfo(const char *from, UINT16 *bytes/* OUT */) {
+ if (*from == 'V') {
+ char *end;
+ long len = strtol((char *)(from + 1), &end, 10);
+ if (len <= 0 || len > RPC_MAX_API_ARG_SIZE) { // LCOV_EXCL_BR_LINE 5: fail safe for libc strtol
+ return -1;
+ }
+ *bytes = (UINT16)len;
+ return (int)(end - from + 1); /* skip ' ' */
+ } else {
+ return -1;
+ }
+}
+
+/** @ingroup RPClib_in
+ */
+
+#define MACRODemarshall(TYPE) \
+ do {\
+ TYPE *p; \
+ if (need_alloc && is_pointer) { \
+ p = rpc_malloc(sizeof(TYPE)); \
+ *(TYPE **)temp = p; \
+ } else { \
+ p = (TYPE *)temp; \
+ } \
+ if (p != NULL) { \
+ ret = DeMarshall##TYPE(from, p); \
+ } \
+ } while(0)
+
+int
+RPC_demarshall_arguments(const char *from, unsigned int size,
+ int need_alloc, int num_args, ...) {
+ rpc_assert(num_args <= RPC_MAX_API_ARG_NUM); // LCOV_EXCL_BR_LINE 6: double check
+ va_list ap;
+ va_start(ap, num_args);
+
+ int ii, error;
+ error = 0;
+ int remain_len = (int)size;
+
+ for(ii = 0 ; ii < num_args && error == 0 && remain_len > 0 ; ii++) {
+ unsigned int code, is_pointer, is_vararray;
+ UINT16 bytes;
+ unsigned int val = va_arg(ap, unsigned int);
+ RPC_marshall_flag flag;
+ flag.all = ntohl(val);
+ code = flag.bits.code;
+ is_vararray = flag.bits.is_vararray;
+ is_pointer = flag.bits.is_pointer;
+ bytes = flag.bits.bytes;
+ rpc_assert(bytes <= RPC_MAX_API_ARG_SIZE); // LCOV_EXCL_BR_LINE 6: double check
+
+
+ void *temp = va_arg(ap, void *);
+ int ret = -1;
+
+ if (*from == 'N') { /* NULL pointer */
+ if (bytes > 0 || is_pointer != 0) {
+ if (need_alloc) {
+ *(void **)temp = NULL;
+ } else {
+ /* do nothing */
+ }
+ ret = 1;
+ }
+ } else if (*from == 'P') { /* Pointer(no content) */
+ if (need_alloc) {
+ if (bytes > 0) { /* String type or user-defined type */
+ *(void **)temp = rpc_malloc(bytes);
+ } else if (is_pointer != 0) { /* Other pointers */
+ *(void **)temp = rpc_malloc(_ENOUGH_SPACE_FOR_ALL_TYPES);
+ }
+ ret = 1;
+ }
+ } else { /* non-NULL pointer */
+ if ( is_vararray ) { /* Variable-length array */
+ ret = DemarshallVararrayInfo(from, &bytes);
+ if( ret < 0 ) {
+ va_end(ap);
+ return -1; /* pgr0524 */
+ }
+ char *p;
+ if (need_alloc) {
+ p = rpc_malloc(sizeof(char)*bytes);
+ *(char **)temp = p;
+ } else {
+ p = (char *)temp; /* pgr0524 */
+ }
+ if (p != NULL) {
+ memcpy(p, from + ret, bytes);
+ ret += bytes;
+ }
+ } else {
+ switch(code) {
+ case rpc_CHAR:
+ case rpc_INT8:
+ case rpc_UINT8:
+ MACRODemarshall(UINT8); /* pgr0524 */ // LCOV_EXCL_BR_LINE 15: marco defined in rpc_marshall.c
+ break;
+ case rpc_INT16:
+ case rpc_UINT16:
+ MACRODemarshall(UINT16); /* pgr0524 */ // LCOV_EXCL_BR_LINE 15: marco defined in rpc_marshall.c
+ break;
+ case rpc_INT:
+ case rpc_SINT:
+ case rpc_UINT:
+ MACRODemarshall(int); /* pgr0524 */ // LCOV_EXCL_BR_LINE 15: marco defined in rpc_marshall.c
+ break;
+ case rpc_INT32:
+ case rpc_UINT32:
+ MACRODemarshall(UINT32); /* pgr0524 */ // LCOV_EXCL_BR_LINE 15: marco defined in rpc_marshall.c
+ break;
+ case rpc_INT64:
+ case rpc_UINT64:
+ MACRODemarshall(UINT64); /* pgr0524 */ // LCOV_EXCL_BR_LINE 15: marco defined in rpc_marshall.c
+ break;
+ case rpc_FLOAT:
+ MACRODemarshall(float); /* pgr0524 */ // LCOV_EXCL_BR_LINE 15: marco defined in rpc_marshall.c
+ break;
+ case rpc_DOUBLE:
+ MACRODemarshall(double); /* pgr0524 */ // LCOV_EXCL_BR_LINE 15: marco defined in rpc_marshall.c
+ break;
+ case rpc_USER_DEFINED: {
+ UINT8 *p;
+ if (need_alloc && is_pointer) {
+ p = rpc_malloc(bytes);
+ *(UINT8 **)temp = p;
+ } else {
+ p = (UINT8 *)temp; /* pgr0524 */
+ }
+ if (p != NULL) {
+ ret = DeMarshallUINT8Stream(from, p, bytes);
+ }
+ break;
+ }
+ case rpc_STRING: {
+ char *p;
+ if (need_alloc) {
+ p = rpc_malloc(sizeof(char)*bytes);
+ *(char **)temp = p;
+ } else {
+ p = (char *)temp; /* pgr0524 */
+ }
+ if (p != NULL) {
+ ret = DeMarshallString(from, p, bytes);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ if (ret < 0) {
+ error = 1;
+ } else {
+ remain_len -= ret;
+ from += ret;
+ }
+ }
+ va_end(ap);
+
+ if (error) {
+ return -1; /* pgr0524 */
+ } else {
+ return 0; /* pgr0524 */
+ }
+}
+
+void
+RPC_marshall_free(int num, ...) {
+ va_list ap;
+ va_start(ap, num);
+
+ int i;
+ for(i = 0 ; i < num ; i++) {
+ void *ptr = va_arg(ap, void *); // LCOV_EXCL_BR_LINE 15: macro defined in stdarg.h
+ if (ptr != NULL) {
+ rpc_free(ptr);
+ }
+ }
+ va_end(ap);
+}