Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #94097

Re: Generic read/write function - casting vs union

From Ben Bacarisse <ben.usenet@bsb.me.uk>
Newsgroups comp.lang.c
Subject Re: Generic read/write function - casting vs union
Date 2016-09-26 19:23 +0100
Organization A noiseless patient Spider
Message-ID <87shsmcyff.fsf@bsb.me.uk> (permalink)
References <ns08ge$o5v$1@dont-email.me> <kfn4m58eymd.fsf@x-alumni2.alumni.caltech.edu> <nsb5p2$e34$1@dont-email.me>

Show all headers | View raw


Noob <root@127.0.0.1> writes:

> On 22/09/2016 17:35, Tim Rentsch wrote:
>
>> Something crucial has been left out, specifically the definitions
>> of the wrapper functions that call access().  Based on the above
>> outline it looks like read() and write() simply make (or would
>> make) a local union object, and then call access() with the
>> address of that object.  But if that is true there is no point to
>> incrementing buf->in (or buf->out) since the value is then just
>> thrown away.  (And the void* types for 'buf' in the original
>> prototypes do nothing to unmuddy the water.)  Can you please
>> supply all the relevant details?  Generally my answers are
>> better if I don't have to shoot in the dark.
>
> The crucial missing piece of information is that the contents
> of the buffer need to be "unswizzled" because what is stored
> on the device differs from what is shown to upper layers.
>
> To recap, I'm supposed to implement
>
>   void foo_read (void *dev, uint8_t *buf, int len);
>   void foo_write(void *dev, const uint8_t *buf, int len);
>
> The "elementary" read and write functions are
>
>   void elem_read (void *dev, uint8_t *buf, int len);
>   void elem_write(void *dev, const uint8_t *buf, int len);
>
> If there were no swizzling requirement, I'd just say
>
>   foo_read = elem_read;
>   foo_write = elem_write;
>
> and call it a day.
>
>
> But actually I have to read a few bytes, skip a few,
> read a few more, etc.
>
> So foo_read looks like this:
>
> void foo_read (void *dev, uint8_t *buf, int len)
> {
>   elem_read(dev, buf, 12); buf += 12;
>   skip_forward(dev, 30);
>
>   elem_read(dev, buf, 15); buf += 15;
>   skip_forward(dev, 33);
>
>   elem_read(dev, buf, 17); buf += 17;
>   skip_forward(dev, 22);
>
>   /*** snip ***/
> }
>
> and it turns out the write function is exactly the same
> with elem_read changed to elem_write.
>
> So it makes sense (in my opinion) to implement foo_access()
> to avoid duplicating code between foo_read and foo_write.
>
> I hope my description was clear (enough).
>
>
> So my implementation looks more like this:
>
> void foo_generic(void *dev, uint8_t *buf, int len, int dir)
> {
>   elem_dispatch(dev, buf, 12, dir); buf += 12;
>   skip_forward(dev, 30);
>
>   elem_dispatch(dev, buf, 15, dir); buf += 15;
>   skip_forward(dev, 33);
>
>   elem_dispatch(dev, buf, 17, dir); buf += 17;
>   skip_forward(dev, 22);
>
>   /*** snip ***/
> }
>
> And of course elem_dispatch calls either elem_read or elem_write
> based on the dir parameter. But this solution requires casting
> away the constness of the write buffer.

Hmmm...  You might consider passing both a pointer to const data and a
pointer to non-const data, and using whichever is NULL as the condition
to dispatch on:

void foo_generic(void *dev, uint8_t *rd_buf, const uint8_t *wr_buf, int len)
{
   elem_dispatch(dev, rd_buf, wr_buf, 12); buf += 12;
   skip_forward(dev, 30);

   /* ... */
}

void elem_dispatch(void *dev, uint8_t *rd_buf, const uint8_t *wr_buf, int len)
{
   if (rd_buf) elem_read (dev, rd_buf, len);
   else        elem_write(dev, wr_buf, len);
}

void foo_read(void *dev, uint8_t *buf, int len)
{
   foo_generic(dev, buf, 0, len);
}

void foo_write(void *dev, const uint8_t *buf, int len)
{
   foo_generic(dev, 0, buf, len);
}

<snip>
-- 
Ben.

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Generic read/write function - casting vs union Noob <root@127.0.0.1> - 2016-09-22 11:33 +0200
  Re: Generic read/write function - casting vs union Richard Heathfield <rjh@cpax.org.uk> - 2016-09-22 11:07 +0100
    Re: Generic read/write function - casting vs union Noob <root@127.0.0.1> - 2016-09-22 12:36 +0200
      Re: Generic read/write function - casting vs union Richard Heathfield <rjh@cpax.org.uk> - 2016-09-22 14:07 +0100
    Re: Generic read/write function - casting vs union Keith Thompson <kst-u@mib.org> - 2016-09-22 11:48 -0700
    Re: Generic read/write function - casting vs union raltbos@xs4all.nl (Richard Bos) - 2016-09-23 19:42 +0000
  Re: Generic read/write function - casting vs union BartC <bc@freeuk.com> - 2016-09-22 13:11 +0100
    Re: Generic read/write function - casting vs union Noob <root@127.0.0.1> - 2016-09-22 14:46 +0200
      Re: Generic read/write function - casting vs union David Brown <david.brown@hesbynett.no> - 2016-09-22 15:10 +0200
        Re: Generic read/write function - casting vs union Noob <root@127.0.0.1> - 2016-09-22 15:36 +0200
          Re: Generic read/write function - casting vs union Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-09-22 19:28 -0700
          Re: Generic read/write function - casting vs union David Brown <david.brown@hesbynett.no> - 2016-09-23 09:59 +0200
      Re: Generic read/write function - casting vs union Barry Schwarz <schwarzb@dqel.com> - 2016-09-22 20:11 -0700
      Re: Generic read/write function - casting vs union Richard Damon <Richard@Damon-Family.org> - 2016-09-23 11:13 -0400
  Re: Generic read/write function - casting vs union Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-22 08:35 -0700
    Re: Generic read/write function - casting vs union Noob <root@127.0.0.1> - 2016-09-25 23:17 +0200
    Re: Generic read/write function - casting vs union Noob <root@127.0.0.1> - 2016-09-26 14:54 +0200
      Re: Generic read/write function - casting vs union boon <root@localhost.localdomain> - 2016-09-26 19:47 +0200
      Re: Generic read/write function - casting vs union Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-09-26 19:23 +0100
      Re: Generic read/write function - casting vs union Tim Rentsch <txr@alumni.caltech.edu> - 2016-09-27 13:10 -0700
      Re: Generic read/write function - casting vs union David Thompson <dave.thompson2@verizon.net> - 2016-10-16 18:08 -0400
  Re: Generic read/write function - casting vs union Anton Shepelev <anton.txt@gmail.com> - 2016-10-17 23:40 +0300
  Re: Generic read/write function - casting vs union albert@cherry.spenarnc.xs4all.nl (Albert van der Horst) - 2016-12-11 15:20 +0100
    Re: Generic read/write function - casting vs union supercat@casperkitty.com - 2016-12-11 09:38 -0800

csiph-web