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


Groups > comp.lang.c > #94082

Re: Generic read/write function - casting vs union

From Noob <root@127.0.0.1>
Newsgroups comp.lang.c
Subject Re: Generic read/write function - casting vs union
Date 2016-09-26 14:54 +0200
Organization A noiseless patient Spider
Message-ID <nsb5p2$e34$1@dont-email.me> (permalink)
References <ns08ge$o5v$1@dont-email.me> <kfn4m58eymd.fsf@x-alumni2.alumni.caltech.edu>

Show all headers | View raw


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.

So it was suggested to me to use a union-based solution.

Regards.

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