PageRenderTime 785ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/r1.0/result_buffer.cc

http://mod-ndb.googlecode.com/
C++ | 91 lines | 55 code | 15 blank | 21 comment | 10 complexity | 7389cc6f1fcbad874807d601f85f756a MD5 | raw file
  1. /* Copyright (C) 2006 MySQL AB
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; either version 2 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  13. */
  14. #include "mod_ndb.h"
  15. char * result_buffer::init(request_rec *r, size_t size) {
  16. alloc_sz = size;
  17. sz = 0;
  18. if(buff) free(buff);
  19. buff = (char *) malloc(alloc_sz);
  20. if(!buff) log_err(r->server, "mod_ndb result_buffer::init() out of memory");
  21. return buff;
  22. }
  23. /* prepare(size_t len): make room for *len* new characters in the buffer.
  24. Expect them to be placed there one at a time using putc or out(fmt, ...).
  25. It is OK to prepare more space than you will actually use.
  26. */
  27. bool result_buffer::prepare(size_t len) {
  28. char *old_buff = buff;
  29. register size_t new_sz = sz + len;
  30. if(new_sz > alloc_sz) {
  31. register int factor = (new_sz / alloc_sz) + 1;
  32. alloc_sz *= factor;
  33. buff = (char *) realloc(old_buff, alloc_sz);
  34. if(! buff) {
  35. free(old_buff);
  36. return false;
  37. }
  38. }
  39. return true;
  40. }
  41. void result_buffer::out(size_t len, const char *s) {
  42. if(len == 0 || (! this->prepare(len))) return;
  43. char *dst = buff + sz;
  44. sz += len;
  45. while(len--) *dst++ = *s++;
  46. }
  47. void result_buffer::out(const char *fmt, ... ) {
  48. va_list args;
  49. size_t old_size = sz;
  50. bool try_again;
  51. char *old_buff;
  52. do {
  53. try_again = false;
  54. va_start(args,fmt);
  55. sz += vsnprintf((buff + sz), alloc_sz - sz, fmt, args);
  56. va_end(args);
  57. if(sz >= alloc_sz) {
  58. try_again = true;
  59. // The write was truncated. Get a bigger buffer and do it again
  60. alloc_sz *= 4;
  61. sz = old_size;
  62. old_buff = buff;
  63. buff = (char *) realloc(old_buff, alloc_sz);
  64. if(! buff) {
  65. free(old_buff);
  66. return;
  67. }
  68. }
  69. } while(try_again);
  70. }
  71. result_buffer::~result_buffer() {
  72. if(buff) free(buff);
  73. }