wrqueue.c
上传用户:xmgzy123
上传日期:2007-01-07
资源大小:373k
文件大小:5k
源码类别:

SCSI/ASPI

开发平台:

WINDOWS

  1. /*
  2.  * wrqueue.c - Copyright (C) 1999,2000 Jay A. Key
  3.  *
  4.  * Implements a simple wrap-around queue.  Add to the tail and read from
  5.  * the head.
  6.  *
  7.  **********************************************************************
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22.  *
  23.  */
  24. #include <windows.h>
  25. #include <stdio.h>
  26. #include <malloc.h>
  27. #include "wrqueue.h"
  28. int wrqInitQueue( LPWRQUEUE q, int max )
  29. {
  30.   if ( !q )
  31.     return 0;
  32.   memset( q, 0, sizeof(*q) );
  33.   if ( max <= 0 )
  34.     return 0;
  35.   q->data = (unsigned char *)malloc( max );
  36.   if ( !q->data )
  37.     return 0;
  38.   q->head = q->tail = q->data;
  39.   q->dataLen = max;
  40.   memset( q->data, ' ', max );
  41.   InitializeCriticalSection( &q->inUse );
  42.   return -1;
  43. }
  44. void wrqDeinitQueue( LPWRQUEUE q )
  45. {
  46.   if ( !q )
  47.     return;
  48.   DeleteCriticalSection( &q->inUse );
  49.   if ( q->data && q->dataLen )
  50.     free( q->data );
  51.   memset( q, 0, sizeof(*q) );
  52. }
  53. int wrqFreeSpace( LPWRQUEUE q )
  54. {
  55.   int retVal;
  56.   if ( !q )
  57.     return 0;
  58.   EnterCriticalSection( &q->inUse );
  59.   retVal = q->dataLen - q->bytesUsed;
  60.   LeaveCriticalSection( &q->inUse );
  61.   return retVal;
  62. }
  63. int wrqNumUsed( LPWRQUEUE q )
  64. {
  65.   int retVal;
  66.   if ( !q )
  67.     return 0;
  68.   EnterCriticalSection( &q->inUse );
  69.   retVal = q->bytesUsed;
  70.   LeaveCriticalSection( &q->inUse );
  71.   return retVal;
  72. }
  73. /*
  74.  * returns the number of bytes enqueued
  75.  */
  76. int wrqEnqueue( LPWRQUEUE q, unsigned char *buf, int numBytes )
  77. {
  78.   unsigned char *end;
  79.   int retVal = 0;
  80.   if ( !q || !buf )
  81.     return 0;
  82.   EnterCriticalSection( &q->inUse );
  83.   //debugQueue( q );
  84.   end = q->data + q->dataLen;
  85.   if ( numBytes > ( q->dataLen - q->bytesUsed ) )
  86.     numBytes = q->dataLen - q->bytesUsed;
  87.   q->bytesUsed += numBytes;
  88.   retVal = numBytes;
  89.   /* if it all fits without wrap-around, just copy it */
  90.   if ( q->tail + numBytes < end )
  91.     {
  92.       memcpy( q->tail, buf, numBytes );
  93.       q->tail += numBytes;
  94.     }
  95.   else
  96.     {
  97.       memcpy( q->tail, buf, end - q->tail );
  98.       buf += (end - q->tail);
  99.       numBytes -= (end - q->tail);
  100.       q->tail = q->data;
  101.       memcpy( q->tail, buf, numBytes );
  102.       q->tail += numBytes;
  103.     }
  104.   //debugQueue( q );
  105.   LeaveCriticalSection( &q->inUse );
  106.   return retVal;
  107. }
  108. int wrqDequeue( LPWRQUEUE q, unsigned char **buf, int max )
  109. {
  110.   unsigned char *end;
  111.   int retVal = 0;
  112.   if ( !q || !buf || !q->bytesUsed  || !*buf )
  113.     return 0;
  114.   EnterCriticalSection( &q->inUse );
  115.   //debugQueue( q );
  116.   end = q->data + q->dataLen;
  117.   if ( max > q->bytesUsed )
  118.     max = q->bytesUsed;
  119.   retVal = max;
  120.   q->bytesUsed -= max;
  121.   if ( q->head + max < end )
  122.     {
  123. #if 1
  124.       memcpy( *buf, q->head, max );
  125. #else
  126.       // return a pointer to the memory instead of copying it,
  127.       // to try and speed up.  Since 1 min of audio represents
  128.       // 10 MB of data, this could have a rather large effect
  129.       *buf = q->head;
  130. #endif
  131.       q->head += max;
  132.     }
  133.   else
  134.     {
  135.       unsigned char *p;
  136.       p = *buf;
  137.       memcpy( p, q->head, end - q->head );
  138.       p += (end - q->head);
  139.       max -= (end - q->head);
  140.       q->head = q->data;
  141.       memcpy( p, q->head, max );
  142.       q->head += max;
  143.     }
  144.   if ( q->bytesUsed == 0 )
  145.     q->head = q->tail = q->data;
  146.   //debugQueue( q );
  147. #if 0
  148.   if ( q->hWaitForDequeue && (wrqNumUsed( q ) < 15000) )
  149. #else
  150.   if ( q->hWaitForDequeue && (wrqFreeSpace( q ) > q->iNumWait) )
  151. #endif
  152.     {
  153.       SetEvent( q->hWaitForDequeue );
  154.       q->hWaitForDequeue = NULL;
  155.     }
  156.   LeaveCriticalSection( &q->inUse );
  157.   return retVal;
  158. }
  159. #if 0
  160. int debugQueue( LPWRQUEUE q )
  161. {
  162.   int i;
  163.   printf( "--------------------n" );
  164.   printf( "data = 0x%08X, head = 0x%08X, tail = 0x%08Xn", q->data,
  165.   q->head, q->tail );
  166.   printf( "dataLen = %d, bytesUsed = %d, end = 0x%08Xn", q->dataLen,
  167.   q->bytesUsed, q->data + q->dataLen );
  168.   for( i = 0; i < q->dataLen; i++ )
  169.     {
  170.       printf( "%c", q->data[i] );
  171.     }
  172.   printf( "n--------------------n" );
  173.   return 0;
  174. }
  175. #endif
  176. void wrqSetWait( LPWRQUEUE q, HANDLE hWait, int numBytes )
  177. {
  178.   if ( !q )
  179.     return;
  180.   EnterCriticalSection( &q->inUse );
  181.   q->hWaitForDequeue = hWait;
  182.   q->iNumWait = numBytes;
  183.   LeaveCriticalSection( &q->inUse );
  184. }