#include "ConstBuffer.h" ConstBuffer::ConstBuffer(unsigned long bufLength, bool bReadWait, bool bWriteWait, unsigned short frameLength) : m_iBufferLength(bufLength) , m_pBuffer(nullptr) , m_bIsOneCycle(true) , m_iReadIndex(0) , m_iWriteIndex(0) , m_bReadWait(bReadWait) , m_bWriteWait(bWriteWait) , m_iFrameLength(frameLength) { m_pBuffer = new unsigned char[bufLength]; } ConstBuffer::~ConstBuffer() { if (m_pBuffer != nullptr) { delete m_pBuffer; } } // 写数据 int ConstBuffer::write(unsigned char* data, unsigned short length) { if (length > m_iBufferLength) { // 写入帧长不满足要求 return -1; } // if (!verifyFrameLength(data, length)) { // //帧长不匹配 // return -2; //} /*QByteArray byteArr((char*)data, length);*/ QMutexLocker locker(&m_mutex); while (IsFull(length)) { // 当读写指针在同一周期内时 if (m_bWriteWait) { // add wait here,to wait for sufficient buf to write m_condWrite.wait(&m_mutex); } else { return 0; } } for (int i = 0; i < length; i++) { m_pBuffer[m_iWriteIndex] = data[i]; // 想缓存中写入数据 m_iWriteIndex++; if (m_iWriteIndex == m_iBufferLength) { // 当缓存已经写满数据 m_iWriteIndex = 0; m_bIsOneCycle = false; } } if (m_bWriteWait) { m_condRead.wakeOne(); } return length; } // 读数据 unsigned short ConstBuffer::read(unsigned char* data, unsigned short length) { if (m_iFrameLength > length) { // 读取数据长度小于帧长 return -1; } { QMutexLocker locker(&m_mutex); // 当帧长为空时 while (IsEmpty(m_iFrameLength)) { if (m_bReadWait) { // add wait here, to wait for sufficient data to read m_condRead.wait(&m_mutex); } else { return 0; } } for (int i = 0; i < m_iFrameLength; i++) { data[i] = m_pBuffer[m_iReadIndex]; m_iReadIndex++; if (m_iReadIndex >= m_iBufferLength) { m_iReadIndex -= m_iBufferLength; m_bIsOneCycle = true; } } } if (m_bReadWait) { m_condWrite.wakeOne(); } return m_iFrameLength; } void ConstBuffer::clear() { m_bIsOneCycle = true; m_iReadIndex = 0; m_iWriteIndex = 0; } // 验证帧长 bool ConstBuffer::verifyFrameLength(unsigned char* buf, unsigned short length) { if (length != m_iFrameLength) { return 0; } return 1; } // memory is full, no place to write // two different situations: readIndex and writeIndex is in one cycle or not // one argument: the length of frame bool ConstBuffer::IsFull(unsigned short length) { if (m_bIsOneCycle) { return m_iWriteIndex + length > m_iReadIndex + m_iBufferLength; } return m_iWriteIndex + length > m_iReadIndex; } // memory is empty, no data to read // two different situations: readIndex and writeIndex is in one cycle or not bool ConstBuffer::IsEmpty(unsigned short length) { if (m_bIsOneCycle == true) { return m_iReadIndex + length > m_iWriteIndex; } return m_iReadIndex + length >= m_iBufferLength + m_iWriteIndex; }