<commit_before>/*
 * File: include/commonpp/net/http/Request.hpp
 * Part of commonpp.
 *
 * Distributed under the 2-clause BSD licence (See LICENCE.TXT file at the
 * project root).
 *
 * Copyright (c) 2015 <NAME>.  All rights reserved.
 *
 */

#pragma once

#include <string>
#include <vector>
#include <initializer_list>

#include <boost/algorithm/string.hpp>

#include <commonpp/core/string/stringify.hpp>
#include <commonpp/core/LoggingInterface.hpp>
#include "detail/validators.hpp"

namespace commonpp
{
namespace net
{
namespace http
{

class Request
{
public:
    using VKV = std::vector<std::pair<std::string, std::string>>;
    struct Headers : public VKV
    {
    };
    struct QueryParams : public VKV
    {
    };

    Request(std::string method = "GET")
    : method_(std::move(method))
    {}

    template <typename Validator, typename Serializer>
    struct Wrapper
    {
        template <typename K, typename VT>
        Wrapper& operator+=(std::pair<K, VT> header)
        {
            std::string value = string::stringify(std::move(header.second));

            if (!Validator::validate(header.first, value))
            {
                throw std::invalid_argument("invalid pair");
            }

            vector.emplace_back(Serializer::key(std::move(header.first)),
                                Serializer::value(std::move(value)));
            return *this;
        }

        VKV& vector;
    };

    Request& method(const std::string& method)
    {
        method_ = std::move(method);
        return *this;
    }

    Request& path(std::string path)
    {
        path_ = std::move(path);
        return *this;
    }

    Wrapper<detail::HeaderValidator, detail::NullSerializer> headers()
    {
        return {headers_};
    }

    Wrapper<detail::NullValidator, detail::QuerySerializer> query()
    {
        return {query_};
    }

    template <typename Iterator>
    Request& body(Iterator begin, Iterator end)
    {
        auto distance = std::distance(begin, end);
        body_.reserve(body_.size() + distance);
        body_.insert(std::end(body_), begin, end);
        return *this;
    }

    template <typename T>
    Request& body(const T& t)
    {
        return body(std::begin(t), std::end(t));
    }

    Request& body(const char* str)
    {
        auto begin = str;
        auto end = str + ::strlen(str);
        return body(begin, end);
    }

    Request& body(std::vector<char> body)
    {
        body_ = std::move(body);
        return *this;
    }

    Request& minor(int m)
    {
        minor_ = m;
        return *this;<commit_msg>Add bodyAppend() and change body() to not append data<commit_after>/*
 * File: include/commonpp/net/http/Request.hpp
 * Part of commonpp.
 *
 * Distributed under the 2-clause BSD licence (See LICENCE.TXT file at the
 * project root).
 *
 * Copyright (c) 2015 <NAME>.  All rights reserved.
 *
 */

#pragma once

#include <string>
#include <vector>
#include <initializer_list>

#include <boost/algorithm/string.hpp>

#include <commonpp/core/string/stringify.hpp>
#include <commonpp/core/LoggingInterface.hpp>
#include "detail/validators.hpp"

namespace commonpp
{
namespace net
{
namespace http
{

class Request
{
public:
    using VKV = std::vector<std::pair<std::string, std::string>>;
    struct Headers : public VKV
    {
    };
    struct QueryParams : public VKV
    {
    };

    Request(std::string method = "GET")
    : method_(std::move(method))
    {}

    template <typename Validator, typename Serializer>
    struct Wrapper
    {
        template <typename K, typename VT>
        Wrapper& operator+=(std::pair<K, VT> header)
        {
            std::string value = string::stringify(std::move(header.second));

            if (!Validator::validate(header.first, value))
            {
                throw std::invalid_argument("invalid pair");
            }

            vector.emplace_back(Serializer::key(std::move(header.first)),
                                Serializer::value(std::move(value)));
            return *this;
        }

        VKV& vector;
    };

    Request& method(const std::string& method)
    {
        method_ = std::move(method);
        return *this;
    }

    Request& path(std::string path)
    {
        path_ = std::move(path);
        return *this;
    }

    Wrapper<detail::HeaderValidator, detail::NullSerializer> headers()
    {
        return {headers_};
    }

    Wrapper<detail::NullValidator, detail::QuerySerializer> query()
    {
        return {query_};
    }

    template <typename Iterator>
    Request& bodyAppend(Iterator begin, Iterator end)
    {
        auto distance = std::distance(begin, end);
        body_.reserve(body_.size() + distance);
        body_.insert(std::end(body_), begin, end);
        return *this;
    }

    template <typename T>
    Request& bodyAppend(const T& t)
    {
        return bodyAppend(std::begin(t), std::end(t));
    }

    Request& bodyAppend(const char *str)
    {
        auto begin = str;
        auto end = str + ::strlen(str);
        return bodyAppend(begin, end);
    }

    template <typename Iterator>
    Request& body(Iterator begin, Iterator end)
    {
        body_.assign(begin, end);
        return *this;
    }

    template <typename T>
    Request& body(const T& t)
    {
        return body(std::begin(t), std::end(t));
    }

    Request& body(const char* str)
    {
        auto begin = str;
        auto end = str + ::strlen(str);
        return body(begin, end);
    }

    Request& body(std::vector<char> body)
    {
        body_ = std::move(body);
        return *this;
    }

    Request& minor(int m)
    {
        minor_ = m;
        return *this;
{'fraction_non_alphanumeric': 0.13232447650888615, 'fraction_numerical': 0.0017596339961288051, 'mean_word_length': 2.367298578199052, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2748680', 'n_tokens_mistral': 1767, 'n_tokens_neox': 1707, 'n_words': 403}