1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/*****************************************************************************/
/* Mime.h Copyright (c) Ladislav Zezula 2021 */
/*---------------------------------------------------------------------------*/
/* MIME parsing functions for CascLib */
/*---------------------------------------------------------------------------*/
/* Date Ver Who Comment */
/* -------- ---- --- ------- */
/* 21.01.21 1.00 Lad Created */
/*****************************************************************************/
#ifndef __MIME_H__
#define __MIME_H__
//-----------------------------------------------------------------------------
// MIME constants
#define MAX_LENGTH_BOUNDARY 128
enum CASC_MIME_ENCODING
{
MimeEncodingTextPlain,
MimeEncodingBase64,
MimeEncodingQuotedPrintable,
MimeEncodingMax
};
//-----------------------------------------------------------------------------
// Structure for caching parsed HTTP response information
struct CASC_MIME_HTTP
{
CASC_MIME_HTTP()
{
response_valid = content_length = content_offset = total_length = 0;
}
bool IsDataComplete(const char * response, size_t response_length);
size_t response_valid; // Nonzero if this is an already parsed HTTP response
size_t content_length; // Parsed value of "Content-Length"
size_t content_offset; // Offset of the HTTP data, relative to the begin of the response
size_t total_length; // Expected total length of the HTTP response (content_offset + content_size)
};
//-----------------------------------------------------------------------------
// MIME blob class
struct CASC_MIME_BLOB
{
CASC_MIME_BLOB(char * mime_ptr, char * mime_end);
~CASC_MIME_BLOB();
char * GetNextLine();
char * ptr;
char * end;
};
//-----------------------------------------------------------------------------
// MIME class
class CASC_MIME_ELEMENT
{
public:
CASC_MIME_ELEMENT();
~CASC_MIME_ELEMENT();
unsigned char * GiveAway(size_t * ptr_data_length);
DWORD Load(char * mime_data_begin, char * mime_data_end, const char * boundary_ptr = NULL);
CASC_MIME_ELEMENT * GetChild() { return folder.pChild; }
#ifdef _DEBUG
void Print(size_t nLevel, size_t nIndex);
#endif
protected:
CASC_MIME_ELEMENT * AllocateAndLoadElement(char * a_mime_data, char * a_mime_data_end, const char * boundary_begin);
bool ExtractEncoding(const char * line, CASC_MIME_ENCODING & Encoding);
bool ExtractBoundary(const char * line);
DWORD DecodeTextPlain(char * content_begin, char * content_end, unsigned char * data_ptr, size_t * ptr_length);
DWORD DecodeQuotedPrintable(char * content_begin, char * content_end, unsigned char * data_ptr, size_t * ptr_length);
DWORD DecodeBase64(char * content_begin, char * content_end, unsigned char * data_ptr, size_t * ptr_length);
struct
{
CASC_MIME_ELEMENT * pChild; // Pointer to the first child
CASC_MIME_ELEMENT * pNext; // Pointer to the next-in-folder element
} folder;
struct
{
unsigned char * begin;
size_t length;
} data;
char boundary[MAX_LENGTH_BOUNDARY];
};
class CASC_MIME
{
public:
CASC_MIME();
~CASC_MIME();
unsigned char * GiveAway(size_t * ptr_data_length);
DWORD Load(char * data, size_t length);
DWORD Load(LPCTSTR fileName);
#ifdef _DEBUG
void Print();
#endif
protected:
CASC_MIME_ELEMENT root;
};
//-----------------------------------------------------------------------------
// HTTP helpers
bool IsHttpResponseComplete(CASC_MIME_HTTP & HttpInfo, const char * response, size_t response_length);
#endif // __MIME_H__
|