CNDP  22.08.0
cli_gapbuf.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2019-2022 Intel Corporation.
3  */
4 /* inspired by an email/code written by: Joseph H. Allen, 9/10/89 */
5 
6 #include <stdlib.h> // for realloc, NULL
7 #include <string.h> // for memmove, strlen
8 #include <cne_log.h> // for cne_panic
9 #include <stdint.h> // for uint32_t
10 
11 #include "cne_common.h" // for CNDP_API
12 
13 #ifndef _CLI_GAPBUF_H_
14 #define _CLI_GAPBUF_H_
15 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #define GB_DEFAULT_GAP_SIZE 8
27 
28 struct gapbuf {
29  char *buf;
30  char *ebuf;
31  char *point;
32  char *gap;
33  char *egap;
34 };
35 
42 CNDP_API struct gapbuf *gb_create(void);
43 
52 CNDP_API void gb_destroy(struct gapbuf *gb);
53 
64 CNDP_API int gb_init_buf(struct gapbuf *gb, int size);
65 
74 CNDP_API int gb_reset_buf(struct gapbuf *gb);
75 
88 CNDP_API uint32_t gb_copy_to_buf(struct gapbuf *gb, char *dst, uint32_t size);
89 
100 CNDP_API void gb_dump(struct gapbuf *gb, const char *msg);
101 
102 /********************************************************/
103 
112 static inline uint32_t
113 gb_buf_size(struct gapbuf *gb)
114 {
115  return gb->ebuf - gb->buf;
116 }
117 
126 static inline uint32_t
127 gb_gap_size(struct gapbuf *gb)
128 {
129  return gb->egap - gb->gap;
130 }
131 
140 static inline uint32_t
141 gb_data_size(struct gapbuf *gb)
142 {
143  return (gb->ebuf - gb->buf) - (gb->egap - gb->gap);
144 }
145 
154 static inline char *
155 gb_start_of_buf(struct gapbuf *gb)
156 {
157  return gb->buf;
158 }
159 
168 static inline char *
169 gb_start_of_gap(struct gapbuf *gb)
170 {
171  return gb->gap;
172 }
173 
182 static inline char *
183 gb_end_of_gap(struct gapbuf *gb)
184 {
185  return gb->egap;
186 }
187 
196 static inline char *
197 gb_end_of_buf(struct gapbuf *gb)
198 {
199  return gb->ebuf;
200 }
201 
210 static inline char *
211 gb_point_at(struct gapbuf *gb)
212 {
213  return gb->point;
214 }
215 
224 static inline int
225 gb_point_at_start(struct gapbuf *gb)
226 {
227  return (gb->point == gb->buf);
228 }
229 
238 static inline int
239 gb_point_at_end(struct gapbuf *gb)
240 {
241  return (gb->ebuf == gb->point);
242 }
243 
252 static inline int
253 gb_point_at_gap(struct gapbuf *gb)
254 {
255  return (gb->gap == gb->point);
256 }
257 
268 static inline void
269 gb_set_point(struct gapbuf *gb, int idx)
270 {
271  if (idx == -1) {
272  gb->point = gb->ebuf;
273  return;
274  }
275  gb->point = gb->buf + idx;
276  if (gb->point > gb->gap)
277  gb->point += gb->egap - gb->gap;
278 }
279 
288 static inline int
289 gb_point_offset(struct gapbuf *gb)
290 {
291  if (gb->point > gb->egap)
292  return (gb->point - gb->buf) - (gb->egap - gb->gap);
293  else
294  return gb->point - gb->buf;
295 }
296 
305 static inline int
306 gb_eof(struct gapbuf *gb)
307 {
308  return (gb->point == gb->gap) ? (gb->egap == gb->ebuf) : (gb->point == gb->ebuf);
309 }
310 
311 /********************************************************/
312 
321 static inline void
322 gb_move_gap_to_point(struct gapbuf *gb)
323 {
324  if (gb->point == gb->gap)
325  return;
326 
327  if (gb->point == gb->egap)
328  gb->point = gb->gap;
329  else {
330  int cnt;
331 
332  if (gb->point < gb->gap) {
333  cnt = gb->gap - gb->point;
334  memmove(gb->egap - cnt, gb->point, cnt);
335  gb->egap -= cnt;
336  gb->gap = gb->point;
337  } else if (gb->point > gb->egap) {
338  cnt = gb->point - gb->egap;
339  memmove(gb->gap, gb->egap, cnt);
340  gb->gap += cnt;
341  gb->egap = gb->point;
342  gb->point = gb->gap;
343  } else { /* This case when point is between gap and egap. */
344  cnt = gb->point - gb->gap;
345  memmove(gb->gap, gb->egap, cnt);
346  gb->egap += cnt;
347  gb->gap += cnt;
348  gb->point = gb->gap;
349  }
350  }
351 }
352 
363 static inline void
364 gb_expand_buf(struct gapbuf *gb, uint32_t more)
365 {
366  if (((gb->ebuf - gb->buf) + more) > gb_buf_size(gb)) {
367  char *old = gb->buf;
368 
369  more = (gb->ebuf - gb->buf) + more + GB_DEFAULT_GAP_SIZE;
370 
371  gb->buf = (char *)realloc(gb->buf, more);
372  if (gb->buf == NULL)
373  cne_panic("realloc(%d) in %s failed", more, __func__);
374 
375  gb->point += (gb->buf - old);
376  gb->ebuf += (gb->buf - old);
377  gb->gap += (gb->buf - old);
378  gb->egap += (gb->buf - old);
379  }
380 }
381 
392 static inline void
393 gb_expand_gap(struct gapbuf *gb, uint32_t size)
394 {
395  if (size > gb_gap_size(gb)) {
396  size += GB_DEFAULT_GAP_SIZE;
397 
398  gb_expand_buf(gb, size);
399 
400  memmove(gb->egap + size, gb->egap, gb->ebuf - gb->egap);
401 
402  gb->egap += size;
403  gb->ebuf += size;
404  }
405 }
406 
415 static inline char
416 gb_get(struct gapbuf *gb)
417 {
418  if (gb->point == gb->gap)
419  gb->point = gb->egap;
420 
421  return *gb->point;
422 }
423 
432 static inline char
433 gb_get_prev(struct gapbuf *gb)
434 {
435  if (gb->point == gb->egap)
436  gb->point = gb->gap;
437 
438  if (gb->point == gb->buf) {
439  if (gb->point == gb->gap)
440  return '\0';
441  else
442  return *gb->point;
443  }
444 
445  return *(gb->point - 1);
446 }
447 
456 static inline char
457 gb_get_next(struct gapbuf *gb)
458 {
459  if (gb->point == gb->gap)
460  gb->point = gb->egap;
461 
462  if (gb->point == gb->ebuf)
463  return *gb->point;
464 
465  return *(gb->point + 1);
466 }
467 
478 static inline void
479 gb_put(struct gapbuf *gb, char c)
480 {
481  if (gb->point == gb->gap)
482  gb->point = gb->egap;
483 
484  if (gb->point == gb->ebuf) {
485  gb_expand_buf(gb, 1);
486  gb->ebuf++;
487  }
488 
489  *gb->point = c;
490 }
491 
500 static inline char
501 gb_getc(struct gapbuf *gb)
502 {
503  if (gb->point == gb->gap) {
504  gb->point = gb->egap + 1;
505  return *gb->egap;
506  }
507 
508  return *(gb->point++);
509 }
510 
521 static inline char
522 gb_getc_prev(struct gapbuf *gb)
523 {
524  if (gb->point == gb->egap)
525  gb->point = gb->gap;
526 
527  return *(--gb->point);
528 }
529 
540 static inline void
541 gb_putc(struct gapbuf *gb, char c)
542 {
544 
545  if (gb->point == gb->ebuf) {
546  gb_expand_buf(gb, 1);
547  gb->ebuf++;
548  }
549  *(gb->gap++) = c;
550  gb->point++;
551 }
552 
563 static inline void
564 gb_insert(struct gapbuf *gb, char c)
565 {
566  if (gb->point != gb->gap)
568 
569  if (gb->gap == gb->egap)
570  gb_expand_gap(gb, 1);
571 
572  gb_putc(gb, c);
573 }
574 
585 static inline void
586 gb_del(struct gapbuf *gb, int cnt)
587 {
588  if (gb->point != gb->gap)
590 
591  gb->egap += cnt;
592 }
593 
606 static inline uint32_t
607 gb_str_insert(struct gapbuf *gb, char *str, uint32_t size)
608 {
609  int len;
610 
611  if (size == 0)
612  size = strlen(str);
613  if (size == 0)
614  return 0;
615 
617 
618  if (size > gb_gap_size(gb))
619  gb_expand_gap(gb, size);
620 
621  len = size;
622  do {
623  gb_putc(gb, *str++);
624  } while (--size);
625 
626  return len;
627 }
628 
629 /********************************************************/
630 
639 static inline uint32_t
640 gb_left_data_size(struct gapbuf *gb)
641 {
642  return gb->gap - gb->buf;
643 }
644 
653 static inline uint32_t
654 gb_right_data_size(struct gapbuf *gb)
655 {
656  if (gb_eof(gb))
657  return 0;
658  return gb->ebuf - gb->egap;
659 }
660 
669 static inline void
670 gb_move_right(struct gapbuf *gb)
671 {
672  if (gb->point == gb->gap)
673  gb->point = gb->egap;
674  gb->point = ((gb->point + 1) > gb->ebuf) ? gb->ebuf : (gb->point + 1);
675 }
676 
685 static inline void
686 gb_move_left(struct gapbuf *gb)
687 {
688  if (gb->point == gb->egap)
689  gb->point = gb->gap;
690  gb->point = ((gb->point - 1) < gb->buf) ? gb->buf : (gb->point - 1);
691 }
692 
693 #ifdef __cplusplus
694 }
695 #endif
696 
697 #endif /* _CLI_GAPBUF_H_ */
static void gb_move_gap_to_point(struct gapbuf *gb)
Definition: cli_gapbuf.h:322
static char gb_get_prev(struct gapbuf *gb)
Definition: cli_gapbuf.h:433
CNDP_API uint32_t gb_copy_to_buf(struct gapbuf *gb, char *dst, uint32_t size)
static void gb_set_point(struct gapbuf *gb, int idx)
Definition: cli_gapbuf.h:269
static void gb_move_left(struct gapbuf *gb)
Definition: cli_gapbuf.h:686
static void gb_put(struct gapbuf *gb, char c)
Definition: cli_gapbuf.h:479
static char gb_getc_prev(struct gapbuf *gb)
Definition: cli_gapbuf.h:522
CNDP_API void gb_dump(struct gapbuf *gb, const char *msg)
static int gb_point_offset(struct gapbuf *gb)
Definition: cli_gapbuf.h:289
static int gb_point_at_end(struct gapbuf *gb)
Definition: cli_gapbuf.h:239
static int gb_point_at_start(struct gapbuf *gb)
Definition: cli_gapbuf.h:225
CNDP_API struct gapbuf * gb_create(void)
static char * gb_start_of_buf(struct gapbuf *gb)
Definition: cli_gapbuf.h:155
static void gb_putc(struct gapbuf *gb, char c)
Definition: cli_gapbuf.h:541
static void gb_del(struct gapbuf *gb, int cnt)
Definition: cli_gapbuf.h:586
static char * gb_end_of_gap(struct gapbuf *gb)
Definition: cli_gapbuf.h:183
static void gb_insert(struct gapbuf *gb, char c)
Definition: cli_gapbuf.h:564
static uint32_t gb_str_insert(struct gapbuf *gb, char *str, uint32_t size)
Definition: cli_gapbuf.h:607
static char * gb_point_at(struct gapbuf *gb)
Definition: cli_gapbuf.h:211
static char gb_get(struct gapbuf *gb)
Definition: cli_gapbuf.h:416
CNDP_API int gb_reset_buf(struct gapbuf *gb)
static void gb_expand_gap(struct gapbuf *gb, uint32_t size)
Definition: cli_gapbuf.h:393
static void gb_expand_buf(struct gapbuf *gb, uint32_t more)
Definition: cli_gapbuf.h:364
static int gb_eof(struct gapbuf *gb)
Definition: cli_gapbuf.h:306
static uint32_t gb_left_data_size(struct gapbuf *gb)
Definition: cli_gapbuf.h:640
static void gb_move_right(struct gapbuf *gb)
Definition: cli_gapbuf.h:670
static int gb_point_at_gap(struct gapbuf *gb)
Definition: cli_gapbuf.h:253
static char gb_get_next(struct gapbuf *gb)
Definition: cli_gapbuf.h:457
static uint32_t gb_right_data_size(struct gapbuf *gb)
Definition: cli_gapbuf.h:654
CNDP_API int gb_init_buf(struct gapbuf *gb, int size)
static char * gb_end_of_buf(struct gapbuf *gb)
Definition: cli_gapbuf.h:197
static uint32_t gb_data_size(struct gapbuf *gb)
Definition: cli_gapbuf.h:141
static char gb_getc(struct gapbuf *gb)
Definition: cli_gapbuf.h:501
static char * gb_start_of_gap(struct gapbuf *gb)
Definition: cli_gapbuf.h:169
CNDP_API void gb_destroy(struct gapbuf *gb)
static uint32_t gb_buf_size(struct gapbuf *gb)
Definition: cli_gapbuf.h:113
static uint32_t gb_gap_size(struct gapbuf *gb)
Definition: cli_gapbuf.h:127
#define cne_panic(format, args...)
Definition: cne_log.h:300