MIDLC IDL Compiler

Michael B Allen mba2000 at ioplex.com
Sat Jan 15 23:10:37 GMT 2005

On Sat, 15 Jan 2005 18:06:17 +1100
Andrew Tridgell <tridge at osdl.org> wrote:

>  struct ndr_push {
> 	uint32_t flags; /* LIBNDR_FLAG_* */
> 	uint8_t *data;
> 	uint32_t alloc_size;
> 	uint32_t offset;
> 	struct ndr_token_list *relative_list;
> 	/* this is used to ensure we generate unique reference IDs */
> 	uint32_t ptr_count;
>  };
> I should point out why I chose this layout.
> The 'offset' field is like your 'dst' field, but its an offset
> relative to the base data pointer, so it doesn't need to be updated
> after a realloc, which arguably makes it less error prone.

Actually I have to use offsets too or the realloc is going to really mess up
my pointers. So I'm NOT going to use the buf_t thing. I'm going to end up
with the same arrangement as your code but with a small change. So far my
protos are going to be like:

int enc_TYPE(struct ndr *ndr, TYPE *obj, size_t *off);

The 'offset' has to be passed along as it changes temporarily as deferred
objects are encoded. Otherwise 'struct ndr' is now basically 'struct

> The 'ptr_count' is used to cope with full NDR pointers, mostly so that
> ethereal doesn't choke on them (it wants them to increment in the
> exact way given in the spec, tho it seems that Microsofts NDR layer
> doesn't care).

Unique pointers are a salted address' and I have a very simple map for DCE
pointers which gives properly incremented referents.

> What strategy do you plan to use for big/little endian? I chose quite
> a different method to MIDL, and each has its advantages. 

Right now I handle this in the leaf routines but to be honest I've never
even seen NDR with bigendian in it so for all I know it could be totally
wrong. For example to encode a long I have:

enc_ndr_long(struct ndr *ndr, uint32_t val, size_t *off)
    unsigned char *dst;

    if (ndr_chksize(ndr, *off + 4) == -1) {
        return -1;

    dst = ndr->data + *off; 
    if (ndr->bigendian) {
        dst[0] = (val >> 24) & 0xFF; 
        dst[1] = (val >> 16) & 0xFF; 
        dst[2] = (val >> 8) & 0xFF; 
        dst[3] = val & 0xFF; 
    } else {
        dst[0] = val & 0xFF; 
        dst[1] = (val >> 8) & 0xFF; 
        dst[2] = (val >> 16) & 0xFF; 
        dst[3] = (val >> 24) & 0xFF; 
    *off += 4;

    return 0;

Greedo shoots first? Not in my Star Wars.

More information about the samba-technical mailing list