/* * Adds IOV entries for the non-fixed portions of the arguments in vec. * This could also add handles/descriptors to the array to send. */ static BoolValue AddNonfixedForWrite(NaClSrpcArg** vec, size_t vec_len, size_t max_iov_len, struct NaClImcMsgIoVec* iov, size_t* iov_len, NaClSrpcImcDescType* descs, size_t* desc_len, size_t* expected_bytes) { size_t i; size_t element_size; nacl_abi_size_t count; void* base; /* Add IOV entries for the array/string types in vec. */ for (i = 0; i < vec_len; ++i) { switch (vec[i]->tag) { case NACL_SRPC_ARG_TYPE_BOOL: case NACL_SRPC_ARG_TYPE_DOUBLE: case NACL_SRPC_ARG_TYPE_INT: case NACL_SRPC_ARG_TYPE_INVALID: case NACL_SRPC_ARG_TYPE_LONG: case NACL_SRPC_ARG_TYPE_OBJECT: case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY: /* Scalar types are handled by fixed iovs alone. */ break; case NACL_SRPC_ARG_TYPE_HANDLE: /* Handles are added into the desc array. */ descs[*desc_len] = vec[i]->u.hval; ++*desc_len; break; case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY: case NACL_SRPC_ARG_TYPE_INT_ARRAY: case NACL_SRPC_ARG_TYPE_LONG_ARRAY: count = vec[i]->u.count; base = vec[i]->arrays.oval; element_size = ArrayElementSize(vec[i]); /* Check that computing the number of bytes will not overflow. */ if (SIZE_T_MAX / element_size < count) { return BoolFalse; } AddIovEntry(base, element_size * count, max_iov_len, iov, iov_len, expected_bytes); break; case NACL_SRPC_ARG_TYPE_STRING: count = (nacl_abi_size_t) strlen(vec[i]->arrays.str) + 1; base = vec[i]->arrays.oval; vec[i]->u.count = count; AddIovEntry(base, count, max_iov_len, iov, iov_len, expected_bytes); break; } } return BoolTrue; }
unsigned int ArrayHash(void *arr1) { char *arr = arr1; int i,len = ArrayElementSize(arr1) * ArrayLength(arr1); unsigned int hash = 5381; int c; for (i=0;i<len;i++) { c = arr[i]; hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ } return hash; }
/* * Adds the IOV entries for the nonfixed portions of an argument vector to * read. For receiving requests we need to allocate memory for the nonfixed * portions of both the inputs and results, but we do not read the results * vector's nonfixed portion. For receiving responses we do not allocate * memory for the nonfixed portion (the caller has already done that), but we * read the nonfixed portion of results. * If it returns BoolFalse, some memory may have been allocated. It is the * caller's responsibility to clean up in that case. */ static BoolValue AddNonfixedForRead(NaClSrpcArg** vec, size_t vec_len, size_t max_iov_len, BoolValue alloc_value, BoolValue read_value, struct NaClImcMsgIoVec* iov, size_t* iov_len, size_t* expected_bytes) { size_t i; /* Initialize the array pointers to allow cleanup if errors happen. */ if (alloc_value) { for (i = 0; i < vec_len; ++i) { vec[i]->arrays.oval = NULL; } } for (i = 0; i < vec_len; ++i) { size_t count = vec[i]->u.count; void* base = 0; size_t element_size = ArrayElementSize(vec[i]); if (element_size == 0) { /* Skip fixed size arguments. */ continue; } if (SIZE_T_MAX / element_size < count) { return BoolFalse; } base = vec[i]->arrays.oval; if (alloc_value) { base = malloc(element_size * count); if (base == 0) { return BoolFalse; } vec[i]->arrays.oval = base; } if (read_value) { AddIovEntry(base, element_size * count, max_iov_len, iov, iov_len, expected_bytes); } } return BoolTrue; }
int WriteArray(Stream *st,void *arr) { return st->Write(st,arr,ArrayLength(arr)*ArrayElementSize(arr)); }