C++版循环缓冲区类

51 篇文章 1 订阅

[cpp]  view plain  copy
 print ?
  1. // 声明  
  2. class CCycleBuffer    
  3. {  
  4. public:  
  5.  BOOL isFull();  
  6.  BOOL isEmpty();  
  7.  void Empty();  
  8.  int GetLength();  
  9.  CCycleBuffer(int size);  
  10.  virtual ~CCycleBuffer();  
  11.  int Write(char* buf, int count);  
  12.  int Read(char* buf, int count);  
  13. private:  
  14.  BOOL m_bEmpty, m_bFull;  
  15.  char * m_pBuf;  
  16.  int m_nBufSize;  
  17.  int m_nReadPos;  
  18.  int m_nWritePos;  
  19. };  
  20. // 定义  
  21. CCycleBuffer::CCycleBuffer(int size)  
  22. {  
  23.  m_nBufSize = size;  
  24.  m_nReadPos = 0;  
  25.  m_nWritePos = 0;  
  26.  m_pBuf = new char[m_nBufSize];  
  27.  m_bEmpty = TRUE;  
  28.  m_bFull = FALSE;  
  29. }  
  30. CCycleBuffer::~CCycleBuffer()  
  31. {  
  32.  delete[] m_pBuf;  
  33. }  
  34. /************************************************************************/  
  35. /* 向缓冲区写入数据,返回实际写入的字节数                               */  
  36. /************************************************************************/  
  37. int CCycleBuffer::Write(char* buf, int count)  
  38. {  
  39.  if(count <= 0) return 0;  
  40.  m_bEmpty = FALSE;  
  41.  // 缓冲区已满,不能继续写入  
  42.  if(m_bFull)   
  43.  {  
  44.   return 0;  
  45.  }  
  46.  else if(m_nReadPos == m_nWritePos) // 缓冲区为空时  
  47.  {  
  48.   /*                          == 内存模型 == 
  49.              (empty)             m_nReadPos                (empty)                       
  50.   |----------------------------------|-----------------------------------------| 
  51.                                 m_nWritePos        m_nBufSize 
  52.   */  
  53.   int leftcount = m_nBufSize - m_nWritePos;  
  54.   if(leftcount > count)  
  55.   {  
  56.    CopyMemory(m_pBuf + m_nWritePos, buf, count);  
  57.    m_nWritePos += count;  
  58.    m_bFull = (m_nWritePos == m_nReadPos);  
  59.    return count;  
  60.   }  
  61.   else  
  62.   {  
  63.    CopyMemory(m_pBuf + m_nWritePos, buf, leftcount);  
  64.    m_nWritePos = (m_nReadPos > count - leftcount) ? count - leftcount : m_nWritePos;  
  65.    CopyMemory(m_pBuf, buf + leftcount, m_nWritePos);  
  66.    m_bFull = (m_nWritePos == m_nReadPos);  
  67.    return leftcount + m_nWritePos;  
  68.   }  
  69.  }   
  70.  else if(m_nReadPos < m_nWritePos) // 有剩余空间可写入  
  71.  {  
  72.   /*                           == 内存模型 == 
  73.         (empty)                 (data)                     (empty) 
  74.   |-------------------|----------------------------|---------------------------| 
  75.                 m_nReadPos                m_nWritePos       (leftcount)            
  76.   */  
  77.   // 剩余缓冲区大小(从写入位置到缓冲区尾)  
  78.   int leftcount = m_nBufSize - m_nWritePos;    
  79.   if(leftcount > count)   // 有足够的剩余空间存放  
  80.   {  
  81.    CopyMemory(m_pBuf + m_nWritePos, buf, count);  
  82.    m_nWritePos += count;  
  83.    m_bFull = (m_nReadPos == m_nWritePos);  
  84.    ASSERT(m_nReadPos <= m_nBufSize);  
  85.    ASSERT(m_nWritePos <= m_nBufSize);      
  86.    return count;  
  87.   }  
  88.   else       // 剩余空间不足  
  89.   {  
  90.    // 先填充满剩余空间,再回头找空间存放  
  91.    CopyMemory(m_pBuf + m_nWritePos, buf, leftcount);  
  92.    int m_nWritePos = (m_nReadPos >= count - leftcount) ? count - leftcount : m_nReadPos;  
  93.    CopyMemory(m_pBuf, buf + leftcount, m_nWritePos);  
  94.    m_bFull = (m_nReadPos == m_nWritePos);     
  95.    ASSERT(m_nReadPos <= m_nBufSize);  
  96.    ASSERT(m_nWritePos <= m_nBufSize);   
  97.    return leftcount + m_nWritePos;  
  98.   }  
  99.  }  
  100.  else  
  101.  {  
  102.   /*                          == 内存模型 == 
  103.         (unread)                 (read)                     (unread) 
  104.   |-------------------|----------------------------|---------------------------| 
  105.                  m_nWritePos    (leftcount)    m_nReadPos                       
  106.   */  
  107.   int leftcount = m_nReadPos - m_nWritePos;  
  108.   if(leftcount > count)  
  109.   {  
  110.    // 有足够的剩余空间存放  
  111.    CopyMemory(m_pBuf + m_nWritePos, buf, count);  
  112.    m_nWritePos += count;  
  113.    m_bFull = (m_nReadPos == m_nWritePos);  
  114.    ASSERT(m_nReadPos <= m_nBufSize);  
  115.    ASSERT(m_nWritePos <= m_nBufSize);   
  116.    return count;  
  117.   }  
  118.   else  
  119.   {  
  120.    // 剩余空间不足时要丢弃后面的数据  
  121.    CopyMemory(m_pBuf + m_nWritePos, buf, leftcount);  
  122.    m_nWritePos += leftcount;  
  123.    m_bFull = (m_nReadPos == m_nWritePos);  
  124.    ASSERT(m_bFull);  
  125.    ASSERT(m_nReadPos <= m_nBufSize);  
  126.    ASSERT(m_nWritePos <= m_nBufSize);     
  127.    return leftcount;  
  128.   }  
  129.  }  
  130. }  
  131. /************************************************************************/  
  132. /* 从缓冲区读数据,返回实际读取的字节数                                 */  
  133. /************************************************************************/  
  134. int CCycleBuffer::Read(char* buf, int count)  
  135. {  
  136.  if(count <= 0) return 0;  
  137.  m_bFull = FALSE;  
  138.  if(m_bEmpty)       // 缓冲区空,不能继续读取数据  
  139.  {  
  140.   return 0;  
  141.  }  
  142.  else if(m_nReadPos == m_nWritePos)   // 缓冲区满时  
  143.  {  
  144.   /*                          == 内存模型 == 
  145.      (data)          m_nReadPos                (data)     
  146.   |--------------------------------|--------------------------------------------| 
  147.          m_nWritePos         m_nBufSize 
  148.   */  
  149.   int leftcount = m_nBufSize - m_nReadPos;  
  150.   if(leftcount > count)  
  151.   {  
  152.    CopyMemory(buf, m_pBuf + m_nReadPos, count);  
  153.    m_nReadPos += count;  
  154.    m_bEmpty = (m_nReadPos == m_nWritePos);  
  155.    return count;  
  156.   }  
  157.   else  
  158.   {  
  159.    CopyMemory(buf, m_pBuf + m_nReadPos, leftcount);  
  160.    m_nReadPos = (m_nWritePos > count - leftcount) ? count - leftcount : m_nWritePos;  
  161.    CopyMemory(buf + leftcount, m_pBuf, m_nReadPos);  
  162.    m_bEmpty = (m_nReadPos == m_nWritePos);  
  163.    return leftcount + m_nReadPos;  
  164.   }  
  165.  }  
  166.  else if(m_nReadPos < m_nWritePos)   // 写指针在前(未读数据是连接的)  
  167.  {  
  168.   /*                          == 内存模型 == 
  169.         (read)                 (unread)                      (read)     
  170.   |-------------------|----------------------------|---------------------------| 
  171.                 m_nReadPos                m_nWritePos                     m_nBufSize 
  172.   */  
  173.   int leftcount = m_nWritePos - m_nReadPos;  
  174.   int c = (leftcount > count) ? count : leftcount;  
  175.   CopyMemory(buf, m_pBuf + m_nReadPos, c);  
  176.   m_nReadPos += c;  
  177.   m_bEmpty = (m_nReadPos == m_nWritePos);  
  178.   ASSERT(m_nReadPos <= m_nBufSize);  
  179.   ASSERT(m_nWritePos <= m_nBufSize);  
  180.   return c;  
  181.  }  
  182.  else          // 读指针在前(未读数据可能是不连接的)  
  183.  {  
  184.   /*                          == 内存模型 == 
  185.           (unread)                (read)                      (unread) 
  186.   |-------------------|----------------------------|---------------------------| 
  187.                  m_nWritePos                  m_nReadPos                  m_nBufSize 
  188.   
  189.   */  
  190.   int leftcount = m_nBufSize - m_nReadPos;  
  191.   if(leftcount > count)   // 未读缓冲区够大,直接读取数据  
  192.   {  
  193.    CopyMemory(buf, m_pBuf + m_nReadPos, count);  
  194.    m_nReadPos += count;  
  195.    m_bEmpty = (m_nReadPos == m_nWritePos);  
  196.    ASSERT(m_nReadPos <= m_nBufSize);  
  197.    ASSERT(m_nWritePos <= m_nBufSize);  
  198.    return count;  
  199.   }  
  200.   else       // 未读缓冲区不足,需回到缓冲区头开始读  
  201.   {  
  202.    CopyMemory(buf, m_pBuf + m_nReadPos, leftcount);  
  203.    m_nReadPos = (m_nWritePos >= count - leftcount) ? count - leftcount : m_nWritePos;  
  204.    CopyMemory(buf, m_pBuf, m_nReadPos);  
  205.    m_bEmpty = (m_nReadPos == m_nWritePos);  
  206.    ASSERT(m_nReadPos <= m_nBufSize);  
  207.    ASSERT(m_nWritePos <= m_nBufSize);  
  208.    return leftcount + m_nReadPos;  
  209.   }    
  210.  }  
  211. }  
  212. /************************************************************************/  
  213. /* 获取缓冲区有效数据长度                                               */  
  214. /************************************************************************/  
  215. int CCycleBuffer::GetLength()  
  216. {  
  217.  if(m_bEmpty)  
  218.  {  
  219.   return 0;  
  220.  }  
  221.  else if(m_bFull)  
  222.  {  
  223.   return m_nBufSize;  
  224.  }  
  225.  else if(m_nReadPos < m_nWritePos)  
  226.  {  
  227.   return m_nWritePos - m_nReadPos;  
  228.  }  
  229.  else  
  230.  {  
  231.   return m_nBufSize - m_nReadPos + m_nWritePos;  
  232.  }  
  233. }  
  234. void CCycleBuffer::Empty()  
  235. {  
  236.  m_nReadPos = 0;  
  237.  m_nWritePos = 0;  
  238.  m_bEmpty = TRUE;  
  239.  m_bFull = FALSE;  
  240. }  
  241. BOOL CCycleBuffer::isEmpty()  
  242. {  
  243.  return m_bEmpty;  
  244. }  
  245. BOOL CCycleBuffer::isFull()  
  246. {  
  247.  return m_bFull;  
  248. }  
 

