You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
236 lines
4.0 KiB
236 lines
4.0 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
chunk.hxx
|
|
|
|
Abstract:
|
|
|
|
Contains a generic chunked transfer implimentation
|
|
|
|
Author:
|
|
|
|
Arthur L Bierer (arthurbi) 03-May-1997
|
|
|
|
Revision History:
|
|
|
|
03-May-1997 arthurbi
|
|
Created
|
|
|
|
--*/
|
|
|
|
//
|
|
// defines
|
|
//
|
|
|
|
#define BASE_HEX 16
|
|
|
|
//
|
|
// structures/types
|
|
//
|
|
|
|
//
|
|
// CHUNK_STATE - enumerated set of states that our chunked-transfer can use.
|
|
//
|
|
|
|
|
|
|
|
typedef enum {
|
|
CHUNK_STATE_START,
|
|
CHUNK_STATE_SIZE_PARSE,
|
|
CHUNK_STATE_EXT_PARSE,
|
|
CHUNK_STATE_SIZE_CRLF,
|
|
CHUNK_STATE_DATA_PARSE,
|
|
CHUNK_STATE_DATA_CRLF,
|
|
CHUNK_STATE_ZERO_FOOTER,
|
|
CHUNK_STATE_ZERO_FOOTER_NAME,
|
|
CHUNK_STATE_ZERO_FOOTER_VALUE,
|
|
CHUNK_STATE_ZERO_FOOTER_CRLF,
|
|
CHUNK_STATE_ZERO_FOOTER_FINAL_CRLF,
|
|
CHUNK_STATE_FINISHED
|
|
} CHUNK_STATE, * LPCHUNK_STATE;
|
|
|
|
|
|
//
|
|
// CHUNK_TOKEN - enumerated set of tokens that can be parsed off of chunk stream
|
|
//
|
|
|
|
typedef enum {
|
|
CHUNK_TOKEN_DIGIT,
|
|
CHUNK_TOKEN_DATA,
|
|
CHUNK_TOKEN_COLON,
|
|
CHUNK_TOKEN_CR,
|
|
CHUNK_TOKEN_LF,
|
|
CHUNK_TOKEN_INVALID
|
|
} CHUNK_TOKEN, * LPCHUNK_TOKEN;
|
|
|
|
|
|
|
|
class CHUNK_TRANSFER {
|
|
|
|
private:
|
|
|
|
//
|
|
// _csState - Current State that we are in for parsing chunked encoding
|
|
//
|
|
|
|
CHUNK_STATE _csState;
|
|
|
|
|
|
//
|
|
// CHUNK_STATE_SIZE_PARSE: below are vars used for this state
|
|
//
|
|
|
|
//
|
|
// _dwCalculatedChunkSize - current value used in processing the chunk size
|
|
// number.
|
|
//
|
|
|
|
DWORD _dwCalculatedChunkSize;
|
|
|
|
//
|
|
// CHUNK_STATE_SIZE_CRLF, CHUNK_STATE_DATA_CRLF, CHUNK_STATE_ZERO_SIZE_CRLF,
|
|
// CHUNK_STATE_ZERO_FOOTER_CRLF: below are vars used to track the CRLF pair
|
|
// when in the above states.
|
|
//
|
|
|
|
//
|
|
// _dwCr & _dwLf - Count of CR & LF bytes
|
|
//
|
|
|
|
DWORD _dwCr;
|
|
DWORD _dwLf;
|
|
|
|
inline
|
|
VOID
|
|
ClearCrLf(
|
|
VOID
|
|
)
|
|
{
|
|
_dwCr = 0;
|
|
_dwLf = 0;
|
|
}
|
|
|
|
inline
|
|
BOOL
|
|
IsCrLf(
|
|
VOID
|
|
)
|
|
{
|
|
if ( _dwCr == 1 && _dwLf == 1 )
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// CHUNK_STATE_DATA_PARSE: below are vars used to track parsing of this data
|
|
//
|
|
|
|
//
|
|
// _dwChunkDataSize - size of current chunk that we are reading data from
|
|
//
|
|
|
|
DWORD _dwChunkDataSize;
|
|
|
|
//
|
|
// _dwChunkDataOffset - Count of bytes that have already been read from this chunk
|
|
//
|
|
|
|
DWORD _dwChunkDataRead;
|
|
|
|
//
|
|
// CHUNK_STATE_ZERO_FOOTER: below are vars used to track footer parsing
|
|
//
|
|
inline
|
|
VOID
|
|
SetState(
|
|
CHUNK_STATE csState
|
|
)
|
|
{
|
|
_csState = csState;
|
|
}
|
|
|
|
VOID
|
|
ResetSubStateInfo(
|
|
VOID
|
|
)
|
|
{
|
|
_dwCalculatedChunkSize = 0;
|
|
_dwCr = 0;
|
|
_dwLf = 0;
|
|
_dwChunkDataSize = 0;
|
|
_dwChunkDataRead = 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
CHUNK_TRANSFER(
|
|
VOID
|
|
)
|
|
{
|
|
ResetSubStateInfo();
|
|
|
|
_csState = CHUNK_STATE_START;
|
|
}
|
|
|
|
|
|
~CHUNK_TRANSFER(
|
|
VOID
|
|
)
|
|
{
|
|
}
|
|
|
|
DWORD
|
|
ParseChunkInput(
|
|
IN LPSTR lpInputBuffer,
|
|
IN DWORD dwInputBufferSize,
|
|
OUT LPSTR *lplpInputBufferNew,
|
|
OUT LPDWORD lpdwInputBufferNewSize
|
|
);
|
|
|
|
inline
|
|
CHUNK_TOKEN
|
|
GetToken(
|
|
IN OUT LPSTR *lplpInputBuffer,
|
|
IN LPSTR lpEndOfInputBuffer,
|
|
OUT LPDWORD lpdwValue,
|
|
IN DWORD dwExpectedTokenSize,
|
|
OUT LPDWORD lpdwBytesTokenized
|
|
);
|
|
|
|
|
|
|
|
DWORD
|
|
BytesRemaining(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
Reset(
|
|
VOID
|
|
)
|
|
{
|
|
ResetSubStateInfo();
|
|
_csState = CHUNK_STATE_START;
|
|
}
|
|
|
|
BOOL
|
|
IsFinished(
|
|
VOID
|
|
)
|
|
{
|
|
return (( _csState == CHUNK_STATE_FINISHED ) ? TRUE : FALSE );
|
|
}
|
|
|
|
};
|