Lely core libraries  2.3.4
buf.c
Go to the documentation of this file.
1 
24 #include "can.h"
25 #define LELY_CAN_BUF_INLINE extern inline
26 #include <lely/can/buf.h>
27 #include <lely/util/errnum.h>
28 
29 #include <assert.h>
30 #if !LELY_NO_MALLOC
31 #include <stdlib.h>
32 #include <string.h>
33 #endif
34 
35 #ifndef LELY_CAN_BUF_SIZE
37 #define LELY_CAN_BUF_SIZE 16
38 #endif
39 
40 void
41 can_buf_fini(struct can_buf *buf)
42 {
43  assert(buf);
44 
45 #if LELY_NO_MALLOC
46  (void)buf;
47 #else
48  free(buf->ptr);
49 #endif
50 }
51 
52 size_t
53 can_buf_reserve(struct can_buf *buf, size_t n)
54 {
55  assert(buf);
56 
57  const size_t capacity = can_buf_capacity(buf);
58  if (n <= capacity)
59  return capacity;
60 
61 #if LELY_NO_MALLOC
63  return 0;
64 #else
65  size_t size = LELY_CAN_BUF_SIZE;
66  while (size - 1 < can_buf_size(buf) + n)
67  size *= 2;
68  size--;
69 
70  // Reallocate the existing buffer.
71  struct can_msg *ptr =
72  realloc(buf->ptr, (size + 1) * sizeof(struct can_msg));
73  if (!ptr) {
74 #if !LELY_NO_ERRNO
75  set_errc(errno2c(errno));
76 #endif
77  return 0;
78  }
79  buf->ptr = ptr;
80 
81  // If the buffer consists of two regions (because of wrapping), move the
82  // second region to the end of the buffer.
83  size_t begin = buf->begin & buf->size;
84  size_t end = buf->end & buf->size;
85  if (begin > end) {
86  struct can_msg *endptr = buf->ptr + buf->size + 1;
87  struct can_msg *srcptr = buf->ptr + begin;
88  begin += size - buf->size;
89  struct can_msg *dstptr = buf->ptr + begin;
90  memmove(dstptr, srcptr,
91  (endptr - srcptr) * sizeof(struct can_msg));
92  buf->begin = begin;
93  buf->end = end;
94  }
95 
96  buf->size = size;
97 
98  return can_buf_capacity(buf);
99 #endif
100 }
#define LELY_CAN_BUF_SIZE
The minimum size (in number of frames) of a CAN frame buffer.
Definition: buf.c:37
size_t can_buf_reserve(struct can_buf *buf, size_t n)
Resizes a CAN frame buffer, if necessary, to make room for at least n additional frames.
Definition: buf.c:53
void can_buf_fini(struct can_buf *buf)
Finalizes a CAN frame buffer.
Definition: buf.c:41
This header file is part of the CAN library; it contains the CAN frame buffer declarations.
LELY_CAN_BUF_INLINE size_t can_buf_capacity(const struct can_buf *buf)
Returns the number of frames available for writing in a CAN buffer.
Definition: buf.h:195
LELY_CAN_BUF_INLINE size_t can_buf_size(const struct can_buf *buf)
Returns the number of frames available for reading in a CAN buffer.
Definition: buf.h:186
This header file is part of the utilities library; it contains the native and platform-independent er...
@ ERRNUM_NOMEM
Not enough space.
Definition: errnum.h:172
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Definition: errnum.c:944
int errno2c(int errnum)
Transforms a standard C error number to a native error code.
Definition: errnum.c:46
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Definition: errnum.h:424
This is the internal header file of the CAN bus operation queue functions.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
This header file is part of the C11 and POSIX compatibility library; it includes <string....
A CAN frame buffer.
Definition: buf.h:42
struct can_msg * ptr
A pointer to the allocated memory for the buffer.
Definition: buf.h:44
size_t end
The offset (with respect to ptr) of one past the last value available for reading (and the first avai...
Definition: buf.h:63
size_t begin
The offset (with respect to ptr) of the first value available for reading (and two past the last avai...
Definition: buf.h:57
size_t size
The total size (in number of frames) of the buffer, excluding the unused frame used to distinguish be...
Definition: buf.h:51
A CAN or CAN FD format frame.
Definition: msg.h:87