1/*
2 * Copyright 2022 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6#ifndef _B_HTTP_FIELDS_H_
7#define _B_HTTP_FIELDS_H_
8
9#include <list>
10#include <optional>
11#include <string_view>
12#include <variant>
13#include <vector>
14
15#include <ErrorsExt.h>
16#include <String.h>
17
18
19namespace BPrivate {
20
21namespace Network {
22
23
24class BHttpFields
25{
26public:
27		// Exceptions
28	class InvalidInput;
29
30	// Wrapper Types
31	class FieldName;
32	class Field;
33
34	// Type Aliases
35	using ConstIterator = std::list<Field>::const_iterator;
36
37	// Constructors & Destructor
38								BHttpFields();
39								BHttpFields(std::initializer_list<Field> fields);
40								BHttpFields(const BHttpFields& other);
41								BHttpFields(BHttpFields&& other);
42								~BHttpFields() noexcept;
43
44	// Assignment operators
45			BHttpFields&		operator=(const BHttpFields&);
46			BHttpFields&		operator=(BHttpFields&&) noexcept;
47
48	// Access list
49			const Field&		operator[](size_t index) const;
50
51	// Modifiers
52			void				AddField(const std::string_view& name,
53									const std::string_view& value);
54			void				AddField(BString& field);
55			void				AddFields(std::initializer_list<Field> fields);
56			void				RemoveField(const std::string_view& name) noexcept;
57			void				RemoveField(ConstIterator it) noexcept;
58			void				MakeEmpty() noexcept;
59
60	// Querying
61			ConstIterator		FindField(const std::string_view& name) const noexcept;
62			size_t				CountFields() const noexcept;
63			size_t				CountFields(const std::string_view& name) const noexcept;
64
65	// Range-based iteration
66			ConstIterator		begin() const noexcept;
67			ConstIterator		end() const noexcept;
68
69private:
70			std::list<Field>	fFields;
71};
72
73
74class BHttpFields::InvalidInput : public BError
75{
76public:
77								InvalidInput(const char* origin, BString input);
78
79	virtual	const char*			Message() const noexcept override;
80	virtual	BString				DebugMessage() const override;
81
82			BString				input;
83};
84
85
86class BHttpFields::FieldName
87{
88public:
89	// Comparison
90			bool				operator==(const BString& other) const noexcept;
91			bool				operator==(const std::string_view& other) const noexcept;
92			bool				operator==(const FieldName& other) const noexcept;
93
94	// Conversion
95	operator					std::string_view() const;
96
97private:
98	friend class BHttpFields;
99
100								FieldName() noexcept;
101								FieldName(const std::string_view& name) noexcept;
102								FieldName(const FieldName& other) noexcept;
103								FieldName(FieldName&&) noexcept;
104			FieldName&			operator=(const FieldName& other) noexcept;
105			FieldName&			operator=(FieldName&&) noexcept;
106
107			std::string_view	fName;
108};
109
110
111class BHttpFields::Field
112{
113public:
114	// Constructors
115								Field() noexcept;
116								Field(const std::string_view& name, const std::string_view& value);
117								Field(BString& field);
118								Field(const Field& other);
119								Field(Field&&) noexcept;
120
121	// Assignment
122			Field&				operator=(const Field& other);
123			Field&				operator=(Field&& other) noexcept;
124
125	// Access Operators
126			const FieldName&	Name() const noexcept;
127			std::string_view	Value() const noexcept;
128			std::string_view	RawField() const noexcept;
129			bool				IsEmpty() const noexcept;
130
131private:
132	friend class BHttpFields;
133
134								Field(BString&& rawField);
135
136			std::optional<BString> fRawField;
137
138			FieldName			fName;
139			std::string_view	fValue;
140};
141
142
143} // namespace Network
144
145} // namespace BPrivate
146
147#endif // _B_HTTP_FIELDS_H_
148