chunk.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #ifndef CMARK_CHUNK_H
  2. #define CMARK_CHUNK_H
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <assert.h>
  6. #include "cmark.h"
  7. #include "buffer.h"
  8. #include "cmark_ctype.h"
  9. #define CMARK_CHUNK_EMPTY \
  10. { NULL, 0, 0 }
  11. typedef struct {
  12. unsigned char *data;
  13. bufsize_t len;
  14. bufsize_t alloc; // also implies a NULL-terminated string
  15. } cmark_chunk;
  16. static CMARK_INLINE void cmark_chunk_free(cmark_mem *mem, cmark_chunk *c) {
  17. if (c->alloc)
  18. mem->free(c->data);
  19. c->data = NULL;
  20. c->alloc = 0;
  21. c->len = 0;
  22. }
  23. static CMARK_INLINE void cmark_chunk_ltrim(cmark_chunk *c) {
  24. assert(!c->alloc);
  25. while (c->len && cmark_isspace(c->data[0])) {
  26. c->data++;
  27. c->len--;
  28. }
  29. }
  30. static CMARK_INLINE void cmark_chunk_rtrim(cmark_chunk *c) {
  31. assert(!c->alloc);
  32. while (c->len > 0) {
  33. if (!cmark_isspace(c->data[c->len - 1]))
  34. break;
  35. c->len--;
  36. }
  37. }
  38. static CMARK_INLINE void cmark_chunk_trim(cmark_chunk *c) {
  39. cmark_chunk_ltrim(c);
  40. cmark_chunk_rtrim(c);
  41. }
  42. static CMARK_INLINE bufsize_t cmark_chunk_strchr(cmark_chunk *ch, int c,
  43. bufsize_t offset) {
  44. const unsigned char *p =
  45. (unsigned char *)memchr(ch->data + offset, c, ch->len - offset);
  46. return p ? (bufsize_t)(p - ch->data) : ch->len;
  47. }
  48. static CMARK_INLINE const char *cmark_chunk_to_cstr(cmark_mem *mem,
  49. cmark_chunk *c) {
  50. unsigned char *str;
  51. if (c->alloc) {
  52. return (char *)c->data;
  53. }
  54. str = (unsigned char *)mem->calloc(c->len + 1, 1);
  55. if (c->len > 0) {
  56. memcpy(str, c->data, c->len);
  57. }
  58. str[c->len] = 0;
  59. c->data = str;
  60. c->alloc = 1;
  61. return (char *)str;
  62. }
  63. static CMARK_INLINE void cmark_chunk_set_cstr(cmark_mem *mem, cmark_chunk *c,
  64. const char *str) {
  65. unsigned char *old = c->alloc ? c->data : NULL;
  66. if (str == NULL) {
  67. c->len = 0;
  68. c->data = NULL;
  69. c->alloc = 0;
  70. } else {
  71. c->len = (bufsize_t)strlen(str);
  72. c->data = (unsigned char *)mem->calloc(c->len + 1, 1);
  73. c->alloc = 1;
  74. memcpy(c->data, str, c->len + 1);
  75. }
  76. if (old != NULL) {
  77. mem->free(old);
  78. }
  79. }
  80. static CMARK_INLINE cmark_chunk cmark_chunk_literal(const char *data) {
  81. bufsize_t len = data ? (bufsize_t)strlen(data) : 0;
  82. cmark_chunk c = {(unsigned char *)data, len, 0};
  83. return c;
  84. }
  85. static CMARK_INLINE cmark_chunk cmark_chunk_dup(const cmark_chunk *ch,
  86. bufsize_t pos, bufsize_t len) {
  87. cmark_chunk c = {ch->data + pos, len, 0};
  88. return c;
  89. }
  90. static CMARK_INLINE cmark_chunk cmark_chunk_buf_detach(cmark_strbuf *buf) {
  91. cmark_chunk c;
  92. c.len = buf->size;
  93. c.data = cmark_strbuf_detach(buf);
  94. c.alloc = 1;
  95. return c;
  96. }
  97. #endif