8ccf8fb44d
This change also drops the principle that fields with the same keys would be grouped together. This was initially inspired by Boost::Beast, but it means a lot of extra copying of data when adding/organizing the list, as well as inefficient querying on each add. Now that the design choice is to fully go for the raw string as underlying data storage, that choice is not necessary. In the future it may be able to emulate the grouping or retrieving of lists of values in the API, rather than as a fundamental principle of the data storage. Change-Id: I2667cfa38eb3b7b75393ee71fb038231a40b4193
134 lines
3.2 KiB
C++
Executable File
134 lines
3.2 KiB
C++
Executable File
/*
|
|
* Copyright 2022 Haiku Inc. All rights reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
|
|
#ifndef _B_HTTP_FIELDS_H_
|
|
#define _B_HTTP_FIELDS_H_
|
|
|
|
#include <list>
|
|
#include <optional>
|
|
#include <string_view>
|
|
#include <variant>
|
|
#include <vector>
|
|
|
|
#include <ErrorsExt.h>
|
|
#include <String.h>
|
|
|
|
|
|
namespace BPrivate {
|
|
|
|
namespace Network {
|
|
|
|
|
|
class BHttpFields {
|
|
public:
|
|
// Exceptions
|
|
class InvalidInput : public BError {
|
|
public:
|
|
InvalidInput(const char* origin, BString input);
|
|
|
|
virtual const char* Message() const noexcept override;
|
|
virtual BString DebugMessage() const override;
|
|
|
|
BString input;
|
|
};
|
|
|
|
// Wrapper Types
|
|
class FieldName {
|
|
public:
|
|
// Comparison
|
|
bool operator==(const BString& other) const noexcept;
|
|
bool operator==(const std::string_view& other) const noexcept;
|
|
bool operator==(const FieldName& other) const noexcept;
|
|
|
|
// Conversion
|
|
operator std::string_view() const;
|
|
private:
|
|
friend class BHttpFields;
|
|
FieldName() noexcept;
|
|
FieldName(const std::string_view& name) noexcept;
|
|
FieldName(const FieldName& other) noexcept;
|
|
FieldName(FieldName&&) noexcept;
|
|
FieldName& operator=(const FieldName& other) noexcept;
|
|
FieldName& operator=(FieldName&&) noexcept;
|
|
|
|
std::string_view fName;
|
|
};
|
|
|
|
class Field {
|
|
public:
|
|
// Constructors
|
|
Field() noexcept;
|
|
Field(const std::string_view& name, const std::string_view& value);
|
|
Field(BString& field);
|
|
Field(const Field& other);
|
|
Field(Field&&) noexcept;
|
|
|
|
// Assignment
|
|
Field& operator=(const Field& other);
|
|
Field& operator=(Field&& other) noexcept;
|
|
|
|
// Access Operators
|
|
const FieldName& Name() const noexcept;
|
|
std::string_view Value() const noexcept;
|
|
std::string_view RawField() const noexcept;
|
|
bool IsEmpty() const noexcept;
|
|
|
|
private:
|
|
friend class BHttpFields;
|
|
|
|
Field(BString&& rawField);
|
|
|
|
std::optional<BString> fRawField;
|
|
|
|
FieldName fName;
|
|
std::string_view fValue;
|
|
};
|
|
|
|
// Type Aliases
|
|
using ConstIterator = std::list<Field>::const_iterator;
|
|
|
|
// Constructors & Destructor
|
|
BHttpFields();
|
|
BHttpFields(std::initializer_list<Field> fields);
|
|
BHttpFields(const BHttpFields& other);
|
|
BHttpFields(BHttpFields&& other);
|
|
~BHttpFields() noexcept;
|
|
|
|
// Assignment operators
|
|
BHttpFields& operator=(const BHttpFields&);
|
|
BHttpFields& operator=(BHttpFields&&) noexcept;
|
|
|
|
// Access list
|
|
const Field& operator[](size_t index) const;
|
|
|
|
// Modifiers
|
|
void AddField(const std::string_view& name,
|
|
const std::string_view& value);
|
|
void AddField(BString& field);
|
|
void AddFields(std::initializer_list<Field> fields);
|
|
void RemoveField(const std::string_view& name) noexcept;
|
|
void RemoveField(ConstIterator it) noexcept;
|
|
void MakeEmpty() noexcept;
|
|
|
|
// Querying
|
|
ConstIterator FindField(const std::string_view& name) const noexcept;
|
|
size_t CountFields() const noexcept;
|
|
|
|
// Range-based iteration
|
|
ConstIterator begin() const noexcept;
|
|
ConstIterator end() const noexcept;
|
|
|
|
private:
|
|
std::list<Field> fFields;
|
|
};
|
|
|
|
|
|
} // namespace Network
|
|
|
|
} // namespace BPrivate
|
|
|
|
#endif // _B_HTTP_FIELDS_H_
|
|
|