You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

VarBuffer.cpp 4.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "VarBuffer.h"
  2. VarBuffer::VarBuffer(unsigned long length, bool bReadWait, bool bWriteWait)
  3. : m_iBufferLength(length)
  4. , m_pBuffer(nullptr)
  5. , m_iReadIndex(0)
  6. , m_iWriteIndex(0)
  7. , m_bIsOneCycle(true)
  8. , m_bReadWait(bReadWait)
  9. , m_bWriteWait(bWriteWait)
  10. {
  11. m_pBuffer = new unsigned char[length];
  12. }
  13. VarBuffer::~VarBuffer()
  14. {
  15. if (nullptr != m_pBuffer)
  16. delete m_pBuffer;
  17. }
  18. // detect the frame length, frame length is an unsigned short
  19. unsigned short VarBuffer::GetFrameLength()
  20. {
  21. int diff = m_iBufferLength - m_iReadIndex;
  22. if (diff >= 6 && m_pBuffer[m_iReadIndex] == 0xEB && m_pBuffer[m_iReadIndex + 1] == 0x90)
  23. return m_pBuffer[m_iReadIndex + 5] * 256 + m_pBuffer[m_iReadIndex + 4];
  24. else if (diff < 6 && m_pBuffer[m_iReadIndex % m_iBufferLength] == 0xEB
  25. && m_pBuffer[(m_iReadIndex + 1) % m_iBufferLength] == 0x90)
  26. return m_pBuffer[(m_iReadIndex + 5) % m_iBufferLength] * 256
  27. + m_pBuffer[(m_iReadIndex + 4) % m_iBufferLength];
  28. else
  29. throw "GET FRAME LENGTH ERROR: didn't read the right frame head";
  30. }
  31. // verify the to-be-written frame length, frame length is an unsigned short
  32. bool VarBuffer::verifyFrameLength(unsigned char* buf, unsigned short length)
  33. {
  34. if (buf[0] != 0xEB || buf[1] != 0x90) {
  35. return false;
  36. }
  37. if (*(reinterpret_cast<unsigned short*>(buf + VarHeadLength)) != length) {
  38. // printf("%x, %x, %x \n", buf[2], buf[3]*256, length);
  39. return false;
  40. }
  41. return true;
  42. }
  43. // read data from memory to an output buffer
  44. // two arguments: the point and the length of output buffer
  45. // correct: return frame length
  46. // error: return -1
  47. unsigned short VarBuffer::read(unsigned char* buf, unsigned short length)
  48. {
  49. int frameLength = 0;
  50. {
  51. QMutexLocker locker(&m_mutex);
  52. while (IsEmpty(0)) {
  53. if (m_bReadWait) {
  54. // add wait here, to wait for sufficient data to read
  55. m_condRead.wait(&m_mutex);
  56. } else {
  57. return 0;
  58. }
  59. }
  60. frameLength = GetFrameLength();
  61. if (frameLength > length) {
  62. // throw "READ ERROR: the frame data length is larger than output data buffer";
  63. return -1;
  64. }
  65. for (int i = 0; i < frameLength; i++) {
  66. buf[i] = m_pBuffer[m_iReadIndex];
  67. m_iReadIndex++;
  68. if (m_iReadIndex >= m_iBufferLength) {
  69. m_iReadIndex = 0;
  70. m_bIsOneCycle = true;
  71. }
  72. }
  73. }
  74. m_condWrite.wakeOne();
  75. return frameLength;
  76. }
  77. // write one frame data to memory
  78. // one argument: the length of frame to write in (unsigned short)
  79. int VarBuffer::write(unsigned char* buf, unsigned short length)
  80. {
  81. if (length < MIN_FRAME_LENGTH || length > m_iBufferLength) {
  82. return -1;
  83. }
  84. {
  85. QMutexLocker locker(&m_mutex);
  86. while (IsFull(length)) {
  87. if (m_bWriteWait) {
  88. // add wait here, to wait for sufficient data to read
  89. m_condWrite.wait(&m_mutex);
  90. } else {
  91. return 0;
  92. }
  93. }
  94. for (int i = 0; i < length; i++) {
  95. m_pBuffer[m_iWriteIndex] = buf[i];
  96. m_iWriteIndex++;
  97. if (m_iWriteIndex == m_iBufferLength) {
  98. m_iWriteIndex = 0;
  99. m_bIsOneCycle = false;
  100. }
  101. }
  102. }
  103. m_condRead.wakeOne();
  104. return length;
  105. }
  106. // memory is full, no place to write
  107. // tow different situations: readIndex and writeIndex is in one cycle or not
  108. // one argument: the length of frame
  109. bool VarBuffer::IsFull(unsigned short length)
  110. {
  111. if (m_bIsOneCycle == true) {
  112. return m_iWriteIndex + length > m_iReadIndex + m_iBufferLength;
  113. }
  114. return m_iWriteIndex + length > m_iReadIndex;
  115. }
  116. // memory is empty, no data to read
  117. // tow different situations: readIndex and writeIndex is in one cycle or not
  118. bool VarBuffer::IsEmpty(unsigned short length)
  119. {
  120. if (m_bIsOneCycle == true) {
  121. return m_iReadIndex + length >= m_iWriteIndex;
  122. // return m_iReadIndex == m_iWriteIndex;
  123. }
  124. return m_iReadIndex + length >= m_iWriteIndex + m_iBufferLength;
  125. // return m_iReadIndex == m_iWriteIndex + m_iBufferLength;
  126. }