rcpp_framework/core/http_message_body.h

159 lines
3.3 KiB
C++

/**
*
* HttpMessageBody.h
* An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* Drogon
*
*/
#pragma once
#include "core/string_view.h"
#include <string>
namespace drogon
{
class HttpMessageBody
{
public:
enum class BodyType
{
kNone = 0,
kString,
kStringView
};
BodyType bodyType()
{
return type_;
}
virtual const char *data() const
{
return nullptr;
}
virtual char *data()
{
return nullptr;
}
virtual size_t length() const
{
return 0;
}
virtual const std::string &getString() const = 0;
virtual std::string &getString() = 0;
virtual void append(const char *buf, size_t len)
{
}
virtual ~HttpMessageBody()
{
}
protected:
BodyType type_{BodyType::kNone};
};
class HttpMessageStringBody : public HttpMessageBody
{
public:
HttpMessageStringBody()
{
type_ = BodyType::kString;
}
HttpMessageStringBody(const std::string &body) : body_(body)
{
type_ = BodyType::kString;
}
HttpMessageStringBody(std::string &&body) : body_(std::move(body))
{
type_ = BodyType::kString;
}
virtual const char *data() const override
{
return body_.data();
}
virtual char *data() override
{
return const_cast<char *>(body_.data());
}
virtual size_t length() const override
{
return body_.length();
}
virtual const std::string &getString() const override
{
return body_;
}
virtual std::string &getString() override
{
return body_;
}
virtual void append(const char *buf, size_t len) override
{
body_.append(buf, len);
}
private:
std::string body_;
};
class HttpMessageStringViewBody : public HttpMessageBody
{
public:
HttpMessageStringViewBody(const char *buf, size_t len) : body_(buf, len)
{
type_ = BodyType::kStringView;
}
virtual const char *data() const override
{
return body_.data();
}
virtual char *data() override
{
return const_cast<char *>(body_.data());
}
virtual size_t length() const override
{
return body_.length();
}
virtual const std::string &getString() const override
{
if (!bodyString_)
{
if (!body_.empty())
{
bodyString_ =
std::make_unique<std::string>(body_.data(), body_.length());
}
else
{
bodyString_ = std::make_unique<std::string>();
}
}
return *bodyString_;
}
virtual std::string &getString() override
{
if (!bodyString_)
{
if (!body_.empty())
{
bodyString_ =
std::make_unique<std::string>(body_.data(), body_.length());
}
else
{
bodyString_ = std::make_unique<std::string>();
}
}
return *bodyString_;
}
private:
string_view body_;
mutable std::unique_ptr<std::string> bodyString_;
};
} // namespace drogon