Commit ae78eb49 authored by Chuck Lever's avatar Chuck Lever
Browse files

xdrgen: Implement short (16-bit) integer types



"short" and "unsigned short" types are not defined in RFC 4506, but
are supported by the rpcgen program. An upcoming protocol
specification includes at least one "unsigned short" field, so xdrgen
needs to implement support for these types.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 789477b8
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -46,6 +46,66 @@ xdrgen_encode_bool(struct xdr_stream *xdr, bool val)
	return true;
}

/*
 * De facto (non-standard but commonly implemented) signed short type:
 *  - Wire sends sign-extended 32-bit value (e.g., 0xFFFFFFFF)
 *  - be32_to_cpup() returns u32 (0xFFFFFFFF)
 *  - Explicit (s16) cast truncates to 16 bits (0xFFFF = -1)
 */
static inline bool
xdrgen_decode_short(struct xdr_stream *xdr, s16 *ptr)
{
	__be32 *p = xdr_inline_decode(xdr, XDR_UNIT);

	if (unlikely(!p))
		return false;
	*ptr = (s16)be32_to_cpup(p);
	return true;
}

/*
 * De facto (non-standard but commonly implemented) signed short type:
 *  - C integer promotion sign-extends s16 val to int before passing to
 *    cpu_to_be32()
 *  - This is well-defined: -1 as s16 -1 as int 0xFFFFFFFF on wire
 */
static inline bool
xdrgen_encode_short(struct xdr_stream *xdr, s16 val)
{
	__be32 *p = xdr_reserve_space(xdr, XDR_UNIT);

	if (unlikely(!p))
		return false;
	*p = cpu_to_be32(val);
	return true;
}

/*
 * De facto (non-standard but commonly implemented) unsigned short type:
 * 16-bit integer zero-extended to fill one XDR_UNIT.
 */
static inline bool
xdrgen_decode_unsigned_short(struct xdr_stream *xdr, u16 *ptr)
{
	__be32 *p = xdr_inline_decode(xdr, XDR_UNIT);

	if (unlikely(!p))
		return false;
	*ptr = (u16)be32_to_cpup(p);
	return true;
}

static inline bool
xdrgen_encode_unsigned_short(struct xdr_stream *xdr, u16 val)
{
	__be32 *p = xdr_reserve_space(xdr, XDR_UNIT);

	if (unlikely(!p))
		return false;
	*p = cpu_to_be32(val);
	return true;
}

static inline bool
xdrgen_decode_int(struct xdr_stream *xdr, s32 *ptr)
{
+2 −0
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ def kernel_c_type(spec: _XdrTypeSpecifier) -> str:
    """Return name of C type"""
    builtin_native_c_type = {
        "bool": "bool",
        "short": "s16",
        "unsigned_short": "u16",
        "int": "s32",
        "unsigned_int": "u32",
        "long": "s32",
+4 −0
Original line number Diff line number Diff line
@@ -20,9 +20,11 @@ constant : decimal_constant | hexadecimal_constant | octal_consta
type_specifier          : unsigned_hyper
                        | unsigned_long
                        | unsigned_int
                        | unsigned_short
                        | hyper
                        | long
                        | int
                        | short
                        | float
                        | double
                        | quadruple
@@ -35,9 +37,11 @@ type_specifier : unsigned_hyper
unsigned_hyper          : "unsigned" "hyper"
unsigned_long           : "unsigned" "long"
unsigned_int            : "unsigned" "int"
unsigned_short          : "unsigned" "short"
hyper                   : "hyper"
long                    : "long"
int                     : "int"
short                   : "short"
float                   : "float"
double                  : "double"
quadruple               : "quadruple"
+4 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ def xdr_quadlen(val: str) -> int:
symbolic_widths = {
    "void": ["XDR_void"],
    "bool": ["XDR_bool"],
    "short": ["XDR_short"],
    "unsigned_short": ["XDR_unsigned_short"],
    "int": ["XDR_int"],
    "unsigned_int": ["XDR_unsigned_int"],
    "long": ["XDR_long"],
@@ -48,6 +50,8 @@ symbolic_widths = {
max_widths = {
    "void": 0,
    "bool": 1,
    "short": 1,
    "unsigned_short": 1,
    "int": 1,
    "unsigned_int": 1,
    "long": 1,