Wheefun I/O Library  0.0.5
Useful I/O Primitives.
device.h
Go to the documentation of this file.
1 /* WFIO - the Wheefun IO Library
2  Copyright (C) 2018 Phillip Kilgore
3 
4  This program is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program. If not, see <https://www.gnu.org/licenses/>.
16 
17  Additionally, you should have recieved a copy of the GNU Classpath
18  exception, which amends the license to generally permit linking against
19  the software provided herein.
20 */
21 
22 #ifndef WFIO_DEVICE_H
23 #define WFIO_DEVICE_H
24 
34 #include <wfio/type.h>
35 #include <stdarg.h>
36 
38 
50 typedef struct wfio_device_vtable_t {
54  void (*close)(struct wfio_device_t* dev);
55 
59  size_t (*read)(struct wfio_device_t* dev, void* buf, size_t sz,
60  size_t elem);
61 
65  size_t (*write)(struct wfio_device_t* dev, const void* buf,
66  size_t sz, size_t elem);
67 
71  int (*seek)(struct wfio_device_t* dev, wfio_off_t offset,
72  wfio_whence_t whence);
73 
77  wfio_off_t (*tell)(struct wfio_device_t* dev);
78 
82  struct wfio_device_t* (*dup)(struct wfio_device_t* dev);
83 
87  int (*flush)(struct wfio_device_t* dev);
88 
92  size_t (*setbufsz)(struct wfio_device_t* dev, size_t len);
93 
97  size_t (*getbufsz)(struct wfio_device_t* dev);
98 
102  int (*dcntl)(struct wfio_device_t* dev, int cmd, va_list args);
103 
107  int (*ioctl)(struct wfio_device_t* dev, int cmd, va_list args);
109 
113 typedef enum wfio_device_flag_t {
118 
131 
136 
142 
151 
152  /* Convenience Flags */
153 
160 
164 typedef struct wfio_device_t {
169 
173  size_t refcount;
174 
178  int flags;
179 
183  int ecode;
184 
188  union {
189  signed int sint;
190  unsigned int uint;
191  wfio_fd_t fd;
192  struct wfio_iobuf_t* iobuf;
193  struct wfio_device_t* slave;
194  struct wfio_binstream_t* bin;
195  void* other;
196 
197  /* Buffered versions */
198 
199  struct {
200  signed int sint;
201  struct wfio_iobuf_t* buf;
202  } b_sint;
203 
204  struct {
205  unsigned int uint;
206  struct wfio_iobuf_t* buf;
207  } b_uint;
208 
209  struct {
210  wfio_fd_t fd;
211  struct wfio_iobuf_t* buf;
212  } b_fd;
213  } impl;
214 } wfio_device_t;
215 
224  const wfio_device_vtable_t* vtable, void* data, int* error);
225 
234  const wfio_device_vtable_t* vtable, int data, int* error);
235 
252  int ioshare);
253 
268  return wfio_device_ioshare(dev, WFIO_IOSHARE_O_ACQUIRE) != NULL;
269 }
270 
282 
294 
299  if (!dev) {
300  return 0;
301  }
302  else if (!dev->flags)
303  return wfio_device_forceClassify(dev);
304  else
305  return 1;
306 }
307 
322  size_t sz, size_t elem) {
323  if (dev)
324  return dev->vtable->read(dev, buf, sz, elem);
325  return WFIO_NPOS;
326 }
327 
341  size_t len) {
342  if (dev)
343  return dev->vtable->read(dev, buf, 1, len);
344  return WFIO_NPOS;
345 }
346 
357  unsigned char ret;
358  if (wfio_device_read(dev, &ret, 1, 1) != -1)
359  return ret;
360  else
361  return -1;
362 }
363 
377 WFIO_INLINE size_t wfio_device_write(wfio_device_t* dev, const void* buf,
378  size_t sz, size_t elem) {
379  if (dev)
380  return dev->vtable->write(dev, buf, sz, elem);
381  return WFIO_NPOS;
382 }
383 
397  const void* buf, size_t len) {
398  if (dev)
399  return dev->vtable->write(dev, buf, 1, len);
400  return WFIO_NPOS;
401 }
402 
414  char c) {
415  return wfio_device_write(dev, &c, 1, 1) == 1;
416 }
417 
433  wfio_whence_t whence) {
434  if (dev)
435  return dev->vtable->seek(dev, offset, whence);
436  return -1;
437 }
438 
447  if (!dev) {
448  return 0;
449  }
450  else if (!dev->flags)
452  return dev->flags & WFIO_DEVICE_SEEKABLE;
453 }
454 
466  if (dev)
467  return dev->vtable->tell(dev);
468  return -1;
469 }
470 
481  if (dev)
482  return dev->vtable->dup(dev);
483  return 0;
484 }
485 
509  size_t sz) {
510  if (dev)
511  return dev->vtable->setbufsz(dev, sz);
512  return WFIO_NPOS;
513 }
514 
527  if (dev)
528  return dev->vtable->getbufsz(dev);
529  return WFIO_NPOS;
530 }
531 
546  return wfio_device_getbufsz(dev) != 0;
547 }
548 
562  if (dev)
563  return dev->vtable->flush(dev);
564  return 0;
565 }
566 
588  wfio_dcntl_t cmd, va_list va);
589 
614  wfio_dcntl_t cmd, ...) {
615  register int ret;
616  va_list va;
617  va_start(va, cmd);
618  ret = wfio_device_vdcntl(dev, cmd, va);
619  va_end(va);
620  return ret;
621 }
622 
642 WFIO_DLL int wfio_device_vioctl(wfio_device_t* dev, int cmd,
643  va_list va);
644 
667  int cmd, ...) {
668  register int ret;
669  va_list va;
670  va_start(va, cmd);
671  ret = wfio_device_vioctl(dev, cmd, va);
672  va_end(va);
673  return ret;
674 }
675 
690  size_t* copied);
691 
701  struct wfio_iobuf_t* buf);
702 
712  struct wfio_iobuf_t* buf);
713 
714 /* dcntl Functions */
715 
727  return wfio_device_dcntl(dev, WFIO_DCNTL_GETFD);
728 }
729 
742  int flags) {
743  return wfio_device_dcntl(dev, WFIO_DCNTL_SETFLAGS, flags);
744 }
745 
758 }
759 
772  size_t len) {
773  return wfio_device_dcntl(dev, WFIO_DCNTL_TRUNCATE, len);
774 }
775 
777 
778 #ifdef __cplusplus
779 namespace wfio {
783  WFIO_CXX_DLL class Device {
785 
786  public:
787 
792 
799  class CXXStrategy {
800  public:
801 
814  virtual size_t read(CType dev, void* buf,
815  size_t sz, size_t elem) = 0;
816 
830  virtual size_t write(CType dev, const void* buf,
831  size_t sz, size_t elem) = 0;
832 
845  virtual int seek(CType dev, off_t offset,
846  wfio_whence_t whence) = 0;
847 
848 
858  virtual off_t tell(CType dev) = 0;
859 
860 
869  virtual int flush(CType dev) = 0;
870 
871 
884  virtual size_t setbufsz(CType dev, size_t len) = 0;
885 
886 
896  virtual size_t getbufsz(CType dev) const = 0;
897 
898 
907  virtual int dcntl(CType dev, int cmd,
908  va_list args) = 0;
909 
910 
919  virtual int ioctl(CType dev, int cmd,
920  va_list args) = 0;
921 
928  virtual ~CXXStrategy();
929  };
930 
936  inline Device() : m_dev(NULL) {}
937 
949  inline Device(CType dev, bool acquire=true)
950  : m_dev(dev) {
951  if (acquire)
953  }
954 
964  inline Device(CType dev, IOShare ioshare) :
965  m_dev(::wfio_device_ioshare(dev, ioshare)) {}
966 
978  WFIO_CXX_DLL Device(CXXStrategy* strategy);
979 
986  inline Device(const Device& dev) : m_dev(dev.m_dev) {
987  ::wfio_device_acquire(m_dev);
988  }
989 
996  inline ~Device() {
997  ::wfio_device_close(m_dev);
998  }
999 
1000  /* Read */
1001 
1002 
1015  inline size_t read(void* buf, size_t sz, size_t elem) {
1016  return ::wfio_device_read(m_dev, buf, sz, elem);
1017  }
1018 
1028  inline size_t read(void* buf, size_t len) {
1029  return ::wfio_device_read(m_dev, buf, 1, len);
1030  }
1031 
1038  inline int read() {
1040  }
1041 
1042  /* Write */
1043 
1056  inline size_t write(const void* buf, size_t sz,
1057  size_t elem) {
1058  return ::wfio_device_write(m_dev, buf, sz, elem);
1059  }
1060 
1072  inline size_t write(const void* buf, size_t len) {
1073  return ::wfio_device_write(m_dev, buf, 1, len);
1074  }
1075 
1085  inline bool write(char c) {
1086  return ::wfio_device_writeb(m_dev, c) == 1;
1087  }
1088 
1089  /* Seek */
1090 
1099  inline bool seek(wfio_off_t offset, wfio_whence_t whence) {
1100  return ::wfio_device_seek(m_dev, offset, whence);
1101  }
1102 
1110  inline wfio_off_t tell() const {
1112  }
1113 
1114  /* Dup */
1115 
1121  inline Device dup() {
1122  return Device(::wfio_device_dup(m_dev), false);
1123  }
1124 
1125  /* Buffering */
1126 
1132  inline bool flush() {
1134  }
1135 
1149  inline size_t bufsz(size_t len) {
1150  return ::wfio_device_setbufsz(m_dev, len);
1151  }
1152 
1160  inline size_t bufsz() const {
1162  }
1163 
1174  inline bool buffered() const {
1175  return bufsz() == 0;
1176  }
1177 
1178  /* dcntl */
1179 
1197  inline int dcntl(::wfio_dcntl_t cmd, ...) {
1198  register int ret;
1199  va_list va;
1200  va_start(va, cmd);
1201  ret = ::wfio_device_dcntl(m_dev, cmd, va);
1202  va_end(va);
1203  return ret;
1204  }
1205 
1206  /* ioctl */
1207 
1224  inline int ioctl(int cmd, ...) {
1225  register int ret;
1226  va_list va;
1227  va_start(va, cmd);
1228  ret = ::wfio_device_ioctl(m_dev, cmd, va);
1229  va_end(va);
1230  return ret;
1231  }
1232 
1233  /* Other */
1234 
1239  inline int flags() const throw() {
1240  return m_dev->flags;
1241  }
1242 
1247  inline int ecode() const throw() {
1248  return m_dev->ecode;
1249  }
1250 
1257  inline void ecode(int ecode) throw() {
1258  if (m_dev)
1259  m_dev->ecode = ecode;
1260  }
1261 
1271  inline bool valid() const throw() {
1272  return m_dev != NULL;
1273  }
1274 
1280  inline operator bool() const throw() {
1281  return m_dev != 0;
1282  }
1283 
1288  inline operator ::wfio_device_t*() throw() {
1289  return m_dev;
1290  }
1291 
1304  WFIO_CXX_DLL Device& operator=(const Device& rhs);
1305  };
1306 };
1307 #endif
1308 
1309 #endif
The root namespace for WFIO.
Definition: bin.h:879
Device(CType dev, IOShare ioshare)
Wrap a wfio:device_t using an IOShare.
Definition: device.h:964
size_t(* read)(struct wfio_device_t *dev, void *buf, size_t sz, size_t elem)
Read from this device.
Definition: device.h:59
const struct wfio_device_vtable_t * vtable
This device&#39;s virtual table.
Definition: device.h:168
The virtual table for a wfio_device_t.
Definition: device.h:50
WFIO_DLL wfio_device_t * wfio_device_from_voidp(const wfio_device_vtable_t *vtable, void *data, int *error)
Open a new device from a VTable and a void pointer representing the implementation.
size_t bufsz() const
Obtain the buffer size for this Device.
Definition: device.h:1160
#define WFIO_DLL
Mark the symbol as an element of the library.
Definition: host.h:397
WFIO_INLINE int wfio_device_dcntl(wfio_device_t *dev, wfio_dcntl_t cmd,...)
Perform device-independent I/O control on this device.
Definition: device.h:613
WFIO_C_BEGIN typedef long int wfio_off_t
An integer corresponding to a device offset.
Definition: iotype.h:48
#define WFIO_C_BEGIN
Definition: host.h:477
WFIO_INLINE size_t wfio_device_read(wfio_device_t *dev, void *buf, size_t sz, size_t elem)
Read from the supplied device.
Definition: device.h:321
#define WFIO_DLL_FASTCALL
Shorthand for WFIO_DLL WFIO_FASTCALL.
Definition: host.h:425
WFIO_INLINE int wfio_device_flush(wfio_device_t *dev)
Attempt to flush this device.
Definition: device.h:561
The device flags were set.
Definition: device.h:117
WFIO_DLL int wfio_device_vdcntl(wfio_device_t *dev, wfio_dcntl_t cmd, va_list va)
Perform device-independent I/O control on this device using a va_list.
wfio_device_flag_t
Flags applying to a device.
Definition: device.h:113
WFIO_ALWAYS_INLINE int wfio_device_isBuffered(wfio_device_t *dev)
Determine whether or not the device is buffered.
Definition: device.h:545
size_t(* getbufsz)(struct wfio_device_t *dev)
Obtain the size of the buffer associated this device.
Definition: device.h:97
The device is allowed to seek.
Definition: device.h:130
size_t refcount
This device&#39;s virtual count.
Definition: device.h:173
Obtain the file&#39;s current file descriptor.
Definition: iotype.h:193
The device is both readable and writable.
Definition: device.h:157
WFIO_DLL_FASTCALL size_t wfio_device_readbuf(wfio_device_t *dev, struct wfio_iobuf_t *buf)
Read the contents of the device dev into buf.
wfio_off_t(* tell)(struct wfio_device_t *dev)
Obtain the current stream position for this device.
Definition: device.h:77
WFIO_DLL_FASTCALL size_t wfio_device_writebuf(wfio_device_t *dev, struct wfio_iobuf_t *buf)
Write the contents of the buffer buf into dev.
#define WFIO_ALWAYS_INLINE
Mark this symbol to be forced inline.
Definition: host.h:447
WFIO_ALWAYS_INLINE int wfio_device_setflags(wfio_device_t *dev, int flags)
Set the flags for this device.
Definition: device.h:741
~Device()
Release this Device.
Definition: device.h:996
Device(CType dev, bool acquire=true)
Wrap a wfio_device_t.
Definition: device.h:949
WFIO_INLINE int wfio_device_seek(wfio_device_t *dev, wfio_off_t offset, wfio_whence_t whence)
Seek to a position in the stream.
Definition: device.h:432
wfio_whence_t
The type corresponding to the point of reference in a seek operation.
Definition: iotype.h:60
void(* close)(struct wfio_device_t *dev)
Close this device.
Definition: device.h:54
Device dup()
Duplicate this Device.
Definition: device.h:1121
int(* seek)(struct wfio_device_t *dev, wfio_off_t offset, wfio_whence_t whence)
Seek to a particular stream position in this device.
Definition: device.h:71
void ecode(int ecode)
Set the error code associated with this Device.
Definition: device.h:1257
WFIO_ALWAYS_INLINE int wfio_device_truncate(wfio_device_t *dev, size_t len)
Truncate the file to the specified length.
Definition: device.h:771
WFIO_INLINE int wfio_device_readb(wfio_device_t *dev)
Read a single byte from the supplied device.
Definition: device.h:356
WFIO_INLINE size_t wfio_device_getbufsz(wfio_device_t *dev)
Obtain the buffer size.
Definition: device.h:526
An IO sharing mode.
Definition: iotype.h:253
WFIO_DLL int wfio_device_vioctl(wfio_device_t *dev, int cmd, va_list va)
Perform device-dependent I/O control on this device.
int wfio_fd_t
The type corresponding a file descriptor.
Definition: iotype.h:108
size_t read(void *buf, size_t len)
Write a vector of bytes to this Device.
Definition: device.h:1028
WFIO_INLINE size_t wfio_device_setbufsz(wfio_device_t *dev, size_t sz)
Set the buffer size.
Definition: device.h:508
WFIO_DLL int wfio_device_sink(wfio_device_t *src, wfio_device_t *dest, size_t *copied)
Copy the contents of the device src into dest.
WFIO_INLINE size_t wfio_device_writeb(wfio_device_t *dev, char c)
Write a single byte to the supplied device.
Definition: device.h:413
::wfio_device_t * CType
The C type from which a Device is derived.
Definition: device.h:791
WFIO_INLINE int wfio_device_ioctl(wfio_device_t *dev, int cmd,...)
Perform device-dependent I/O control on this device.
Definition: device.h:666
wfio_dcntl_t
A command to be supplied to a device or similar stream.
Definition: iotype.h:175
WFIO_ALWAYS_INLINE int wfio_device_getflags(wfio_device_t *dev)
Obtain the flags for this device.
Definition: device.h:756
A C++ wrapper for a wfio_device_t.
Definition: device.h:783
bool seek(wfio_off_t offset, wfio_whence_t whence)
Seek to a position in this Device.
Definition: device.h:1099
WFIO_INLINE size_t wfio_device_write(wfio_device_t *dev, const void *buf, size_t sz, size_t elem)
Write to the supplied device.
Definition: device.h:377
const int flags
Flags associated with this buffer.
Definition: iobuf.h:126
A strategy for a device.
Definition: device.h:799
int ioctl(int cmd,...)
Perform device-dependent I/O control on this Device.
Definition: device.h:1224
WFIO_INLINE wfio_off_t wfio_device_tell(wfio_device_t *dev)
Determine the current stream position of this device.
Definition: device.h:465
The device may be read.
Definition: device.h:122
A stream intended for binary output.
Definition: bin.h:54
Device(const Device &dev)
Copy-construct a device.
Definition: device.h:986
size_t bufsz(size_t len)
Set the buffer size for this Device.
Definition: device.h:1149
size_t write(const void *buf, size_t sz, size_t elem)
Write a vector of elements to this Device.
Definition: device.h:1056
A constant indicating no position.
Definition: iotype.h:226
struct wfio_device_t wfio_device_t
A simple, byte-oriented channel.
WFIO_INLINE int wfio_device_classify(wfio_device_t *dev)
Conditionally classify a device.
Definition: device.h:298
Obtain the flags associated with this device.
Definition: iotype.h:205
The device is reserved by WFIO or some other library and should not have its device handle freed...
Definition: device.h:141
bool flush()
Attempt to flush this Device.
Definition: device.h:1132
size_t read(void *buf, size_t sz, size_t elem)
Write elements to this Device.
Definition: device.h:1015
#define WFIO_INLINE
Mark this symbol for inlining.
Definition: host.h:377
#define WFIO_C_END
Definition: host.h:485
WFIO_DLL wfio_device_t * wfio_device_from_int(const wfio_device_vtable_t *vtable, int data, int *error)
Open a new device from a VTable and an integral handle representing the implementation.
WFIO_DLL int wfio_device_forceClassify(wfio_device_t *dev)
Deduce the appropriate flags for this device if they have not already been set.
A simple, byte-oriented channel.
Definition: device.h:164
size_t(* write)(struct wfio_device_t *dev, const void *buf, size_t sz, size_t elem)
Write to this device.
Definition: device.h:65
WFIO_ALWAYS_INLINE int wfio_device_acquire(wfio_device_t *dev)
Share this device by acquiring it.
Definition: device.h:267
An IOShare mode indicating that the stream is acquired.
Definition: iotype.h:148
The device may be written.
Definition: device.h:126
int flags
This device&#39;s flags.
Definition: device.h:178
Set the length of a device&#39;s backing store.
Definition: iotype.h:219
int(* ioctl)(struct wfio_device_t *dev, int cmd, va_list args)
Perform device-specific I/O control on the underlying device.
Definition: device.h:107
int(* flush)(struct wfio_device_t *dev)
Flush the underlying buffer.
Definition: device.h:87
size_t(* setbufsz)(struct wfio_device_t *dev, size_t len)
Ensure that the buffer is exactly len bytes long.
Definition: device.h:92
WFIO_INLINE size_t wfio_device_readbV(wfio_device_t *dev, void *buf, size_t len)
Read a vector of bytes from the supplied device.
Definition: device.h:340
int ecode
This device&#39;s last error.
Definition: device.h:183
Device()
Construct the default Device.
Definition: device.h:936
Attempt to change the flags associated with this device.
Definition: iotype.h:200
WFIO_INLINE wfio_device_t * wfio_device_dup(wfio_device_t *dev)
Duplicate this device.
Definition: device.h:480
::wfio_off_t off_t
An integer corresponding to a device offset.
Definition: iotype.h:234
WFIO_DLL void wfio_device_close(wfio_device_t *dev)
Close the supplied device.
int ecode() const
Obtain the error code associated with this Device.
Definition: device.h:1247
WFIO_DLL_FASTCALL wfio_device_t * wfio_device_ioshare(wfio_device_t *dev, int ioshare)
Share this device with the supplied ioshare mode.
size_t write(const void *buf, size_t len)
Write a vector of bytes to this Device.
Definition: device.h:1072
A generic I/O buffer.
Definition: iobuf.h:122
struct wfio_device_t *(* dup)(struct wfio_device_t *dev)
Duplicate this device.
Definition: device.h:82
int flags() const
Obtain the flags vector associated with this Device.
Definition: device.h:1239
int dcntl(::wfio_dcntl_t cmd,...)
Perform device-independent I/O control on this Device.
Definition: device.h:1197
WFIO_INLINE size_t wfio_device_writebV(wfio_device_t *dev, const void *buf, size_t len)
Write a vector of bytes to the supplied device.
Definition: device.h:396
bool valid() const
Determine if this Device is valid.
Definition: device.h:1271
int read()
Read a single byte from this Device.
Definition: device.h:1038
WFIO_ALWAYS_INLINE wfio_fd_t wfio_device_getfd(wfio_device_t *dev)
Obtain the file descriptor for this device.
Definition: device.h:726
bool buffered() const
Determine whether or not the device is buffered.
Definition: device.h:1174
This device is nonblocking.
Definition: device.h:135
bool write(char c)
Write a single byte to this Device.
Definition: device.h:1085
wfio_off_t tell() const
Determine the current stream position of this Device.
Definition: device.h:1110
A device-specific flag.
Definition: device.h:150
Shared type definitions.
WFIO_INLINE int wfio_device_canSeek(wfio_device_t *dev)
Determine whether or not this device is capable of seeking.
Definition: device.h:446
int(* dcntl)(struct wfio_device_t *dev, int cmd, va_list args)
Perform device-independent control on this device.
Definition: device.h:102
WFIO_C_BEGIN struct wfio_device_vtable_t wfio_device_vtable_t
The virtual table for a wfio_device_t.