上面这个版本是windows C++版,下面的是标准C++版

[cpp]  view plain  copy
 print ?
  1. #ifndef __test__CCycleBuffer__  
  2. #define __test__CCycleBuffer__  
  3.   
  4. #include <iostream>  
  5. #include <assert.h>  
  6. class CCycleBuffer  
  7. {  
  8. public:  
  9.     bool isFull();  
  10.     bool isEmpty();  
  11.     void Empty();  
  12.     int GetLength();  
  13.     CCycleBuffer(int size);  
  14.     virtual ~CCycleBuffer();  
  15.     int Write(char* buf, int count);  
  16.     int Read(char* buf, int count);  
  17. private:  
  18.     bool m_bEmpty, m_bFull;  
  19.     char * m_pBuf;  
  20.     int m_nBufSize;  
  21.     int m_nReadPos;  
  22.     int m_nWritePos;  
  23.       
  24. public:  
  25.     int GetReadPos() { return m_nReadPos; }  
  26.     int GetWritePos() { return m_nWritePos; }  
  27. };  
  28. #endif /* defined(__test__CCycleBuffer__) */  

[cpp]  view plain  copy
 print ?
  1. #include "CCycleBuffer.h"  
  2. // 定义  
  3. CCycleBuffer::CCycleBuffer(int size)  
  4. {  
  5.     m_nBufSize = size;  
  6.     m_nReadPos = 0;  
  7.     m_nWritePos = 0;  
  8.     m_pBuf = new char[m_nBufSize];  
  9.     m_bEmpty = true;  
  10.     m_bFull = false;  
  11. }  
  12. CCycleBuffer::~CCycleBuffer()  
  13. {  
  14.     delete[] m_pBuf;  
  15. }  
  16. /************************************************************************/  
  17. /* 向缓冲区写入数据,返回实际写入的字节数                               */  
  18. /************************************************************************/  
  19. int CCycleBuffer::Write(char* buf, int count)  
  20. {  
  21.     if(count <= 0) return 0;  
  22.     m_bEmpty = false;  
  23.     // 缓冲区已满,不能继续写入  
  24.     if(m_bFull)  
  25.     {  
  26.         return 0;  
  27.     }  
  28.     else if(m_nReadPos == m_nWritePos) // 缓冲区为空时  
  29.     {  
  30.         /*                          == 内存模型 == 
  31.          (empty)             m_nReadPos                (empty) 
  32.          |----------------------------------|-----------------------------------------| 
  33.          m_nWritePos        m_nBufSize 
  34.          */  
  35.         int leftcount = m_nBufSize - m_nWritePos;  
  36.         if(leftcount > count)  
  37.         {  
  38.             memcpy(m_pBuf + m_nWritePos, buf, count);  
  39.             m_nWritePos += count;  
  40.             m_bFull = (m_nWritePos == m_nReadPos);  
  41.             return count;  
  42.         }  
  43.         else  
  44.         {  
  45.             memcpy(m_pBuf + m_nWritePos, buf, leftcount);  
  46.             m_nWritePos = (m_nReadPos > count - leftcount) ? count - leftcount : m_nWritePos;  
  47.             memcpy(m_pBuf, buf + leftcount, m_nWritePos);  
  48.             m_bFull = (m_nWritePos == m_nReadPos);  
  49.             return leftcount + m_nWritePos;  
  50.         }  
  51.     }  
  52.     else if(m_nReadPos < m_nWritePos) // 有剩余空间可写入  
  53.     {  
  54.         /*                           == 内存模型 == 
  55.          (empty)                 (data)                     (empty) 
  56.          |-------------------|----------------------------|---------------------------| 
  57.          m_nReadPos                m_nWritePos       (leftcount) 
  58.          */  
  59.         // 剩余缓冲区大小(从写入位置到缓冲区尾)  
  60.         int leftcount = m_nBufSize - m_nWritePos;  
  61.         if(leftcount > count)   // 有足够的剩余空间存放  
  62.         {  
  63.             memcpy(m_pBuf + m_nWritePos, buf, count);  
  64.             m_nWritePos += count;  
  65.             m_bFull = (m_nReadPos == m_nWritePos);  
  66.             assert(m_nReadPos <= m_nBufSize);  
  67.             assert(m_nWritePos <= m_nBufSize);  
  68.             return count;  
  69.         }  
  70.         else       // 剩余空间不足  
  71.         {  
  72.             // 先填充满剩余空间,再回头找空间存放  
  73.             memcpy(m_pBuf + m_nWritePos, buf, leftcount);  
  74.             m_nWritePos = (m_nReadPos >= count - leftcount) ? count - leftcount : m_nReadPos;  
  75.             memcpy(m_pBuf, buf + leftcount, m_nWritePos);  
  76.             m_bFull = (m_nReadPos == m_nWritePos);  
  77.             assert(m_nReadPos <= m_nBufSize);  
  78.             assert(m_nWritePos <= m_nBufSize);  
  79.             return leftcount + m_nWritePos;  
  80.         }  
  81.     }  
  82.     else  
  83.     {  
  84.         /*                          == 内存模型 == 
  85.          (unread)                 (read)                     (unread) 
  86.          |-------------------|----------------------------|---------------------------| 
  87.          m_nWritePos    (leftcount)    m_nReadPos 
  88.          */  
  89.         int leftcount = m_nReadPos - m_nWritePos;  
  90.         if(leftcount > count)  
  91.         {  
  92.             // 有足够的剩余空间存放  
  93.             memcpy(m_pBuf + m_nWritePos, buf, count);  
  94.             m_nWritePos += count;  
  95.             m_bFull = (m_nReadPos == m_nWritePos);  
  96.             assert(m_nReadPos <= m_nBufSize);  
  97.             assert(m_nWritePos <= m_nBufSize);  
  98.             return count;  
  99.         }  
  100.         else  
  101.         {  
  102.             // 剩余空间不足时要丢弃后面的数据  
  103.             memcpy(m_pBuf + m_nWritePos, buf, leftcount);  
  104.             m_nWritePos += leftcount;  
  105.             m_bFull = (m_nReadPos == m_nWritePos);  
  106.             assert(m_bFull);  
  107.             assert(m_nReadPos <= m_nBufSize);  
  108.             assert(m_nWritePos <= m_nBufSize);  
  109.             return leftcount;  
  110.         }  
  111.     }  
  112. }  
  113. /************************************************************************/  
  114. /* 从缓冲区读数据,返回实际读取的字节数                                 */  
  115. /************************************************************************/  
  116. int CCycleBuffer::Read(char* buf, int count)  
  117. {  
  118.     if(count <= 0) return 0;  
  119.     m_bFull = false;  
  120.     if(m_bEmpty)       // 缓冲区空,不能继续读取数据  
  121.     {  
  122.         return 0;  
  123.     }  
  124.     else if(m_nReadPos == m_nWritePos)   // 缓冲区满时  
  125.     {  
  126.         /*                          == 内存模型 == 
  127.          (data)          m_nReadPos                (data) 
  128.          |--------------------------------|--------------------------------------------| 
  129.          m_nWritePos         m_nBufSize 
  130.          */  
  131.         int leftcount = m_nBufSize - m_nReadPos;  
  132.         if(leftcount > count)  
  133.         {  
  134.             memcpy(buf, m_pBuf + m_nReadPos, count);  
  135.             m_nReadPos += count;  
  136.             m_bEmpty = (m_nReadPos == m_nWritePos);  
  137.             return count;  
  138.         }  
  139.         else  
  140.         {  
  141.             memcpy(buf, m_pBuf + m_nReadPos, leftcount);  
  142.             m_nReadPos = (m_nWritePos > count - leftcount) ? count - leftcount : m_nWritePos;  
  143.             memcpy(buf + leftcount, m_pBuf, m_nReadPos);  
  144.             m_bEmpty = (m_nReadPos == m_nWritePos);  
  145.             return leftcount + m_nReadPos;  
  146.         }  
  147.     }  
  148.     else if(m_nReadPos < m_nWritePos)   // 写指针在前(未读数据是连接的)  
  149.     {  
  150.         /*                          == 内存模型 == 
  151.          (read)                 (unread)                      (read) 
  152.          |-------------------|----------------------------|---------------------------| 
  153.          m_nReadPos                m_nWritePos                     m_nBufSize 
  154.          */  
  155.         int leftcount = m_nWritePos - m_nReadPos;  
  156.         int c = (leftcount > count) ? count : leftcount;  
  157.         memcpy(buf, m_pBuf + m_nReadPos, c);  
  158.         m_nReadPos += c;  
  159.         m_bEmpty = (m_nReadPos == m_nWritePos);  
  160.         assert(m_nReadPos <= m_nBufSize);  
  161.         assert(m_nWritePos <= m_nBufSize);  
  162.         return c;  
  163.     }  
  164.     else          // 读指针在前(未读数据可能是不连接的)  
  165.     {  
  166.         /*                          == 内存模型 == 
  167.          (unread)                (read)                      (unread) 
  168.          |-------------------|----------------------------|---------------------------| 
  169.          m_nWritePos                  m_nReadPos                  m_nBufSize 
  170.           
  171.          */  
  172.         int leftcount = m_nBufSize - m_nReadPos;  
  173.         if(leftcount > count)   // 未读缓冲区够大,直接读取数据  
  174.         {  
  175.             memcpy(buf, m_pBuf + m_nReadPos, count);  
  176.             m_nReadPos += count;  
  177.             m_bEmpty = (m_nReadPos == m_nWritePos);  
  178.             assert(m_nReadPos <= m_nBufSize);  
  179.             assert(m_nWritePos <= m_nBufSize);  
  180.             return count;  
  181.         }  
  182.         else       // 未读缓冲区不足,需回到缓冲区头开始读  
  183.         {  
  184.             memcpy(buf, m_pBuf + m_nReadPos, leftcount);  
  185.             m_nReadPos = (m_nWritePos >= count - leftcount) ? count - leftcount : m_nWritePos;  
  186.             memcpy(buf, m_pBuf, m_nReadPos);  
  187.             m_bEmpty = (m_nReadPos == m_nWritePos);    
  188.             assert(m_nReadPos <= m_nBufSize);    
  189.             assert(m_nWritePos <= m_nBufSize);    
  190.             return leftcount + m_nReadPos;    
  191.         }      
  192.     }    
  193. }    
  194. /************************************************************************/    
  195. /* 获取缓冲区有效数据长度                                               */    
  196. /************************************************************************/    
  197. int CCycleBuffer::GetLength()    
  198. {    
  199.     if(m_bEmpty)    
  200.     {    
  201.         return 0;    
  202.     }    
  203.     else if(m_bFull)    
  204.     {    
  205.         return m_nBufSize;    
  206.     }    
  207.     else if(m_nReadPos < m_nWritePos)    
  208.     {    
  209.         return m_nWritePos - m_nReadPos;    
  210.     }    
  211.     else    
  212.     {    
  213.         return m_nBufSize - m_nReadPos + m_nWritePos;    
  214.     }    
  215. }    
  216. void CCycleBuffer::Empty()    
  217. {    
  218.     m_nReadPos = 0;    
  219.     m_nWritePos = 0;    
  220.     m_bEmpty = true;  
  221.     m_bFull = false;  
  222. }    
  223. bool CCycleBuffer::isEmpty()  
  224. {    
  225.     return m_bEmpty;    
  226. }    
  227. bool CCycleBuffer::isFull()  
  228. {    
  229.     return m_bFull;    
  230. }  


