strbuffer.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (c) 2009-2012 Petri Lehtinen <petri@digip.org>
  3. *
  4. * Jansson is free software; you can redistribute it and/or modify
  5. * it under the terms of the MIT license. See LICENSE for details.
  6. */
  7. #define _GNU_SOURCE
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "jansson_private.h"
  11. #include "strbuffer.h"
  12. #define STRBUFFER_MIN_SIZE 16
  13. #define STRBUFFER_FACTOR 2
  14. #define STRBUFFER_SIZE_MAX ((size_t)-1)
  15. int strbuffer_init(strbuffer_t *strbuff)
  16. {
  17. strbuff->size = STRBUFFER_MIN_SIZE;
  18. strbuff->length = 0;
  19. strbuff->value = jsonp_malloc(strbuff->size);
  20. if(!strbuff->value)
  21. return -1;
  22. /* initialize to empty */
  23. strbuff->value[0] = '\0';
  24. return 0;
  25. }
  26. void strbuffer_close(strbuffer_t *strbuff)
  27. {
  28. jsonp_free(strbuff->value);
  29. strbuff->size = 0;
  30. strbuff->length = 0;
  31. strbuff->value = NULL;
  32. }
  33. void strbuffer_clear(strbuffer_t *strbuff)
  34. {
  35. strbuff->length = 0;
  36. strbuff->value[0] = '\0';
  37. }
  38. const char *strbuffer_value(const strbuffer_t *strbuff)
  39. {
  40. return strbuff->value;
  41. }
  42. char *strbuffer_steal_value(strbuffer_t *strbuff)
  43. {
  44. char *result = strbuff->value;
  45. strbuffer_init(strbuff);
  46. return result;
  47. }
  48. int strbuffer_append(strbuffer_t *strbuff, const char *string)
  49. {
  50. return strbuffer_append_bytes(strbuff, string, strlen(string));
  51. }
  52. int strbuffer_append_byte(strbuffer_t *strbuff, char byte)
  53. {
  54. return strbuffer_append_bytes(strbuff, &byte, 1);
  55. }
  56. int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, size_t size)
  57. {
  58. if(size >= strbuff->size - strbuff->length)
  59. {
  60. size_t new_size;
  61. char *new_value;
  62. /* avoid integer overflow */
  63. if (strbuff->size > STRBUFFER_SIZE_MAX / STRBUFFER_FACTOR
  64. || size > STRBUFFER_SIZE_MAX - 1
  65. || strbuff->length > STRBUFFER_SIZE_MAX - 1 - size)
  66. return -1;
  67. new_size = max(strbuff->size * STRBUFFER_FACTOR,
  68. strbuff->length + size + 1);
  69. new_value = jsonp_malloc(new_size);
  70. if(!new_value)
  71. return -1;
  72. memcpy(new_value, strbuff->value, strbuff->length);
  73. jsonp_free(strbuff->value);
  74. strbuff->value = new_value;
  75. strbuff->size = new_size;
  76. }
  77. memcpy(strbuff->value + strbuff->length, data, size);
  78. strbuff->length += size;
  79. strbuff->value[strbuff->length] = '\0';
  80. return 0;
  81. }
  82. char strbuffer_pop(strbuffer_t *strbuff)
  83. {
  84. if(strbuff->length > 0) {
  85. char c = strbuff->value[--strbuff->length];
  86. strbuff->value[strbuff->length] = '\0';
  87. return c;
  88. }
  89. else
  90. return '\0';
  91. }