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.
268 lines
6.0 KiB
268 lines
6.0 KiB
/*++
|
|
|
|
Copyright (c) 2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
chunkflt.hxx
|
|
|
|
Abstract:
|
|
|
|
Contains a filter for encoding and decoding chunked transfers.
|
|
|
|
Contents:
|
|
BaseFilter
|
|
FILTER_LIST
|
|
ChunkDecodeContext
|
|
ChunkFilter
|
|
|
|
Author:
|
|
|
|
Oliver Wallace (oliverw) 13-Feb-2001
|
|
|
|
Revision History:
|
|
|
|
13-Feb-2001 oliverw
|
|
Created
|
|
|
|
--*/
|
|
|
|
// Base class meant for when additional filters will be available.
|
|
class BaseFilter
|
|
{
|
|
public:
|
|
virtual HRESULT Reset(DWORD_PTR dwContext)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT
|
|
Decode(
|
|
IN DWORD_PTR dwContext,
|
|
IN OUT LPBYTE pInBuffer,
|
|
IN DWORD dwInBufSize,
|
|
IN OUT LPBYTE *ppOutBuffer,
|
|
IN OUT LPDWORD pdwOutBufSize,
|
|
OUT LPDWORD pdwBytesRead,
|
|
OUT LPDWORD pdwBytesWritten
|
|
)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT
|
|
Encode(
|
|
DWORD_PTR dwContext,
|
|
IN OUT LPBYTE pInBuffer,
|
|
IN DWORD dwInBufSize,
|
|
IN OUT LPBYTE *ppOutBuffer,
|
|
IN OUT LPDWORD pdwOutBufSize,
|
|
OUT LPDWORD pdwBytesRead,
|
|
OUT LPDWORD pdwBytesWritten
|
|
)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT RegisterContext(OUT DWORD_PTR *pdwContext)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual HRESULT UnregisterContext(IN DWORD_PTR dwContext)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
virtual BOOL IsFinished(IN DWORD_PTR dwContext)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
typedef struct FILTER_LIST_ENTRY
|
|
{
|
|
DWORD_PTR dwContext; // Registered context associated with pFilter
|
|
BaseFilter *pFilter; // Data Filter used to encode/decode dwContext
|
|
FILTER_LIST_ENTRY *pNext;
|
|
}
|
|
FILTER_LIST_ENTRY, * LPFILTER_LIST_ENTRY;
|
|
|
|
|
|
class FILTER_LIST
|
|
{
|
|
|
|
/*++
|
|
|
|
Class Description:
|
|
|
|
The FILTER_LIST class defines the data filter list used to encode/decode
|
|
data when sending/receiving data.
|
|
|
|
Post v5, this will need some extensions:
|
|
- Make this a priority list to accommodate mroe flexible encoding order.
|
|
- Implement Encode method to process upload filters once support is added.
|
|
- Add smartness to Encode/Decode methods to buffer data.
|
|
|
|
--*/
|
|
public:
|
|
FILTER_LIST()
|
|
{
|
|
_pFilterEntry = NULL;
|
|
_uFilterCount = 0;
|
|
}
|
|
|
|
~FILTER_LIST()
|
|
{
|
|
ClearList();
|
|
}
|
|
|
|
// Always inserts as the beginning of the list
|
|
BOOL
|
|
Insert(IN BaseFilter *pFilter, IN DWORD_PTR dwContext);
|
|
|
|
VOID
|
|
ClearList();
|
|
|
|
DWORD
|
|
Decode(
|
|
IN OUT LPBYTE pInBuffer,
|
|
IN DWORD dwInBufSize,
|
|
IN OUT LPBYTE *ppOutBuffer,
|
|
IN OUT LPDWORD pdwOutBufSize,
|
|
OUT LPDWORD pdwBytesRead,
|
|
OUT LPDWORD pdwBytesWritten
|
|
);
|
|
|
|
// Right now, there should never be more than just the chunk filter.
|
|
BOOL IsFinished()
|
|
{
|
|
if (_pFilterEntry)
|
|
return _pFilterEntry->pFilter->IsFinished(_pFilterEntry->dwContext);
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
private:
|
|
LPFILTER_LIST_ENTRY _pFilterEntry;
|
|
UINT _uFilterCount;
|
|
};
|
|
|
|
|
|
// Chunk filter state table, data and object prototypes.
|
|
|
|
// Various token flags to describe the current byte being parsed.
|
|
//
|
|
// NOTE: Make sure you update the global table in chunkflt.cxx
|
|
// if this list is modified.
|
|
typedef enum
|
|
{
|
|
CHUNK_TOKEN_DIGIT = 0,
|
|
CHUNK_TOKEN_CR,
|
|
CHUNK_TOKEN_LF,
|
|
CHUNK_TOKEN_COLON,
|
|
CHUNK_TOKEN_DATA,
|
|
CHUNK_TOKEN_LAST = CHUNK_TOKEN_DATA
|
|
} CHUNK_TOKEN_VALUE;
|
|
|
|
// NOTE: Do NOT update this without updating the table in chunkflt.cxx
|
|
// which maps tokens for the current state to the next state.
|
|
typedef enum
|
|
{
|
|
CHUNK_DECODE_STATE_START = 0,
|
|
CHUNK_DECODE_STATE_SIZE,
|
|
CHUNK_DECODE_STATE_SIZE_CRLF,
|
|
CHUNK_DECODE_STATE_EXT,
|
|
CHUNK_DECODE_STATE_DATA,
|
|
CHUNK_DECODE_STATE_DATA_CRLF,
|
|
CHUNK_DECODE_STATE_FOOTER_NAME,
|
|
CHUNK_DECODE_STATE_FOOTER_VALUE,
|
|
CHUNK_DECODE_STATE_FINAL_CRLF,
|
|
CHUNK_DECODE_STATE_ERROR,
|
|
CHUNK_DECODE_STATE_FINISHED,
|
|
CHUNK_DECODE_STATE_LAST = CHUNK_DECODE_STATE_FINISHED
|
|
} CHUNK_DECODE_STATE, *LPCHUNK_DECODE_STATE;
|
|
|
|
class ChunkDecodeContext
|
|
{
|
|
private:
|
|
CHUNK_DECODE_STATE m_eDecodeState;
|
|
DWORD m_dwParsedSize;
|
|
|
|
friend class ChunkFilter;
|
|
|
|
public:
|
|
|
|
ChunkDecodeContext() { Reset(); }
|
|
|
|
// TODO: Consider subclassing contexts because they share common
|
|
// properties/methods that could be virtual (e.g. Get/SetState).
|
|
CHUNK_DECODE_STATE
|
|
GetState()
|
|
{
|
|
return m_eDecodeState;
|
|
}
|
|
|
|
VOID
|
|
SetState(CHUNK_DECODE_STATE eNewState)
|
|
{
|
|
m_eDecodeState = eNewState;
|
|
}
|
|
|
|
VOID Reset()
|
|
{
|
|
m_eDecodeState = CHUNK_DECODE_STATE_START;
|
|
m_dwParsedSize = 0;
|
|
}
|
|
};
|
|
|
|
class ChunkFilter : public BaseFilter
|
|
{
|
|
public:
|
|
// TODO: Provide an init method that is chunked-specific
|
|
// (e.g. set size for chunked uploads)
|
|
|
|
HRESULT Reset(DWORD_PTR dwContext);
|
|
|
|
HRESULT
|
|
Decode(
|
|
IN DWORD_PTR dwContext,
|
|
IN OUT LPBYTE pInBuffer,
|
|
IN DWORD dwInBufSize,
|
|
IN OUT LPBYTE *ppOutBuffer,
|
|
IN OUT LPDWORD pdwOutBufSize,
|
|
OUT LPDWORD pdwBytesRead,
|
|
OUT LPDWORD pdwBytesWritten
|
|
);
|
|
|
|
HRESULT
|
|
Encode(
|
|
IN DWORD_PTR dwContext,
|
|
IN OUT LPBYTE pInBuffer,
|
|
IN DWORD dwInBufSize,
|
|
OUT LPBYTE *ppOutBuffer,
|
|
OUT LPDWORD pdwOutBufSize,
|
|
OUT LPDWORD pdwBytesRead,
|
|
OUT LPDWORD pdwBytesWritten
|
|
);
|
|
|
|
HRESULT RegisterContext(OUT DWORD_PTR *pdwContext);
|
|
|
|
HRESULT UnregisterContext(IN DWORD_PTR dwContext);
|
|
|
|
BOOL
|
|
IsFinished(IN DWORD_PTR dwContext)
|
|
{
|
|
if (dwContext)
|
|
return ((reinterpret_cast<ChunkDecodeContext *>(dwContext))->GetState() ==
|
|
CHUNK_DECODE_STATE_FINISHED ? TRUE : FALSE);
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|