增加一个Objective_c的测试用例

[cpp]  view plain  copy
 print ?
  1. int* dataint = new int[10]();  
  2. CCycleBuffer buffer(100);  
  3. char* datachar = (char *)dataint;  
  4. int* resint = new int[10]();  
  5. char* reschar = (char*)resint;  
  6. int num = 0;  
  7. while(1)  
  8. {  
  9.     int a = 0;  
  10.     if(buffer.GetLength()<60)  
  11.     {  
  12.         dataint[0] = num;  
  13.         //qDebug("write 之前 m_nReadPos:%d,m_nWritePos:%d,Length:%d",buffer.getStart(),buffer.getEnd(),buffer.getLength());  
  14.         a = buffer.Write(datachar,10*4);  
  15.         if(a<=0)  
  16.             NSLog(@"写失败");  
  17.         NSLog(@"write %d之后 m_nReadPos:%d,m_nWritePos:%d,Length:%d", a, buffer.GetReadPos() , buffer.GetWritePos(),buffer.GetLength());  
  18.         num++;  
  19.     }  
  20.     if(buffer.GetLength()<60)  
  21.     {  
  22.         dataint[0] = num;  
  23.         NSLog(@"write 之前 m_nReadPos:%d,m_nWritePos:%d,Length:%d", buffer.GetReadPos() , buffer.GetWritePos(),buffer.GetLength());  
  24.         a = buffer.Write(datachar,10*4);  
  25.         if(a<=0)  
  26.             NSLog(@"写失败");  
  27.         NSLog(@"write %d之后 m_nReadPos:%d,m_nWritePos:%d,Length:%d", a, buffer.GetReadPos() , buffer.GetWritePos(),buffer.GetLength());  
  28.         num++;  
  29.     }  
  30.     if(buffer.GetLength()>=10*4)  
  31.     {  
  32.         NSLog(@"read 之前 m_nReadPos:%d,m_nWritePos:%d,Length:%d", buffer.GetReadPos() , buffer.GetWritePos(),buffer.GetLength());  
  33.         a = buffer.Read(reschar,10*4);  
  34.         NSLog(@"read %d之后 m_nReadPos:%d,m_nWritePos:%d,Length:%d", a, buffer.GetReadPos() , buffer.GetWritePos(),buffer.GetLength());  
  35.     }  
  36. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值