tb_tempbuffer.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // ================================================================================
  2. // == This file is a part of Turbo Badger. (C) 2011-2014, Emil Segerås ==
  3. // == See tb_core.h for more information. ==
  4. // ================================================================================
  5. #include "tb_tempbuffer.h"
  6. #include <assert.h>
  7. #include <stdlib.h>
  8. #include <memory.h>
  9. #include <string.h>
  10. namespace tb {
  11. static char *p_realloc(char *buf, size_t size) { return (char *) realloc(buf, size); }
  12. static void p_free(char *buf) { free(buf); }
  13. TBTempBuffer::TBTempBuffer()
  14. : m_data(0)
  15. , m_data_size(0)
  16. , m_append_pos(0)
  17. {
  18. }
  19. TBTempBuffer::~TBTempBuffer()
  20. {
  21. p_free(m_data);
  22. }
  23. void TBTempBuffer::SetAppendPos(int append_pos)
  24. {
  25. assert(append_pos >= 0 && append_pos <= m_data_size);
  26. m_append_pos = append_pos;
  27. }
  28. bool TBTempBuffer::Reserve(int size)
  29. {
  30. if (size > m_data_size)
  31. {
  32. char *new_data = p_realloc(m_data, size);
  33. if (!new_data)
  34. return false;
  35. m_data = new_data;
  36. m_data_size = size;
  37. }
  38. return true;
  39. }
  40. int TBTempBuffer::GetAppendReserveSize(int needed_size) const
  41. {
  42. // Reserve some extra memory to reduce the reserve calls.
  43. needed_size *= 2;
  44. return needed_size < 32 ? 32 : needed_size;
  45. }
  46. bool TBTempBuffer::Append(const char *data, int size)
  47. {
  48. if (m_append_pos + size > m_data_size && !Reserve(GetAppendReserveSize(m_append_pos + size)))
  49. return false;
  50. memcpy(m_data + m_append_pos, data, size);
  51. m_append_pos += size;
  52. return true;
  53. }
  54. bool TBTempBuffer::AppendSpace(int size)
  55. {
  56. if (m_append_pos + size > m_data_size && !Reserve(GetAppendReserveSize(m_append_pos + size)))
  57. return false;
  58. m_append_pos += size;
  59. return true;
  60. }
  61. bool TBTempBuffer::AppendString(const char *str)
  62. {
  63. // Add 1 to include the null termination in the data.
  64. if (Append(str, strlen(str) + 1))
  65. {
  66. // Now remove the null termination from the append position
  67. // again, so another call will append to the same string (instead of
  68. // after the null termination of the first string)
  69. m_append_pos--;
  70. return true;
  71. }
  72. return false;
  73. }
  74. bool TBTempBuffer::AppendPath(const char *full_path_and_filename)
  75. {
  76. const char *str_start = full_path_and_filename;
  77. while (const char *next = strpbrk(full_path_and_filename, "\\/"))
  78. full_path_and_filename = next + 1;
  79. if (str_start == full_path_and_filename) // Filename contained no path
  80. {
  81. str_start = "./";
  82. full_path_and_filename = str_start + 2;
  83. }
  84. int len = full_path_and_filename - str_start;
  85. if (Reserve(len + 1))
  86. {
  87. // Add the string, and nulltermination.
  88. Append(str_start, len);
  89. Append("", 1);
  90. // Remove null termination from append pos again (see details in AppendString).
  91. m_append_pos--;
  92. return true;
  93. }
  94. return false;
  95. }
  96. }; // namespace tb