/*++ Copyright (c) 1994 Microsoft Corporation Module Name: buffer.h Abstract: Contains manifests, macros, types and typedefs for buffer.c Author: Richard L Firth (rfirth) 31-Oct-1994 Revision History: 31-Oct-1994 rfirth Created --*/ #if defined(__cplusplus) extern "C" { #endif // // manifests // // // LOOK_AHEAD_LENGTH - read enough characters to comprise the maximum (32-bit) // length returned by gopher+ // #define LOOK_AHEAD_LENGTH sizeof("+4294967296\r\n") // 12 // // BUFFER_INFO - structure maintains information about responses from gopher // server. The same data can be shared amongst many requests // typedef struct { // // ReferenceCount - number of VIEW_INFO structures referencing this buffer // LONG ReferenceCount; // // Flags - information about the buffer // DWORD Flags; // // RequestEvent - the owner of this event is the only thread which can // make the gopher request that creates this buffer info. All other // requesters for the same information wait for the first thread to signal // the event, then just read the data returned by the first thread // // HANDLE RequestEvent; // // RequestWaiters - used in conjunction with RequestEvent. If this field // is 0 by the time the initial requester thread comes to signal the // event, it can do away with the event altogether, since it was only // required to stop those other threads from making a redundant request // // DWORD RequestWaiters; // // ConnectedSocket - contains socket we are using to receive the data in // the buffer, and the index into the parent SESSION_INFO's // ADDRESS_INFO_LIST of the address used to connect the socket // // CONNECTED_SOCKET ConnectedSocket; ICSocket * Socket; // // ResponseLength - the response length as told to us by the gopher+ server // int ResponseLength; // // BufferLength - length of Buffer // DWORD BufferLength; // // Buffer - containing response // LPBYTE Buffer; // // ResponseInfo - we read the gopher+ header information (i.e. length) here. // The main reason is so that we can determine the length of a gopher+ file // even though we were given a zero-length user buffer // char ResponseInfo[LOOK_AHEAD_LENGTH]; // // BytesRemaining - number of bytes left in ResponseInfo that are data // int BytesRemaining; // // DataBytes - pointer into ResponseInfo where data bytes start // LPBYTE DataBytes; // // CriticalSection - used to serialize readers // // CRITICAL_SECTION CriticalSection; } BUFFER_INFO, *LPBUFFER_INFO; // // BUFFER_INFO flags // #define BI_RECEIVE_COMPLETE 0x00000001 // receiver thread has finished #define BI_DOT_AT_END 0x00000002 // buffer terminated with ".\r\n" #define BI_BUFFER_RESPONSE 0x00000004 // response is buffered internally #define BI_ERROR_RESPONSE 0x00000008 // the server responded with an error #define BI_MOVEABLE 0x00000010 // buffer is moveable memory #define BI_FIRST_RECEIVE 0x00000020 // this is the first receive #define BI_OWN_BUFFER 0x00000040 // set if we own the buffer (directory) // // external data // DEBUG_DATA_EXTERN(LONG, NumberOfBuffers); // // prototypes // LPBUFFER_INFO CreateBuffer( OUT LPDWORD Error ); VOID DestroyBuffer( IN LPBUFFER_INFO BufferInfo ); VOID AcquireBufferLock( IN LPBUFFER_INFO BufferInfo ); VOID ReleaseBufferLock( IN LPBUFFER_INFO BufferInfo ); VOID ReferenceBuffer( IN LPBUFFER_INFO BufferInfo ); LPBUFFER_INFO DereferenceBuffer( IN LPBUFFER_INFO BufferInfo ); // // macros // #if INET_DEBUG #define BUFFER_CREATED() ++NumberOfBuffers #define BUFFER_DESTROYED() --NumberOfBuffers #define ASSERT_NO_BUFFERS() \ if (NumberOfBuffers != 0) { \ INET_ASSERT(FALSE); \ } #else #define BUFFER_CREATED() /* NOTHING */ #define BUFFER_DESTROYED() /* NOTHING */ #define ASSERT_NO_BUFFERS() /* NOTHING */ #endif #if defined(__cplusplus) } #endif