Added http + linux stuff
This commit is contained in:
parent
7bcafe1afd
commit
a6d1de6c1a
41
rudict/rudict/http/Jamfile
Normal file
41
rudict/rudict/http/Jamfile
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
#
|
||||||
|
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
#
|
||||||
|
|
||||||
|
subproject libs/asio/example/http/server ;
|
||||||
|
|
||||||
|
project boost : $(BOOST_ROOT) ;
|
||||||
|
|
||||||
|
if $(UNIX)
|
||||||
|
{
|
||||||
|
switch $(JAMUNAME)
|
||||||
|
{
|
||||||
|
case SunOS* :
|
||||||
|
{
|
||||||
|
SOCKET_LIBS = <find-library>socket <find-library>nsl ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exe http_server
|
||||||
|
: <lib>@boost/libs/thread/build/boost_thread
|
||||||
|
<lib>@boost/libs/system/build/boost_system
|
||||||
|
connection.cpp
|
||||||
|
connection_manager.cpp
|
||||||
|
main.cpp
|
||||||
|
mime_types.cpp
|
||||||
|
reply.cpp
|
||||||
|
request_handler.cpp
|
||||||
|
request_parser.cpp
|
||||||
|
server.cpp
|
||||||
|
: <include>$(BOOST_ROOT)
|
||||||
|
<include>../../../../..
|
||||||
|
<define>BOOST_ALL_NO_LIB=1
|
||||||
|
<threading>multi
|
||||||
|
<mingw><*><find-library>ws2_32
|
||||||
|
<mingw><*><find-library>mswsock
|
||||||
|
$(SOCKET_LIBS)
|
||||||
|
;
|
46
rudict/rudict/http/Jamfile.v2
Normal file
46
rudict/rudict/http/Jamfile.v2
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
#
|
||||||
|
# Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
#
|
||||||
|
|
||||||
|
import os ;
|
||||||
|
|
||||||
|
if [ os.name ] = SOLARIS
|
||||||
|
{
|
||||||
|
lib socket ;
|
||||||
|
lib nsl ;
|
||||||
|
}
|
||||||
|
else if [ os.name ] = NT
|
||||||
|
{
|
||||||
|
lib ws2_32 ;
|
||||||
|
lib mswsock ;
|
||||||
|
}
|
||||||
|
else if [ os.name ] = HPUX
|
||||||
|
{
|
||||||
|
lib ipv6 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
exe server
|
||||||
|
: connection.cpp
|
||||||
|
connection_manager.cpp
|
||||||
|
main.cpp
|
||||||
|
mime_types.cpp
|
||||||
|
reply.cpp
|
||||||
|
request_handler.cpp
|
||||||
|
request_parser.cpp
|
||||||
|
server.cpp
|
||||||
|
/boost/system//boost_system
|
||||||
|
/boost/thread//boost_thread
|
||||||
|
: <define>BOOST_ALL_NO_LIB=1
|
||||||
|
<threading>multi
|
||||||
|
<os>SOLARIS:<library>socket
|
||||||
|
<os>SOLARIS:<library>nsl
|
||||||
|
<os>NT:<define>_WIN32_WINNT=0x0501
|
||||||
|
<os>NT,<toolset>gcc:<library>ws2_32
|
||||||
|
<os>NT,<toolset>gcc:<library>mswsock
|
||||||
|
<os>NT,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS
|
||||||
|
<os>HPUX,<toolset>gcc:<define>_XOPEN_SOURCE_EXTENDED
|
||||||
|
<os>HPUX:<library>ipv6
|
||||||
|
;
|
94
rudict/rudict/http/connection.cpp
Normal file
94
rudict/rudict/http/connection.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
//
|
||||||
|
// connection.cpp
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "connection.hpp"
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
#include "connection_manager.hpp"
|
||||||
|
#include "request_handler.hpp"
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
connection::connection(boost::asio::ip::tcp::socket socket,
|
||||||
|
connection_manager& manager, request_handler& handler)
|
||||||
|
: socket_(std::move(socket)),
|
||||||
|
connection_manager_(manager),
|
||||||
|
request_handler_(handler)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void connection::start()
|
||||||
|
{
|
||||||
|
do_read();
|
||||||
|
}
|
||||||
|
|
||||||
|
void connection::stop()
|
||||||
|
{
|
||||||
|
socket_.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void connection::do_read()
|
||||||
|
{
|
||||||
|
auto self(shared_from_this());
|
||||||
|
socket_.async_read_some(boost::asio::buffer(buffer_),
|
||||||
|
[this, self](boost::system::error_code ec, std::size_t bytes_transferred)
|
||||||
|
{
|
||||||
|
if (!ec)
|
||||||
|
{
|
||||||
|
request_parser::result_type result;
|
||||||
|
std::tie(result, std::ignore) = request_parser_.parse(
|
||||||
|
request_, buffer_.data(), buffer_.data() + bytes_transferred);
|
||||||
|
|
||||||
|
if (result == request_parser::good)
|
||||||
|
{
|
||||||
|
request_handler_.handle_request(request_, reply_);
|
||||||
|
do_write();
|
||||||
|
}
|
||||||
|
else if (result == request_parser::bad)
|
||||||
|
{
|
||||||
|
reply_ = reply::stock_reply(reply::bad_request);
|
||||||
|
do_write();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do_read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ec != boost::asio::error::operation_aborted)
|
||||||
|
{
|
||||||
|
connection_manager_.stop(shared_from_this());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void connection::do_write()
|
||||||
|
{
|
||||||
|
auto self(shared_from_this());
|
||||||
|
boost::asio::async_write(socket_, reply_.to_buffers(),
|
||||||
|
[this, self](boost::system::error_code ec, std::size_t)
|
||||||
|
{
|
||||||
|
if (!ec)
|
||||||
|
{
|
||||||
|
// Initiate graceful connection closure.
|
||||||
|
boost::system::error_code ignored_ec;
|
||||||
|
socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both,
|
||||||
|
ignored_ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ec != boost::asio::error::operation_aborted)
|
||||||
|
{
|
||||||
|
connection_manager_.stop(shared_from_this());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
79
rudict/rudict/http/connection.hpp
Normal file
79
rudict/rudict/http/connection.hpp
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
//
|
||||||
|
// connection.hpp
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HTTP_CONNECTION_HPP
|
||||||
|
#define HTTP_CONNECTION_HPP
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
#include "boost/asio.hpp"
|
||||||
|
#include "reply.hpp"
|
||||||
|
#include "request.hpp"
|
||||||
|
#include "request_handler.hpp"
|
||||||
|
#include "request_parser.hpp"
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
class connection_manager;
|
||||||
|
|
||||||
|
/// Represents a single connection from a client.
|
||||||
|
class connection
|
||||||
|
: public std::enable_shared_from_this<connection>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
connection(const connection&) = delete;
|
||||||
|
connection& operator=(const connection&) = delete;
|
||||||
|
|
||||||
|
/// Construct a connection with the given socket.
|
||||||
|
explicit connection(boost::asio::ip::tcp::socket socket,
|
||||||
|
connection_manager& manager, request_handler& handler);
|
||||||
|
|
||||||
|
/// Start the first asynchronous operation for the connection.
|
||||||
|
void start();
|
||||||
|
|
||||||
|
/// Stop all asynchronous operations associated with the connection.
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Perform an asynchronous read operation.
|
||||||
|
void do_read();
|
||||||
|
|
||||||
|
/// Perform an asynchronous write operation.
|
||||||
|
void do_write();
|
||||||
|
|
||||||
|
/// Socket for the connection.
|
||||||
|
boost::asio::ip::tcp::socket socket_;
|
||||||
|
|
||||||
|
/// The manager for this connection.
|
||||||
|
connection_manager& connection_manager_;
|
||||||
|
|
||||||
|
/// The handler used to process the incoming request.
|
||||||
|
request_handler& request_handler_;
|
||||||
|
|
||||||
|
/// Buffer for incoming data.
|
||||||
|
std::array<char, 8192> buffer_;
|
||||||
|
|
||||||
|
/// The incoming request.
|
||||||
|
request request_;
|
||||||
|
|
||||||
|
/// The parser for the incoming request.
|
||||||
|
request_parser request_parser_;
|
||||||
|
|
||||||
|
/// The reply to be sent back to the client.
|
||||||
|
reply reply_;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::shared_ptr<connection> connection_ptr;
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
||||||
|
|
||||||
|
#endif // HTTP_CONNECTION_HPP
|
40
rudict/rudict/http/connection_manager.cpp
Normal file
40
rudict/rudict/http/connection_manager.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// connection_manager.cpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "connection_manager.hpp"
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
connection_manager::connection_manager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void connection_manager::start(connection_ptr c)
|
||||||
|
{
|
||||||
|
connections_.insert(c);
|
||||||
|
c->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void connection_manager::stop(connection_ptr c)
|
||||||
|
{
|
||||||
|
connections_.erase(c);
|
||||||
|
c->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void connection_manager::stop_all()
|
||||||
|
{
|
||||||
|
for (auto c: connections_)
|
||||||
|
c->stop();
|
||||||
|
connections_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
48
rudict/rudict/http/connection_manager.hpp
Normal file
48
rudict/rudict/http/connection_manager.hpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// connection_manager.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HTTP_CONNECTION_MANAGER_HPP
|
||||||
|
#define HTTP_CONNECTION_MANAGER_HPP
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include "connection.hpp"
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
/// Manages open connections so that they may be cleanly stopped when the server
|
||||||
|
/// needs to shut down.
|
||||||
|
class connection_manager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
connection_manager(const connection_manager&) = delete;
|
||||||
|
connection_manager& operator=(const connection_manager&) = delete;
|
||||||
|
|
||||||
|
/// Construct a connection manager.
|
||||||
|
connection_manager();
|
||||||
|
|
||||||
|
/// Add the specified connection to the manager and start it.
|
||||||
|
void start(connection_ptr c);
|
||||||
|
|
||||||
|
/// Stop the specified connection.
|
||||||
|
void stop(connection_ptr c);
|
||||||
|
|
||||||
|
/// Stop all connections.
|
||||||
|
void stop_all();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// The managed connections.
|
||||||
|
std::set<connection_ptr> connections_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
||||||
|
|
||||||
|
#endif // HTTP_CONNECTION_MANAGER_HPP
|
28
rudict/rudict/http/header.hpp
Normal file
28
rudict/rudict/http/header.hpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// header.hpp
|
||||||
|
// ~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HTTP_HEADER_HPP
|
||||||
|
#define HTTP_HEADER_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
struct header
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
std::string value;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
||||||
|
|
||||||
|
#endif // HTTP_HEADER_HPP
|
43
rudict/rudict/http/main.cpp
Normal file
43
rudict/rudict/http/main.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// main.cpp
|
||||||
|
// ~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include "server.hpp"
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Check command line arguments.
|
||||||
|
if (argc != 4)
|
||||||
|
{
|
||||||
|
std::cerr << "Usage: http_server <address> <port> <doc_root>\n";
|
||||||
|
std::cerr << " For IPv4, try:\n";
|
||||||
|
std::cerr << " receiver 0.0.0.0 80 .\n";
|
||||||
|
std::cerr << " For IPv6, try:\n";
|
||||||
|
std::cerr << " receiver 0::0 80 .\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialise the server.
|
||||||
|
http::server::server s(argv[1], argv[2], argv[3]);
|
||||||
|
|
||||||
|
// Run the server until stopped.
|
||||||
|
s.run();
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << "exception: " << e.what() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
45
rudict/rudict/http/mime_types.cpp
Normal file
45
rudict/rudict/http/mime_types.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
//
|
||||||
|
// mime_types.cpp
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "mime_types.hpp"
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
namespace mime_types {
|
||||||
|
|
||||||
|
struct mapping
|
||||||
|
{
|
||||||
|
const char* extension;
|
||||||
|
const char* mime_type;
|
||||||
|
} mappings[] =
|
||||||
|
{
|
||||||
|
{ "gif", "image/gif" },
|
||||||
|
{ "htm", "text/html" },
|
||||||
|
{ "html", "text/html" },
|
||||||
|
{ "jpg", "image/jpeg" },
|
||||||
|
{ "png", "image/png" }
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string extension_to_type(const std::string& extension)
|
||||||
|
{
|
||||||
|
for (mapping m: mappings)
|
||||||
|
{
|
||||||
|
if (m.extension == extension)
|
||||||
|
{
|
||||||
|
return m.mime_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "text/plain";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mime_types
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
27
rudict/rudict/http/mime_types.hpp
Normal file
27
rudict/rudict/http/mime_types.hpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// mime_types.hpp
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HTTP_MIME_TYPES_HPP
|
||||||
|
#define HTTP_MIME_TYPES_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
namespace mime_types {
|
||||||
|
|
||||||
|
/// Convert a file extension into a MIME type.
|
||||||
|
std::string extension_to_type(const std::string& extension);
|
||||||
|
|
||||||
|
} // namespace mime_types
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
||||||
|
|
||||||
|
#endif // HTTP_MIME_TYPES_HPP
|
255
rudict/rudict/http/reply.cpp
Normal file
255
rudict/rudict/http/reply.cpp
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
//
|
||||||
|
// reply.cpp
|
||||||
|
// ~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "reply.hpp"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
namespace status_strings {
|
||||||
|
|
||||||
|
const std::string ok =
|
||||||
|
"HTTP/1.0 200 OK\r\n";
|
||||||
|
const std::string created =
|
||||||
|
"HTTP/1.0 201 Created\r\n";
|
||||||
|
const std::string accepted =
|
||||||
|
"HTTP/1.0 202 Accepted\r\n";
|
||||||
|
const std::string no_content =
|
||||||
|
"HTTP/1.0 204 No Content\r\n";
|
||||||
|
const std::string multiple_choices =
|
||||||
|
"HTTP/1.0 300 Multiple Choices\r\n";
|
||||||
|
const std::string moved_permanently =
|
||||||
|
"HTTP/1.0 301 Moved Permanently\r\n";
|
||||||
|
const std::string moved_temporarily =
|
||||||
|
"HTTP/1.0 302 Moved Temporarily\r\n";
|
||||||
|
const std::string not_modified =
|
||||||
|
"HTTP/1.0 304 Not Modified\r\n";
|
||||||
|
const std::string bad_request =
|
||||||
|
"HTTP/1.0 400 Bad Request\r\n";
|
||||||
|
const std::string unauthorized =
|
||||||
|
"HTTP/1.0 401 Unauthorized\r\n";
|
||||||
|
const std::string forbidden =
|
||||||
|
"HTTP/1.0 403 Forbidden\r\n";
|
||||||
|
const std::string not_found =
|
||||||
|
"HTTP/1.0 404 Not Found\r\n";
|
||||||
|
const std::string internal_server_error =
|
||||||
|
"HTTP/1.0 500 Internal Server Error\r\n";
|
||||||
|
const std::string not_implemented =
|
||||||
|
"HTTP/1.0 501 Not Implemented\r\n";
|
||||||
|
const std::string bad_gateway =
|
||||||
|
"HTTP/1.0 502 Bad Gateway\r\n";
|
||||||
|
const std::string service_unavailable =
|
||||||
|
"HTTP/1.0 503 Service Unavailable\r\n";
|
||||||
|
|
||||||
|
boost::asio::const_buffer to_buffer(reply::status_type status)
|
||||||
|
{
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case reply::ok:
|
||||||
|
return boost::asio::buffer(ok);
|
||||||
|
case reply::created:
|
||||||
|
return boost::asio::buffer(created);
|
||||||
|
case reply::accepted:
|
||||||
|
return boost::asio::buffer(accepted);
|
||||||
|
case reply::no_content:
|
||||||
|
return boost::asio::buffer(no_content);
|
||||||
|
case reply::multiple_choices:
|
||||||
|
return boost::asio::buffer(multiple_choices);
|
||||||
|
case reply::moved_permanently:
|
||||||
|
return boost::asio::buffer(moved_permanently);
|
||||||
|
case reply::moved_temporarily:
|
||||||
|
return boost::asio::buffer(moved_temporarily);
|
||||||
|
case reply::not_modified:
|
||||||
|
return boost::asio::buffer(not_modified);
|
||||||
|
case reply::bad_request:
|
||||||
|
return boost::asio::buffer(bad_request);
|
||||||
|
case reply::unauthorized:
|
||||||
|
return boost::asio::buffer(unauthorized);
|
||||||
|
case reply::forbidden:
|
||||||
|
return boost::asio::buffer(forbidden);
|
||||||
|
case reply::not_found:
|
||||||
|
return boost::asio::buffer(not_found);
|
||||||
|
case reply::internal_server_error:
|
||||||
|
return boost::asio::buffer(internal_server_error);
|
||||||
|
case reply::not_implemented:
|
||||||
|
return boost::asio::buffer(not_implemented);
|
||||||
|
case reply::bad_gateway:
|
||||||
|
return boost::asio::buffer(bad_gateway);
|
||||||
|
case reply::service_unavailable:
|
||||||
|
return boost::asio::buffer(service_unavailable);
|
||||||
|
default:
|
||||||
|
return boost::asio::buffer(internal_server_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace status_strings
|
||||||
|
|
||||||
|
namespace misc_strings {
|
||||||
|
|
||||||
|
const char name_value_separator[] = { ':', ' ' };
|
||||||
|
const char crlf[] = { '\r', '\n' };
|
||||||
|
|
||||||
|
} // namespace misc_strings
|
||||||
|
|
||||||
|
std::vector<boost::asio::const_buffer> reply::to_buffers()
|
||||||
|
{
|
||||||
|
std::vector<boost::asio::const_buffer> buffers;
|
||||||
|
buffers.push_back(status_strings::to_buffer(status));
|
||||||
|
for (std::size_t i = 0; i < headers.size(); ++i)
|
||||||
|
{
|
||||||
|
header& h = headers[i];
|
||||||
|
buffers.push_back(boost::asio::buffer(h.name));
|
||||||
|
buffers.push_back(boost::asio::buffer(misc_strings::name_value_separator));
|
||||||
|
buffers.push_back(boost::asio::buffer(h.value));
|
||||||
|
buffers.push_back(boost::asio::buffer(misc_strings::crlf));
|
||||||
|
}
|
||||||
|
buffers.push_back(boost::asio::buffer(misc_strings::crlf));
|
||||||
|
buffers.push_back(boost::asio::buffer(content));
|
||||||
|
return buffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace stock_replies {
|
||||||
|
|
||||||
|
const char ok[] = "";
|
||||||
|
const char created[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Created</title></head>"
|
||||||
|
"<body><h1>201 Created</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char accepted[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Accepted</title></head>"
|
||||||
|
"<body><h1>202 Accepted</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char no_content[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>No Content</title></head>"
|
||||||
|
"<body><h1>204 Content</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char multiple_choices[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Multiple Choices</title></head>"
|
||||||
|
"<body><h1>300 Multiple Choices</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char moved_permanently[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Moved Permanently</title></head>"
|
||||||
|
"<body><h1>301 Moved Permanently</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char moved_temporarily[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Moved Temporarily</title></head>"
|
||||||
|
"<body><h1>302 Moved Temporarily</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char not_modified[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Not Modified</title></head>"
|
||||||
|
"<body><h1>304 Not Modified</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char bad_request[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Bad Request</title></head>"
|
||||||
|
"<body><h1>400 Bad Request</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char unauthorized[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Unauthorized</title></head>"
|
||||||
|
"<body><h1>401 Unauthorized</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char forbidden[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Forbidden</title></head>"
|
||||||
|
"<body><h1>403 Forbidden</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char not_found[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Not Found</title></head>"
|
||||||
|
"<body><h1>404 Not Found</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char internal_server_error[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Internal Server Error</title></head>"
|
||||||
|
"<body><h1>500 Internal Server Error</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char not_implemented[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Not Implemented</title></head>"
|
||||||
|
"<body><h1>501 Not Implemented</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char bad_gateway[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Bad Gateway</title></head>"
|
||||||
|
"<body><h1>502 Bad Gateway</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
const char service_unavailable[] =
|
||||||
|
"<html>"
|
||||||
|
"<head><title>Service Unavailable</title></head>"
|
||||||
|
"<body><h1>503 Service Unavailable</h1></body>"
|
||||||
|
"</html>";
|
||||||
|
|
||||||
|
std::string to_string(reply::status_type status)
|
||||||
|
{
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case reply::ok:
|
||||||
|
return ok;
|
||||||
|
case reply::created:
|
||||||
|
return created;
|
||||||
|
case reply::accepted:
|
||||||
|
return accepted;
|
||||||
|
case reply::no_content:
|
||||||
|
return no_content;
|
||||||
|
case reply::multiple_choices:
|
||||||
|
return multiple_choices;
|
||||||
|
case reply::moved_permanently:
|
||||||
|
return moved_permanently;
|
||||||
|
case reply::moved_temporarily:
|
||||||
|
return moved_temporarily;
|
||||||
|
case reply::not_modified:
|
||||||
|
return not_modified;
|
||||||
|
case reply::bad_request:
|
||||||
|
return bad_request;
|
||||||
|
case reply::unauthorized:
|
||||||
|
return unauthorized;
|
||||||
|
case reply::forbidden:
|
||||||
|
return forbidden;
|
||||||
|
case reply::not_found:
|
||||||
|
return not_found;
|
||||||
|
case reply::internal_server_error:
|
||||||
|
return internal_server_error;
|
||||||
|
case reply::not_implemented:
|
||||||
|
return not_implemented;
|
||||||
|
case reply::bad_gateway:
|
||||||
|
return bad_gateway;
|
||||||
|
case reply::service_unavailable:
|
||||||
|
return service_unavailable;
|
||||||
|
default:
|
||||||
|
return internal_server_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace stock_replies
|
||||||
|
|
||||||
|
reply reply::stock_reply(reply::status_type status)
|
||||||
|
{
|
||||||
|
reply rep;
|
||||||
|
rep.status = status;
|
||||||
|
rep.content = stock_replies::to_string(status);
|
||||||
|
rep.headers.resize(2);
|
||||||
|
rep.headers[0].name = "Content-Length";
|
||||||
|
rep.headers[0].value = std::to_string(rep.content.size());
|
||||||
|
rep.headers[1].name = "Content-Type";
|
||||||
|
rep.headers[1].value = "text/html";
|
||||||
|
return rep;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
64
rudict/rudict/http/reply.hpp
Normal file
64
rudict/rudict/http/reply.hpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// reply.hpp
|
||||||
|
// ~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HTTP_REPLY_HPP
|
||||||
|
#define HTTP_REPLY_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include "header.hpp"
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
/// A reply to be sent to a client.
|
||||||
|
struct reply
|
||||||
|
{
|
||||||
|
/// The status of the reply.
|
||||||
|
enum status_type
|
||||||
|
{
|
||||||
|
ok = 200,
|
||||||
|
created = 201,
|
||||||
|
accepted = 202,
|
||||||
|
no_content = 204,
|
||||||
|
multiple_choices = 300,
|
||||||
|
moved_permanently = 301,
|
||||||
|
moved_temporarily = 302,
|
||||||
|
not_modified = 304,
|
||||||
|
bad_request = 400,
|
||||||
|
unauthorized = 401,
|
||||||
|
forbidden = 403,
|
||||||
|
not_found = 404,
|
||||||
|
internal_server_error = 500,
|
||||||
|
not_implemented = 501,
|
||||||
|
bad_gateway = 502,
|
||||||
|
service_unavailable = 503
|
||||||
|
} status;
|
||||||
|
|
||||||
|
/// The headers to be included in the reply.
|
||||||
|
std::vector<header> headers;
|
||||||
|
|
||||||
|
/// The content to be sent in the reply.
|
||||||
|
std::string content;
|
||||||
|
|
||||||
|
/// Convert the reply into a vector of buffers. The buffers do not own the
|
||||||
|
/// underlying memory blocks, therefore the reply object must remain valid and
|
||||||
|
/// not be changed until the write operation has completed.
|
||||||
|
std::vector<boost::asio::const_buffer> to_buffers();
|
||||||
|
|
||||||
|
/// Get a stock reply.
|
||||||
|
static reply stock_reply(status_type status);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
||||||
|
|
||||||
|
#endif // HTTP_REPLY_HPP
|
34
rudict/rudict/http/request.hpp
Normal file
34
rudict/rudict/http/request.hpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
//
|
||||||
|
// request.hpp
|
||||||
|
// ~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HTTP_REQUEST_HPP
|
||||||
|
#define HTTP_REQUEST_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "header.hpp"
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
/// A request received from a client.
|
||||||
|
struct request
|
||||||
|
{
|
||||||
|
std::string method;
|
||||||
|
std::string uri;
|
||||||
|
int http_version_major;
|
||||||
|
int http_version_minor;
|
||||||
|
std::vector<header> headers;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
||||||
|
|
||||||
|
#endif // HTTP_REQUEST_HPP
|
179
rudict/rudict/http/request_handler.cpp
Normal file
179
rudict/rudict/http/request_handler.cpp
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
//
|
||||||
|
// request_handler.cpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "request_handler.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include "mime_types.hpp"
|
||||||
|
#include "reply.hpp"
|
||||||
|
#include "request.hpp"
|
||||||
|
|
||||||
|
#include "boost/algorithm/string.hpp"
|
||||||
|
#include "boost/property_tree/json_parser.hpp"
|
||||||
|
#include "../utf8utf16.h"
|
||||||
|
#include "../noun.h"
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
request_handler::request_handler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void request_handler::handle_request(const request& req, reply& rep)
|
||||||
|
{
|
||||||
|
// Decode url to path.
|
||||||
|
std::string request_path;
|
||||||
|
if (!url_decode(req.uri, request_path))
|
||||||
|
{
|
||||||
|
rep = reply::stock_reply(reply::bad_request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request path must be absolute and not contain "..".
|
||||||
|
if (request_path.empty() || request_path[0] != '/'
|
||||||
|
|| request_path.find("..") != std::wstring::npos)
|
||||||
|
{
|
||||||
|
rep = reply::stock_reply(reply::bad_request);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If path ends in slash (i.e. is a directory) then add "index.html".
|
||||||
|
if (request_path[request_path.size() - 1] == '/')
|
||||||
|
{
|
||||||
|
request_path += "index.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
//Prepare request
|
||||||
|
if (request_path[0] == '/')
|
||||||
|
{
|
||||||
|
request_path = std::string(request_path.begin() + 1, request_path.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::to_lower(request_path);
|
||||||
|
|
||||||
|
|
||||||
|
std::wstring requestedStr = UTF8to16(request_path.c_str());
|
||||||
|
/*
|
||||||
|
requestedStr = L"Âû çàïðîñèëè: " + requestedStr;
|
||||||
|
|
||||||
|
rep.content = UTF16to8(requestedStr.c_str());
|
||||||
|
|
||||||
|
rep.content = "<html><body>" + rep.content + "</body></html>";
|
||||||
|
*/
|
||||||
|
|
||||||
|
boost::property_tree::wptree propertyTree = PrepareReport(requestedStr);
|
||||||
|
|
||||||
|
std::wstringstream output_stream;
|
||||||
|
|
||||||
|
boost::property_tree::write_json(output_stream, propertyTree);
|
||||||
|
|
||||||
|
std::string outputJsonCode = UTF16to8(output_stream.str().c_str());
|
||||||
|
|
||||||
|
rep.status = reply::ok;
|
||||||
|
|
||||||
|
rep.content = outputJsonCode;
|
||||||
|
|
||||||
|
rep.headers.resize(2);
|
||||||
|
rep.headers[0].name = "Content-Length";
|
||||||
|
rep.headers[0].value = std::to_string(rep.content.size());
|
||||||
|
rep.headers[1].name = "Content-Type";
|
||||||
|
rep.headers[1].value = "application/json; charset=utf-8";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool request_handler::url_decode(const std::string& in, std::string& out)
|
||||||
|
{
|
||||||
|
|
||||||
|
out.clear();
|
||||||
|
out.reserve(in.size());
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < in.size(); ++i)
|
||||||
|
{
|
||||||
|
if (in[i] == '%')
|
||||||
|
{
|
||||||
|
if (i + 3 <= in.size())
|
||||||
|
{
|
||||||
|
int value = 0;
|
||||||
|
std::istringstream is(in.substr(i + 1, 2));
|
||||||
|
if (is >> std::hex >> value)
|
||||||
|
{
|
||||||
|
out += static_cast<char>(value);
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (in[i] == '+')
|
||||||
|
{
|
||||||
|
out += ' ';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out += in[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boost::property_tree::wptree PrepareReport(std::wstring request)
|
||||||
|
{
|
||||||
|
boost::property_tree::wptree result;
|
||||||
|
|
||||||
|
if (request.size() < 2)
|
||||||
|
{
|
||||||
|
result.put(L"error", L"String is too short");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<NounStruct> nounStructArr = RecognizeNoun(request);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int id = 0;
|
||||||
|
|
||||||
|
boost::property_tree::wptree nounArr;
|
||||||
|
|
||||||
|
for (auto& nounStruct : nounStructArr)
|
||||||
|
{
|
||||||
|
boost::property_tree::wptree nounTree;
|
||||||
|
|
||||||
|
nounTree.put(L"id", id);
|
||||||
|
nounTree.put(L"declencion", NounDeclencionToWString(std::get<0>(nounStruct.nounTuple)));
|
||||||
|
nounTree.put(L"grammaticalCase", NounGrammaticalCaseToWString(std::get<1>(nounStruct.nounTuple)));
|
||||||
|
nounTree.put(L"number", NounNumberToWString(std::get<2>(nounStruct.nounTuple)));
|
||||||
|
|
||||||
|
|
||||||
|
nounTree.put(L"nominative", nounStruct.noun);
|
||||||
|
|
||||||
|
nounArr.push_back(std::make_pair(L"", nounTree));
|
||||||
|
|
||||||
|
id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.put_child(L"nouns", nounArr);
|
||||||
|
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
48
rudict/rudict/http/request_handler.hpp
Normal file
48
rudict/rudict/http/request_handler.hpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// request_handler.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HTTP_REQUEST_HANDLER_HPP
|
||||||
|
#define HTTP_REQUEST_HANDLER_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "boost/property_tree/ptree.hpp"
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
struct reply;
|
||||||
|
struct request;
|
||||||
|
|
||||||
|
/// The common handler for all incoming requests.
|
||||||
|
class request_handler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
request_handler(const request_handler&) = delete;
|
||||||
|
request_handler& operator=(const request_handler&) = delete;
|
||||||
|
|
||||||
|
/// Construct with a directory containing files to be served.
|
||||||
|
explicit request_handler();
|
||||||
|
|
||||||
|
/// Handle a request and produce a reply.
|
||||||
|
void handle_request(const request& req, reply& rep);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// Perform URL-decoding on a string. Returns false if the encoding was
|
||||||
|
/// invalid.
|
||||||
|
static bool url_decode(const std::string& in, std::string& out);
|
||||||
|
};
|
||||||
|
|
||||||
|
boost::property_tree::wptree PrepareReport(std::wstring request);
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
||||||
|
|
||||||
|
#endif // HTTP_REQUEST_HANDLER_HPP
|
315
rudict/rudict/http/request_parser.cpp
Normal file
315
rudict/rudict/http/request_parser.cpp
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
//
|
||||||
|
// request_parser.cpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "request_parser.hpp"
|
||||||
|
#include "request.hpp"
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
request_parser::request_parser()
|
||||||
|
: state_(method_start)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void request_parser::reset()
|
||||||
|
{
|
||||||
|
state_ = method_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
request_parser::result_type request_parser::consume(request& req, char input)
|
||||||
|
{
|
||||||
|
switch (state_)
|
||||||
|
{
|
||||||
|
case method_start:
|
||||||
|
if (!is_char(input) || is_ctl(input) || is_tspecial(input))
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state_ = method;
|
||||||
|
req.method.push_back(input);
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
case method:
|
||||||
|
if (input == ' ')
|
||||||
|
{
|
||||||
|
state_ = uri;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
req.method.push_back(input);
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
case uri:
|
||||||
|
if (input == ' ')
|
||||||
|
{
|
||||||
|
state_ = http_version_h;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else if (is_ctl(input))
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
req.uri.push_back(input);
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
case http_version_h:
|
||||||
|
if (input == 'H')
|
||||||
|
{
|
||||||
|
state_ = http_version_t_1;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
case http_version_t_1:
|
||||||
|
if (input == 'T')
|
||||||
|
{
|
||||||
|
state_ = http_version_t_2;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
case http_version_t_2:
|
||||||
|
if (input == 'T')
|
||||||
|
{
|
||||||
|
state_ = http_version_p;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
case http_version_p:
|
||||||
|
if (input == 'P')
|
||||||
|
{
|
||||||
|
state_ = http_version_slash;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
case http_version_slash:
|
||||||
|
if (input == '/')
|
||||||
|
{
|
||||||
|
req.http_version_major = 0;
|
||||||
|
req.http_version_minor = 0;
|
||||||
|
state_ = http_version_major_start;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
case http_version_major_start:
|
||||||
|
if (is_digit(input))
|
||||||
|
{
|
||||||
|
req.http_version_major = req.http_version_major * 10 + input - '0';
|
||||||
|
state_ = http_version_major;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
case http_version_major:
|
||||||
|
if (input == '.')
|
||||||
|
{
|
||||||
|
state_ = http_version_minor_start;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else if (is_digit(input))
|
||||||
|
{
|
||||||
|
req.http_version_major = req.http_version_major * 10 + input - '0';
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
case http_version_minor_start:
|
||||||
|
if (is_digit(input))
|
||||||
|
{
|
||||||
|
req.http_version_minor = req.http_version_minor * 10 + input - '0';
|
||||||
|
state_ = http_version_minor;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
case http_version_minor:
|
||||||
|
if (input == '\r')
|
||||||
|
{
|
||||||
|
state_ = expecting_newline_1;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else if (is_digit(input))
|
||||||
|
{
|
||||||
|
req.http_version_minor = req.http_version_minor * 10 + input - '0';
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
case expecting_newline_1:
|
||||||
|
if (input == '\n')
|
||||||
|
{
|
||||||
|
state_ = header_line_start;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
case header_line_start:
|
||||||
|
if (input == '\r')
|
||||||
|
{
|
||||||
|
state_ = expecting_newline_3;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else if (!req.headers.empty() && (input == ' ' || input == '\t'))
|
||||||
|
{
|
||||||
|
state_ = header_lws;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
req.headers.push_back(header());
|
||||||
|
req.headers.back().name.push_back(input);
|
||||||
|
state_ = header_name;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
case header_lws:
|
||||||
|
if (input == '\r')
|
||||||
|
{
|
||||||
|
state_ = expecting_newline_2;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else if (input == ' ' || input == '\t')
|
||||||
|
{
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else if (is_ctl(input))
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state_ = header_value;
|
||||||
|
req.headers.back().value.push_back(input);
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
case header_name:
|
||||||
|
if (input == ':')
|
||||||
|
{
|
||||||
|
state_ = space_before_header_value;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else if (!is_char(input) || is_ctl(input) || is_tspecial(input))
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
req.headers.back().name.push_back(input);
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
case space_before_header_value:
|
||||||
|
if (input == ' ')
|
||||||
|
{
|
||||||
|
state_ = header_value;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
case header_value:
|
||||||
|
if (input == '\r')
|
||||||
|
{
|
||||||
|
state_ = expecting_newline_2;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else if (is_ctl(input))
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
req.headers.back().value.push_back(input);
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
case expecting_newline_2:
|
||||||
|
if (input == '\n')
|
||||||
|
{
|
||||||
|
state_ = header_line_start;
|
||||||
|
return indeterminate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
case expecting_newline_3:
|
||||||
|
return (input == '\n') ? good : bad;
|
||||||
|
default:
|
||||||
|
return bad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool request_parser::is_char(int c)
|
||||||
|
{
|
||||||
|
return c >= 0 && c <= 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool request_parser::is_ctl(int c)
|
||||||
|
{
|
||||||
|
return (c >= 0 && c <= 31) || (c == 127);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool request_parser::is_tspecial(int c)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '(': case ')': case '<': case '>': case '@':
|
||||||
|
case ',': case ';': case ':': case '\\': case '"':
|
||||||
|
case '/': case '[': case ']': case '?': case '=':
|
||||||
|
case '{': case '}': case ' ': case '\t':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool request_parser::is_digit(int c)
|
||||||
|
{
|
||||||
|
return c >= '0' && c <= '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
96
rudict/rudict/http/request_parser.hpp
Normal file
96
rudict/rudict/http/request_parser.hpp
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
//
|
||||||
|
// request_parser.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HTTP_REQUEST_PARSER_HPP
|
||||||
|
#define HTTP_REQUEST_PARSER_HPP
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
struct request;
|
||||||
|
|
||||||
|
/// Parser for incoming requests.
|
||||||
|
class request_parser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Construct ready to parse the request method.
|
||||||
|
request_parser();
|
||||||
|
|
||||||
|
/// Reset to initial parser state.
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
/// Result of parse.
|
||||||
|
enum result_type { good, bad, indeterminate };
|
||||||
|
|
||||||
|
/// Parse some data. The enum return value is good when a complete request has
|
||||||
|
/// been parsed, bad if the data is invalid, indeterminate when more data is
|
||||||
|
/// required. The InputIterator return value indicates how much of the input
|
||||||
|
/// has been consumed.
|
||||||
|
template <typename InputIterator>
|
||||||
|
std::tuple<result_type, InputIterator> parse(request& req,
|
||||||
|
InputIterator begin, InputIterator end)
|
||||||
|
{
|
||||||
|
while (begin != end)
|
||||||
|
{
|
||||||
|
result_type result = consume(req, *begin++);
|
||||||
|
if (result == good || result == bad)
|
||||||
|
return std::make_tuple(result, begin);
|
||||||
|
}
|
||||||
|
return std::make_tuple(indeterminate, begin);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Handle the next character of input.
|
||||||
|
result_type consume(request& req, char input);
|
||||||
|
|
||||||
|
/// Check if a byte is an HTTP character.
|
||||||
|
static bool is_char(int c);
|
||||||
|
|
||||||
|
/// Check if a byte is an HTTP control character.
|
||||||
|
static bool is_ctl(int c);
|
||||||
|
|
||||||
|
/// Check if a byte is defined as an HTTP tspecial character.
|
||||||
|
static bool is_tspecial(int c);
|
||||||
|
|
||||||
|
/// Check if a byte is a digit.
|
||||||
|
static bool is_digit(int c);
|
||||||
|
|
||||||
|
/// The current state of the parser.
|
||||||
|
enum state
|
||||||
|
{
|
||||||
|
method_start,
|
||||||
|
method,
|
||||||
|
uri,
|
||||||
|
http_version_h,
|
||||||
|
http_version_t_1,
|
||||||
|
http_version_t_2,
|
||||||
|
http_version_p,
|
||||||
|
http_version_slash,
|
||||||
|
http_version_major_start,
|
||||||
|
http_version_major,
|
||||||
|
http_version_minor_start,
|
||||||
|
http_version_minor,
|
||||||
|
expecting_newline_1,
|
||||||
|
header_line_start,
|
||||||
|
header_lws,
|
||||||
|
header_name,
|
||||||
|
space_before_header_value,
|
||||||
|
header_value,
|
||||||
|
expecting_newline_2,
|
||||||
|
expecting_newline_3
|
||||||
|
} state_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
||||||
|
|
||||||
|
#endif // HTTP_REQUEST_PARSER_HPP
|
93
rudict/rudict/http/server.cpp
Normal file
93
rudict/rudict/http/server.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
//
|
||||||
|
// server.cpp
|
||||||
|
// ~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "server.hpp"
|
||||||
|
#include <signal.h>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
server::server(const std::string& address, const std::string& port)
|
||||||
|
: io_service_(),
|
||||||
|
signals_(io_service_),
|
||||||
|
acceptor_(io_service_),
|
||||||
|
connection_manager_(),
|
||||||
|
socket_(io_service_),
|
||||||
|
request_handler_()
|
||||||
|
{
|
||||||
|
// Register to handle the signals that indicate when the server should exit.
|
||||||
|
// It is safe to register for the same signal multiple times in a program,
|
||||||
|
// provided all registration for the specified signal is made through Asio.
|
||||||
|
signals_.add(SIGINT);
|
||||||
|
signals_.add(SIGTERM);
|
||||||
|
#if defined(SIGQUIT)
|
||||||
|
signals_.add(SIGQUIT);
|
||||||
|
#endif // defined(SIGQUIT)
|
||||||
|
|
||||||
|
do_await_stop();
|
||||||
|
|
||||||
|
// Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
|
||||||
|
boost::asio::ip::tcp::resolver resolver(io_service_);
|
||||||
|
boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve({address, port});
|
||||||
|
acceptor_.open(endpoint.protocol());
|
||||||
|
acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
|
||||||
|
acceptor_.bind(endpoint);
|
||||||
|
acceptor_.listen();
|
||||||
|
|
||||||
|
do_accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void server::run()
|
||||||
|
{
|
||||||
|
// The io_service::run() call will block until all asynchronous operations
|
||||||
|
// have finished. While the server is running, there is always at least one
|
||||||
|
// asynchronous operation outstanding: the asynchronous accept call waiting
|
||||||
|
// for new incoming connections.
|
||||||
|
io_service_.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void server::do_accept()
|
||||||
|
{
|
||||||
|
acceptor_.async_accept(socket_,
|
||||||
|
[this](boost::system::error_code ec)
|
||||||
|
{
|
||||||
|
// Check whether the server was stopped by a signal before this
|
||||||
|
// completion handler had a chance to run.
|
||||||
|
if (!acceptor_.is_open())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ec)
|
||||||
|
{
|
||||||
|
connection_manager_.start(std::make_shared<connection>(
|
||||||
|
std::move(socket_), connection_manager_, request_handler_));
|
||||||
|
}
|
||||||
|
|
||||||
|
do_accept();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void server::do_await_stop()
|
||||||
|
{
|
||||||
|
signals_.async_wait(
|
||||||
|
[this](boost::system::error_code /*ec*/, int /*signo*/)
|
||||||
|
{
|
||||||
|
// The server is stopped by cancelling all outstanding asynchronous
|
||||||
|
// operations. Once all operations have finished the io_service::run()
|
||||||
|
// call will exit.
|
||||||
|
acceptor_.close();
|
||||||
|
connection_manager_.stop_all();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
66
rudict/rudict/http/server.hpp
Normal file
66
rudict/rudict/http/server.hpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
//
|
||||||
|
// server.hpp
|
||||||
|
// ~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HTTP_SERVER_HPP
|
||||||
|
#define HTTP_SERVER_HPP
|
||||||
|
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include "connection.hpp"
|
||||||
|
#include "connection_manager.hpp"
|
||||||
|
#include "request_handler.hpp"
|
||||||
|
|
||||||
|
namespace http {
|
||||||
|
namespace server {
|
||||||
|
|
||||||
|
/// The top-level class of the HTTP server.
|
||||||
|
class server
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
server(const server&) = delete;
|
||||||
|
server& operator=(const server&) = delete;
|
||||||
|
|
||||||
|
/// Construct the server to listen on the specified TCP address and port, and
|
||||||
|
/// serve up files from the given directory.
|
||||||
|
explicit server(const std::string& address, const std::string& port);
|
||||||
|
|
||||||
|
/// Run the server's io_service loop.
|
||||||
|
void run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Perform an asynchronous accept operation.
|
||||||
|
void do_accept();
|
||||||
|
|
||||||
|
/// Wait for a request to stop the server.
|
||||||
|
void do_await_stop();
|
||||||
|
|
||||||
|
/// The io_service used to perform asynchronous operations.
|
||||||
|
boost::asio::io_service io_service_;
|
||||||
|
|
||||||
|
/// The signal_set is used to register for process termination notifications.
|
||||||
|
boost::asio::signal_set signals_;
|
||||||
|
|
||||||
|
/// Acceptor used to listen for incoming connections.
|
||||||
|
boost::asio::ip::tcp::acceptor acceptor_;
|
||||||
|
|
||||||
|
/// The connection manager which owns all live connections.
|
||||||
|
connection_manager connection_manager_;
|
||||||
|
|
||||||
|
/// The next socket to be accepted.
|
||||||
|
boost::asio::ip::tcp::socket socket_;
|
||||||
|
|
||||||
|
/// The handler for all incoming requests.
|
||||||
|
request_handler request_handler_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace server
|
||||||
|
} // namespace http
|
||||||
|
|
||||||
|
#endif // HTTP_SERVER_HPP
|
82
rudict/rudict/linux/makefile
Normal file
82
rudict/rudict/linux/makefile
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
CC=g++
|
||||||
|
CFLAGS=-Wall -O3 -std=gnu++0x
|
||||||
|
LDFLAGS= -lpthread -lrt -lmysqlconn-static -L/usr/local/lib
|
||||||
|
|
||||||
|
BoostPath=../../../../boost_1_56_0
|
||||||
|
|
||||||
|
|
||||||
|
#======================================================
|
||||||
|
#====================== BOOST =========================
|
||||||
|
#======================================================
|
||||||
|
|
||||||
|
CFLAGS += -I$(BoostPath) -I/usr/local/include -I/home/devuser/workplace/mysql-connector-c++-1.1.4/driver
|
||||||
|
|
||||||
|
#thread
|
||||||
|
LOCAL_SRC_FILES := $(BoostPath)/libs/thread/src/pthread/thread.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/thread/src/pthread/once.cpp
|
||||||
|
|
||||||
|
#signals
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/signals/src/connection.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/signals/src/named_slot_map.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/signals/src/signal_base.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/signals/src/slot.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/signals/src/trackable.cpp
|
||||||
|
|
||||||
|
#system
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/system/src/error_code.cpp
|
||||||
|
|
||||||
|
#regex
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/c_regex_traits.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/cpp_regex_traits.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/cregex.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/fileiter.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/icu.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/instances.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/posix_api.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/regex.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/regex_debug.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/regex_raw_buffer.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/regex_traits_defaults.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/static_mutex.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/usinstances.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/w32_regex_traits.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/wc_regex_traits.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/wide_posix_api.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/regex/src/winstances.cpp
|
||||||
|
|
||||||
|
#date_time
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/date_time/src/gregorian/greg_month.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/date_time/src/gregorian/greg_weekday.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/date_time/src/gregorian/date_generators.cpp
|
||||||
|
|
||||||
|
#filesystem
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/filesystem/src/codecvt_error_category.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/filesystem/src/operations.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/filesystem/src/path.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/filesystem/src/path_traits.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/filesystem/src/portability.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/filesystem/src/unique_path.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/filesystem/src/utf8_codecvt_facet.cpp
|
||||||
|
LOCAL_SRC_FILES += $(BoostPath)/libs/filesystem/src/windows_file_codecvt.cpp
|
||||||
|
|
||||||
|
#======================================================
|
||||||
|
#====================== GAME ==========================
|
||||||
|
#======================================================
|
||||||
|
|
||||||
|
CFLAGS += -I../ntrip
|
||||||
|
LOCAL_SRC_FILES += ../http/connection.cpp
|
||||||
|
LOCAL_SRC_FILES += ../http/connection_manager.cpp
|
||||||
|
LOCAL_SRC_FILES += ../http/mime_types.cpp
|
||||||
|
LOCAL_SRC_FILES += ../http/reply.cpp
|
||||||
|
LOCAL_SRC_FILES += ../http/request_handler.cpp
|
||||||
|
LOCAL_SRC_FILES += ../http/request_parser.cpp
|
||||||
|
LOCAL_SRC_FILES += ../http/server.cpp
|
||||||
|
|
||||||
|
LOCAL_SRC_FILES += ../utf8utf16.cpp
|
||||||
|
LOCAL_SRC_FILES += ../noun.cpp
|
||||||
|
LOCAL_SRC_FILES += ../main.cpp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
all:
|
||||||
|
$(CC) $(LOCAL_SRC_FILES) $(CFLAGS) $(LDFLAGS) -o rudict
|
@ -1,6 +1,8 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "boost/asio.hpp"
|
||||||
|
#include "http/server.hpp"
|
||||||
|
|
||||||
#include "noun.h"
|
#include "noun.h"
|
||||||
|
|
||||||
@ -8,14 +10,29 @@ int main()
|
|||||||
{
|
{
|
||||||
LoadFrequentWordSet();
|
LoadFrequentWordSet();
|
||||||
|
|
||||||
std::wstring s(L"ïîÿñíèöåé");
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
// Initialise the server.
|
||||||
|
http::server::server s("0.0.0.0", "8843");
|
||||||
|
|
||||||
|
// Run the server until stopped.
|
||||||
|
s.run();
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << "exception: " << e.what() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
std::wstring s(L"óðîäàì");
|
||||||
|
|
||||||
std::vector<NounStruct> recognizedResultArr = RecognizeNoun(s);
|
std::vector<NounStruct> recognizedResultArr = RecognizeNoun(s);
|
||||||
|
|
||||||
for (auto& i : recognizedResultArr)
|
for (auto& i : recognizedResultArr)
|
||||||
{
|
{
|
||||||
std::wcout << i.noun << L"\n";
|
std::wcout << i.noun << L"\n";
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,49 @@
|
|||||||
#include <iostream> //Xperimental -- for debug only
|
#include <iostream> //Xperimental -- for debug only
|
||||||
|
|
||||||
|
|
||||||
|
std::wstring NounDeclencionToWString(NounDeclencion nounDeclencion)
|
||||||
|
{
|
||||||
|
switch (nounDeclencion)
|
||||||
|
{
|
||||||
|
case ND_1_HARD: return L"First declencion (hard type), female";
|
||||||
|
case ND_1_SOFT: return L"First declencion (soft type), female";
|
||||||
|
case ND_2_HARD_MALE: return L"Second declencion (hard type), male";
|
||||||
|
case ND_2_SOFT_MALE: return L"Second declencion (soft type), male";
|
||||||
|
case ND_2_NEUTER_O: return L"Second declencion, E-ending, neuter";
|
||||||
|
case ND_2_NEUTER_E: return L"Second declencion, O-ending, neuter";
|
||||||
|
case ND_3: return L"Third declencion, female";
|
||||||
|
}
|
||||||
|
|
||||||
|
return L"";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::wstring NounGrammaticalCaseToWString(NounGrammaticalCase nounGrammaticalCase)
|
||||||
|
{
|
||||||
|
switch (nounGrammaticalCase)
|
||||||
|
{
|
||||||
|
case NGC_P1_NOMINATIVE: return L"Nominative case";
|
||||||
|
case NGC_P2_GENITIVE: return L"Genitive case";
|
||||||
|
case NGC_P3_DATIVE: return L"Dative case";
|
||||||
|
case NGC_P4_ACCUSATIVE: return L"Accusative case";
|
||||||
|
case NGC_P5_INSTRUMENTAL: return L"Instrumental case";
|
||||||
|
case NGC_P6_PREPOSITIONAL: return L"Prepositional case";
|
||||||
|
}
|
||||||
|
|
||||||
|
return L"";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring NounNumberToWString(NounNumber nounNumber)
|
||||||
|
{
|
||||||
|
switch (nounNumber)
|
||||||
|
{
|
||||||
|
case NPF_SINGULAR: return L"Singular form";
|
||||||
|
case NPF_PLURAL: return L"Plural form";
|
||||||
|
}
|
||||||
|
|
||||||
|
return L"";
|
||||||
|
}
|
||||||
|
|
||||||
std::set<std::wstring> frequentWordSet;
|
std::set<std::wstring> frequentWordSet;
|
||||||
|
|
||||||
std::vector<std::wstring> GetAllNounEndingArr()
|
std::vector<std::wstring> GetAllNounEndingArr()
|
||||||
@ -37,112 +80,112 @@ std::vector<std::wstring> GetAllNounEndingArr()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<NounTuple, std::wstring> getNounEndingTable()
|
std::map<NounTuple, StringSet> getNounEndingTable()
|
||||||
{
|
{
|
||||||
std::map<NounTuple, std::wstring> result;
|
std::map<NounTuple, StringSet> result;
|
||||||
|
|
||||||
//Singular
|
//Singular
|
||||||
result[NounTuple{ ND_1_SOFT, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = L"à";
|
result[NounTuple{ ND_1_SOFT, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = StringSet{ L"à" };
|
||||||
result[NounTuple{ ND_1_SOFT, NGC_P2_GENITIVE, NPF_SINGULAR }] = L"è";
|
result[NounTuple{ ND_1_SOFT, NGC_P2_GENITIVE, NPF_SINGULAR }] = StringSet{L"è"};
|
||||||
result[NounTuple{ ND_1_SOFT, NGC_P3_DATIVE, NPF_SINGULAR }] = L"å";
|
result[NounTuple{ ND_1_SOFT, NGC_P3_DATIVE, NPF_SINGULAR }] = StringSet{L"å"};
|
||||||
result[NounTuple{ ND_1_SOFT, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = L"ó";
|
result[NounTuple{ ND_1_SOFT, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = StringSet{L"ó"};
|
||||||
result[NounTuple{ ND_1_SOFT, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = L"îé"; //Xperimental -- need also deal with "îþ" ending
|
result[NounTuple{ ND_1_SOFT, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = StringSet{ L"îé", L"îþ" };
|
||||||
result[NounTuple{ ND_1_SOFT, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = L"å";
|
result[NounTuple{ ND_1_SOFT, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = StringSet{L"å"};
|
||||||
|
|
||||||
result[NounTuple{ ND_1_HARD, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = L"à";
|
result[NounTuple{ ND_1_HARD, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = StringSet{L"à"};
|
||||||
result[NounTuple{ ND_1_HARD, NGC_P2_GENITIVE, NPF_SINGULAR }] = L"û";
|
result[NounTuple{ ND_1_HARD, NGC_P2_GENITIVE, NPF_SINGULAR }] = StringSet{L"û"};
|
||||||
result[NounTuple{ ND_1_HARD, NGC_P3_DATIVE, NPF_SINGULAR }] = L"å";
|
result[NounTuple{ ND_1_HARD, NGC_P3_DATIVE, NPF_SINGULAR }] = StringSet{L"å"};
|
||||||
result[NounTuple{ ND_1_HARD, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = L"ó";
|
result[NounTuple{ ND_1_HARD, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = StringSet{L"ó"};
|
||||||
result[NounTuple{ ND_1_HARD, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = L"îé"; //Xperimental -- need also deal with "îþ" ending
|
result[NounTuple{ ND_1_HARD, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = StringSet{ L"îé", L"îþ", L"åé", L"åþ" };
|
||||||
result[NounTuple{ ND_1_HARD, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = L"å";
|
result[NounTuple{ ND_1_HARD, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = StringSet{L"å"};
|
||||||
|
|
||||||
|
|
||||||
result[NounTuple{ ND_2_HARD_MALE, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = L"";
|
result[NounTuple{ ND_2_HARD_MALE, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = StringSet{L""};
|
||||||
result[NounTuple{ ND_2_HARD_MALE, NGC_P2_GENITIVE, NPF_SINGULAR }] = L"à";
|
result[NounTuple{ ND_2_HARD_MALE, NGC_P2_GENITIVE, NPF_SINGULAR }] = StringSet{L"à"};
|
||||||
result[NounTuple{ ND_2_HARD_MALE, NGC_P3_DATIVE, NPF_SINGULAR }] = L"ó";
|
result[NounTuple{ ND_2_HARD_MALE, NGC_P3_DATIVE, NPF_SINGULAR }] = StringSet{L"ó"};
|
||||||
result[NounTuple{ ND_2_HARD_MALE, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = L"";
|
result[NounTuple{ ND_2_HARD_MALE, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = StringSet{L""};
|
||||||
result[NounTuple{ ND_2_HARD_MALE, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = L"îì";
|
result[NounTuple{ ND_2_HARD_MALE, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = StringSet{L"îì"};
|
||||||
result[NounTuple{ ND_2_HARD_MALE, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = L"å";
|
result[NounTuple{ ND_2_HARD_MALE, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = StringSet{L"å"};
|
||||||
|
|
||||||
result[NounTuple{ ND_2_SOFT_MALE, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = L"ü";
|
result[NounTuple{ ND_2_SOFT_MALE, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = StringSet{L"ü"};
|
||||||
result[NounTuple{ ND_2_SOFT_MALE, NGC_P2_GENITIVE, NPF_SINGULAR }] = L"ÿ";
|
result[NounTuple{ ND_2_SOFT_MALE, NGC_P2_GENITIVE, NPF_SINGULAR }] = StringSet{L"ÿ"};
|
||||||
result[NounTuple{ ND_2_SOFT_MALE, NGC_P3_DATIVE, NPF_SINGULAR }] = L"þ";
|
result[NounTuple{ ND_2_SOFT_MALE, NGC_P3_DATIVE, NPF_SINGULAR }] = StringSet{L"þ"};
|
||||||
result[NounTuple{ ND_2_SOFT_MALE, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = L"ü";
|
result[NounTuple{ ND_2_SOFT_MALE, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = StringSet{L"ü"};
|
||||||
result[NounTuple{ ND_2_SOFT_MALE, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = L"åì";
|
result[NounTuple{ ND_2_SOFT_MALE, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = StringSet{L"åì"};
|
||||||
result[NounTuple{ ND_2_SOFT_MALE, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = L"å";
|
result[NounTuple{ ND_2_SOFT_MALE, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = StringSet{L"å"};
|
||||||
|
|
||||||
|
|
||||||
result[NounTuple{ ND_2_NEUTER_O, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = L"î";
|
result[NounTuple{ ND_2_NEUTER_O, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = StringSet{L"î"};
|
||||||
result[NounTuple{ ND_2_NEUTER_O, NGC_P2_GENITIVE, NPF_SINGULAR }] = L"à";
|
result[NounTuple{ ND_2_NEUTER_O, NGC_P2_GENITIVE, NPF_SINGULAR }] = StringSet{L"à"};
|
||||||
result[NounTuple{ ND_2_NEUTER_O, NGC_P3_DATIVE, NPF_SINGULAR }] = L"ó";
|
result[NounTuple{ ND_2_NEUTER_O, NGC_P3_DATIVE, NPF_SINGULAR }] = StringSet{L"ó"};
|
||||||
result[NounTuple{ ND_2_NEUTER_O, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = L"î";
|
result[NounTuple{ ND_2_NEUTER_O, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = StringSet{L"î"};
|
||||||
result[NounTuple{ ND_2_NEUTER_O, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = L"îì";
|
result[NounTuple{ ND_2_NEUTER_O, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = StringSet{L"îì"};
|
||||||
result[NounTuple{ ND_2_NEUTER_O, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = L"å";
|
result[NounTuple{ ND_2_NEUTER_O, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = StringSet{L"å"};
|
||||||
|
|
||||||
result[NounTuple{ ND_2_NEUTER_E, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = L"å";
|
result[NounTuple{ ND_2_NEUTER_E, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = StringSet{L"å"};
|
||||||
result[NounTuple{ ND_2_NEUTER_E, NGC_P2_GENITIVE, NPF_SINGULAR }] = L"ÿ";
|
result[NounTuple{ ND_2_NEUTER_E, NGC_P2_GENITIVE, NPF_SINGULAR }] = StringSet{L"ÿ"};
|
||||||
result[NounTuple{ ND_2_NEUTER_E, NGC_P3_DATIVE, NPF_SINGULAR }] = L"þ";
|
result[NounTuple{ ND_2_NEUTER_E, NGC_P3_DATIVE, NPF_SINGULAR }] = StringSet{L"þ"};
|
||||||
result[NounTuple{ ND_2_NEUTER_E, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = L"å";
|
result[NounTuple{ ND_2_NEUTER_E, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = StringSet{L"å"};
|
||||||
result[NounTuple{ ND_2_NEUTER_E, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = L"åì";
|
result[NounTuple{ ND_2_NEUTER_E, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = StringSet{L"åì"};
|
||||||
result[NounTuple{ ND_2_NEUTER_E, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = L"å";
|
result[NounTuple{ ND_2_NEUTER_E, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = StringSet{L"å"};
|
||||||
|
|
||||||
result[NounTuple{ ND_3, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = L"ü";
|
result[NounTuple{ ND_3, NGC_P1_NOMINATIVE, NPF_SINGULAR }] = StringSet{L"ü"};
|
||||||
result[NounTuple{ ND_3, NGC_P2_GENITIVE, NPF_SINGULAR }] = L"è";
|
result[NounTuple{ ND_3, NGC_P2_GENITIVE, NPF_SINGULAR }] = StringSet{L"è"};
|
||||||
result[NounTuple{ ND_3, NGC_P3_DATIVE, NPF_SINGULAR }] = L"è";
|
result[NounTuple{ ND_3, NGC_P3_DATIVE, NPF_SINGULAR }] = StringSet{L"è"};
|
||||||
result[NounTuple{ ND_3, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = L"ü";
|
result[NounTuple{ ND_3, NGC_P4_ACCUSATIVE, NPF_SINGULAR }] = StringSet{L"ü"};
|
||||||
result[NounTuple{ ND_3, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = L"üþ";
|
result[NounTuple{ ND_3, NGC_P5_INSTRUMENTAL, NPF_SINGULAR }] = StringSet{L"üþ"};
|
||||||
result[NounTuple{ ND_3, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = L"è";
|
result[NounTuple{ ND_3, NGC_P6_PREPOSITIONAL, NPF_SINGULAR }] = StringSet{L"è"};
|
||||||
|
|
||||||
//Plural
|
//Plural
|
||||||
result[NounTuple{ ND_1_SOFT, NGC_P1_NOMINATIVE, NPF_PLURAL }] = L"è";
|
result[NounTuple{ ND_1_SOFT, NGC_P1_NOMINATIVE, NPF_PLURAL }] = StringSet{L"è"};
|
||||||
result[NounTuple{ ND_1_SOFT, NGC_P2_GENITIVE, NPF_PLURAL }] = L""; //Xperimental -- need special modificator for suffix
|
result[NounTuple{ ND_1_SOFT, NGC_P2_GENITIVE, NPF_PLURAL }] = StringSet{L""}; //Xperimental -- need special modificator for suffix
|
||||||
result[NounTuple{ ND_1_SOFT, NGC_P3_DATIVE, NPF_PLURAL }] = L"àì";
|
result[NounTuple{ ND_1_SOFT, NGC_P3_DATIVE, NPF_PLURAL }] = StringSet{L"àì"};
|
||||||
result[NounTuple{ ND_1_SOFT, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = L"è";
|
result[NounTuple{ ND_1_SOFT, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = StringSet{L"è"};
|
||||||
result[NounTuple{ ND_1_SOFT, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = L"àìè";
|
result[NounTuple{ ND_1_SOFT, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = StringSet{L"àìè"};
|
||||||
result[NounTuple{ ND_1_SOFT, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = L"àõ";
|
result[NounTuple{ ND_1_SOFT, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = StringSet{L"àõ"};
|
||||||
|
|
||||||
result[NounTuple{ ND_1_HARD, NGC_P1_NOMINATIVE, NPF_PLURAL }] = L"è";
|
result[NounTuple{ ND_1_HARD, NGC_P1_NOMINATIVE, NPF_PLURAL }] = StringSet{L"è"};
|
||||||
result[NounTuple{ ND_1_HARD, NGC_P2_GENITIVE, NPF_PLURAL }] = L"";
|
result[NounTuple{ ND_1_HARD, NGC_P2_GENITIVE, NPF_PLURAL }] = StringSet{L""};
|
||||||
result[NounTuple{ ND_1_HARD, NGC_P3_DATIVE, NPF_PLURAL }] = L"àì";
|
result[NounTuple{ ND_1_HARD, NGC_P3_DATIVE, NPF_PLURAL }] = StringSet{L"àì"};
|
||||||
result[NounTuple{ ND_1_HARD, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = L"";
|
result[NounTuple{ ND_1_HARD, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = StringSet{L""};
|
||||||
result[NounTuple{ ND_1_HARD, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = L"àìè";
|
result[NounTuple{ ND_1_HARD, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = StringSet{L"àìè"};
|
||||||
result[NounTuple{ ND_1_HARD, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = L"àõ";
|
result[NounTuple{ ND_1_HARD, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = StringSet{L"àõ"};
|
||||||
|
|
||||||
|
|
||||||
result[NounTuple{ ND_2_HARD_MALE, NGC_P1_NOMINATIVE, NPF_PLURAL }] = L"û";
|
result[NounTuple{ ND_2_HARD_MALE, NGC_P1_NOMINATIVE, NPF_PLURAL }] = StringSet{L"û"};
|
||||||
result[NounTuple{ ND_2_HARD_MALE, NGC_P2_GENITIVE, NPF_PLURAL }] = L"îâ";
|
result[NounTuple{ ND_2_HARD_MALE, NGC_P2_GENITIVE, NPF_PLURAL }] = StringSet{L"îâ"};
|
||||||
result[NounTuple{ ND_2_HARD_MALE, NGC_P3_DATIVE, NPF_PLURAL }] = L"àì";
|
result[NounTuple{ ND_2_HARD_MALE, NGC_P3_DATIVE, NPF_PLURAL }] = StringSet{L"àì"};
|
||||||
result[NounTuple{ ND_2_HARD_MALE, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = L"û";
|
result[NounTuple{ ND_2_HARD_MALE, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = StringSet{L"û"};
|
||||||
result[NounTuple{ ND_2_HARD_MALE, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = L"àìè";
|
result[NounTuple{ ND_2_HARD_MALE, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = StringSet{L"àìè"};
|
||||||
result[NounTuple{ ND_2_HARD_MALE, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = L"àõ";
|
result[NounTuple{ ND_2_HARD_MALE, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = StringSet{L"àõ"};
|
||||||
|
|
||||||
result[NounTuple{ ND_2_SOFT_MALE, NGC_P1_NOMINATIVE, NPF_PLURAL }] = L"è";
|
result[NounTuple{ ND_2_SOFT_MALE, NGC_P1_NOMINATIVE, NPF_PLURAL }] = StringSet{L"è"};
|
||||||
result[NounTuple{ ND_2_SOFT_MALE, NGC_P2_GENITIVE, NPF_PLURAL }] = L"åé";
|
result[NounTuple{ ND_2_SOFT_MALE, NGC_P2_GENITIVE, NPF_PLURAL }] = StringSet{L"åé"};
|
||||||
result[NounTuple{ ND_2_SOFT_MALE, NGC_P3_DATIVE, NPF_PLURAL }] = L"ÿì";
|
result[NounTuple{ ND_2_SOFT_MALE, NGC_P3_DATIVE, NPF_PLURAL }] = StringSet{L"ÿì"};
|
||||||
result[NounTuple{ ND_2_SOFT_MALE, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = L"è";
|
result[NounTuple{ ND_2_SOFT_MALE, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = StringSet{L"è"};
|
||||||
result[NounTuple{ ND_2_SOFT_MALE, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = L"è";
|
result[NounTuple{ ND_2_SOFT_MALE, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = StringSet{L"è"};
|
||||||
result[NounTuple{ ND_2_SOFT_MALE, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = L"ÿõ";
|
result[NounTuple{ ND_2_SOFT_MALE, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = StringSet{L"ÿõ"};
|
||||||
|
|
||||||
result[NounTuple{ ND_2_NEUTER_O, NGC_P1_NOMINATIVE, NPF_PLURAL }] = L"à";
|
result[NounTuple{ ND_2_NEUTER_O, NGC_P1_NOMINATIVE, NPF_PLURAL }] = StringSet{L"à"};
|
||||||
result[NounTuple{ ND_2_NEUTER_O, NGC_P2_GENITIVE, NPF_PLURAL }] = L"";
|
result[NounTuple{ ND_2_NEUTER_O, NGC_P2_GENITIVE, NPF_PLURAL }] = StringSet{L""};
|
||||||
result[NounTuple{ ND_2_NEUTER_O, NGC_P3_DATIVE, NPF_PLURAL }] = L"àì";
|
result[NounTuple{ ND_2_NEUTER_O, NGC_P3_DATIVE, NPF_PLURAL }] = StringSet{L"àì"};
|
||||||
result[NounTuple{ ND_2_NEUTER_O, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = L"à";
|
result[NounTuple{ ND_2_NEUTER_O, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = StringSet{L"à"};
|
||||||
result[NounTuple{ ND_2_NEUTER_O, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = L"àìè";
|
result[NounTuple{ ND_2_NEUTER_O, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = StringSet{L"àìè"};
|
||||||
result[NounTuple{ ND_2_NEUTER_O, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = L"àõ";
|
result[NounTuple{ ND_2_NEUTER_O, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = StringSet{L"àõ"};
|
||||||
|
|
||||||
result[NounTuple{ ND_2_NEUTER_E, NGC_P1_NOMINATIVE, NPF_PLURAL }] = L"ÿ";
|
result[NounTuple{ ND_2_NEUTER_E, NGC_P1_NOMINATIVE, NPF_PLURAL }] = StringSet{L"ÿ"};
|
||||||
result[NounTuple{ ND_2_NEUTER_E, NGC_P2_GENITIVE, NPF_PLURAL }] = L"åé";
|
result[NounTuple{ ND_2_NEUTER_E, NGC_P2_GENITIVE, NPF_PLURAL }] = StringSet{L"åé"};
|
||||||
result[NounTuple{ ND_2_NEUTER_E, NGC_P3_DATIVE, NPF_PLURAL }] = L"ÿì";
|
result[NounTuple{ ND_2_NEUTER_E, NGC_P3_DATIVE, NPF_PLURAL }] = StringSet{L"ÿì"};
|
||||||
result[NounTuple{ ND_2_NEUTER_E, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = L"ÿ";
|
result[NounTuple{ ND_2_NEUTER_E, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = StringSet{L"ÿ"};
|
||||||
result[NounTuple{ ND_2_NEUTER_E, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = L"ÿìè";
|
result[NounTuple{ ND_2_NEUTER_E, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = StringSet{L"ÿìè"};
|
||||||
result[NounTuple{ ND_2_NEUTER_E, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = L"ÿõ";
|
result[NounTuple{ ND_2_NEUTER_E, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = StringSet{L"ÿõ"};
|
||||||
|
|
||||||
result[NounTuple{ ND_3, NGC_P1_NOMINATIVE, NPF_PLURAL }] = L"è";
|
result[NounTuple{ ND_3, NGC_P1_NOMINATIVE, NPF_PLURAL }] = StringSet{L"è"};
|
||||||
result[NounTuple{ ND_3, NGC_P2_GENITIVE, NPF_PLURAL }] = L"åé";
|
result[NounTuple{ ND_3, NGC_P2_GENITIVE, NPF_PLURAL }] = StringSet{L"åé"};
|
||||||
result[NounTuple{ ND_3, NGC_P3_DATIVE, NPF_PLURAL }] = L"ÿì";
|
result[NounTuple{ ND_3, NGC_P3_DATIVE, NPF_PLURAL }] = StringSet{L"ÿì"};
|
||||||
result[NounTuple{ ND_3, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = L"è";
|
result[NounTuple{ ND_3, NGC_P4_ACCUSATIVE, NPF_PLURAL }] = StringSet{L"è"};
|
||||||
result[NounTuple{ ND_3, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = L"ÿìè";
|
result[NounTuple{ ND_3, NGC_P5_INSTRUMENTAL, NPF_PLURAL }] = StringSet{L"ÿìè"};
|
||||||
result[NounTuple{ ND_3, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = L"ÿõ";
|
result[NounTuple{ ND_3, NGC_P6_PREPOSITIONAL, NPF_PLURAL }] = StringSet{L"ÿõ"};
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -252,7 +295,7 @@ std::vector<NounTuple> GetPossibleNounTupleArr(std::wstring nounEnding)
|
|||||||
|
|
||||||
for (auto i : nounEndingTable)
|
for (auto i : nounEndingTable)
|
||||||
{
|
{
|
||||||
if (i.second == nounEnding)
|
if (i.second.count(nounEnding) != 0)
|
||||||
{
|
{
|
||||||
result.push_back(i.first);
|
result.push_back(i.first);
|
||||||
}
|
}
|
||||||
@ -282,7 +325,14 @@ std::wstring RestoreNounByTuple(std::wstring nounBase, NounTuple nounTuple)
|
|||||||
|
|
||||||
NounTuple nominativeNounTuple{ std::get<0>(nounTuple), NGC_P1_NOMINATIVE, NPF_SINGULAR };
|
NounTuple nominativeNounTuple{ std::get<0>(nounTuple), NGC_P1_NOMINATIVE, NPF_SINGULAR };
|
||||||
|
|
||||||
return nounBase + nounEndingTable[nominativeNounTuple];
|
auto nounEndingSet = nounEndingTable[nominativeNounTuple];
|
||||||
|
|
||||||
|
if (nounEndingSet.size() != 1)
|
||||||
|
{
|
||||||
|
throw std::exception("There is problem - noun have more than 1 form!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return nounBase + *(nounEndingTable[nominativeNounTuple].begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<NounStruct> RecognizeNoun(std::wstring noun)
|
std::vector<NounStruct> RecognizeNoun(std::wstring noun)
|
||||||
@ -304,6 +354,7 @@ std::vector<NounStruct> RecognizeNoun(std::wstring noun)
|
|||||||
{
|
{
|
||||||
std::wstring nounNominative = RestoreNounByTuple(nounBase, nounTuple);
|
std::wstring nounNominative = RestoreNounByTuple(nounBase, nounTuple);
|
||||||
|
|
||||||
|
|
||||||
auto possibleNounDetectionSet = GetPossibleNounDeclencionSet(nounNominative);
|
auto possibleNounDetectionSet = GetPossibleNounDeclencionSet(nounNominative);
|
||||||
|
|
||||||
if (possibleNounDetectionSet.count(std::get<0>(nounTuple)) != 0)
|
if (possibleNounDetectionSet.count(std::get<0>(nounTuple)) != 0)
|
||||||
@ -313,6 +364,7 @@ std::vector<NounStruct> RecognizeNoun(std::wstring noun)
|
|||||||
result.push_back({ nounTuple, nounNominative });
|
result.push_back({ nounTuple, nounNominative });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,10 +37,16 @@ enum NounNumber
|
|||||||
NPF_PLURAL
|
NPF_PLURAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::wstring NounDeclencionToWString(NounDeclencion nounDeclencion);
|
||||||
|
std::wstring NounGrammaticalCaseToWString(NounGrammaticalCase nounGrammaticalCase);
|
||||||
|
std::wstring NounNumberToWString(NounNumber nounNumber);
|
||||||
|
|
||||||
typedef std::tuple<NounDeclencion, NounGrammaticalCase, NounNumber> NounTuple;
|
typedef std::tuple<NounDeclencion, NounGrammaticalCase, NounNumber> NounTuple;
|
||||||
|
|
||||||
|
typedef std::set<std::wstring> StringSet;
|
||||||
|
|
||||||
std::vector<std::wstring> GetAllNounEndingArr();
|
std::vector<std::wstring> GetAllNounEndingArr();
|
||||||
std::map<NounTuple, std::wstring> getNounEndingTable();
|
std::map<NounTuple, StringSet> getNounEndingTable();
|
||||||
|
|
||||||
bool NounIsInDictionary(std::wstring nounNominative);
|
bool NounIsInDictionary(std::wstring nounNominative);
|
||||||
|
|
||||||
|
@ -19,14 +19,14 @@
|
|||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v120</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v120</PlatformToolset>
|
<PlatformToolset>v120</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>NotSet</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
@ -44,11 +44,12 @@
|
|||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>C:/Workplace/boost_1_56_0</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>C:/Workplace/boost_1_57_0</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_WIN32_WINNT=0x0501;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalLibraryDirectories>C:/Workplace/boost_1_56_0/stage/lib</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>C:/Workplace/boost_1_57_0/stage/lib</AdditionalLibraryDirectories>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@ -58,21 +59,40 @@
|
|||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>C:/Workplace/boost_1_56_0</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>C:/Workplace/boost_1_57_0</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_WIN32_WINNT=0x0501;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<AdditionalLibraryDirectories>C:/Workplace/boost_1_56_0/stage/lib</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>C:/Workplace/boost_1_57_0/stage/lib</AdditionalLibraryDirectories>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="http\connection.cpp" />
|
||||||
|
<ClCompile Include="http\connection_manager.cpp" />
|
||||||
|
<ClCompile Include="http\mime_types.cpp" />
|
||||||
|
<ClCompile Include="http\reply.cpp" />
|
||||||
|
<ClCompile Include="http\request_handler.cpp" />
|
||||||
|
<ClCompile Include="http\request_parser.cpp" />
|
||||||
|
<ClCompile Include="http\server.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="noun.cpp" />
|
<ClCompile Include="noun.cpp" />
|
||||||
|
<ClCompile Include="utf8utf16.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="http\connection.hpp" />
|
||||||
|
<ClInclude Include="http\connection_manager.hpp" />
|
||||||
|
<ClInclude Include="http\header.hpp" />
|
||||||
|
<ClInclude Include="http\mime_types.hpp" />
|
||||||
|
<ClInclude Include="http\reply.hpp" />
|
||||||
|
<ClInclude Include="http\request.hpp" />
|
||||||
|
<ClInclude Include="http\request_handler.hpp" />
|
||||||
|
<ClInclude Include="http\request_parser.hpp" />
|
||||||
|
<ClInclude Include="http\server.hpp" />
|
||||||
<ClInclude Include="noun.h" />
|
<ClInclude Include="noun.h" />
|
||||||
|
<ClInclude Include="utf8utf16.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Source Files\http">
|
||||||
|
<UniqueIdentifier>{4536720e-6df6-4fd1-b1c8-2f89090479f7}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="main.cpp">
|
<ClCompile Include="main.cpp">
|
||||||
@ -21,10 +24,64 @@
|
|||||||
<ClCompile Include="noun.cpp">
|
<ClCompile Include="noun.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="http\connection.cpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="http\connection_manager.cpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="http\mime_types.cpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="http\reply.cpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="http\request_handler.cpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="http\request_parser.cpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="http\server.cpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="utf8utf16.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="noun.h">
|
<ClInclude Include="noun.h">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="http\connection.hpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="http\connection_manager.hpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="http\header.hpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="http\mime_types.hpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="http\reply.hpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="http\request.hpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="http\request_handler.hpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="http\request_parser.hpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="http\server.hpp">
|
||||||
|
<Filter>Source Files\http</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="utf8utf16.h">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
49
rudict/rudict/utf8utf16.cpp
Normal file
49
rudict/rudict/utf8utf16.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#include "utf8utf16.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <locale>
|
||||||
|
#include <codecvt>
|
||||||
|
|
||||||
|
std::string UTF16to8(const wchar_t * in)
|
||||||
|
{
|
||||||
|
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
|
||||||
|
std::string s = conv.to_bytes(in);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring UTF8to16(const char * in)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::wstring out;
|
||||||
|
if (in == NULL)
|
||||||
|
return out;
|
||||||
|
|
||||||
|
unsigned int codepoint;
|
||||||
|
while (*in != 0)
|
||||||
|
{
|
||||||
|
unsigned char ch = static_cast<unsigned char>(*in);
|
||||||
|
if (ch <= 0x7f)
|
||||||
|
codepoint = ch;
|
||||||
|
else if (ch <= 0xbf)
|
||||||
|
codepoint = (codepoint << 6) | (ch & 0x3f);
|
||||||
|
else if (ch <= 0xdf)
|
||||||
|
codepoint = ch & 0x1f;
|
||||||
|
else if (ch <= 0xef)
|
||||||
|
codepoint = ch & 0x0f;
|
||||||
|
else
|
||||||
|
codepoint = ch & 0x07;
|
||||||
|
++in;
|
||||||
|
if (((*in & 0xc0) != 0x80) && (codepoint <= 0x10ffff))
|
||||||
|
{
|
||||||
|
if (codepoint > 0xffff)
|
||||||
|
{
|
||||||
|
out.append(1, static_cast<wchar_t>(0xd800 + (codepoint >> 10)));
|
||||||
|
out.append(1, static_cast<wchar_t>(0xdc00 + (codepoint & 0x03ff)));
|
||||||
|
}
|
||||||
|
else if (codepoint < 0xd800 || codepoint >= 0xe000)
|
||||||
|
out.append(1, static_cast<wchar_t>(codepoint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
17
rudict/rudict/utf8utf16.h
Normal file
17
rudict/rudict/utf8utf16.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef UTF8UTF16_H_INCLUDED
|
||||||
|
#define UTF8UTF16_H_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <cstring>
|
||||||
|
#include <locale>
|
||||||
|
|
||||||
|
std::wstring UTF8to16(const char * in);
|
||||||
|
std::string UTF16to8(const wchar_t * in);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //UTF8UTF16_H_INCLUDED
|
Loading…
Reference in New Issue
Block a user