|
- #include "VarBuffer.h"
-
- VarBuffer::VarBuffer(unsigned long length, bool bReadWait, bool bWriteWait)
- : m_iBufferLength(length)
- , m_pBuffer(nullptr)
- , m_iReadIndex(0)
- , m_iWriteIndex(0)
- , m_bIsOneCycle(true)
- , m_bReadWait(bReadWait)
- , m_bWriteWait(bWriteWait)
- {
- m_pBuffer = new unsigned char[length];
- }
-
- VarBuffer::~VarBuffer()
- {
- if (nullptr != m_pBuffer)
- delete m_pBuffer;
- }
-
- // detect the frame length, frame length is an unsigned short
- unsigned short VarBuffer::GetFrameLength()
- {
- int diff = m_iBufferLength - m_iReadIndex;
- if (diff >= 6 && m_pBuffer[m_iReadIndex] == 0xEB && m_pBuffer[m_iReadIndex + 1] == 0x90)
- return m_pBuffer[m_iReadIndex + 5] * 256 + m_pBuffer[m_iReadIndex + 4];
- else if (diff < 6 && m_pBuffer[m_iReadIndex % m_iBufferLength] == 0xEB
- && m_pBuffer[(m_iReadIndex + 1) % m_iBufferLength] == 0x90)
- return m_pBuffer[(m_iReadIndex + 5) % m_iBufferLength] * 256
- + m_pBuffer[(m_iReadIndex + 4) % m_iBufferLength];
- else
- throw "GET FRAME LENGTH ERROR: didn't read the right frame head";
- }
-
- // verify the to-be-written frame length, frame length is an unsigned short
- bool VarBuffer::verifyFrameLength(unsigned char* buf, unsigned short length)
- {
- if (buf[0] != 0xEB || buf[1] != 0x90) {
- return false;
- }
- if (*(reinterpret_cast<unsigned short*>(buf + VarHeadLength)) != length) {
- // printf("%x, %x, %x \n", buf[2], buf[3]*256, length);
- return false;
- }
- return true;
- }
-
- // read data from memory to an output buffer
- // two arguments: the point and the length of output buffer
- // correct: return frame length
- // error: return -1
- unsigned short VarBuffer::read(unsigned char* buf, unsigned short length)
- {
- int frameLength = 0;
- {
- QMutexLocker locker(&m_mutex);
- while (IsEmpty(0)) {
- if (m_bReadWait) {
- // add wait here, to wait for sufficient data to read
- m_condRead.wait(&m_mutex);
- } else {
- return 0;
- }
- }
- frameLength = GetFrameLength();
- if (frameLength > length) {
- // throw "READ ERROR: the frame data length is larger than output data buffer";
- return -1;
- }
- for (int i = 0; i < frameLength; i++) {
- buf[i] = m_pBuffer[m_iReadIndex];
- m_iReadIndex++;
- if (m_iReadIndex >= m_iBufferLength) {
- m_iReadIndex = 0;
- m_bIsOneCycle = true;
- }
- }
- }
- m_condWrite.wakeOne();
- return frameLength;
- }
-
- // write one frame data to memory
- // one argument: the length of frame to write in (unsigned short)
- int VarBuffer::write(unsigned char* buf, unsigned short length)
- {
- if (length < MIN_FRAME_LENGTH || length > m_iBufferLength) {
- return -1;
- }
- {
- QMutexLocker locker(&m_mutex);
- while (IsFull(length)) {
- if (m_bWriteWait) {
- // add wait here, to wait for sufficient data to read
- m_condWrite.wait(&m_mutex);
- } else {
- return 0;
- }
- }
- for (int i = 0; i < length; i++) {
- m_pBuffer[m_iWriteIndex] = buf[i];
- m_iWriteIndex++;
- if (m_iWriteIndex == m_iBufferLength) {
- m_iWriteIndex = 0;
- m_bIsOneCycle = false;
- }
- }
- }
- m_condRead.wakeOne();
- return length;
- }
-
- // memory is full, no place to write
- // tow different situations: readIndex and writeIndex is in one cycle or not
- // one argument: the length of frame
- bool VarBuffer::IsFull(unsigned short length)
- {
- if (m_bIsOneCycle == true) {
- return m_iWriteIndex + length > m_iReadIndex + m_iBufferLength;
- }
- return m_iWriteIndex + length > m_iReadIndex;
- }
-
- // memory is empty, no data to read
- // tow different situations: readIndex and writeIndex is in one cycle or not
- bool VarBuffer::IsEmpty(unsigned short length)
- {
- if (m_bIsOneCycle == true) {
- return m_iReadIndex + length >= m_iWriteIndex;
- // return m_iReadIndex == m_iWriteIndex;
- }
- return m_iReadIndex + length >= m_iWriteIndex + m_iBufferLength;
- // return m_iReadIndex == m_iWriteIndex + m_iBufferLength;
- }
|