HttpForm.h revision b4665f9a
1/*
2 * Copyright 2010-2013 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _B_HTTP_FORM_H_
6#define _B_HTTP_FORM_H_
7
8
9#include <Path.h>
10#include <String.h>
11
12#include <map>
13
14
15enum form_type {
16	B_HTTP_FORM_URL_ENCODED,
17	B_HTTP_FORM_MULTIPART
18};
19
20
21enum form_content_type {
22	B_HTTPFORM_UNKNOWN,
23	B_HTTPFORM_STRING,
24	B_HTTPFORM_FILE,
25	B_HTTPFORM_BUFFER
26};
27
28
29class BHttpFormData {
30private:
31	// Empty constructor is only kept for compatibility with map<>::operator[],
32	// but never used (see BHttpForm::operator[] which does the necessary
33	// check up)
34								BHttpFormData();
35#if __GNUC__ >= 6
36	friend class std::pair<const BString, BHttpFormData>;
37#else
38	friend class std::map<BString, BHttpFormData>;
39#endif
40
41public:
42								BHttpFormData(const BString& name,
43									const BString& value);
44								BHttpFormData(const BString& name,
45									const BPath& file);
46								BHttpFormData(const BString& name,
47									const void* buffer, ssize_t size);
48								BHttpFormData(const BHttpFormData& other);
49								~BHttpFormData();
50
51	// Retrieve data informations
52			bool				InitCheck() const;
53
54			const BString&		Name() const;
55			const BString&		String() const;
56			const BPath&		File() const;
57			const void*			Buffer() const;
58			ssize_t				BufferSize() const;
59
60			bool				IsFile() const;
61			const BString&		Filename() const;
62			const BString&		MimeType() const;
63			form_content_type	Type() const;
64
65	// Change behavior
66			status_t			MarkAsFile(const BString& filename,
67									const BString& mimeType = "");
68			void				UnmarkAsFile();
69			status_t			CopyBuffer();
70
71	// Overloaded operators
72			BHttpFormData&		operator=(const BHttpFormData& other);
73
74private:
75			form_content_type	fDataType;
76			bool				fCopiedBuffer;
77			bool				fFileMark;
78
79			BString				fName;
80			BString				fStringValue;
81			BPath				fPathValue;
82			const void*			fBufferValue;
83			ssize_t				fBufferSize;
84
85			BString				fFilename;
86			BString				fMimeType;
87};
88
89
90class BHttpForm {
91public:
92	// Nested types
93	class Iterator;
94	typedef std::map<BString, BHttpFormData> FormStorage;
95
96public:
97								BHttpForm();
98								BHttpForm(const BHttpForm& other);
99								BHttpForm(const BString& formString);
100								~BHttpForm();
101
102	// Form string parsing
103			void				ParseString(const BString& formString);
104			BString				RawData() const;
105
106	// Form add
107			status_t			AddString(const BString& name,
108									const BString& value);
109			status_t			AddInt(const BString& name, int32 value);
110			status_t			AddFile(const BString& fieldName,
111									const BPath& file);
112			status_t			AddBuffer(const BString& fieldName,
113									const void* buffer, ssize_t size);
114			status_t			AddBufferCopy(const BString& fieldName,
115									const void* buffer, ssize_t size);
116
117	// Mark a field as a filename
118			void				MarkAsFile(const BString& fieldName,
119									const BString& filename,
120									const BString& mimeType);
121			void				MarkAsFile(const BString& fieldName,
122									const BString& filename);
123			void				UnmarkAsFile(const BString& fieldName);
124
125	// Change form type
126			void				SetFormType(form_type type);
127
128	// Form test
129			bool				HasField(const BString& name) const;
130
131	// Form retrieve
132			BString				GetMultipartHeader(const BString& fieldName) const;
133			form_content_type	GetType(const BString& fieldname) const;
134
135	// Form informations
136			form_type			GetFormType() const;
137			const BString&		GetMultipartBoundary() const;
138			BString				GetMultipartFooter() const;
139			ssize_t				ContentLength() const;
140
141	// Form iterator
142			Iterator			GetIterator();
143
144	// Form clear
145			void				Clear();
146
147	// Overloaded operators
148			BHttpFormData&		operator[](const BString& name);
149
150private:
151			void				_ExtractNameValuePair(const BString& string, int32* index);
152			void				_GenerateMultipartBoundary();
153			BString				_GetMultipartHeader(const BHttpFormData* element) const;
154			form_content_type	_GetType(FormStorage::const_iterator it) const;
155			void				_Erase(FormStorage::iterator it);
156
157private:
158	friend	class Iterator;
159
160			FormStorage			fFields;
161			form_type			fType;
162			BString				fMultipartBoundary;
163};
164
165
166class BHttpForm::Iterator {
167public:
168								Iterator(const Iterator& other);
169
170			BHttpFormData*		Next();
171			bool 				HasNext() const;
172			void				Remove();
173			BString				MultipartHeader();
174
175			Iterator& 			operator=(const Iterator& other);
176
177private:
178								Iterator(BHttpForm* form);
179			void				_FindNext();
180
181private:
182	friend	class BHttpForm;
183
184			BHttpForm*			fForm;
185			BHttpForm::FormStorage::iterator
186								fStdIterator;
187			BHttpFormData*		fElement;
188			BHttpFormData*		fPrevElement;
189};
190
191#endif // _B_HTTP_FORM_H_
192