1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2014 Jason King.
  14  * Copyright 2017 Joyent, Inc.
  15  */
  16 
  17 #ifndef _BUF_H
  18 #define _BUF_H
  19 
  20 #include <sys/types.h>
  21 #include <sys/debug.h>
  22 
  23 #ifdef __cplusplus
  24 extern "C" {
  25 #endif
  26 
  27 typedef struct buf {
  28         uchar_t *b_buf;
  29         uchar_t *b_ptr;
  30         size_t  b_len;
  31         ulong_t b_flags;
  32 } buf_t;
  33 #define BUF_READ        (1UL << 0)
  34 #define BUF_WRITE       (1UL << 1)
  35 #define BUF_EOF         (1UL << 2)
  36 #define BUF_ALLOCED     (1UL << 3)
  37 
  38 #define STRUCT_TO_BUF(st) {             \
  39         .b_buf = (uchar_t *)&(st),  \
  40         .b_ptr = (uchar_t *)&(st),  \
  41         .b_len = sizeof ((st)),         \
  42         .b_flags = 0                    \
  43 }
  44 
  45 #define BUF_IS_WRITE(b) \
  46         VERIFY(((b)->b_flags & BUF_WRITE) && !((b)->b_flags & BUF_READ))
  47 #define BUF_IS_READ(b) \
  48         VERIFY(((b)->b_flags & BUF_READ) && !((b)->b_flags & BUF_WRITE))
  49 
  50 inline boolean_t
  51 buf_eof(const buf_t *b)
  52 {
  53         return (!!(b->b_flags & BUF_EOF));
  54 }
  55 
  56 inline void
  57 buf_skip(buf_t *buf, size_t amt)
  58 {
  59         if (buf_eof(buf))
  60                 return;
  61 
  62         uchar_t *end = buf->b_buf + buf->b_len;
  63         buf->b_ptr += amt;
  64 
  65         if (buf->b_ptr > end) {
  66                 buf->b_ptr = end;
  67                 buf->b_flags |= BUF_EOF;
  68         }
  69 }
  70 
  71 inline void
  72 buf_reset(buf_t *buf)
  73 {
  74         buf->b_ptr = buf->b_buf;
  75         buf->b_flags &= ~(BUF_EOF);
  76 }
  77 
  78 inline size_t
  79 buf_left(const buf_t *buf)
  80 {
  81         if (buf->b_flags & BUF_EOF)
  82                 return (0);
  83         return (buf->b_len - (size_t)(buf->b_ptr - buf->b_buf));
  84 }
  85 
  86 inline void
  87 buf_set_read(buf_t *buf)
  88 {
  89         buf->b_flags &= ~(BUF_READ|BUF_WRITE);
  90         buf->b_flags |= BUF_READ;
  91 }
  92 
  93 inline void
  94 buf_set_write(buf_t *buf)
  95 {
  96         buf->b_flags &= ~(BUF_READ|BUF_WRITE);
  97         buf->b_flags |= BUF_WRITE;
  98 }
  99 
 100 size_t          buf_cat(buf_t *restrict, const buf_t *restrict, size_t);
 101 size_t          buf_copy(buf_t *restrict, const buf_t *restrict, size_t);
 102 void            buf_clear(buf_t *);
 103 void            buf_range(buf_t *restrict, buf_t *restrict, size_t, size_t);
 104 
 105 boolean_t       buf_alloc(buf_t *, size_t);
 106 void            buf_free(buf_t *);
 107 
 108 int             buf_cmp(const buf_t *restrict, const buf_t *restrict);
 109 
 110 void            buf_put8(buf_t *, uint8_t);
 111 void            buf_put32(buf_t *, uint32_t);
 112 void            buf_put64(buf_t *, uint64_t);
 113 
 114 #if 0
 115 void            buf_init(buf_t *, char *, size_t, size_t, boolean_t);
 116 void            buf_range(buf_t *, size_t, buf_t *);
 117 
 118 uint8_t         buf_get8(buf_t *);
 119 uint16_t        buf_get16(buf_t *);
 120 uint32_t        buf_get32(buf_t *);
 121 uint64_t        buf_get64(buf_t *);
 122 size_t          buf_copyfrom(buf_t *, char *, size_t);
 123 
 124 void            buf_put16(buf_t *, uint16_t);
 125 size_t          buf_append(char *, size_t, buf_t *);
 126 #endif
 127 
 128 #ifdef __cplusplus
 129 }
 130 #endif
 131 
 132 #endif /* _BUF_H */