MIDLC IDL Compiler

Michael B Allen mba2000 at ioplex.com
Sat Jan 15 05:43:54 GMT 2005


On Sat, 15 Jan 2005 15:33:41 +1100
Andrew Tridgell <tridge at osdl.org> wrote:

> Lets look at the pattern you use for enc_XXX():
> 
>   int enc_TYPE(struct ndr *ndr, TYPE *obj, unsigned char **dst, unsigned
>   char *dlim);
> 
> You tell me that dlim is a destination "fence post" limit pointer. So
> I presume this means that it is the limit of memory to write to when
> encoding structures into NDR blobs.
> 
> Now notice that it is a "unsigned char *" not a "unsigned char **",
> this means the encoding function can't change its value.
> 
> This implies to me that you are pre-allocating the destination buffer
> _before_ encoding. But what size do you pre-allocate? There is no way
> you can know

Right. My original proposal is wrong. You're right. I wasn't clear in
the course of some of our dialog as to how I arrived at accepting it
as wrong. And I was horribly confused by your original comment. But it
suffices to say I understand now.

To fix the problem I can replace 'unsigned char **dst, unsigned char
**deferred, unsigned char *dlim' with a buf_t structure something like:

  typedef struct {
      unsigned char *data;
      unsigned char *dst;
      unsigned char *deferred;
      unsigned char *dlim;
  } buf_t;

That makes the enc_XXX signatures like:

  int enc_TYPE(struct ndr *ndr, TYPE *obj, buf_t *dst);

Since it has the limit pointer in the buf_t struct and that is passed
to all dec_* functions you CAN advance it as the underlying data buffer
grows.

At least I think this is how it will work. Haven't actually done it yet.

> Note that none of the code you have sent me shows 'dlim' being used in
> any way, its just being passed around everwhere. I guess its checked
> in base functions like enc_ndr_long()

Exactly. You would only ever want/need to check it when you actually
try to touch the buffer. I would post one of the leaf routines I'm using
but they're going to need to change to support the said buf_t thing so ...

> A related problem is the use of 'deferred' and 'dst'. In the code you
> use deferred as a way of holding a buffer offset until later. But this
> makes no sense if you ever call realloc() on the buffer, as then
> deferred would become invalid. This implies to me that you don't
> realloc() the destination buffer, which again tells me you are using a
> fixed size pre-allocated buffer.

Mmm, I didn't really think about the deferred pointer. Thanks for pointing
that out. But if I use the buf_t thing I suppose I can just pass it
to a routine that does the realloc. It will be in a good position to
recompute it appropriately. I think :-/

Mike

-- 
Greedo shoots first? Not in my Star Wars.


More information about the samba-technical mailing list