Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
2.3 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // outbuf.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // Defines the class OutputBuffer.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 08/04/1998 Original version.
  16. // 11/17/1998 Streamline resize().
  17. //
  18. ///////////////////////////////////////////////////////////////////////////////
  19. #include <ias.h>
  20. #include <outbuf.h>
  21. OutputBuffer::OutputBuffer() throw ()
  22. : start(scratch),
  23. next(scratch),
  24. end(scratch + sizeof(scratch))
  25. { }
  26. OutputBuffer::~OutputBuffer() throw ()
  27. {
  28. // Delete the buffer if necessary.
  29. if (start != scratch) { delete[] start; }
  30. }
  31. //////////
  32. // I defined this as a macro to force the compiler to inline it.
  33. //////////
  34. #define QUICK_RESERVE(p, nbyte) \
  35. p = next; if ((next += nbyte) > end) { resize(p); }
  36. // Append an octet string.
  37. void OutputBuffer::append(const BYTE* buf, DWORD buflen)
  38. {
  39. PBYTE p;
  40. QUICK_RESERVE(p, buflen);
  41. memcpy(p, buf, buflen);
  42. }
  43. // Append a null-terminated ANSI string.
  44. void OutputBuffer::append(PCSTR sz)
  45. {
  46. DWORD len = strlen(sz);
  47. PBYTE p;
  48. QUICK_RESERVE(p, len);
  49. memcpy(p, sz, len);
  50. }
  51. // Append a single ANSI character.
  52. void OutputBuffer::append(CHAR ch)
  53. {
  54. PBYTE p;
  55. QUICK_RESERVE(p, 1);
  56. *p = (BYTE)ch;
  57. }
  58. // Reserves 'nbyte' bytes in the buffer and returns a pointer to the
  59. // reserved bytes.
  60. PBYTE OutputBuffer::reserve(DWORD nbyte)
  61. {
  62. PBYTE p;
  63. QUICK_RESERVE(p, nbyte);
  64. return p;
  65. }
  66. void OutputBuffer::resize(PBYTE& cursor)
  67. {
  68. // Convert everything to relative offsets.
  69. ptrdiff_t cursorOffset = cursor - start;
  70. ptrdiff_t nextOffset = next - start;
  71. ptrdiff_t endOffset = end - start;
  72. // We always at least double the buffer.
  73. endOffset *= 2;
  74. // Make sure it's big enough to hold the next chunk.
  75. if (endOffset < nextOffset) { endOffset = nextOffset; }
  76. // Allocate the new buffer and copy in the existing bytes.
  77. PBYTE newBuffer = new BYTE[(size_t)endOffset];
  78. memcpy(newBuffer, start, (size_t)cursorOffset);
  79. // Release the old buffer if necessary.
  80. if (start != scratch) { delete[] start; }
  81. // Save the new buffer.
  82. start = newBuffer;
  83. // Convert from offsets back to absolutes.
  84. next = start + nextOffset;
  85. cursor = start + cursorOffset;
  86. end = start + endOffset;
  87. }