2
0

memblock.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /* Copyright information is at end of file */
  2. #include "xmlrpc_config.h"
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include "mallocvar.h"
  8. #include "xmlrpc-c/util_int.h"
  9. #include "xmlrpc-c/util.h"
  10. #ifdef EFENCE
  11. /* when looking for corruption don't allocate extra slop */
  12. #define BLOCK_ALLOC_MIN (1)
  13. #else
  14. #define BLOCK_ALLOC_MIN (16)
  15. #endif
  16. #define BLOCK_ALLOC_MAX (128 * 1024 * 1024)
  17. xmlrpc_mem_block *
  18. xmlrpc_mem_block_new(xmlrpc_env * const envP,
  19. size_t const size) {
  20. xmlrpc_mem_block * block;
  21. XMLRPC_ASSERT_ENV_OK(envP);
  22. MALLOCVAR(block);
  23. if (block == NULL)
  24. xmlrpc_faultf(envP, "Can't allocate memory block");
  25. else {
  26. xmlrpc_mem_block_init(envP, block, size);
  27. if (envP->fault_occurred) {
  28. free(block);
  29. block = NULL;
  30. }
  31. }
  32. return block;
  33. }
  34. /* Destroy an existing xmlrpc_mem_block, and everything it contains. */
  35. void
  36. xmlrpc_mem_block_free(xmlrpc_mem_block * const blockP) {
  37. XMLRPC_ASSERT(blockP != NULL);
  38. XMLRPC_ASSERT(blockP->_block != NULL);
  39. xmlrpc_mem_block_clean(blockP);
  40. free(blockP);
  41. }
  42. /* Initialize the contents of the provided xmlrpc_mem_block. */
  43. void
  44. xmlrpc_mem_block_init(xmlrpc_env * const envP,
  45. xmlrpc_mem_block * const blockP,
  46. size_t const size) {
  47. XMLRPC_ASSERT_ENV_OK(envP);
  48. XMLRPC_ASSERT(blockP != NULL);
  49. blockP->_size = size;
  50. if (size < BLOCK_ALLOC_MIN)
  51. blockP->_allocated = BLOCK_ALLOC_MIN;
  52. else
  53. blockP->_allocated = size;
  54. blockP->_block = (void*) malloc(blockP->_allocated);
  55. if (!blockP->_block)
  56. xmlrpc_faultf(envP, "Can't allocate %u-byte memory block",
  57. (unsigned)blockP->_allocated);
  58. }
  59. /* Deallocate the contents of the provided xmlrpc_mem_block, but not
  60. the block itself.
  61. */
  62. void
  63. xmlrpc_mem_block_clean(xmlrpc_mem_block * const blockP) {
  64. XMLRPC_ASSERT(blockP != NULL);
  65. XMLRPC_ASSERT(blockP->_block != NULL);
  66. free(blockP->_block);
  67. blockP->_block = XMLRPC_BAD_POINTER;
  68. }
  69. /* Get the size of the xmlrpc_mem_block. */
  70. size_t
  71. xmlrpc_mem_block_size(const xmlrpc_mem_block * const blockP) {
  72. XMLRPC_ASSERT(blockP != NULL);
  73. return blockP->_size;
  74. }
  75. /* Get the contents of the xmlrpc_mem_block. */
  76. void *
  77. xmlrpc_mem_block_contents(const xmlrpc_mem_block * const blockP) {
  78. XMLRPC_ASSERT(blockP != NULL);
  79. return blockP->_block;
  80. }
  81. /* Resize an xmlrpc_mem_block, preserving as much of the contents as
  82. possible.
  83. */
  84. void
  85. xmlrpc_mem_block_resize (xmlrpc_env * const envP,
  86. xmlrpc_mem_block * const blockP,
  87. size_t const size) {
  88. size_t proposed_alloc;
  89. void* new_block;
  90. XMLRPC_ASSERT_ENV_OK(envP);
  91. XMLRPC_ASSERT(blockP != NULL);
  92. /* Check to see if we already have enough space. Maybe we'll get lucky. */
  93. if (size <= blockP->_allocated) {
  94. blockP->_size = size;
  95. return;
  96. }
  97. /* Calculate a new allocation size. */
  98. #ifdef EFENCE
  99. proposed_alloc = size;
  100. #else
  101. proposed_alloc = blockP->_allocated;
  102. while (proposed_alloc < size && proposed_alloc <= BLOCK_ALLOC_MAX)
  103. proposed_alloc *= 2;
  104. #endif /* DEBUG_MEM_ERRORS */
  105. if (proposed_alloc > BLOCK_ALLOC_MAX)
  106. XMLRPC_FAIL(envP, XMLRPC_INTERNAL_ERROR, "Memory block too large");
  107. /* Allocate our new memory block. */
  108. new_block = (void*) malloc(proposed_alloc);
  109. XMLRPC_FAIL_IF_NULL(new_block, envP, XMLRPC_INTERNAL_ERROR,
  110. "Can't resize memory block");
  111. /* Copy over our data and update the xmlrpc_mem_block struct. */
  112. memcpy(new_block, blockP->_block, blockP->_size);
  113. free(blockP->_block);
  114. blockP->_block = new_block;
  115. blockP->_size = size;
  116. blockP->_allocated = proposed_alloc;
  117. cleanup:
  118. return;
  119. }
  120. void
  121. xmlrpc_mem_block_append(xmlrpc_env * const envP,
  122. xmlrpc_mem_block * const blockP,
  123. const void * const data,
  124. size_t const len) {
  125. size_t const originalSize = blockP->_size;
  126. XMLRPC_ASSERT_ENV_OK(envP);
  127. XMLRPC_ASSERT(blockP != NULL);
  128. xmlrpc_mem_block_resize(envP, blockP, originalSize + len);
  129. if (!envP->fault_occurred) {
  130. memcpy(((unsigned char*) blockP->_block) + originalSize, data, len);
  131. }
  132. }
  133. /* Copyright (C) 2001 by First Peer, Inc. All rights reserved.
  134. **
  135. ** Redistribution and use in source and binary forms, with or without
  136. ** modification, are permitted provided that the following conditions
  137. ** are met:
  138. ** 1. Redistributions of source code must retain the above copyright
  139. ** notice, this list of conditions and the following disclaimer.
  140. ** 2. Redistributions in binary form must reproduce the above copyright
  141. ** notice, this list of conditions and the following disclaimer in the
  142. ** documentation and/or other materials provided with the distribution.
  143. ** 3. The name of the author may not be used to endorse or promote products
  144. ** derived from this software without specific prior written permission.
  145. **
  146. ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  147. ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  148. ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  149. ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  150. ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  151. ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  152. ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  153. ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  154. ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  155. ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  156. ** SUCH DAMAGE.
  157. */