From 846ee2c850dbb7c17a65a127ceb96b644682321e Mon Sep 17 00:00:00 2001 From: Alisamar Husain Date: Thu, 27 Apr 2023 17:14:18 +0530 Subject: [PATCH] Fix editorconfig --- examples/server/crow.h | 17002 +++++++++++++++++------------------ examples/server/server.cpp | 844 +- 2 files changed, 8923 insertions(+), 8923 deletions(-) diff --git a/examples/server/crow.h b/examples/server/crow.h index 3cff9fad9..74fefaee3 100644 --- a/examples/server/crow.h +++ b/examples/server/crow.h @@ -1,7 +1,7 @@ /*BSD 3-Clause License Copyright (c) 2014-2017, ipkn - 2020-2022, CrowCpp + 2020-2022, CrowCpp All rights reserved. Redistribution and use in source and binary forms, with or without @@ -49,13 +49,13 @@ The Crow logo and other graphic material (excluding third party logos) used are /* #define - specifies log level */ /* - Debug = 0 - Info = 1 - Warning = 2 - Error = 3 - Critical = 4 + Debug = 0 + Info = 1 + Warning = 2 + Error = 3 + Critical = 4 - default to INFO + default to INFO */ #ifndef CROW_LOG_LEVEL #define CROW_LOG_LEVEL 1 @@ -105,117 +105,117 @@ The Crow logo and other graphic material (excluding third party logos) used are namespace crow { - const std::unordered_map mime_types{ - {"shtml", "text/html"}, - {"htm", "text/html"}, - {"html", "text/html"}, - {"css", "text/css"}, - {"xml", "text/xml"}, - {"gif", "image/gif"}, - {"jpg", "image/jpeg"}, - {"jpeg", "image/jpeg"}, - {"js", "application/javascript"}, - {"atom", "application/atom+xml"}, - {"rss", "application/rss+xml"}, - {"mml", "text/mathml"}, - {"txt", "text/plain"}, - {"jad", "text/vnd.sun.j2me.app-descriptor"}, - {"wml", "text/vnd.wap.wml"}, - {"htc", "text/x-component"}, - {"avif", "image/avif"}, - {"png", "image/png"}, - {"svgz", "image/svg+xml"}, - {"svg", "image/svg+xml"}, - {"tiff", "image/tiff"}, - {"tif", "image/tiff"}, - {"wbmp", "image/vnd.wap.wbmp"}, - {"webp", "image/webp"}, - {"ico", "image/x-icon"}, - {"jng", "image/x-jng"}, - {"bmp", "image/x-ms-bmp"}, - {"woff", "font/woff"}, - {"woff2", "font/woff2"}, - {"ear", "application/java-archive"}, - {"war", "application/java-archive"}, - {"jar", "application/java-archive"}, - {"json", "application/json"}, - {"hqx", "application/mac-binhex40"}, - {"doc", "application/msword"}, - {"pdf", "application/pdf"}, - {"ai", "application/postscript"}, - {"eps", "application/postscript"}, - {"ps", "application/postscript"}, - {"rtf", "application/rtf"}, - {"m3u8", "application/vnd.apple.mpegurl"}, - {"kml", "application/vnd.google-earth.kml+xml"}, - {"kmz", "application/vnd.google-earth.kmz"}, - {"xls", "application/vnd.ms-excel"}, - {"eot", "application/vnd.ms-fontobject"}, - {"ppt", "application/vnd.ms-powerpoint"}, - {"odg", "application/vnd.oasis.opendocument.graphics"}, - {"odp", "application/vnd.oasis.opendocument.presentation"}, - {"ods", "application/vnd.oasis.opendocument.spreadsheet"}, - {"odt", "application/vnd.oasis.opendocument.text"}, - {"pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"}, - {"xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}, - {"docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, - {"wmlc", "application/vnd.wap.wmlc"}, - {"wasm", "application/wasm"}, - {"7z", "application/x-7z-compressed"}, - {"cco", "application/x-cocoa"}, - {"jardiff", "application/x-java-archive-diff"}, - {"jnlp", "application/x-java-jnlp-file"}, - {"run", "application/x-makeself"}, - {"pm", "application/x-perl"}, - {"pl", "application/x-perl"}, - {"pdb", "application/x-pilot"}, - {"prc", "application/x-pilot"}, - {"rar", "application/x-rar-compressed"}, - {"rpm", "application/x-redhat-package-manager"}, - {"sea", "application/x-sea"}, - {"swf", "application/x-shockwave-flash"}, - {"sit", "application/x-stuffit"}, - {"tk", "application/x-tcl"}, - {"tcl", "application/x-tcl"}, - {"crt", "application/x-x509-ca-cert"}, - {"pem", "application/x-x509-ca-cert"}, - {"der", "application/x-x509-ca-cert"}, - {"xpi", "application/x-xpinstall"}, - {"xhtml", "application/xhtml+xml"}, - {"xspf", "application/xspf+xml"}, - {"zip", "application/zip"}, - {"dll", "application/octet-stream"}, - {"exe", "application/octet-stream"}, - {"bin", "application/octet-stream"}, - {"deb", "application/octet-stream"}, - {"dmg", "application/octet-stream"}, - {"img", "application/octet-stream"}, - {"iso", "application/octet-stream"}, - {"msm", "application/octet-stream"}, - {"msp", "application/octet-stream"}, - {"msi", "application/octet-stream"}, - {"kar", "audio/midi"}, - {"midi", "audio/midi"}, - {"mid", "audio/midi"}, - {"mp3", "audio/mpeg"}, - {"ogg", "audio/ogg"}, - {"m4a", "audio/x-m4a"}, - {"ra", "audio/x-realaudio"}, - {"3gp", "video/3gpp"}, - {"3gpp", "video/3gpp"}, - {"ts", "video/mp2t"}, - {"mp4", "video/mp4"}, - {"mpg", "video/mpeg"}, - {"mpeg", "video/mpeg"}, - {"mov", "video/quicktime"}, - {"webm", "video/webm"}, - {"flv", "video/x-flv"}, - {"m4v", "video/x-m4v"}, - {"mng", "video/x-mng"}, - {"asf", "video/x-ms-asf"}, - {"asx", "video/x-ms-asf"}, - {"wmv", "video/x-ms-wmv"}, - {"avi", "video/x-msvideo"}}; + const std::unordered_map mime_types{ + {"shtml", "text/html"}, + {"htm", "text/html"}, + {"html", "text/html"}, + {"css", "text/css"}, + {"xml", "text/xml"}, + {"gif", "image/gif"}, + {"jpg", "image/jpeg"}, + {"jpeg", "image/jpeg"}, + {"js", "application/javascript"}, + {"atom", "application/atom+xml"}, + {"rss", "application/rss+xml"}, + {"mml", "text/mathml"}, + {"txt", "text/plain"}, + {"jad", "text/vnd.sun.j2me.app-descriptor"}, + {"wml", "text/vnd.wap.wml"}, + {"htc", "text/x-component"}, + {"avif", "image/avif"}, + {"png", "image/png"}, + {"svgz", "image/svg+xml"}, + {"svg", "image/svg+xml"}, + {"tiff", "image/tiff"}, + {"tif", "image/tiff"}, + {"wbmp", "image/vnd.wap.wbmp"}, + {"webp", "image/webp"}, + {"ico", "image/x-icon"}, + {"jng", "image/x-jng"}, + {"bmp", "image/x-ms-bmp"}, + {"woff", "font/woff"}, + {"woff2", "font/woff2"}, + {"ear", "application/java-archive"}, + {"war", "application/java-archive"}, + {"jar", "application/java-archive"}, + {"json", "application/json"}, + {"hqx", "application/mac-binhex40"}, + {"doc", "application/msword"}, + {"pdf", "application/pdf"}, + {"ai", "application/postscript"}, + {"eps", "application/postscript"}, + {"ps", "application/postscript"}, + {"rtf", "application/rtf"}, + {"m3u8", "application/vnd.apple.mpegurl"}, + {"kml", "application/vnd.google-earth.kml+xml"}, + {"kmz", "application/vnd.google-earth.kmz"}, + {"xls", "application/vnd.ms-excel"}, + {"eot", "application/vnd.ms-fontobject"}, + {"ppt", "application/vnd.ms-powerpoint"}, + {"odg", "application/vnd.oasis.opendocument.graphics"}, + {"odp", "application/vnd.oasis.opendocument.presentation"}, + {"ods", "application/vnd.oasis.opendocument.spreadsheet"}, + {"odt", "application/vnd.oasis.opendocument.text"}, + {"pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"}, + {"xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}, + {"docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, + {"wmlc", "application/vnd.wap.wmlc"}, + {"wasm", "application/wasm"}, + {"7z", "application/x-7z-compressed"}, + {"cco", "application/x-cocoa"}, + {"jardiff", "application/x-java-archive-diff"}, + {"jnlp", "application/x-java-jnlp-file"}, + {"run", "application/x-makeself"}, + {"pm", "application/x-perl"}, + {"pl", "application/x-perl"}, + {"pdb", "application/x-pilot"}, + {"prc", "application/x-pilot"}, + {"rar", "application/x-rar-compressed"}, + {"rpm", "application/x-redhat-package-manager"}, + {"sea", "application/x-sea"}, + {"swf", "application/x-shockwave-flash"}, + {"sit", "application/x-stuffit"}, + {"tk", "application/x-tcl"}, + {"tcl", "application/x-tcl"}, + {"crt", "application/x-x509-ca-cert"}, + {"pem", "application/x-x509-ca-cert"}, + {"der", "application/x-x509-ca-cert"}, + {"xpi", "application/x-xpinstall"}, + {"xhtml", "application/xhtml+xml"}, + {"xspf", "application/xspf+xml"}, + {"zip", "application/zip"}, + {"dll", "application/octet-stream"}, + {"exe", "application/octet-stream"}, + {"bin", "application/octet-stream"}, + {"deb", "application/octet-stream"}, + {"dmg", "application/octet-stream"}, + {"img", "application/octet-stream"}, + {"iso", "application/octet-stream"}, + {"msm", "application/octet-stream"}, + {"msp", "application/octet-stream"}, + {"msi", "application/octet-stream"}, + {"kar", "audio/midi"}, + {"midi", "audio/midi"}, + {"mid", "audio/midi"}, + {"mp3", "audio/mpeg"}, + {"ogg", "audio/ogg"}, + {"m4a", "audio/x-m4a"}, + {"ra", "audio/x-realaudio"}, + {"3gp", "video/3gpp"}, + {"3gpp", "video/3gpp"}, + {"ts", "video/mp2t"}, + {"mp4", "video/mp4"}, + {"mpg", "video/mpeg"}, + {"mpeg", "video/mpeg"}, + {"mov", "video/quicktime"}, + {"webm", "video/webm"}, + {"flv", "video/x-flv"}, + {"m4v", "video/x-m4v"}, + {"mng", "video/x-mng"}, + {"asf", "video/x-ms-asf"}, + {"asx", "video/x-ms-asf"}, + {"wmv", "video/x-ms-wmv"}, + {"avi", "video/x-msvideo"}}; } #pragma once @@ -226,33 +226,33 @@ namespace crow namespace crow { - /// Hashing function for ci_map (unordered_multimap). - struct ci_hash - { - size_t operator()(const std::string &key) const - { - std::size_t seed = 0; - std::locale locale; + /// Hashing function for ci_map (unordered_multimap). + struct ci_hash + { + size_t operator()(const std::string &key) const + { + std::size_t seed = 0; + std::locale locale; - for (auto c : key) - { - boost::hash_combine(seed, std::toupper(c, locale)); - } + for (auto c : key) + { + boost::hash_combine(seed, std::toupper(c, locale)); + } - return seed; - } - }; + return seed; + } + }; - /// Equals function for ci_map (unordered_multimap). - struct ci_key_eq - { - bool operator()(const std::string &l, const std::string &r) const - { - return boost::iequals(l, r); - } - }; + /// Equals function for ci_map (unordered_multimap). + struct ci_key_eq + { + bool operator()(const std::string &l, const std::string &r) const + { + return boost::iequals(l, r); + } + }; - using ci_map = std::unordered_multimap; + using ci_map = std::unordered_multimap; } // namespace crow #pragma once @@ -261,18 +261,18 @@ namespace crow namespace crow { - /// An abstract class that allows any other class to be returned by a handler. - struct returnable - { - std::string content_type; - virtual std::string dump() const = 0; + /// An abstract class that allows any other class to be returned by a handler. + struct returnable + { + std::string content_type; + virtual std::string dump() const = 0; - returnable(std::string ctype) : content_type{ctype} - { - } + returnable(std::string ctype) : content_type{ctype} + { + } - virtual ~returnable(){}; - }; + virtual ~returnable(){}; + }; } // namespace crow #pragma once @@ -286,162 +286,162 @@ namespace crow namespace crow { - enum class LogLevel - { + enum class LogLevel + { #ifndef ERROR #ifndef DEBUG - DEBUG = 0, - INFO, - WARNING, - ERROR, - CRITICAL, + DEBUG = 0, + INFO, + WARNING, + ERROR, + CRITICAL, #endif #endif - Debug = 0, - Info, - Warning, - Error, - Critical, - }; + Debug = 0, + Info, + Warning, + Error, + Critical, + }; - class ILogHandler - { - public: - virtual void log(std::string message, LogLevel level) = 0; - }; + class ILogHandler + { + public: + virtual void log(std::string message, LogLevel level) = 0; + }; - class CerrLogHandler : public ILogHandler - { - public: - void log(std::string message, LogLevel level) override - { - std::string prefix; - switch (level) - { - case LogLevel::Debug: - prefix = "DEBUG "; - break; - case LogLevel::Info: - prefix = "INFO "; - break; - case LogLevel::Warning: - prefix = "WARNING "; - break; - case LogLevel::Error: - prefix = "ERROR "; - break; - case LogLevel::Critical: - prefix = "CRITICAL"; - break; - } - std::cerr << std::string("(") + timestamp() + std::string(") [") + prefix + std::string("] ") + message << std::endl; - } + class CerrLogHandler : public ILogHandler + { + public: + void log(std::string message, LogLevel level) override + { + std::string prefix; + switch (level) + { + case LogLevel::Debug: + prefix = "DEBUG "; + break; + case LogLevel::Info: + prefix = "INFO "; + break; + case LogLevel::Warning: + prefix = "WARNING "; + break; + case LogLevel::Error: + prefix = "ERROR "; + break; + case LogLevel::Critical: + prefix = "CRITICAL"; + break; + } + std::cerr << std::string("(") + timestamp() + std::string(") [") + prefix + std::string("] ") + message << std::endl; + } - private: - static std::string timestamp() - { - char date[32]; - time_t t = time(0); + private: + static std::string timestamp() + { + char date[32]; + time_t t = time(0); - tm my_tm; + tm my_tm; #if defined(_MSC_VER) || defined(__MINGW32__) #ifdef CROW_USE_LOCALTIMEZONE - localtime_s(&my_tm, &t); + localtime_s(&my_tm, &t); #else - gmtime_s(&my_tm, &t); + gmtime_s(&my_tm, &t); #endif #else #ifdef CROW_USE_LOCALTIMEZONE - localtime_r(&t, &my_tm); + localtime_r(&t, &my_tm); #else - gmtime_r(&t, &my_tm); + gmtime_r(&t, &my_tm); #endif #endif - size_t sz = strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", &my_tm); - return std::string(date, date + sz); - } - }; + size_t sz = strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", &my_tm); + return std::string(date, date + sz); + } + }; - class logger - { - public: - logger(LogLevel level) : level_(level) - { - } - ~logger() - { + class logger + { + public: + logger(LogLevel level) : level_(level) + { + } + ~logger() + { #ifdef CROW_ENABLE_LOGGING - if (level_ >= get_current_log_level()) - { - get_handler_ref()->log(stringstream_.str(), level_); - } + if (level_ >= get_current_log_level()) + { + get_handler_ref()->log(stringstream_.str(), level_); + } #endif - } + } - // - template - logger &operator<<(T const &value) - { + // + template + logger &operator<<(T const &value) + { #ifdef CROW_ENABLE_LOGGING - if (level_ >= get_current_log_level()) - { - stringstream_ << value; - } + if (level_ >= get_current_log_level()) + { + stringstream_ << value; + } #endif - return *this; - } + return *this; + } - // - static void setLogLevel(LogLevel level) { get_log_level_ref() = level; } + // + static void setLogLevel(LogLevel level) { get_log_level_ref() = level; } - static void setHandler(ILogHandler *handler) { get_handler_ref() = handler; } + static void setHandler(ILogHandler *handler) { get_handler_ref() = handler; } - static LogLevel get_current_log_level() { return get_log_level_ref(); } + static LogLevel get_current_log_level() { return get_log_level_ref(); } - private: - // - static LogLevel &get_log_level_ref() - { - static LogLevel current_level = static_cast(CROW_LOG_LEVEL); - return current_level; - } - static ILogHandler *&get_handler_ref() - { - static CerrLogHandler default_handler; - static ILogHandler *current_handler = &default_handler; - return current_handler; - } + private: + // + static LogLevel &get_log_level_ref() + { + static LogLevel current_level = static_cast(CROW_LOG_LEVEL); + return current_level; + } + static ILogHandler *&get_handler_ref() + { + static CerrLogHandler default_handler; + static ILogHandler *current_handler = &default_handler; + return current_handler; + } - // - std::ostringstream stringstream_; - LogLevel level_; - }; + // + std::ostringstream stringstream_; + LogLevel level_; + }; } // namespace crow #define CROW_LOG_CRITICAL \ - if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical) \ - crow::logger(crow::LogLevel::Critical) + if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical) \ + crow::logger(crow::LogLevel::Critical) #define CROW_LOG_ERROR \ - if (crow::logger::get_current_log_level() <= crow::LogLevel::Error) \ - crow::logger(crow::LogLevel::Error) + if (crow::logger::get_current_log_level() <= crow::LogLevel::Error) \ + crow::logger(crow::LogLevel::Error) #define CROW_LOG_WARNING \ - if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning) \ - crow::logger(crow::LogLevel::Warning) + if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning) \ + crow::logger(crow::LogLevel::Warning) #define CROW_LOG_INFO \ - if (crow::logger::get_current_log_level() <= crow::LogLevel::Info) \ - crow::logger(crow::LogLevel::Info) + if (crow::logger::get_current_log_level() <= crow::LogLevel::Info) \ + crow::logger(crow::LogLevel::Info) #define CROW_LOG_DEBUG \ - if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug) \ - crow::logger(crow::LogLevel::Debug) + if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug) \ + crow::logger(crow::LogLevel::Debug) #pragma once namespace crow { - constexpr const char VERSION[] = "1.0"; + constexpr const char VERSION[] = "1.0"; } /* @@ -473,199 +473,199 @@ namespace crow #include namespace sha1 { - class SHA1 - { - public: - typedef uint32_t digest32_t[5]; - typedef uint8_t digest8_t[20]; - inline static uint32_t LeftRotate(uint32_t value, size_t count) - { - return (value << count) ^ (value >> (32 - count)); - } - SHA1() { reset(); } - virtual ~SHA1() {} - SHA1(const SHA1 &s) { *this = s; } - const SHA1 &operator=(const SHA1 &s) - { - memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t)); - memcpy(m_block, s.m_block, 64); - m_blockByteIndex = s.m_blockByteIndex; - m_byteCount = s.m_byteCount; - return *this; - } - SHA1 &reset() - { - m_digest[0] = 0x67452301; - m_digest[1] = 0xEFCDAB89; - m_digest[2] = 0x98BADCFE; - m_digest[3] = 0x10325476; - m_digest[4] = 0xC3D2E1F0; - m_blockByteIndex = 0; - m_byteCount = 0; - return *this; - } - SHA1 &processByte(uint8_t octet) - { - this->m_block[this->m_blockByteIndex++] = octet; - ++this->m_byteCount; - if (m_blockByteIndex == 64) - { - this->m_blockByteIndex = 0; - processBlock(); - } - return *this; - } - SHA1 &processBlock(const void *const start, const void *const end) - { - const uint8_t *begin = static_cast(start); - const uint8_t *finish = static_cast(end); - while (begin != finish) - { - processByte(*begin); - begin++; - } - return *this; - } - SHA1 &processBytes(const void *const data, size_t len) - { - const uint8_t *block = static_cast(data); - processBlock(block, block + len); - return *this; - } - const uint32_t *getDigest(digest32_t digest) - { - size_t bitCount = this->m_byteCount * 8; - processByte(0x80); - if (this->m_blockByteIndex > 56) - { - while (m_blockByteIndex != 0) - { - processByte(0); - } - while (m_blockByteIndex < 56) - { - processByte(0); - } - } - else - { - while (m_blockByteIndex < 56) - { - processByte(0); - } - } - processByte(0); - processByte(0); - processByte(0); - processByte(0); - processByte(static_cast((bitCount >> 24) & 0xFF)); - processByte(static_cast((bitCount >> 16) & 0xFF)); - processByte(static_cast((bitCount >> 8) & 0xFF)); - processByte(static_cast((bitCount)&0xFF)); + class SHA1 + { + public: + typedef uint32_t digest32_t[5]; + typedef uint8_t digest8_t[20]; + inline static uint32_t LeftRotate(uint32_t value, size_t count) + { + return (value << count) ^ (value >> (32 - count)); + } + SHA1() { reset(); } + virtual ~SHA1() {} + SHA1(const SHA1 &s) { *this = s; } + const SHA1 &operator=(const SHA1 &s) + { + memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t)); + memcpy(m_block, s.m_block, 64); + m_blockByteIndex = s.m_blockByteIndex; + m_byteCount = s.m_byteCount; + return *this; + } + SHA1 &reset() + { + m_digest[0] = 0x67452301; + m_digest[1] = 0xEFCDAB89; + m_digest[2] = 0x98BADCFE; + m_digest[3] = 0x10325476; + m_digest[4] = 0xC3D2E1F0; + m_blockByteIndex = 0; + m_byteCount = 0; + return *this; + } + SHA1 &processByte(uint8_t octet) + { + this->m_block[this->m_blockByteIndex++] = octet; + ++this->m_byteCount; + if (m_blockByteIndex == 64) + { + this->m_blockByteIndex = 0; + processBlock(); + } + return *this; + } + SHA1 &processBlock(const void *const start, const void *const end) + { + const uint8_t *begin = static_cast(start); + const uint8_t *finish = static_cast(end); + while (begin != finish) + { + processByte(*begin); + begin++; + } + return *this; + } + SHA1 &processBytes(const void *const data, size_t len) + { + const uint8_t *block = static_cast(data); + processBlock(block, block + len); + return *this; + } + const uint32_t *getDigest(digest32_t digest) + { + size_t bitCount = this->m_byteCount * 8; + processByte(0x80); + if (this->m_blockByteIndex > 56) + { + while (m_blockByteIndex != 0) + { + processByte(0); + } + while (m_blockByteIndex < 56) + { + processByte(0); + } + } + else + { + while (m_blockByteIndex < 56) + { + processByte(0); + } + } + processByte(0); + processByte(0); + processByte(0); + processByte(0); + processByte(static_cast((bitCount >> 24) & 0xFF)); + processByte(static_cast((bitCount >> 16) & 0xFF)); + processByte(static_cast((bitCount >> 8) & 0xFF)); + processByte(static_cast((bitCount)&0xFF)); - memcpy(digest, m_digest, 5 * sizeof(uint32_t)); - return digest; - } - const uint8_t *getDigestBytes(digest8_t digest) - { - digest32_t d32; - getDigest(d32); - size_t di = 0; - digest[di++] = ((d32[0] >> 24) & 0xFF); - digest[di++] = ((d32[0] >> 16) & 0xFF); - digest[di++] = ((d32[0] >> 8) & 0xFF); - digest[di++] = ((d32[0]) & 0xFF); + memcpy(digest, m_digest, 5 * sizeof(uint32_t)); + return digest; + } + const uint8_t *getDigestBytes(digest8_t digest) + { + digest32_t d32; + getDigest(d32); + size_t di = 0; + digest[di++] = ((d32[0] >> 24) & 0xFF); + digest[di++] = ((d32[0] >> 16) & 0xFF); + digest[di++] = ((d32[0] >> 8) & 0xFF); + digest[di++] = ((d32[0]) & 0xFF); - digest[di++] = ((d32[1] >> 24) & 0xFF); - digest[di++] = ((d32[1] >> 16) & 0xFF); - digest[di++] = ((d32[1] >> 8) & 0xFF); - digest[di++] = ((d32[1]) & 0xFF); + digest[di++] = ((d32[1] >> 24) & 0xFF); + digest[di++] = ((d32[1] >> 16) & 0xFF); + digest[di++] = ((d32[1] >> 8) & 0xFF); + digest[di++] = ((d32[1]) & 0xFF); - digest[di++] = ((d32[2] >> 24) & 0xFF); - digest[di++] = ((d32[2] >> 16) & 0xFF); - digest[di++] = ((d32[2] >> 8) & 0xFF); - digest[di++] = ((d32[2]) & 0xFF); + digest[di++] = ((d32[2] >> 24) & 0xFF); + digest[di++] = ((d32[2] >> 16) & 0xFF); + digest[di++] = ((d32[2] >> 8) & 0xFF); + digest[di++] = ((d32[2]) & 0xFF); - digest[di++] = ((d32[3] >> 24) & 0xFF); - digest[di++] = ((d32[3] >> 16) & 0xFF); - digest[di++] = ((d32[3] >> 8) & 0xFF); - digest[di++] = ((d32[3]) & 0xFF); + digest[di++] = ((d32[3] >> 24) & 0xFF); + digest[di++] = ((d32[3] >> 16) & 0xFF); + digest[di++] = ((d32[3] >> 8) & 0xFF); + digest[di++] = ((d32[3]) & 0xFF); - digest[di++] = ((d32[4] >> 24) & 0xFF); - digest[di++] = ((d32[4] >> 16) & 0xFF); - digest[di++] = ((d32[4] >> 8) & 0xFF); - digest[di++] = ((d32[4]) & 0xFF); - return digest; - } + digest[di++] = ((d32[4] >> 24) & 0xFF); + digest[di++] = ((d32[4] >> 16) & 0xFF); + digest[di++] = ((d32[4] >> 8) & 0xFF); + digest[di++] = ((d32[4]) & 0xFF); + return digest; + } - protected: - void processBlock() - { - uint32_t w[80]; - for (size_t i = 0; i < 16; i++) - { - w[i] = (m_block[i * 4 + 0] << 24); - w[i] |= (m_block[i * 4 + 1] << 16); - w[i] |= (m_block[i * 4 + 2] << 8); - w[i] |= (m_block[i * 4 + 3]); - } - for (size_t i = 16; i < 80; i++) - { - w[i] = LeftRotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1); - } + protected: + void processBlock() + { + uint32_t w[80]; + for (size_t i = 0; i < 16; i++) + { + w[i] = (m_block[i * 4 + 0] << 24); + w[i] |= (m_block[i * 4 + 1] << 16); + w[i] |= (m_block[i * 4 + 2] << 8); + w[i] |= (m_block[i * 4 + 3]); + } + for (size_t i = 16; i < 80; i++) + { + w[i] = LeftRotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1); + } - uint32_t a = m_digest[0]; - uint32_t b = m_digest[1]; - uint32_t c = m_digest[2]; - uint32_t d = m_digest[3]; - uint32_t e = m_digest[4]; + uint32_t a = m_digest[0]; + uint32_t b = m_digest[1]; + uint32_t c = m_digest[2]; + uint32_t d = m_digest[3]; + uint32_t e = m_digest[4]; - for (std::size_t i = 0; i < 80; ++i) - { - uint32_t f = 0; - uint32_t k = 0; + for (std::size_t i = 0; i < 80; ++i) + { + uint32_t f = 0; + uint32_t k = 0; - if (i < 20) - { - f = (b & c) | (~b & d); - k = 0x5A827999; - } - else if (i < 40) - { - f = b ^ c ^ d; - k = 0x6ED9EBA1; - } - else if (i < 60) - { - f = (b & c) | (b & d) | (c & d); - k = 0x8F1BBCDC; - } - else - { - f = b ^ c ^ d; - k = 0xCA62C1D6; - } - uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i]; - e = d; - d = c; - c = LeftRotate(b, 30); - b = a; - a = temp; - } + if (i < 20) + { + f = (b & c) | (~b & d); + k = 0x5A827999; + } + else if (i < 40) + { + f = b ^ c ^ d; + k = 0x6ED9EBA1; + } + else if (i < 60) + { + f = (b & c) | (b & d) | (c & d); + k = 0x8F1BBCDC; + } + else + { + f = b ^ c ^ d; + k = 0xCA62C1D6; + } + uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i]; + e = d; + d = c; + c = LeftRotate(b, 30); + b = a; + a = temp; + } - m_digest[0] += a; - m_digest[1] += b; - m_digest[2] += c; - m_digest[3] += d; - m_digest[4] += e; - } + m_digest[0] += a; + m_digest[1] += b; + m_digest[2] += c; + m_digest[3] += d; + m_digest[4] += e; + } - private: - digest32_t m_digest; - uint8_t m_block[64]; - size_t m_blockByteIndex; - size_t m_byteCount; - }; + private: + digest32_t m_digest; + uint8_t m_block[64]; + size_t m_blockByteIndex; + size_t m_byteCount; + }; } #endif @@ -681,31 +681,31 @@ namespace sha1 namespace crow { - // ---------------------------------------------------------------------------- - // qs_parse (modified) - // https://github.com/bartgrantham/qs_parse - // ---------------------------------------------------------------------------- - /* Similar to strncmp, but handles URL-encoding for either string */ - int qs_strncmp(const char *s, const char *qs, size_t n); + // ---------------------------------------------------------------------------- + // qs_parse (modified) + // https://github.com/bartgrantham/qs_parse + // ---------------------------------------------------------------------------- + /* Similar to strncmp, but handles URL-encoding for either string */ + int qs_strncmp(const char *s, const char *qs, size_t n); - /* Finds the beginning of each key/value pair and stores a pointer in qs_kv. - * Also decodes the value portion of the k/v pair *in-place*. In a future - * enhancement it will also have a compile-time option of sorting qs_kv - * alphabetically by key. */ - int qs_parse(char *qs, char *qs_kv[], int qs_kv_size); + /* Finds the beginning of each key/value pair and stores a pointer in qs_kv. + * Also decodes the value portion of the k/v pair *in-place*. In a future + * enhancement it will also have a compile-time option of sorting qs_kv + * alphabetically by key. */ + int qs_parse(char *qs, char *qs_kv[], int qs_kv_size); - /* Used by qs_parse to decode the value portion of a k/v pair */ - int qs_decode(char *qs); + /* Used by qs_parse to decode the value portion of a k/v pair */ + int qs_decode(char *qs); - /* Looks up the value according to the key on a pre-processed query string - * A future enhancement will be a compile-time option to look up the key - * in a pre-sorted qs_kv array via a binary search. */ - // char * qs_k2v(const char * key, char * qs_kv[], int qs_kv_size); - char *qs_k2v(const char *key, char *const *qs_kv, int qs_kv_size, int nth); + /* Looks up the value according to the key on a pre-processed query string + * A future enhancement will be a compile-time option to look up the key + * in a pre-sorted qs_kv array via a binary search. */ + // char * qs_k2v(const char * key, char * qs_kv[], int qs_kv_size); + char *qs_k2v(const char *key, char *const *qs_kv, int qs_kv_size, int nth); - /* Non-destructive lookup of value, based on key. User provides the - * destinaton string and length. */ - char *qs_scanvalue(const char *key, const char *qs, char *val, size_t val_len); + /* Non-destructive lookup of value, based on key. User provides the + * destinaton string and length. */ + char *qs_scanvalue(const char *key, const char *qs, char *val, size_t val_len); // TODO: implement sorting of the qs_kv array; for now ensure it's not compiled #undef _qsSORTING @@ -713,460 +713,460 @@ namespace crow // isxdigit _is_ available in , but let's avoid another header instead #define CROW_QS_ISHEX(x) ((((x) >= '0' && (x) <= '9') || ((x) >= 'A' && (x) <= 'F') || ((x) >= 'a' && (x) <= 'f')) ? 1 : 0) #define CROW_QS_HEX2DEC(x) (((x) >= '0' && (x) <= '9') ? (x)-48 : ((x) >= 'A' && (x) <= 'F') ? (x)-55 \ - : ((x) >= 'a' && (x) <= 'f') ? (x)-87 \ - : 0) + : ((x) >= 'a' && (x) <= 'f') ? (x)-87 \ + : 0) #define CROW_QS_ISQSCHR(x) ((((x) == '=') || ((x) == '#') || ((x) == '&') || ((x) == '\0')) ? 0 : 1) - inline int qs_strncmp(const char *s, const char *qs, size_t n) - { - int i = 0; - unsigned char u1, u2, unyb, lnyb; + inline int qs_strncmp(const char *s, const char *qs, size_t n) + { + int i = 0; + unsigned char u1, u2, unyb, lnyb; - while (n-- > 0) - { - u1 = static_cast(*s++); - u2 = static_cast(*qs++); + while (n-- > 0) + { + u1 = static_cast(*s++); + u2 = static_cast(*qs++); - if (!CROW_QS_ISQSCHR(u1)) - { - u1 = '\0'; - } - if (!CROW_QS_ISQSCHR(u2)) - { - u2 = '\0'; - } + if (!CROW_QS_ISQSCHR(u1)) + { + u1 = '\0'; + } + if (!CROW_QS_ISQSCHR(u2)) + { + u2 = '\0'; + } - if (u1 == '+') - { - u1 = ' '; - } - if (u1 == '%') // easier/safer than scanf - { - unyb = static_cast(*s++); - lnyb = static_cast(*s++); - if (CROW_QS_ISHEX(unyb) && CROW_QS_ISHEX(lnyb)) - u1 = (CROW_QS_HEX2DEC(unyb) * 16) + CROW_QS_HEX2DEC(lnyb); - else - u1 = '\0'; - } + if (u1 == '+') + { + u1 = ' '; + } + if (u1 == '%') // easier/safer than scanf + { + unyb = static_cast(*s++); + lnyb = static_cast(*s++); + if (CROW_QS_ISHEX(unyb) && CROW_QS_ISHEX(lnyb)) + u1 = (CROW_QS_HEX2DEC(unyb) * 16) + CROW_QS_HEX2DEC(lnyb); + else + u1 = '\0'; + } - if (u2 == '+') - { - u2 = ' '; - } - if (u2 == '%') // easier/safer than scanf - { - unyb = static_cast(*qs++); - lnyb = static_cast(*qs++); - if (CROW_QS_ISHEX(unyb) && CROW_QS_ISHEX(lnyb)) - u2 = (CROW_QS_HEX2DEC(unyb) * 16) + CROW_QS_HEX2DEC(lnyb); - else - u2 = '\0'; - } + if (u2 == '+') + { + u2 = ' '; + } + if (u2 == '%') // easier/safer than scanf + { + unyb = static_cast(*qs++); + lnyb = static_cast(*qs++); + if (CROW_QS_ISHEX(unyb) && CROW_QS_ISHEX(lnyb)) + u2 = (CROW_QS_HEX2DEC(unyb) * 16) + CROW_QS_HEX2DEC(lnyb); + else + u2 = '\0'; + } - if (u1 != u2) - return u1 - u2; - if (u1 == '\0') - return 0; - i++; - } - if (CROW_QS_ISQSCHR(*qs)) - return -1; - else - return 0; - } + if (u1 != u2) + return u1 - u2; + if (u1 == '\0') + return 0; + i++; + } + if (CROW_QS_ISQSCHR(*qs)) + return -1; + else + return 0; + } - inline int qs_parse(char *qs, char *qs_kv[], int qs_kv_size) - { - int i, j; - char *substr_ptr; + inline int qs_parse(char *qs, char *qs_kv[], int qs_kv_size) + { + int i, j; + char *substr_ptr; - for (i = 0; i < qs_kv_size; i++) - qs_kv[i] = NULL; + for (i = 0; i < qs_kv_size; i++) + qs_kv[i] = NULL; - // find the beginning of the k/v substrings or the fragment - substr_ptr = qs + strcspn(qs, "?#"); - if (substr_ptr[0] != '\0') - substr_ptr++; - else - return 0; // no query or fragment + // find the beginning of the k/v substrings or the fragment + substr_ptr = qs + strcspn(qs, "?#"); + if (substr_ptr[0] != '\0') + substr_ptr++; + else + return 0; // no query or fragment - i = 0; - while (i < qs_kv_size) - { - qs_kv[i] = substr_ptr; - j = strcspn(substr_ptr, "&"); - if (substr_ptr[j] == '\0') - { - i++; - break; - } // x &'s -> means x iterations of this loop -> means *x+1* k/v pairs - substr_ptr += j + 1; - i++; - } + i = 0; + while (i < qs_kv_size) + { + qs_kv[i] = substr_ptr; + j = strcspn(substr_ptr, "&"); + if (substr_ptr[j] == '\0') + { + i++; + break; + } // x &'s -> means x iterations of this loop -> means *x+1* k/v pairs + substr_ptr += j + 1; + i++; + } - // we only decode the values in place, the keys could have '='s in them - // which will hose our ability to distinguish keys from values later - for (j = 0; j < i; j++) - { - substr_ptr = qs_kv[j] + strcspn(qs_kv[j], "=&#"); - if (substr_ptr[0] == '&' || substr_ptr[0] == '\0') // blank value: skip decoding - substr_ptr[0] = '\0'; - else - qs_decode(++substr_ptr); - } + // we only decode the values in place, the keys could have '='s in them + // which will hose our ability to distinguish keys from values later + for (j = 0; j < i; j++) + { + substr_ptr = qs_kv[j] + strcspn(qs_kv[j], "=&#"); + if (substr_ptr[0] == '&' || substr_ptr[0] == '\0') // blank value: skip decoding + substr_ptr[0] = '\0'; + else + qs_decode(++substr_ptr); + } #ifdef _qsSORTING // TODO: qsort qs_kv, using qs_strncmp() for the comparison #endif - return i; - } + return i; + } - inline int qs_decode(char *qs) - { - int i = 0, j = 0; + inline int qs_decode(char *qs) + { + int i = 0, j = 0; - while (CROW_QS_ISQSCHR(qs[j])) - { - if (qs[j] == '+') - { - qs[i] = ' '; - } - else if (qs[j] == '%') // easier/safer than scanf - { - if (!CROW_QS_ISHEX(qs[j + 1]) || !CROW_QS_ISHEX(qs[j + 2])) - { - qs[i] = '\0'; - return i; - } - qs[i] = (CROW_QS_HEX2DEC(qs[j + 1]) * 16) + CROW_QS_HEX2DEC(qs[j + 2]); - j += 2; - } - else - { - qs[i] = qs[j]; - } - i++; - j++; - } - qs[i] = '\0'; + while (CROW_QS_ISQSCHR(qs[j])) + { + if (qs[j] == '+') + { + qs[i] = ' '; + } + else if (qs[j] == '%') // easier/safer than scanf + { + if (!CROW_QS_ISHEX(qs[j + 1]) || !CROW_QS_ISHEX(qs[j + 2])) + { + qs[i] = '\0'; + return i; + } + qs[i] = (CROW_QS_HEX2DEC(qs[j + 1]) * 16) + CROW_QS_HEX2DEC(qs[j + 2]); + j += 2; + } + else + { + qs[i] = qs[j]; + } + i++; + j++; + } + qs[i] = '\0'; - return i; - } + return i; + } - inline char *qs_k2v(const char *key, char *const *qs_kv, int qs_kv_size, int nth = 0) - { - int i; - size_t key_len, skip; + inline char *qs_k2v(const char *key, char *const *qs_kv, int qs_kv_size, int nth = 0) + { + int i; + size_t key_len, skip; - key_len = strlen(key); + key_len = strlen(key); #ifdef _qsSORTING // TODO: binary search for key in the sorted qs_kv #else // _qsSORTING - for (i = 0; i < qs_kv_size; i++) - { - // we rely on the unambiguous '=' to find the value in our k/v pair - if (qs_strncmp(key, qs_kv[i], key_len) == 0) - { - skip = strcspn(qs_kv[i], "="); - if (qs_kv[i][skip] == '=') - skip++; - // return (zero-char value) ? ptr to trailing '\0' : ptr to value - if (nth == 0) - return qs_kv[i] + skip; - else - --nth; - } - } + for (i = 0; i < qs_kv_size; i++) + { + // we rely on the unambiguous '=' to find the value in our k/v pair + if (qs_strncmp(key, qs_kv[i], key_len) == 0) + { + skip = strcspn(qs_kv[i], "="); + if (qs_kv[i][skip] == '=') + skip++; + // return (zero-char value) ? ptr to trailing '\0' : ptr to value + if (nth == 0) + return qs_kv[i] + skip; + else + --nth; + } + } #endif // _qsSORTING - return nullptr; - } + return nullptr; + } - inline boost::optional> qs_dict_name2kv(const char *dict_name, char *const *qs_kv, int qs_kv_size, int nth = 0) - { - int i; - size_t name_len, skip_to_eq, skip_to_brace_open, skip_to_brace_close; + inline boost::optional> qs_dict_name2kv(const char *dict_name, char *const *qs_kv, int qs_kv_size, int nth = 0) + { + int i; + size_t name_len, skip_to_eq, skip_to_brace_open, skip_to_brace_close; - name_len = strlen(dict_name); + name_len = strlen(dict_name); #ifdef _qsSORTING // TODO: binary search for key in the sorted qs_kv #else // _qsSORTING - for (i = 0; i < qs_kv_size; i++) - { - if (strncmp(dict_name, qs_kv[i], name_len) == 0) - { - skip_to_eq = strcspn(qs_kv[i], "="); - if (qs_kv[i][skip_to_eq] == '=') - skip_to_eq++; - skip_to_brace_open = strcspn(qs_kv[i], "["); - if (qs_kv[i][skip_to_brace_open] == '[') - skip_to_brace_open++; - skip_to_brace_close = strcspn(qs_kv[i], "]"); + for (i = 0; i < qs_kv_size; i++) + { + if (strncmp(dict_name, qs_kv[i], name_len) == 0) + { + skip_to_eq = strcspn(qs_kv[i], "="); + if (qs_kv[i][skip_to_eq] == '=') + skip_to_eq++; + skip_to_brace_open = strcspn(qs_kv[i], "["); + if (qs_kv[i][skip_to_brace_open] == '[') + skip_to_brace_open++; + skip_to_brace_close = strcspn(qs_kv[i], "]"); - if (skip_to_brace_open <= skip_to_brace_close && - skip_to_brace_open > 0 && - skip_to_brace_close > 0 && - nth == 0) - { - auto key = std::string(qs_kv[i] + skip_to_brace_open, skip_to_brace_close - skip_to_brace_open); - auto value = std::string(qs_kv[i] + skip_to_eq); - return boost::make_optional(std::make_pair(key, value)); - } - else - { - --nth; - } - } - } + if (skip_to_brace_open <= skip_to_brace_close && + skip_to_brace_open > 0 && + skip_to_brace_close > 0 && + nth == 0) + { + auto key = std::string(qs_kv[i] + skip_to_brace_open, skip_to_brace_close - skip_to_brace_open); + auto value = std::string(qs_kv[i] + skip_to_eq); + return boost::make_optional(std::make_pair(key, value)); + } + else + { + --nth; + } + } + } #endif // _qsSORTING - return boost::none; - } + return boost::none; + } - inline char *qs_scanvalue(const char *key, const char *qs, char *val, size_t val_len) - { - size_t i, key_len; - const char *tmp; + inline char *qs_scanvalue(const char *key, const char *qs, char *val, size_t val_len) + { + size_t i, key_len; + const char *tmp; - // find the beginning of the k/v substrings - if ((tmp = strchr(qs, '?')) != NULL) - qs = tmp + 1; + // find the beginning of the k/v substrings + if ((tmp = strchr(qs, '?')) != NULL) + qs = tmp + 1; - key_len = strlen(key); - while (qs[0] != '#' && qs[0] != '\0') - { - if (qs_strncmp(key, qs, key_len) == 0) - break; - qs += strcspn(qs, "&") + 1; - } + key_len = strlen(key); + while (qs[0] != '#' && qs[0] != '\0') + { + if (qs_strncmp(key, qs, key_len) == 0) + break; + qs += strcspn(qs, "&") + 1; + } - if (qs[0] == '\0') - return NULL; + if (qs[0] == '\0') + return NULL; - qs += strcspn(qs, "=&#"); - if (qs[0] == '=') - { - qs++; - i = strcspn(qs, "&=#"); + qs += strcspn(qs, "=&#"); + if (qs[0] == '=') + { + qs++; + i = strcspn(qs, "&=#"); #ifdef _MSC_VER - strncpy_s(val, val_len, qs, (val_len - 1) < (i + 1) ? (val_len - 1) : (i + 1)); + strncpy_s(val, val_len, qs, (val_len - 1) < (i + 1) ? (val_len - 1) : (i + 1)); #else - strncpy(val, qs, (val_len - 1) < (i + 1) ? (val_len - 1) : (i + 1)); + strncpy(val, qs, (val_len - 1) < (i + 1) ? (val_len - 1) : (i + 1)); #endif - qs_decode(val); - } - else - { - if (val_len > 0) - val[0] = '\0'; - } + qs_decode(val); + } + else + { + if (val_len > 0) + val[0] = '\0'; + } - return val; - } + return val; + } } // ---------------------------------------------------------------------------- namespace crow { - /// A class to represent any data coming after the `?` in the request URL into key-value pairs. - class query_string - { - public: - static const int MAX_KEY_VALUE_PAIRS_COUNT = 256; + /// A class to represent any data coming after the `?` in the request URL into key-value pairs. + class query_string + { + public: + static const int MAX_KEY_VALUE_PAIRS_COUNT = 256; - query_string() - { - } + query_string() + { + } - query_string(const query_string &qs) - : url_(qs.url_) - { - for (auto p : qs.key_value_pairs_) - { - key_value_pairs_.push_back((char *)(p - qs.url_.c_str() + url_.c_str())); - } - } + query_string(const query_string &qs) + : url_(qs.url_) + { + for (auto p : qs.key_value_pairs_) + { + key_value_pairs_.push_back((char *)(p - qs.url_.c_str() + url_.c_str())); + } + } - query_string &operator=(const query_string &qs) - { - url_ = qs.url_; - key_value_pairs_.clear(); - for (auto p : qs.key_value_pairs_) - { - key_value_pairs_.push_back((char *)(p - qs.url_.c_str() + url_.c_str())); - } - return *this; - } + query_string &operator=(const query_string &qs) + { + url_ = qs.url_; + key_value_pairs_.clear(); + for (auto p : qs.key_value_pairs_) + { + key_value_pairs_.push_back((char *)(p - qs.url_.c_str() + url_.c_str())); + } + return *this; + } - query_string &operator=(query_string &&qs) - { - key_value_pairs_ = std::move(qs.key_value_pairs_); - char *old_data = (char *)qs.url_.c_str(); - url_ = std::move(qs.url_); - for (auto &p : key_value_pairs_) - { - p += (char *)url_.c_str() - old_data; - } - return *this; - } + query_string &operator=(query_string &&qs) + { + key_value_pairs_ = std::move(qs.key_value_pairs_); + char *old_data = (char *)qs.url_.c_str(); + url_ = std::move(qs.url_); + for (auto &p : key_value_pairs_) + { + p += (char *)url_.c_str() - old_data; + } + return *this; + } - query_string(std::string url) - : url_(std::move(url)) - { - if (url_.empty()) - return; + query_string(std::string url) + : url_(std::move(url)) + { + if (url_.empty()) + return; - key_value_pairs_.resize(MAX_KEY_VALUE_PAIRS_COUNT); + key_value_pairs_.resize(MAX_KEY_VALUE_PAIRS_COUNT); - int count = qs_parse(&url_[0], &key_value_pairs_[0], MAX_KEY_VALUE_PAIRS_COUNT); - key_value_pairs_.resize(count); - } + int count = qs_parse(&url_[0], &key_value_pairs_[0], MAX_KEY_VALUE_PAIRS_COUNT); + key_value_pairs_.resize(count); + } - void clear() - { - key_value_pairs_.clear(); - url_.clear(); - } + void clear() + { + key_value_pairs_.clear(); + url_.clear(); + } - friend std::ostream &operator<<(std::ostream &os, const query_string &qs) - { - os << "[ "; - for (size_t i = 0; i < qs.key_value_pairs_.size(); ++i) - { - if (i) - os << ", "; - os << qs.key_value_pairs_[i]; - } - os << " ]"; - return os; - } + friend std::ostream &operator<<(std::ostream &os, const query_string &qs) + { + os << "[ "; + for (size_t i = 0; i < qs.key_value_pairs_.size(); ++i) + { + if (i) + os << ", "; + os << qs.key_value_pairs_[i]; + } + os << " ]"; + return os; + } - /// Get a value from a name, used for `?name=value`. + /// Get a value from a name, used for `?name=value`. - /// - /// Note: this method returns the value of the first occurrence of the key only, to return all occurrences, see \ref get_list(). - char *get(const std::string &name) const - { - char *ret = qs_k2v(name.c_str(), key_value_pairs_.data(), key_value_pairs_.size()); - return ret; - } + /// + /// Note: this method returns the value of the first occurrence of the key only, to return all occurrences, see \ref get_list(). + char *get(const std::string &name) const + { + char *ret = qs_k2v(name.c_str(), key_value_pairs_.data(), key_value_pairs_.size()); + return ret; + } - /// Works similar to \ref get() except it removes the item from the query string. - char *pop(const std::string &name) - { - char *ret = get(name); - if (ret != nullptr) - { - for (unsigned int i = 0; i < key_value_pairs_.size(); i++) - { - std::string str_item(key_value_pairs_[i]); - if (str_item.substr(0, name.size() + 1) == name + '=') - { - key_value_pairs_.erase(key_value_pairs_.begin() + i); - break; - } - } - } - return ret; - } + /// Works similar to \ref get() except it removes the item from the query string. + char *pop(const std::string &name) + { + char *ret = get(name); + if (ret != nullptr) + { + for (unsigned int i = 0; i < key_value_pairs_.size(); i++) + { + std::string str_item(key_value_pairs_[i]); + if (str_item.substr(0, name.size() + 1) == name + '=') + { + key_value_pairs_.erase(key_value_pairs_.begin() + i); + break; + } + } + } + return ret; + } - /// Returns a list of values, passed as `?name[]=value1&name[]=value2&...name[]=valuen` with n being the size of the list. + /// Returns a list of values, passed as `?name[]=value1&name[]=value2&...name[]=valuen` with n being the size of the list. - /// - /// Note: Square brackets in the above example are controlled by `use_brackets` boolean (true by default). If set to false, the example becomes `?name=value1,name=value2...name=valuen` - std::vector get_list(const std::string &name, bool use_brackets = true) const - { - std::vector ret; - std::string plus = name + (use_brackets ? "[]" : ""); - char *element = nullptr; + /// + /// Note: Square brackets in the above example are controlled by `use_brackets` boolean (true by default). If set to false, the example becomes `?name=value1,name=value2...name=valuen` + std::vector get_list(const std::string &name, bool use_brackets = true) const + { + std::vector ret; + std::string plus = name + (use_brackets ? "[]" : ""); + char *element = nullptr; - int count = 0; - while (1) - { - element = qs_k2v(plus.c_str(), key_value_pairs_.data(), key_value_pairs_.size(), count++); - if (!element) - break; - ret.push_back(element); - } - return ret; - } + int count = 0; + while (1) + { + element = qs_k2v(plus.c_str(), key_value_pairs_.data(), key_value_pairs_.size(), count++); + if (!element) + break; + ret.push_back(element); + } + return ret; + } - /// Similar to \ref get_list() but it removes the - std::vector pop_list(const std::string &name, bool use_brackets = true) - { - std::vector ret = get_list(name, use_brackets); - if (!ret.empty()) - { - for (unsigned int i = 0; i < key_value_pairs_.size(); i++) - { - std::string str_item(key_value_pairs_[i]); - if ((use_brackets ? (str_item.substr(0, name.size() + 3) == name + "[]=") : (str_item.substr(0, name.size() + 1) == name + '='))) - { - key_value_pairs_.erase(key_value_pairs_.begin() + i--); - } - } - } - return ret; - } + /// Similar to \ref get_list() but it removes the + std::vector pop_list(const std::string &name, bool use_brackets = true) + { + std::vector ret = get_list(name, use_brackets); + if (!ret.empty()) + { + for (unsigned int i = 0; i < key_value_pairs_.size(); i++) + { + std::string str_item(key_value_pairs_[i]); + if ((use_brackets ? (str_item.substr(0, name.size() + 3) == name + "[]=") : (str_item.substr(0, name.size() + 1) == name + '='))) + { + key_value_pairs_.erase(key_value_pairs_.begin() + i--); + } + } + } + return ret; + } - /// Works similar to \ref get_list() except the brackets are mandatory must not be empty. + /// Works similar to \ref get_list() except the brackets are mandatory must not be empty. - /// - /// For example calling `get_dict(yourname)` on `?yourname[sub1]=42&yourname[sub2]=84` would give a map containing `{sub1 : 42, sub2 : 84}`. - /// - /// if your query string has both empty brackets and ones with a key inside, use pop_list() to get all the values without a key before running this method. - std::unordered_map get_dict(const std::string &name) const - { - std::unordered_map ret; + /// + /// For example calling `get_dict(yourname)` on `?yourname[sub1]=42&yourname[sub2]=84` would give a map containing `{sub1 : 42, sub2 : 84}`. + /// + /// if your query string has both empty brackets and ones with a key inside, use pop_list() to get all the values without a key before running this method. + std::unordered_map get_dict(const std::string &name) const + { + std::unordered_map ret; - int count = 0; - while (1) - { - if (auto element = qs_dict_name2kv(name.c_str(), key_value_pairs_.data(), key_value_pairs_.size(), count++)) - ret.insert(*element); - else - break; - } - return ret; - } + int count = 0; + while (1) + { + if (auto element = qs_dict_name2kv(name.c_str(), key_value_pairs_.data(), key_value_pairs_.size(), count++)) + ret.insert(*element); + else + break; + } + return ret; + } - /// Works the same as \ref get_dict() but removes the values from the query string. - std::unordered_map pop_dict(const std::string &name) - { - std::unordered_map ret = get_dict(name); - if (!ret.empty()) - { - for (unsigned int i = 0; i < key_value_pairs_.size(); i++) - { - std::string str_item(key_value_pairs_[i]); - if (str_item.substr(0, name.size() + 1) == name + '[') - { - key_value_pairs_.erase(key_value_pairs_.begin() + i--); - } - } - } - return ret; - } + /// Works the same as \ref get_dict() but removes the values from the query string. + std::unordered_map pop_dict(const std::string &name) + { + std::unordered_map ret = get_dict(name); + if (!ret.empty()) + { + for (unsigned int i = 0; i < key_value_pairs_.size(); i++) + { + std::string str_item(key_value_pairs_[i]); + if (str_item.substr(0, name.size() + 1) == name + '[') + { + key_value_pairs_.erase(key_value_pairs_.begin() + i--); + } + } + } + return ret; + } - std::vector keys() const - { - std::vector ret; - for (auto element : key_value_pairs_) - { - std::string str_element(element); - ret.emplace_back(str_element.substr(0, str_element.find('='))); - } - return ret; - } + std::vector keys() const + { + std::vector ret; + for (auto element : key_value_pairs_) + { + std::string str_element(element); + ret.emplace_back(str_element.substr(0, str_element.find('='))); + } + return ret; + } - private: - std::string url_; - std::vector key_value_pairs_; - }; + private: + std::string url_; + std::vector key_value_pairs_; + }; } // end namespace @@ -1180,126 +1180,126 @@ namespace crow namespace crow { - namespace detail - { + namespace detail + { - /// A class for scheduling functions to be called after a specific amount of ticks. A tick is equal to 1 second. - class task_timer - { - public: - using task_type = std::function; - using identifier_type = size_t; + /// A class for scheduling functions to be called after a specific amount of ticks. A tick is equal to 1 second. + class task_timer + { + public: + using task_type = std::function; + using identifier_type = size_t; - private: - using clock_type = std::chrono::steady_clock; - using time_type = clock_type::time_point; + private: + using clock_type = std::chrono::steady_clock; + using time_type = clock_type::time_point; - public: - task_timer(boost::asio::io_service &io_service) : io_service_(io_service), deadline_timer_(io_service_) - { - deadline_timer_.expires_from_now(boost::posix_time::seconds(1)); - deadline_timer_.async_wait( - std::bind(&task_timer::tick_handler, this, std::placeholders::_1)); - } + public: + task_timer(boost::asio::io_service &io_service) : io_service_(io_service), deadline_timer_(io_service_) + { + deadline_timer_.expires_from_now(boost::posix_time::seconds(1)); + deadline_timer_.async_wait( + std::bind(&task_timer::tick_handler, this, std::placeholders::_1)); + } - ~task_timer() { deadline_timer_.cancel(); } + ~task_timer() { deadline_timer_.cancel(); } - void cancel(identifier_type id) - { - tasks_.erase(id); - CROW_LOG_DEBUG << "task_timer cancelled: " << this << ' ' << id; - } + void cancel(identifier_type id) + { + tasks_.erase(id); + CROW_LOG_DEBUG << "task_timer cancelled: " << this << ' ' << id; + } - /// Schedule the given task to be executed after the default amount of ticks. + /// Schedule the given task to be executed after the default amount of ticks. - /// - /// \return identifier_type Used to cancel the thread. - /// It is not bound to this task_timer instance and in some cases could lead to - /// undefined behavior if used with other task_timer objects or after the task - /// has been successfully executed. - identifier_type schedule(const task_type &task) - { - tasks_.insert( - {++highest_id_, - {clock_type::now() + std::chrono::seconds(get_default_timeout()), - task}}); - CROW_LOG_DEBUG << "task_timer scheduled: " << this << ' ' << highest_id_; - return highest_id_; - } + /// + /// \return identifier_type Used to cancel the thread. + /// It is not bound to this task_timer instance and in some cases could lead to + /// undefined behavior if used with other task_timer objects or after the task + /// has been successfully executed. + identifier_type schedule(const task_type &task) + { + tasks_.insert( + {++highest_id_, + {clock_type::now() + std::chrono::seconds(get_default_timeout()), + task}}); + CROW_LOG_DEBUG << "task_timer scheduled: " << this << ' ' << highest_id_; + return highest_id_; + } - /// Schedule the given task to be executed after the given time. + /// Schedule the given task to be executed after the given time. - /// - /// \param timeout The amount of ticks (seconds) to wait before execution. - /// - /// \return identifier_type Used to cancel the thread. - /// It is not bound to this task_timer instance and in some cases could lead to - /// undefined behavior if used with other task_timer objects or after the task - /// has been successfully executed. - identifier_type schedule(const task_type &task, std::uint8_t timeout) - { - tasks_.insert({++highest_id_, - {clock_type::now() + std::chrono::seconds(timeout), task}}); - CROW_LOG_DEBUG << "task_timer scheduled: " << this << ' ' << highest_id_; - return highest_id_; - } + /// + /// \param timeout The amount of ticks (seconds) to wait before execution. + /// + /// \return identifier_type Used to cancel the thread. + /// It is not bound to this task_timer instance and in some cases could lead to + /// undefined behavior if used with other task_timer objects or after the task + /// has been successfully executed. + identifier_type schedule(const task_type &task, std::uint8_t timeout) + { + tasks_.insert({++highest_id_, + {clock_type::now() + std::chrono::seconds(timeout), task}}); + CROW_LOG_DEBUG << "task_timer scheduled: " << this << ' ' << highest_id_; + return highest_id_; + } - /// Set the default timeout for this task_timer instance. (Default: 5) + /// Set the default timeout for this task_timer instance. (Default: 5) - /// - /// \param timeout The amount of ticks (seconds) to wait before execution. - void set_default_timeout(std::uint8_t timeout) { default_timeout_ = timeout; } + /// + /// \param timeout The amount of ticks (seconds) to wait before execution. + void set_default_timeout(std::uint8_t timeout) { default_timeout_ = timeout; } - /// Get the default timeout. (Default: 5) - std::uint8_t get_default_timeout() const { return default_timeout_; } + /// Get the default timeout. (Default: 5) + std::uint8_t get_default_timeout() const { return default_timeout_; } - private: - void process_tasks() - { - time_type current_time = clock_type::now(); - std::vector finished_tasks; + private: + void process_tasks() + { + time_type current_time = clock_type::now(); + std::vector finished_tasks; - for (const auto &task : tasks_) - { - if (task.second.first < current_time) - { - (task.second.second)(); - finished_tasks.push_back(task.first); - CROW_LOG_DEBUG << "task_timer called: " << this << ' ' << task.first; - } - } + for (const auto &task : tasks_) + { + if (task.second.first < current_time) + { + (task.second.second)(); + finished_tasks.push_back(task.first); + CROW_LOG_DEBUG << "task_timer called: " << this << ' ' << task.first; + } + } - for (const auto &task : finished_tasks) - tasks_.erase(task); + for (const auto &task : finished_tasks) + tasks_.erase(task); - // If no task is currently scheduled, reset the issued ids back to 0. - if (tasks_.empty()) - highest_id_ = 0; - } + // If no task is currently scheduled, reset the issued ids back to 0. + if (tasks_.empty()) + highest_id_ = 0; + } - void tick_handler(const boost::system::error_code &ec) - { - if (ec) - return; + void tick_handler(const boost::system::error_code &ec) + { + if (ec) + return; - process_tasks(); + process_tasks(); - deadline_timer_.expires_from_now(boost::posix_time::seconds(1)); - deadline_timer_.async_wait( - std::bind(&task_timer::tick_handler, this, std::placeholders::_1)); - } + deadline_timer_.expires_from_now(boost::posix_time::seconds(1)); + deadline_timer_.async_wait( + std::bind(&task_timer::tick_handler, this, std::placeholders::_1)); + } - private: - std::uint8_t default_timeout_{5}; - boost::asio::io_service &io_service_; - boost::asio::deadline_timer deadline_timer_; - std::map> tasks_; + private: + std::uint8_t default_timeout_{5}; + boost::asio::io_service &io_service_; + boost::asio::deadline_timer deadline_timer_; + std::map> tasks_; - // A continuosly increasing number to be issued to threads to identify them. - // If no tasks are scheduled, it will be reset to 0. - identifier_type highest_id_{0}; - }; - } // namespace detail + // A continuosly increasing number to be issued to threads to identify them. + // If no tasks are scheduled, it will be reset to 0. + identifier_type highest_id_{0}; + }; + } // namespace detail } // namespace crow #pragma once @@ -1315,160 +1315,160 @@ namespace crow #endif namespace crow { - using namespace boost; - using tcp = asio::ip::tcp; + using namespace boost; + using tcp = asio::ip::tcp; - /// A wrapper for the asio::ip::tcp::socket and asio::ssl::stream - struct SocketAdaptor - { - using context = void; - SocketAdaptor(boost::asio::io_service &io_service, context *) : socket_(io_service) - { - } + /// A wrapper for the asio::ip::tcp::socket and asio::ssl::stream + struct SocketAdaptor + { + using context = void; + SocketAdaptor(boost::asio::io_service &io_service, context *) : socket_(io_service) + { + } - boost::asio::io_service &get_io_service() - { - return GET_IO_SERVICE(socket_); - } + boost::asio::io_service &get_io_service() + { + return GET_IO_SERVICE(socket_); + } - /// Get the TCP socket handling data trasfers, regardless of what layer is handling transfers on top of the socket. - tcp::socket &raw_socket() - { - return socket_; - } + /// Get the TCP socket handling data trasfers, regardless of what layer is handling transfers on top of the socket. + tcp::socket &raw_socket() + { + return socket_; + } - /// Get the object handling data transfers, this can be either a TCP socket or an SSL stream (if SSL is enabled). - tcp::socket &socket() - { - return socket_; - } + /// Get the object handling data transfers, this can be either a TCP socket or an SSL stream (if SSL is enabled). + tcp::socket &socket() + { + return socket_; + } - tcp::endpoint remote_endpoint() - { - return socket_.remote_endpoint(); - } + tcp::endpoint remote_endpoint() + { + return socket_.remote_endpoint(); + } - bool is_open() - { - return socket_.is_open(); - } + bool is_open() + { + return socket_.is_open(); + } - void close() - { - boost::system::error_code ec; - socket_.close(ec); - } + void close() + { + boost::system::error_code ec; + socket_.close(ec); + } - void shutdown_readwrite() - { - boost::system::error_code ec; - socket_.shutdown(boost::asio::socket_base::shutdown_type::shutdown_both, ec); - } + void shutdown_readwrite() + { + boost::system::error_code ec; + socket_.shutdown(boost::asio::socket_base::shutdown_type::shutdown_both, ec); + } - void shutdown_write() - { - boost::system::error_code ec; - socket_.shutdown(boost::asio::socket_base::shutdown_type::shutdown_send, ec); - } + void shutdown_write() + { + boost::system::error_code ec; + socket_.shutdown(boost::asio::socket_base::shutdown_type::shutdown_send, ec); + } - void shutdown_read() - { - boost::system::error_code ec; - socket_.shutdown(boost::asio::socket_base::shutdown_type::shutdown_receive, ec); - } + void shutdown_read() + { + boost::system::error_code ec; + socket_.shutdown(boost::asio::socket_base::shutdown_type::shutdown_receive, ec); + } - template - void start(F f) - { - f(boost::system::error_code()); - } + template + void start(F f) + { + f(boost::system::error_code()); + } - tcp::socket socket_; - }; + tcp::socket socket_; + }; #ifdef CROW_ENABLE_SSL - struct SSLAdaptor - { - using context = boost::asio::ssl::context; - using ssl_socket_t = boost::asio::ssl::stream; - SSLAdaptor(boost::asio::io_service &io_service, context *ctx) : ssl_socket_(new ssl_socket_t(io_service, *ctx)) - { - } + struct SSLAdaptor + { + using context = boost::asio::ssl::context; + using ssl_socket_t = boost::asio::ssl::stream; + SSLAdaptor(boost::asio::io_service &io_service, context *ctx) : ssl_socket_(new ssl_socket_t(io_service, *ctx)) + { + } - boost::asio::ssl::stream &socket() - { - return *ssl_socket_; - } + boost::asio::ssl::stream &socket() + { + return *ssl_socket_; + } - tcp::socket::lowest_layer_type & - raw_socket() - { - return ssl_socket_->lowest_layer(); - } + tcp::socket::lowest_layer_type & + raw_socket() + { + return ssl_socket_->lowest_layer(); + } - tcp::endpoint remote_endpoint() - { - return raw_socket().remote_endpoint(); - } + tcp::endpoint remote_endpoint() + { + return raw_socket().remote_endpoint(); + } - bool is_open() - { - return ssl_socket_ ? raw_socket().is_open() : false; - } + bool is_open() + { + return ssl_socket_ ? raw_socket().is_open() : false; + } - void close() - { - if (is_open()) - { - boost::system::error_code ec; - raw_socket().close(ec); - } - } + void close() + { + if (is_open()) + { + boost::system::error_code ec; + raw_socket().close(ec); + } + } - void shutdown_readwrite() - { - if (is_open()) - { - boost::system::error_code ec; - raw_socket().shutdown(boost::asio::socket_base::shutdown_type::shutdown_both, ec); - } - } + void shutdown_readwrite() + { + if (is_open()) + { + boost::system::error_code ec; + raw_socket().shutdown(boost::asio::socket_base::shutdown_type::shutdown_both, ec); + } + } - void shutdown_write() - { - if (is_open()) - { - boost::system::error_code ec; - raw_socket().shutdown(boost::asio::socket_base::shutdown_type::shutdown_send, ec); - } - } + void shutdown_write() + { + if (is_open()) + { + boost::system::error_code ec; + raw_socket().shutdown(boost::asio::socket_base::shutdown_type::shutdown_send, ec); + } + } - void shutdown_read() - { - if (is_open()) - { - boost::system::error_code ec; - raw_socket().shutdown(boost::asio::socket_base::shutdown_type::shutdown_receive, ec); - } - } + void shutdown_read() + { + if (is_open()) + { + boost::system::error_code ec; + raw_socket().shutdown(boost::asio::socket_base::shutdown_type::shutdown_receive, ec); + } + } - boost::asio::io_service &get_io_service() - { - return GET_IO_SERVICE(raw_socket()); - } + boost::asio::io_service &get_io_service() + { + return GET_IO_SERVICE(raw_socket()); + } - template - void start(F f) - { - ssl_socket_->async_handshake(boost::asio::ssl::stream_base::server, - [f](const boost::system::error_code &ec) - { - f(ec); - }); - } + template + void start(F f) + { + ssl_socket_->async_handshake(boost::asio::ssl::stream_base::server, + [f](const boost::system::error_code &ec) + { + f(ec); + }); + } - std::unique_ptr> ssl_socket_; - }; + std::unique_ptr> ssl_socket_; + }; #endif } // namespace crow @@ -1494,732 +1494,732 @@ namespace crow namespace crow { - /// @cond SKIP - namespace black_magic - { + /// @cond SKIP + namespace black_magic + { #ifndef CROW_MSVC_WORKAROUND - /// Out of Range Exception for const_str - struct OutOfRange - { - OutOfRange(unsigned /*pos*/, unsigned /*length*/) {} - }; - /// Helper function to throw an exception if i is larger than len - constexpr unsigned requires_in_range(unsigned i, unsigned len) - { - return i >= len ? throw OutOfRange(i, len) : i; - } + /// Out of Range Exception for const_str + struct OutOfRange + { + OutOfRange(unsigned /*pos*/, unsigned /*length*/) {} + }; + /// Helper function to throw an exception if i is larger than len + constexpr unsigned requires_in_range(unsigned i, unsigned len) + { + return i >= len ? throw OutOfRange(i, len) : i; + } - /// A constant string implementation. - class const_str - { - const char *const begin_; - unsigned size_; + /// A constant string implementation. + class const_str + { + const char *const begin_; + unsigned size_; - public: - template - constexpr const_str(const char (&arr)[N]) : begin_(arr), size_(N - 1) - { - static_assert(N >= 1, "not a string literal"); - } - constexpr char operator[](unsigned i) const - { - return requires_in_range(i, size_), begin_[i]; - } + public: + template + constexpr const_str(const char (&arr)[N]) : begin_(arr), size_(N - 1) + { + static_assert(N >= 1, "not a string literal"); + } + constexpr char operator[](unsigned i) const + { + return requires_in_range(i, size_), begin_[i]; + } - constexpr operator const char *() const - { - return begin_; - } + constexpr operator const char *() const + { + return begin_; + } - constexpr const char *begin() const { return begin_; } - constexpr const char *end() const { return begin_ + size_; } + constexpr const char *begin() const { return begin_; } + constexpr const char *end() const { return begin_ + size_; } - constexpr unsigned size() const - { - return size_; - } - }; + constexpr unsigned size() const + { + return size_; + } + }; - constexpr unsigned find_closing_tag(const_str s, unsigned p) - { - return s[p] == '>' ? p : find_closing_tag(s, p + 1); - } + constexpr unsigned find_closing_tag(const_str s, unsigned p) + { + return s[p] == '>' ? p : find_closing_tag(s, p + 1); + } - /// Check that the CROW_ROUTE string is valid - constexpr bool is_valid(const_str s, unsigned i = 0, int f = 0) - { - return i == s.size() ? f == 0 : f < 0 || f >= 2 ? false - : s[i] == '<' ? is_valid(s, i + 1, f + 1) - : s[i] == '>' ? is_valid(s, i + 1, f - 1) - : is_valid(s, i + 1, f); - } + /// Check that the CROW_ROUTE string is valid + constexpr bool is_valid(const_str s, unsigned i = 0, int f = 0) + { + return i == s.size() ? f == 0 : f < 0 || f >= 2 ? false + : s[i] == '<' ? is_valid(s, i + 1, f + 1) + : s[i] == '>' ? is_valid(s, i + 1, f - 1) + : is_valid(s, i + 1, f); + } - constexpr bool is_equ_p(const char *a, const char *b, unsigned n) - { - return *a == 0 && *b == 0 && n == 0 ? true : (*a == 0 || *b == 0) ? false - : n == 0 ? true - : *a != *b ? false - : is_equ_p(a + 1, b + 1, n - 1); - } + constexpr bool is_equ_p(const char *a, const char *b, unsigned n) + { + return *a == 0 && *b == 0 && n == 0 ? true : (*a == 0 || *b == 0) ? false + : n == 0 ? true + : *a != *b ? false + : is_equ_p(a + 1, b + 1, n - 1); + } - constexpr bool is_equ_n(const_str a, unsigned ai, const_str b, unsigned bi, unsigned n) - { - return ai + n > a.size() || bi + n > b.size() ? false : n == 0 ? true - : a[ai] != b[bi] ? false - : is_equ_n(a, ai + 1, b, bi + 1, n - 1); - } + constexpr bool is_equ_n(const_str a, unsigned ai, const_str b, unsigned bi, unsigned n) + { + return ai + n > a.size() || bi + n > b.size() ? false : n == 0 ? true + : a[ai] != b[bi] ? false + : is_equ_n(a, ai + 1, b, bi + 1, n - 1); + } - constexpr bool is_int(const_str s, unsigned i) - { - return is_equ_n(s, i, "", 0, 5); - } + constexpr bool is_int(const_str s, unsigned i) + { + return is_equ_n(s, i, "", 0, 5); + } - constexpr bool is_uint(const_str s, unsigned i) - { - return is_equ_n(s, i, "", 0, 6); - } + constexpr bool is_uint(const_str s, unsigned i) + { + return is_equ_n(s, i, "", 0, 6); + } - constexpr bool is_float(const_str s, unsigned i) - { - return is_equ_n(s, i, "", 0, 7) || - is_equ_n(s, i, "", 0, 8); - } + constexpr bool is_float(const_str s, unsigned i) + { + return is_equ_n(s, i, "", 0, 7) || + is_equ_n(s, i, "", 0, 8); + } - constexpr bool is_str(const_str s, unsigned i) - { - return is_equ_n(s, i, "", 0, 5) || - is_equ_n(s, i, "", 0, 8); - } + constexpr bool is_str(const_str s, unsigned i) + { + return is_equ_n(s, i, "", 0, 5) || + is_equ_n(s, i, "", 0, 8); + } - constexpr bool is_path(const_str s, unsigned i) - { - return is_equ_n(s, i, "", 0, 6); - } + constexpr bool is_path(const_str s, unsigned i) + { + return is_equ_n(s, i, "", 0, 6); + } #endif - template - struct parameter_tag - { - static const int value = 0; - }; + template + struct parameter_tag + { + static const int value = 0; + }; #define CROW_INTERNAL_PARAMETER_TAG(t, i) \ - template <> \ - struct parameter_tag \ - { \ - static const int value = i; \ - } - CROW_INTERNAL_PARAMETER_TAG(int, 1); - CROW_INTERNAL_PARAMETER_TAG(char, 1); - CROW_INTERNAL_PARAMETER_TAG(short, 1); - CROW_INTERNAL_PARAMETER_TAG(long, 1); - CROW_INTERNAL_PARAMETER_TAG(long long, 1); - CROW_INTERNAL_PARAMETER_TAG(unsigned int, 2); - CROW_INTERNAL_PARAMETER_TAG(unsigned char, 2); - CROW_INTERNAL_PARAMETER_TAG(unsigned short, 2); - CROW_INTERNAL_PARAMETER_TAG(unsigned long, 2); - CROW_INTERNAL_PARAMETER_TAG(unsigned long long, 2); - CROW_INTERNAL_PARAMETER_TAG(double, 3); - CROW_INTERNAL_PARAMETER_TAG(std::string, 4); + template <> \ + struct parameter_tag \ + { \ + static const int value = i; \ + } + CROW_INTERNAL_PARAMETER_TAG(int, 1); + CROW_INTERNAL_PARAMETER_TAG(char, 1); + CROW_INTERNAL_PARAMETER_TAG(short, 1); + CROW_INTERNAL_PARAMETER_TAG(long, 1); + CROW_INTERNAL_PARAMETER_TAG(long long, 1); + CROW_INTERNAL_PARAMETER_TAG(unsigned int, 2); + CROW_INTERNAL_PARAMETER_TAG(unsigned char, 2); + CROW_INTERNAL_PARAMETER_TAG(unsigned short, 2); + CROW_INTERNAL_PARAMETER_TAG(unsigned long, 2); + CROW_INTERNAL_PARAMETER_TAG(unsigned long long, 2); + CROW_INTERNAL_PARAMETER_TAG(double, 3); + CROW_INTERNAL_PARAMETER_TAG(std::string, 4); #undef CROW_INTERNAL_PARAMETER_TAG - template - struct compute_parameter_tag_from_args_list; + template + struct compute_parameter_tag_from_args_list; - template <> - struct compute_parameter_tag_from_args_list<> - { - static const int value = 0; - }; + template <> + struct compute_parameter_tag_from_args_list<> + { + static const int value = 0; + }; - template - struct compute_parameter_tag_from_args_list - { - static const int sub_value = - compute_parameter_tag_from_args_list::value; - static const int value = - parameter_tag::type>::value ? sub_value * 6 + parameter_tag::type>::value : sub_value; - }; + template + struct compute_parameter_tag_from_args_list + { + static const int sub_value = + compute_parameter_tag_from_args_list::value; + static const int value = + parameter_tag::type>::value ? sub_value * 6 + parameter_tag::type>::value : sub_value; + }; - static inline bool is_parameter_tag_compatible(uint64_t a, uint64_t b) - { - if (a == 0) - return b == 0; - if (b == 0) - return a == 0; - int sa = a % 6; - int sb = a % 6; - if (sa == 5) - sa = 4; - if (sb == 5) - sb = 4; - if (sa != sb) - return false; - return is_parameter_tag_compatible(a / 6, b / 6); - } + static inline bool is_parameter_tag_compatible(uint64_t a, uint64_t b) + { + if (a == 0) + return b == 0; + if (b == 0) + return a == 0; + int sa = a % 6; + int sb = a % 6; + if (sa == 5) + sa = 4; + if (sb == 5) + sb = 4; + if (sa != sb) + return false; + return is_parameter_tag_compatible(a / 6, b / 6); + } - static inline unsigned find_closing_tag_runtime(const char *s, unsigned p) - { - return s[p] == 0 ? throw std::runtime_error("unmatched tag <") : s[p] == '>' ? p - : find_closing_tag_runtime(s, p + 1); - } + static inline unsigned find_closing_tag_runtime(const char *s, unsigned p) + { + return s[p] == 0 ? throw std::runtime_error("unmatched tag <") : s[p] == '>' ? p + : find_closing_tag_runtime(s, p + 1); + } - static inline uint64_t get_parameter_tag_runtime(const char *s, unsigned p = 0) - { - return s[p] == 0 ? 0 : s[p] == '<' ? (std::strncmp(s + p, "", 5) == 0 ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 1 : std::strncmp(s + p, "", 6) == 0 ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 2 - : (std::strncmp(s + p, "", 7) == 0 || std::strncmp(s + p, "", 8) == 0) ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 3 - : (std::strncmp(s + p, "", 5) == 0 || std::strncmp(s + p, "", 8) == 0) ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 4 - : std::strncmp(s + p, "", 6) == 0 ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 5 - : throw std::runtime_error("invalid parameter type")) - : get_parameter_tag_runtime(s, p + 1); - } + static inline uint64_t get_parameter_tag_runtime(const char *s, unsigned p = 0) + { + return s[p] == 0 ? 0 : s[p] == '<' ? (std::strncmp(s + p, "", 5) == 0 ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 1 : std::strncmp(s + p, "", 6) == 0 ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 2 + : (std::strncmp(s + p, "", 7) == 0 || std::strncmp(s + p, "", 8) == 0) ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 3 + : (std::strncmp(s + p, "", 5) == 0 || std::strncmp(s + p, "", 8) == 0) ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 4 + : std::strncmp(s + p, "", 6) == 0 ? get_parameter_tag_runtime(s, find_closing_tag_runtime(s, p)) * 6 + 5 + : throw std::runtime_error("invalid parameter type")) + : get_parameter_tag_runtime(s, p + 1); + } #ifndef CROW_MSVC_WORKAROUND - constexpr uint64_t get_parameter_tag(const_str s, unsigned p = 0) - { - return p == s.size() ? 0 : s[p] == '<' ? (is_int(s, p) ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 1 : is_uint(s, p) ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 2 - : is_float(s, p) ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 3 - : is_str(s, p) ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 4 - : is_path(s, p) ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 5 - : throw std::runtime_error("invalid parameter type")) - : get_parameter_tag(s, p + 1); - } + constexpr uint64_t get_parameter_tag(const_str s, unsigned p = 0) + { + return p == s.size() ? 0 : s[p] == '<' ? (is_int(s, p) ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 1 : is_uint(s, p) ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 2 + : is_float(s, p) ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 3 + : is_str(s, p) ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 4 + : is_path(s, p) ? get_parameter_tag(s, find_closing_tag(s, p)) * 6 + 5 + : throw std::runtime_error("invalid parameter type")) + : get_parameter_tag(s, p + 1); + } #endif - template - struct S - { - template - using push = S; - template - using push_back = S; - template