mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2024-11-14 04:57:21 +01:00
192 lines
4.9 KiB
C++
192 lines
4.9 KiB
C++
/**
|
|
*
|
|
* HttpViewData.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 <core/any.h>
|
|
#include <trantor/utils/Logger.h>
|
|
#include <trantor/utils/MsgBuffer.h>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
|
|
namespace drogon
|
|
{
|
|
/// This class represents the data set displayed in views.
|
|
class HttpViewData
|
|
{
|
|
public:
|
|
/// The function template is used to get an item in the data set by the key
|
|
/// parameter.
|
|
template <typename T>
|
|
const T &get(const std::string &key) const
|
|
{
|
|
const static T nullVal = T();
|
|
auto it = viewData_.find(key);
|
|
if (it != viewData_.end())
|
|
{
|
|
if (typeid(T) == it->second.type())
|
|
{
|
|
return *(any_cast<T>(&(it->second)));
|
|
}
|
|
else
|
|
{
|
|
LOG_ERROR << "Bad type";
|
|
}
|
|
}
|
|
return nullVal;
|
|
}
|
|
|
|
/// Insert an item identified by the key parameter into the data set;
|
|
void insert(const std::string &key, any &&obj)
|
|
{
|
|
viewData_[key] = std::move(obj);
|
|
}
|
|
void insert(const std::string &key, const any &obj)
|
|
{
|
|
viewData_[key] = obj;
|
|
}
|
|
|
|
/// Insert an item identified by the key parameter into the data set; The
|
|
/// item is converted to a string.
|
|
template <typename T>
|
|
void insertAsString(const std::string &key, T &&val)
|
|
{
|
|
std::stringstream ss;
|
|
ss << val;
|
|
viewData_[key] = ss.str();
|
|
}
|
|
|
|
/// Insert a formated string identified by the key parameter.
|
|
void insertFormattedString(const std::string &key, const char *format, ...)
|
|
{
|
|
std::string strBuffer;
|
|
strBuffer.resize(128);
|
|
va_list ap, backup_ap;
|
|
va_start(ap, format);
|
|
va_copy(backup_ap, ap);
|
|
auto result = vsnprintf((char *)strBuffer.data(),
|
|
strBuffer.size(),
|
|
format,
|
|
backup_ap);
|
|
va_end(backup_ap);
|
|
if ((result >= 0) &&
|
|
((std::string::size_type)result < strBuffer.size()))
|
|
{
|
|
strBuffer.resize(result);
|
|
}
|
|
else
|
|
{
|
|
while (true)
|
|
{
|
|
if (result < 0)
|
|
{
|
|
// Older snprintf() behavior. Just try doubling the buffer
|
|
// size
|
|
strBuffer.resize(strBuffer.size() * 2);
|
|
}
|
|
else
|
|
{
|
|
strBuffer.resize(result + 1);
|
|
}
|
|
|
|
va_copy(backup_ap, ap);
|
|
auto result = vsnprintf((char *)strBuffer.data(),
|
|
strBuffer.size(),
|
|
format,
|
|
backup_ap);
|
|
va_end(backup_ap);
|
|
|
|
if ((result >= 0) &&
|
|
((std::string::size_type)result < strBuffer.size()))
|
|
{
|
|
strBuffer.resize(result);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
va_end(ap);
|
|
viewData_[key] = std::move(strBuffer);
|
|
}
|
|
|
|
/// Get the 'any' object by the key parameter.
|
|
any &operator[](const std::string &key) const
|
|
{
|
|
return viewData_[key];
|
|
}
|
|
|
|
/// Translate some special characters to HTML format
|
|
/**
|
|
* such as:
|
|
* @code
|
|
" --> "
|
|
& --> &
|
|
< --> <
|
|
> --> >
|
|
@endcode
|
|
*/
|
|
static std::string htmlTranslate(const char *str, size_t length);
|
|
static std::string htmlTranslate(const std::string &str)
|
|
{
|
|
return htmlTranslate(str.data(), str.length());
|
|
}
|
|
static std::string htmlTranslate(const string_view &str)
|
|
{
|
|
return htmlTranslate(str.data(), str.length());
|
|
}
|
|
static bool needTranslation(const std::string &str)
|
|
{
|
|
for (auto const &c : str)
|
|
{
|
|
switch (c)
|
|
{
|
|
case '"':
|
|
case '&':
|
|
case '<':
|
|
case '>':
|
|
return true;
|
|
default:
|
|
continue;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
static bool needTranslation(const string_view &str)
|
|
{
|
|
for (auto const &c : str)
|
|
{
|
|
switch (c)
|
|
{
|
|
case '"':
|
|
case '&':
|
|
case '<':
|
|
case '>':
|
|
return true;
|
|
default:
|
|
continue;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected:
|
|
using ViewDataMap = std::unordered_map<std::string, any>;
|
|
mutable ViewDataMap viewData_;
|
|
};
|
|
|
|
} // namespace drogon
|