/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <rad/adr_typeset.h>
#include "radproto_util.h"
#include "radproto_adr.h"
#include "protocol.h"
/*
* XDR-like routines for reading and writing ADR data and types.
* There are two major differences between these and "normal" XDR
* routines:
* a) Some take more than two arguments. This is because the
* routines aren't dealing with fixed data structures and
* require additional inputs to perform their processing.
* This is a contributing factor to...
* b) They aren't symmetric. i.e. there are separate routines
* for reading (or sizing) and writing. The only substantial
* effect of merging reading and writing into a single function
* would be to create functions which are large and difficult
* to maintain.
*/
/*
* Marshal type definitions.
*/
static bool_t
{
case DT_ARRAY:
return (FALSE);
break;
case DT_STRUCT: {
return (FALSE);
return (FALSE);
}
break;
}
case DT_UNION: {
(dflt &&
return (FALSE);
return (FALSE);
}
break;
}
case DT_ENUM: {
return (FALSE);
return (FALSE);
}
break;
}
}
return (TRUE);
}
static bool_t
{
int ttype;
return (FALSE);
if (!ADR_DT_DERIVED(ttype))
return (FALSE);
return (FALSE);
switch (ttype) {
case DT_ARRAY: {
goto error;
break;
}
case DT_STRUCT: {
goto error;
sizeof (adr_structfield_t))) == NULL)
goto error;
goto error;
f->sf_nullable = fopt;
}
break;
}
case DT_UNION: {
goto error;
(dflt && (
goto error;
NULL)
goto error;
if (dflt) {
}
return (FALSE);
}
break;
}
case DT_ENUM: {
goto error;
goto error;
sizeof (adr_enumval_t))) == NULL) {
goto error;
}
int eval;
goto error;
goto error;
}
break;
}
}
return (TRUE);
return (FALSE);
}
{
return (FALSE);
return (TRUE);
return (FALSE);
return (TRUE);
}
{
return (FALSE);
if (!ADR_DT_DERIVED(ttype)) {
return (TRUE);
}
return (FALSE);
return (TRUE);
}
{
return (FALSE);
return (FALSE);
}
return (TRUE);
}
{
int ntypes;
return (FALSE);
return (FALSE);
for (int i = 0; i < ntypes; i++)
return (FALSE);
}
return (TRUE);
}
/*
* Normally the absence of a type is represented by void. Attribute/
* method error payload types require additional information: it is
* desirable to distinguish between an operation that doesn't return
* error payload data, and an operation that doesn't return errors.
* We effectively treat an error payload type as "optional data".
*
* Note that we don't use this when serializing standard error types
* at protocol negotiation time.
*/
{
return (FALSE);
if (b)
return (TRUE);
}
{
bool_t b;
return (FALSE);
if (b)
return (TRUE);
}
{
return (FALSE);
return (TRUE);
}
{
return (FALSE);
return (TRUE);
}
/*
* Marshal/unmarshall an interface/version tuple.
*
* nparents indicates how many parent Interfaces should be processed when
* decoding. It isn't used when encoding.
*/
{
int i;
return (FALSE);
}
if (nparents > 0) {
obj->ao_parents =
return (FALSE);
}
}
/* Depth first; primary interface should be last listed */
for (i = 0; i < obj->ao_nparents; i++)
return (FALSE);
return (FALSE);
for (i = 0; i < NSTABILITY; i++)
return (FALSE);
return (TRUE);
}
static int
{
int n = 0;
for (int i = 0; i < obj->ao_nparents; i++)
return (n + 1);
}
/*
* Marshal an interface definition.
*/
{
int i, j;
/*
* Compatible interfaces and their versions
*/
int n = count_parents(obj);
return (FALSE);
/*
* Type definitions
*/
return (FALSE);
/*
* Attributes
*/
return (FALSE);
for (i = 0; i < obj->ao_nattributes; i++) {
return (FALSE);
}
/*
* Methods
*/
return (FALSE);
for (i = 0; i < obj->ao_nmethods; i++) {
return (FALSE);
for (j = 0; j < m->am_nargs; j++) {
adr_parameter_t *p = &m->am_args[j];
return (FALSE);
}
}
/*
* Events
*/
return (FALSE);
for (i = 0; i < obj->ao_nevents; i++) {
return (FALSE);
}
return (TRUE);
}
/*
* Unmarshal an interface definition.
*/
{
return (FALSE);
/*
* Versions
*/
int n;
goto error;
goto error;
/*
* Attributes
*/
goto error;
goto error;
result->ao_nattributes = n;
for (int i = 0; i < result->ao_nattributes; i++) {
goto error;
goto error;
}
/*
* Methods
*/
goto error;
goto error;
result->ao_nmethods = n;
for (int i = 0; i < result->ao_nmethods; i++) {
goto error;
goto error;
goto error;
goto error;
}
}
/*
* Events
*/
goto error;
goto error;
result->ao_nevents = n;
for (int i = 0; i < result->ao_nevents; i++) {
goto error;
}
return (TRUE);
return (FALSE);
}
/*
* Marshal (typed) data.
*/
{
int i;
switch (adr_data_basetype(data)) {
case DT_BOOLEAN:
return (FALSE);
break;
case DT_INT:
return (FALSE);
break;
case DT_LONG:
return (FALSE);
break;
case DT_UINT:
return (FALSE);
break;
case DT_ULONG:
return (FALSE);
break;
case DT_FLOAT:
return (FALSE);
break;
case DT_DOUBLE:
return (FALSE);
break;
case DT_TIME: {
};
return (FALSE);
break;
}
case DT_STRING:
return (FALSE);
break;
case DT_SECRET:
return (FALSE);
break;
case DT_NAME: {
return (FALSE);
return (FALSE);
}
break;
}
case DT_ARRAY:
return (FALSE);
return (FALSE);
}
break;
case DT_STRUCT:
if (sf->sf_nullable) {
return (FALSE);
} else {
return (FALSE);
}
}
break;
case DT_ENUM: {
/* Communicated as an index */
return (FALSE);
break;
}
case DT_OPAQUE:
return (FALSE);
break;
case DT_UNION: {
/* Write arm index, discriminant value */
return (FALSE);
/* Write data, if any */
return (FALSE);
break;
}
}
return (TRUE);
}
/*
* Unmarshal data of the specified type
*/
{
case DT_BOOLEAN: {
bool_t b;
return (FALSE);
break;
}
case DT_INT: {
int i;
return (FALSE);
break;
}
case DT_LONG: {
long long l;
return (FALSE);
break;
}
case DT_UINT: {
unsigned int ui;
return (FALSE);
break;
}
case DT_ULONG: {
unsigned long long ul;
return (FALSE);
break;
}
case DT_FLOAT: {
float f;
return (FALSE);
break;
}
case DT_DOUBLE: {
double d;
if (!xdr_double(xdrs, &d) ||
return (FALSE);
break;
}
case DT_TIME: {
return (FALSE);
break;
}
case DT_NAME: {
char *c = NULL;
return (FALSE);
free(c);
return (FALSE);
}
free(c);
break;
}
case DT_STRING: {
char *c = NULL;
return (FALSE);
break;
}
case DT_SECRET: {
char *c = NULL;
return (FALSE);
break;
}
case DT_ARRAY: {
int i, count;
return (FALSE);
/* Check size; only works for xdrmem */
count);
return (FALSE);
}
return (FALSE);
for (i = 0; i < count; i++)
break;
if (i < count) {
return (FALSE);
}
break;
}
case DT_STRUCT: {
int i;
extern void adr_struct_set_internal(adr_data_t *,
adr_structfield_t *, adr_data_t *);
return (FALSE);
adr_data_t *d;
if (sf->sf_nullable) {
break;
} else {
break;
}
}
return (FALSE);
}
break;
}
case DT_OPAQUE: {
char *c = NULL;
return (FALSE);
/* Check size; only works for xdrmem */
len);
return (FALSE);
}
return (FALSE);
free(c);
return (FALSE);
}
return (FALSE);
break;
}
case DT_ENUM: {
int index;
return (FALSE);
return (FALSE);
}
break;
}
case DT_UNION: {
unsigned int index;
/* Read arm index */
return (FALSE);
if (index > 0) {
} else {
buf))
return (FALSE);
return (FALSE);
}
}
return (FALSE);
/* Read data, if any */
return (FALSE);
}
if ((*data =
== NULL)
return (FALSE);
break;
}
default:
"Invalid deserialized data type (%d)",
return (FALSE);
}
return (TRUE);
}
/*
* Marshal a piece of optional data.
*/
{
return (FALSE);
if (b)
return (TRUE);
}
/*
* Unmarshal a piece of typed optional data.
*/
{
bool_t b;
return (FALSE);
if (b)
else
return (TRUE);
}
{
return (FALSE);
xdr_destroy(&mxdr);
return (FALSE);
}
xdr_destroy(&mxdr);
return (TRUE);
}