MT5APIMemPack.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. //+------------------------------------------------------------------+
  2. //| MetaTrader 5 API |
  3. //| Copyright 2000-2019, MetaQuotes Software Corp. |
  4. //| http://www.metaquotes.net |
  5. //+------------------------------------------------------------------+
  6. #pragma once
  7. //+------------------------------------------------------------------+
  8. //| Class of memory block |
  9. //+------------------------------------------------------------------+
  10. class CMTMemPack
  11. {
  12. private:
  13. //--- constants
  14. enum
  15. {
  16. REALLOC_STEP =1024 // buffer reallocation step
  17. };
  18. private:
  19. //--- data
  20. char *m_buffer; // data
  21. UINT m_buffer_len; // data length
  22. UINT m_buffer_max; // maximum number of bytes in buffer
  23. public:
  24. //--- constructor/destructor
  25. CMTMemPack();
  26. ~CMTMemPack();
  27. //--- correct the length in block
  28. void Clear() { m_buffer_len=0; }
  29. void Shutdown();
  30. bool Reallocate(UINT growsize);
  31. //--- add unformatted data
  32. bool Add(const void *buf,UINT len);
  33. //--- swap array contents
  34. void Swap(CMTMemPack &pack);
  35. //--- buffer access
  36. char* Buffer() { return(m_buffer); }
  37. const UINT Len() const { return(m_buffer_len); }
  38. void Len(UINT val) { if(val<=m_buffer_max) m_buffer_len=val; }
  39. UINT Max() const { return(m_buffer_max); }
  40. };
  41. //+------------------------------------------------------------------+
  42. //| Constructor with memory pre-allocation |
  43. //+------------------------------------------------------------------+
  44. inline CMTMemPack::CMTMemPack()
  45. : m_buffer(NULL),
  46. m_buffer_len(0),
  47. m_buffer_max(0)
  48. {
  49. }
  50. //+------------------------------------------------------------------+
  51. //| |
  52. //+------------------------------------------------------------------+
  53. inline CMTMemPack::~CMTMemPack()
  54. {
  55. Shutdown();
  56. }
  57. //+------------------------------------------------------------------+
  58. //| Add data to buffer |
  59. //+------------------------------------------------------------------+
  60. inline bool CMTMemPack::Add(const void *buf,UINT len)
  61. {
  62. //--- check
  63. if(!buf)
  64. return(false);
  65. //--- check for exceeding buffer size
  66. if(m_buffer==NULL || (len+m_buffer_len)>m_buffer_max)
  67. if(!Reallocate(len+m_buffer_len+REALLOC_STEP))
  68. return(false);
  69. //--- append data to buffer
  70. memcpy(&m_buffer[m_buffer_len],buf,len);
  71. m_buffer_len+=len;
  72. //---
  73. return(true);
  74. }
  75. //+------------------------------------------------------------------+
  76. //| Swap buffer contents |
  77. //+------------------------------------------------------------------+
  78. inline void CMTMemPack::Swap(CMTMemPack &pack)
  79. {
  80. char *buffer; // buffer
  81. UINT buffer_len; // data length
  82. UINT buffer_max; // maximum number of bytes in buffer
  83. //--- check
  84. if(this==&pack)
  85. return;
  86. //--- swap, remember own buffer
  87. buffer =m_buffer;
  88. buffer_len=m_buffer_len;
  89. buffer_max=m_buffer_max;
  90. //--- replace buffer with received one
  91. m_buffer =pack.m_buffer;
  92. m_buffer_len=pack.m_buffer_len;
  93. m_buffer_max=pack.m_buffer_max;
  94. //--- return own buffer
  95. pack.m_buffer =buffer;
  96. pack.m_buffer_len=buffer_len;
  97. pack.m_buffer_max=buffer_max;
  98. }
  99. //+------------------------------------------------------------------+
  100. //| Deallocate memory in MemPack |
  101. //+------------------------------------------------------------------+
  102. inline void CMTMemPack::Shutdown()
  103. {
  104. if(m_buffer) { delete[] m_buffer; m_buffer=NULL; }
  105. m_buffer_max=0;
  106. m_buffer_len=0;
  107. }
  108. //+------------------------------------------------------------------+
  109. //| Reallocate data block |
  110. //+------------------------------------------------------------------+
  111. inline bool CMTMemPack::Reallocate(UINT growsize)
  112. {
  113. char *newbuf;
  114. //--- check sizes
  115. if(growsize<=m_buffer_max) return(true);
  116. //--- try to allocate block of greater size
  117. if((newbuf=new(std::nothrow) char[growsize])==NULL)
  118. return(false);
  119. //--- copy values from old buffer
  120. if(m_buffer)
  121. {
  122. if(m_buffer_len>0) memcpy(newbuf,m_buffer,m_buffer_len);
  123. delete[] m_buffer;
  124. }
  125. m_buffer =newbuf;
  126. m_buffer_max=growsize;
  127. //---
  128. return(true);
  129. }
  130. //+------------------------------------------------------------------+