Адаптировал ассемблерный код для OS X. Добавил простой эхо сервер на boost.asio
This commit is contained in:
parent
28f2e968d8
commit
5b3805e61c
@ -3,10 +3,19 @@ cmake_minimum_required(VERSION 2.8)
|
|||||||
set(MAIN_PROJECT_NAME "cpputil")
|
set(MAIN_PROJECT_NAME "cpputil")
|
||||||
set(SRC_DIR ".")
|
set(SRC_DIR ".")
|
||||||
set(INCLUDE_DIR ../include ./asm/include)
|
set(INCLUDE_DIR ../include ./asm/include)
|
||||||
|
set(ARCH "x86_64")
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
set(SYSTEM "darwin")
|
||||||
|
else()
|
||||||
|
set(SYSTEM "linux")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
SET(CMAKE_ASM_NASM_COMPILER yasm)
|
||||||
|
|
||||||
project(${MAIN_PROJECT_NAME} CXX ASM_NASM)
|
project(${MAIN_PROJECT_NAME} CXX ASM_NASM)
|
||||||
aux_source_directory(${SRC_DIR} SRC_FILES)
|
aux_source_directory(${SRC_DIR} SRC_FILES)
|
||||||
file(GLOB_RECURSE ASM_SRC_FILES "${SRC_DIR}/asm/linux/x86_64" "*.asm")
|
file(GLOB_RECURSE ASM_SRC_FILES "${SRC_DIR}/asm/${SYSTEM}/${ARCH}" "*.asm")
|
||||||
set(SRC_FILES ${SRC_FILES} ${ASM_SRC_FILES})
|
set(SRC_FILES ${SRC_FILES} ${ASM_SRC_FILES})
|
||||||
include_directories(${INCLUDE_DIR})
|
include_directories(${INCLUDE_DIR})
|
||||||
add_library(${MAIN_PROJECT_NAME} STATIC ${SRC_FILES})
|
add_library(${MAIN_PROJECT_NAME} STATIC ${SRC_FILES})
|
||||||
|
|||||||
101
src/asm/darwin/x86_64/ustring_asm.asm
Normal file
101
src/asm/darwin/x86_64/ustring_asm.asm
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
;
|
||||||
|
; public exported functions
|
||||||
|
;
|
||||||
|
|
||||||
|
global __asm_ucs4_strstr
|
||||||
|
global __asm_ucs4_strchr
|
||||||
|
|
||||||
|
;
|
||||||
|
; code section
|
||||||
|
;
|
||||||
|
|
||||||
|
section .text
|
||||||
|
|
||||||
|
; constants
|
||||||
|
|
||||||
|
npos db -1
|
||||||
|
|
||||||
|
;================================================================================
|
||||||
|
;
|
||||||
|
; Поиск подстроки в строке UCS-4 (алгоритм "в лоб", подойдет для коротких строк)
|
||||||
|
;
|
||||||
|
; rdi: указатель на исходную строку
|
||||||
|
; rsi: длина исходной строки символах
|
||||||
|
; rdx: указатель на искомую подстроку
|
||||||
|
; rcx: длина подстроки в символах
|
||||||
|
;
|
||||||
|
;================================================================================
|
||||||
|
|
||||||
|
__asm_ucs4_strstr:
|
||||||
|
|
||||||
|
push r12
|
||||||
|
mov r9d, dword [rdx]
|
||||||
|
mov rax, rdx
|
||||||
|
lea r8, [rdi + rsi*4]
|
||||||
|
lea r10, [rdx + rcx*4]
|
||||||
|
|
||||||
|
strstr_try_next_symbol:
|
||||||
|
|
||||||
|
cmp r9d, dword [rdi]
|
||||||
|
je strstr_init_counter
|
||||||
|
add rdi, 4
|
||||||
|
cmp rdi, r8
|
||||||
|
jne strstr_try_next_symbol
|
||||||
|
pop r12
|
||||||
|
mov rax, 0
|
||||||
|
ret
|
||||||
|
|
||||||
|
strstr_init_counter:
|
||||||
|
|
||||||
|
mov rdx, rax
|
||||||
|
mov r12, rdi
|
||||||
|
|
||||||
|
strstr_symbol_found:
|
||||||
|
|
||||||
|
add rdx, 4
|
||||||
|
cmp rdx, r10
|
||||||
|
je strstr_the_end
|
||||||
|
add r12, 4
|
||||||
|
mov r11d, dword [r12]
|
||||||
|
cmp r11d, dword [rdx]
|
||||||
|
je strstr_symbol_found
|
||||||
|
add rdi, 4
|
||||||
|
jmp strstr_try_next_symbol
|
||||||
|
|
||||||
|
strstr_the_end:
|
||||||
|
|
||||||
|
pop r12
|
||||||
|
mov rax, rdi
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
;================================================================================
|
||||||
|
;
|
||||||
|
; Поиск символа в строке UCS-4
|
||||||
|
;
|
||||||
|
; rdi: указатель на исходную строку
|
||||||
|
; rsi: длина исходной строки символах
|
||||||
|
; rdx: искомый символ
|
||||||
|
;
|
||||||
|
;================================================================================
|
||||||
|
|
||||||
|
__asm_ucs4_strchr:
|
||||||
|
|
||||||
|
xor r8, r8
|
||||||
|
|
||||||
|
try_next_symbol:
|
||||||
|
|
||||||
|
cmp rdx, [rdi]
|
||||||
|
je symbol_found
|
||||||
|
add rdi, 4
|
||||||
|
inc r8
|
||||||
|
cmp rsi, r8
|
||||||
|
jne try_next_symbol
|
||||||
|
mov rax, 0
|
||||||
|
ret
|
||||||
|
|
||||||
|
symbol_found:
|
||||||
|
|
||||||
|
mov rax, rdi
|
||||||
|
|
||||||
|
ret
|
||||||
@ -381,7 +381,7 @@ std::size_t ustring::find(const ustring& str, std::size_t pos /* = 0 */) const
|
|||||||
return npos;
|
return npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__GNUC__) && !defined(__clang__)
|
#if defined(__GNUC__) // GCC and clang
|
||||||
/*
|
/*
|
||||||
char32_t* fpos = reinterpret_cast<char32_t*>(memmem(_pData + pos, (_len - pos)*sizeof(char32_t), str._pData, str._len*sizeof(char32_t)));
|
char32_t* fpos = reinterpret_cast<char32_t*>(memmem(_pData + pos, (_len - pos)*sizeof(char32_t), str._pData, str._len*sizeof(char32_t)));
|
||||||
if(fpos)
|
if(fpos)
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
set(TEST_PROJECT_NAME "cpputil_test")
|
set(TEST_PROJECT_NAME "cpputil_test")
|
||||||
|
set(TEST_SERVER_PROJECT_NAME "server_test")
|
||||||
|
set(TEST_CLIENT_PROJECT_NAME "client_test")
|
||||||
set(SRC_DIR ".")
|
set(SRC_DIR ".")
|
||||||
set(REQUIRED_LIBRARIES cpputil)
|
set(REQUIRED_LIBRARIES cpputil)
|
||||||
set(boost_version 1.56.0)
|
set(boost_version 1.56.0)
|
||||||
@ -45,13 +47,22 @@ ExternalProject_Add(
|
|||||||
LOG_BUILD ON
|
LOG_BUILD ON
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ExternalProject_Get_Property( boost source_dir )
|
||||||
|
set(BOOST_INCLUDE_DIR ${source_dir})
|
||||||
|
INCLUDE_DIRECTORIES(${BOOST_INCLUDE_DIR})
|
||||||
|
|
||||||
project(${TEST_PROJECT_NAME} CXX)
|
project(${TEST_PROJECT_NAME} CXX)
|
||||||
aux_source_directory(${SRC_DIR} TEST_SRC)
|
aux_source_directory(${SRC_DIR}/cpputil TEST_SRC)
|
||||||
add_executable(${TEST_PROJECT_NAME} ${TEST_SRC})
|
add_executable(${TEST_PROJECT_NAME} ${TEST_SRC})
|
||||||
SET_TARGET_PROPERTIES(${TEST_PROJECT_NAME} PROPERTIES ENABLE_EXPORTS TRUE)
|
SET_TARGET_PROPERTIES(${TEST_PROJECT_NAME} PROPERTIES ENABLE_EXPORTS TRUE)
|
||||||
ADD_DEPENDENCIES(${TEST_PROJECT_NAME} googletest cpputil boost)
|
ADD_DEPENDENCIES(${TEST_PROJECT_NAME} googletest cpputil)
|
||||||
|
target_link_libraries(${TEST_PROJECT_NAME} ${REQUIRED_LIBRARIES} ${CMAKE_SOURCE_DIR}/lib/libgtest.a)
|
||||||
|
|
||||||
target_link_libraries(${TEST_PROJECT_NAME} ${REQUIRED_LIBRARIES} ${CMAKE_SOURCE_DIR}/lib/libgtest.a ${CMAKE_SOURCE_DIR}/lib/libboost_coroutine.a)
|
project(${TEST_SERVER_PROJECT_NAME} CXX)
|
||||||
|
aux_source_directory(${SRC_DIR}/server TEST_SERVER_SRC)
|
||||||
|
add_executable(${TEST_SERVER_PROJECT_NAME} ${TEST_SERVER_SRC})
|
||||||
|
add_dependencies(${TEST_SERVER_PROJECT_NAME} boost cpputil)
|
||||||
|
target_link_libraries(${TEST_SERVER_PROJECT_NAME} cpputil ${CMAKE_SOURCE_DIR}/lib/libboost_system.a ${CMAKE_SOURCE_DIR}/lib/libboost_coroutine.a)
|
||||||
|
|
||||||
install(TARGETS ${TEST_PROJECT_NAME}
|
install(TARGETS ${TEST_PROJECT_NAME}
|
||||||
RUNTIME DESTINATION bin
|
RUNTIME DESTINATION bin
|
||||||
|
|||||||
617
test/main.cpp
617
test/main.cpp
@ -1,617 +0,0 @@
|
|||||||
#include "ustring.h"
|
|
||||||
#include "utf.h"
|
|
||||||
#include "logger.h"
|
|
||||||
#include "threadpool.h"
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Данные для тестов
|
|
||||||
//
|
|
||||||
|
|
||||||
// UTF-8
|
|
||||||
const unsigned char helloStrUtf8[] = { 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x0a, 0xd0, 0x9f, 0xd1,
|
|
||||||
0x80, 0xd0, 0xb8, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, 0x82, 0x2c, 0x20, 0xd0, 0x9c, 0xd0, 0xb8, 0xd1,
|
|
||||||
0x80, 0x21, 0x0a, 0xe2, 0x88, 0x86, 0x20, 0x3d, 0x20, 0xf0, 0x9d, 0x9b, 0xbb, 0xc2, 0xb2, 0x0a,
|
|
||||||
0x00 };
|
|
||||||
|
|
||||||
// UTF-16LE
|
|
||||||
const unsigned char helloStrUtf16le[] = { 0x48, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x57, 0x00, 0x6f, 0x00,
|
|
||||||
0x72, 0x00, 0x6c, 0x00, 0x64, 0x00, 0x21, 0x00, 0x0a, 0x00, 0x1f, 0x04, 0x40, 0x04, 0x38, 0x04,
|
|
||||||
0x32, 0x04, 0x35, 0x04, 0x42, 0x04, 0x2c, 0x00, 0x20, 0x00, 0x1c, 0x04, 0x38, 0x04, 0x40, 0x04,
|
|
||||||
0x21, 0x00, 0x0a, 0x00, 0x06, 0x22, 0x20, 0x00, 0x3d, 0x00, 0x20, 0x00, 0x35, 0xd8, 0xfb, 0xde,
|
|
||||||
0xb2, 0x00, 0x0a, 0x00, 0x00, 0x00 };
|
|
||||||
|
|
||||||
// UTF-16BE
|
|
||||||
const unsigned char helloStrUtf16be[] = { 0x00, 0x48, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x57, 0x00, 0x6f,
|
|
||||||
0x00, 0x72, 0x00, 0x6c, 0x00, 0x64, 0x00, 0x21, 0x00, 0x0a, 0x04, 0x1f, 0x04, 0x40, 0x04, 0x38,
|
|
||||||
0x04, 0x32, 0x04, 0x35, 0x04, 0x42, 0x00, 0x2c, 0x00, 0x20, 0x04, 0x1c, 0x04, 0x38, 0x04, 0x40,
|
|
||||||
0x00, 0x21, 0x00, 0x0a, 0x22, 0x06, 0x00, 0x20, 0x00, 0x3d, 0x00, 0x20, 0xd8, 0x35, 0xde, 0xfb,
|
|
||||||
0x00, 0xb2, 0x00, 0x0a, 0x00, 0x00 };
|
|
||||||
|
|
||||||
// UCS-4 (UTF-32LE на x86)
|
|
||||||
const unsigned char helloStrUcs4[] = { 0x48, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
|
|
||||||
0x6f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00,
|
|
||||||
0x72, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
|
|
||||||
0x0a, 0x00, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x38, 0x04, 0x00, 0x00,
|
|
||||||
0x32, 0x04, 0x00, 0x00, 0x35, 0x04, 0x00, 0x00, 0x42, 0x04, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
|
|
||||||
0x20, 0x00, 0x00, 0x00, 0x1c, 0x04, 0x00, 0x00, 0x38, 0x04, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00,
|
|
||||||
0x21, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x22, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
|
||||||
0x3d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xfb, 0xd6, 0x01, 0x00, 0xb2, 0x00, 0x00, 0x00,
|
|
||||||
0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
|
||||||
|
|
||||||
// UTF-32BE
|
|
||||||
const unsigned char helloStrUtf32be[] = { 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x6c,
|
|
||||||
0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x6f,
|
|
||||||
0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x21,
|
|
||||||
0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x04, 0x1f, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x04, 0x38,
|
|
||||||
0x00, 0x00, 0x04, 0x32, 0x00, 0x00, 0x04, 0x35, 0x00, 0x00, 0x04, 0x42, 0x00, 0x00, 0x00, 0x2c,
|
|
||||||
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x1c, 0x00, 0x00, 0x04, 0x38, 0x00, 0x00, 0x04, 0x40,
|
|
||||||
0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x22, 0x06, 0x00, 0x00, 0x00, 0x20,
|
|
||||||
0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0xd6, 0xfb, 0x00, 0x00, 0x00, 0xb2,
|
|
||||||
0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00 };
|
|
||||||
|
|
||||||
// Escaped
|
|
||||||
const char helloStrEscaped[] = "Hello World!\n\\u041F\\u0440\\u0438\\u0432\\u0435\\u0442, \\u041C\\u0438\\u0440!\n\\u2206 = \\U0001D6FB\\u00B2\n";
|
|
||||||
|
|
||||||
// Длина тестовой строки в символах
|
|
||||||
const std::size_t helloStrLen = 33;
|
|
||||||
|
|
||||||
// Некорректные строки для теста обработки ошибок
|
|
||||||
const unsigned char badStrUtf8[] = { 0xd0, 0xdf, 0x00 };
|
|
||||||
const unsigned char badStr2Utf8[] = { 0xf8, 0x9f, 0x00 };
|
|
||||||
const unsigned char badStrUcs4[] = { 0xf8, 0x9f, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00 };
|
|
||||||
const unsigned char badStrUtf16le[] = { 0x35, 0xc8, 0xfb, 0xde, 0x00, 0x00 };
|
|
||||||
const unsigned char badStr2Utf16le[] = { 0x35, 0xd8, 0xfb, 0xce, 0x00, 0x00 };
|
|
||||||
|
|
||||||
// Для теста конкатенации
|
|
||||||
// "Hello "
|
|
||||||
const unsigned char helloPart1Ucs4[] = { 0x48, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
|
|
||||||
0x6f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
|
||||||
|
|
||||||
// "big"
|
|
||||||
const unsigned char helloPart2Ucs4[] = { 0x62, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
|
||||||
|
|
||||||
// " world"
|
|
||||||
const unsigned char helloPart3Ucs4[] = { 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00,
|
|
||||||
0x6c, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
|
||||||
|
|
||||||
// "Hello big world"
|
|
||||||
const unsigned char helloResultUcs4[] = { 0x48, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
|
|
||||||
0x6f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00,
|
|
||||||
0x67, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00,
|
|
||||||
0x72, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Тесты
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Определение длины символа UTF-8
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Convert, utf8_symbol_size)
|
|
||||||
{
|
|
||||||
ASSERT_EQ(1, utf8_get_symbol_size((const char*)&helloStrUtf8[0], false));
|
|
||||||
ASSERT_EQ(2, utf8_get_symbol_size((const char*)&helloStrUtf8[15], false));
|
|
||||||
ASSERT_EQ(4, utf8_get_symbol_size((const char*)&helloStrUtf8[41], false));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Определение длины символа UTF-8 по символу UCS-4
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Convert, utf8_symbol_size_by_ucs4_symbol)
|
|
||||||
{
|
|
||||||
ASSERT_EQ(1, ucs4_get_utf8_symbol_size(*(const char32_t*)&helloStrUcs4[0], false));
|
|
||||||
ASSERT_EQ(2, ucs4_get_utf8_symbol_size(*(const char32_t*)&helloStrUcs4[52], false));
|
|
||||||
ASSERT_EQ(4, ucs4_get_utf8_symbol_size(*(const char32_t*)&helloStrUcs4[120], false));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Определение длины строки UTF-8
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Convert, utf8_length)
|
|
||||||
{
|
|
||||||
ASSERT_EQ(helloStrLen, utf8_str_len((const char*)helloStrUtf8, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Определение длины строки UTF-8 по строке UCS-4
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Convert, utf8_str_len_by_ucs4_str)
|
|
||||||
{
|
|
||||||
ASSERT_EQ(sizeof(helloStrUtf8) - 1, ucs4_get_utf8_str_bytes((const char32_t*)helloStrUcs4, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Определение длины символа UTF-16LE
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Convert, utf16le_symbol_size)
|
|
||||||
{
|
|
||||||
ASSERT_EQ(2, utf16_get_symbol_size((const char16_t*)&helloStrUtf16le[0]));
|
|
||||||
ASSERT_EQ(4, utf16_get_symbol_size((const char16_t*)&helloStrUtf16le[60]));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Определение длины символа UTF-16BE
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Convert, utf16be_symbol_size)
|
|
||||||
{
|
|
||||||
ASSERT_EQ(2, utf16_get_symbol_size((const char16_t*)&helloStrUtf16be[0], BYTE_ORDER_BIG_ENDIAN));
|
|
||||||
ASSERT_EQ(4, utf16_get_symbol_size((const char16_t*)&helloStrUtf16be[60], BYTE_ORDER_BIG_ENDIAN));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Определение длины символа UTF-16 по символу UCS-4
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Convert, utf16_symbol_size_by_ucs4_symbol)
|
|
||||||
{
|
|
||||||
ASSERT_EQ(2, ucs4_get_utf16_symbol_size(*(const char32_t*)&helloStrUcs4[0]));
|
|
||||||
ASSERT_EQ(4, ucs4_get_utf16_symbol_size(*(const char32_t*)&helloStrUcs4[120]));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Определение длины строки UTF-16LE
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Convert, utf16le_length)
|
|
||||||
{
|
|
||||||
ASSERT_EQ(helloStrLen, utf16_str_len((const char16_t*)helloStrUtf16le));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Определение длины строки UTF-16BE
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Convert, utf16be_length)
|
|
||||||
{
|
|
||||||
ASSERT_EQ(helloStrLen, utf16_str_len((const char16_t*)helloStrUtf16be, BYTE_ORDER_BIG_ENDIAN));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Convert, utf16_str_len_by_ucs4_str)
|
|
||||||
{
|
|
||||||
ASSERT_EQ(sizeof(helloStrUtf16le) - 2, ucs4_get_utf16_str_bytes((const char32_t*)helloStrUcs4));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Определение длины строки UTF-32
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Convert, utf32_length)
|
|
||||||
{
|
|
||||||
ASSERT_EQ(helloStrLen, utf32_str_len((const char32_t*)helloStrUcs4));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Конвертирование UTF-8 в UCS-4
|
|
||||||
//
|
|
||||||
TEST(Convert, utf8_to_ucs4)
|
|
||||||
{
|
|
||||||
std::size_t len = utf8_str_len((const char*)helloStrUtf8, false);
|
|
||||||
char32_t* data = new char32_t[len];
|
|
||||||
utf8_to_ucs4((const char*)helloStrUtf8, data, len, false);
|
|
||||||
EXPECT_EQ(0, memcmp(helloStrUcs4, data, len*sizeof(char32_t)));
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Конвертирование UCS-4 в UTF-8
|
|
||||||
//
|
|
||||||
TEST(Convert, ucs4_to_utf8)
|
|
||||||
{
|
|
||||||
std::size_t len = ucs4_get_utf8_str_bytes((const char32_t*)helloStrUcs4, false);
|
|
||||||
std::size_t symbols = utf32_str_len((const char32_t*)helloStrUcs4);
|
|
||||||
char* data = new char[len];
|
|
||||||
ucs4_to_utf8((const char32_t*)helloStrUcs4, data, symbols, false);
|
|
||||||
EXPECT_EQ(0, memcmp(helloStrUtf8, data, len));
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Конвертирование UTF-16LE в UCS-4
|
|
||||||
//
|
|
||||||
TEST(Convert, utf16le_to_ucs4)
|
|
||||||
{
|
|
||||||
std::size_t len = utf16_str_len((const char16_t*)helloStrUtf16le);
|
|
||||||
char32_t* data = new char32_t[len];
|
|
||||||
utf16_to_ucs4((const char16_t*)helloStrUtf16le, data, len);
|
|
||||||
EXPECT_EQ(0, memcmp(helloStrUcs4, data, len*sizeof(char32_t)));
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Конвертирование UCS-4 в UTF-16LE
|
|
||||||
//
|
|
||||||
TEST(Convert, ucs4_to_utf16le)
|
|
||||||
{
|
|
||||||
std::size_t len = ucs4_get_utf16_str_bytes((const char32_t*)helloStrUcs4);
|
|
||||||
std::size_t symbols = utf32_str_len((const char32_t*)helloStrUcs4);
|
|
||||||
char16_t* data = new char16_t[len];
|
|
||||||
ucs4_to_utf16((const char32_t*)helloStrUcs4, data, symbols);
|
|
||||||
EXPECT_EQ(0, memcmp(helloStrUtf16le, data, len));
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Конвертирование UTF-16BE в UCS-4
|
|
||||||
//
|
|
||||||
TEST(Convert, utf16be_to_ucs4)
|
|
||||||
{
|
|
||||||
std::size_t len = utf16_str_len((const char16_t*)helloStrUtf16be);
|
|
||||||
char32_t* data = new char32_t[len];
|
|
||||||
utf16_to_ucs4((const char16_t*)helloStrUtf16be, data, len, BYTE_ORDER_BIG_ENDIAN);
|
|
||||||
EXPECT_EQ(0, memcmp(helloStrUcs4, data, len*sizeof(char32_t)));
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Конвертирование UCS-4 в UTF-16BE
|
|
||||||
//
|
|
||||||
TEST(Convert, ucs4_to_utf16be)
|
|
||||||
{
|
|
||||||
std::size_t len = ucs4_get_utf16_str_bytes((const char32_t*)helloStrUcs4);
|
|
||||||
std::size_t symbols = utf32_str_len((const char32_t*)helloStrUcs4);
|
|
||||||
char16_t* data = new char16_t[len];
|
|
||||||
ucs4_to_utf16((const char32_t*)helloStrUcs4, data, symbols, BYTE_ORDER_BIG_ENDIAN);
|
|
||||||
EXPECT_EQ(0, memcmp(helloStrUtf16be, data, len));
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Тесты на ошибки конвертирования
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Первый байт двухбайтового символа содержит единицы в пяти старших разрядах
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(ConvertError, utf8_length_error)
|
|
||||||
{
|
|
||||||
EXPECT_THROW(utf8_str_len((const char*)badStr2Utf8, false), bad_conversion);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Второй байт двухбайтового символа содержит единицы в двух старших разрядах
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(ConvertError, utf8_decode_error)
|
|
||||||
{
|
|
||||||
std::size_t len = utf8_str_len((const char*)badStrUtf8, false);
|
|
||||||
char32_t* data = new char32_t[len];
|
|
||||||
EXPECT_THROW(utf8_to_ucs4((const char*)badStrUtf8, data, len, false), bad_conversion);
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Некорректное перевое слово суррогатной пары
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(ConvertError, utf16_decode_error)
|
|
||||||
{
|
|
||||||
std::size_t len = utf16_str_len((const char16_t*)badStrUtf16le);
|
|
||||||
char32_t* data = new char32_t[len];
|
|
||||||
EXPECT_THROW(utf16_to_ucs4((const char16_t*)badStrUtf16le, data, len), bad_conversion);
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Некорректное второе слово суррогатной пары
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(ConvertError, utf16_decode_error2)
|
|
||||||
{
|
|
||||||
std::size_t len = utf16_str_len((const char16_t*)badStr2Utf16le);
|
|
||||||
char32_t* data = new char32_t[len];
|
|
||||||
EXPECT_THROW(utf16_to_ucs4((const char16_t*)badStr2Utf16le, data, len), bad_conversion);
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Код символа не входит в диапазон символов UCS-4
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(ConvertError, ucs4_wrong_symbol)
|
|
||||||
{
|
|
||||||
EXPECT_THROW(ucs4_get_utf8_symbol_size(*(const char32_t*)badStrUcs4, false), bad_conversion);
|
|
||||||
EXPECT_THROW(ucs4_get_utf16_symbol_size(*(const char32_t*)badStrUcs4), bad_conversion);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Тесты класса ustring
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// Конструктор из UTF-8
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, utf8_constructor)
|
|
||||||
{
|
|
||||||
ustring str((const char*)helloStrUtf8);
|
|
||||||
ustring str2("Hello\\u0020world!", true);
|
|
||||||
ustring str3("Hello\\u0020world!", false);
|
|
||||||
ustring str4 = "Hello\\u0020world!";
|
|
||||||
|
|
||||||
|
|
||||||
EXPECT_EQ(0, memcmp(helloStrUcs4, str.utf32_str(), sizeof(helloStrUcs4)));
|
|
||||||
EXPECT_TRUE(str2 == "Hello world!");
|
|
||||||
EXPECT_TRUE(str3 == "Hello\\u0020world!");
|
|
||||||
EXPECT_TRUE(str4 == "Hello\\u0020world!");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Конструктор из UTF-16LE
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, utf16_constructor)
|
|
||||||
{
|
|
||||||
ustring str((const char16_t*)helloStrUtf16le);
|
|
||||||
EXPECT_EQ(0, memcmp(helloStrUcs4, str.utf32_str(), sizeof(helloStrUcs4)));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Конструктор из UTF-32LE
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, utf32_constructor)
|
|
||||||
{
|
|
||||||
ustring str((const char32_t*)helloStrUcs4);
|
|
||||||
EXPECT_EQ(0, memcmp(helloStrUcs4, str.utf32_str(), sizeof(helloStrUcs4)));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Оператор UTF-8
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, utf8_cast_operator)
|
|
||||||
{
|
|
||||||
ustring str((const char32_t*)helloStrUcs4);
|
|
||||||
EXPECT_EQ(0, memcmp(helloStrUtf8, str.utf8_str(), sizeof(helloStrUtf8)));
|
|
||||||
EXPECT_EQ(0, memcmp(str.utf8_str(false, true), helloStrEscaped, sizeof(helloStrEscaped)));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Оператор UTF-16LE
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, utf16_cast_operator)
|
|
||||||
{
|
|
||||||
ustring str((const char32_t*)helloStrUcs4);
|
|
||||||
EXPECT_EQ(0, memcmp(helloStrUtf16le, str.utf16_str(), sizeof(helloStrUtf16le)));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Конкатенация строк (operator+=)
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, concat_op_plus_assign)
|
|
||||||
{
|
|
||||||
ustring s1((const char32_t*)helloPart1Ucs4);
|
|
||||||
ustring s2((const char32_t*)helloPart2Ucs4);
|
|
||||||
ustring s3((const char32_t*)helloPart3Ucs4);
|
|
||||||
|
|
||||||
s1 += s2;
|
|
||||||
s1 += s3;
|
|
||||||
|
|
||||||
EXPECT_EQ(0, memcmp(helloResultUcs4, s1.utf32_str(), sizeof(helloResultUcs4)));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Конкатенация строк (operator+)
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, concat_op_plus)
|
|
||||||
{
|
|
||||||
ustring s1((const char32_t*)helloPart1Ucs4);
|
|
||||||
//ustring s2((const char32_t*)helloPart2Ucs4);
|
|
||||||
//ustring s3((const char32_t*)helloPart3Ucs4);
|
|
||||||
|
|
||||||
ustring res = s1 + "big" + " world";
|
|
||||||
|
|
||||||
EXPECT_EQ(0, memcmp(helloResultUcs4, res.utf32_str(), sizeof(helloResultUcs4)));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Поиск символа в строке
|
|
||||||
//
|
|
||||||
TEST(Ustring, find_symbol)
|
|
||||||
{
|
|
||||||
ustring str((const char32_t*)helloResultUcs4);
|
|
||||||
EXPECT_EQ(4, str.find('o'));
|
|
||||||
EXPECT_EQ(11, str.find('o', 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Поиск подстроки в строке
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, find_string)
|
|
||||||
{
|
|
||||||
ustring str = "Hello World! asdf qwerty asdf";
|
|
||||||
EXPECT_EQ(13, str.find("asdf"));
|
|
||||||
EXPECT_EQ(7, str.find("orld"));
|
|
||||||
EXPECT_EQ(25, str.find("asdf", 14));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Вывод в поток std::ostream
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, std_ostream_output)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ustring str((const char32_t*)helloResultUcs4);
|
|
||||||
|
|
||||||
ss << str;
|
|
||||||
EXPECT_EQ(0, strcmp(ss.str().c_str(), "Hello big world"));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Ввод из std::istream
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, std_istream_intput)
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ustring str;
|
|
||||||
|
|
||||||
ss << "big";
|
|
||||||
ss >> str;
|
|
||||||
EXPECT_EQ(0, memcmp(helloPart2Ucs4, str.utf32_str(), sizeof(helloPart2Ucs4)));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Проверка на равенство
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, equality)
|
|
||||||
{
|
|
||||||
ustring str((const char32_t*)helloResultUcs4);
|
|
||||||
ustring str2;
|
|
||||||
|
|
||||||
EXPECT_TRUE(str == "Hello big world");
|
|
||||||
EXPECT_TRUE(str2 == "");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Установление нового значения строки
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, assign_new_value)
|
|
||||||
{
|
|
||||||
ustring s1 = "first string";
|
|
||||||
ustring s2 = "second string";
|
|
||||||
|
|
||||||
s2.assign(s1.utf32_str(false, current_byte_order()) + 6, 6);
|
|
||||||
EXPECT_TRUE(s2 == "string");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Возвращение подстроки
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, substring)
|
|
||||||
{
|
|
||||||
ustring str = "Hello big world!";
|
|
||||||
ustring str2 = str.substr(6, 3);
|
|
||||||
ustring str3 = str.substr(6, ustring::npos);
|
|
||||||
EXPECT_TRUE(str2 == "big");
|
|
||||||
EXPECT_TRUE(str3 == "big world!");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Стирание части строки
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, erasing)
|
|
||||||
{
|
|
||||||
ustring str = "Hello big world!";
|
|
||||||
str.erase(6,4);
|
|
||||||
EXPECT_TRUE(str == "Hello world!");
|
|
||||||
str.erase(5, ustring::npos);
|
|
||||||
EXPECT_TRUE(str == "Hello");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Вставка строки в строку
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, insert_string)
|
|
||||||
{
|
|
||||||
ustring str = "bla-bla";
|
|
||||||
str.insert(0, "begin ");
|
|
||||||
EXPECT_TRUE(str == "begin bla-bla");
|
|
||||||
str.insert(6, "bla ");
|
|
||||||
EXPECT_TRUE(str == "begin bla bla-bla");
|
|
||||||
str.insert(17, " end");
|
|
||||||
EXPECT_TRUE(str == "begin bla bla-bla end");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Замена подстроки строкой
|
|
||||||
//
|
|
||||||
|
|
||||||
TEST(Ustring, replace_string)
|
|
||||||
{
|
|
||||||
ustring str = "111 hello 111 world 111";
|
|
||||||
ustring str2 = str, str3 = str;
|
|
||||||
|
|
||||||
str.replace("111", "2222");
|
|
||||||
EXPECT_TRUE(str == "2222 hello 2222 world 2222");
|
|
||||||
|
|
||||||
str2.replace("111", "22");
|
|
||||||
EXPECT_TRUE(str2 == "22 hello 22 world 22");
|
|
||||||
|
|
||||||
str3.replace("111", "222");
|
|
||||||
EXPECT_TRUE(str3 == "222 hello 222 world 222");
|
|
||||||
|
|
||||||
str2 += " more 22 and 22 more 22";
|
|
||||||
str2.replace("22", "33");
|
|
||||||
EXPECT_TRUE(str2 == "33 hello 33 world 33 more 33 and 33 more 33");
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// threadpool demo
|
|
||||||
//
|
|
||||||
|
|
||||||
void func(std::size_t n)
|
|
||||||
{
|
|
||||||
for(std::size_t j = 0; j < 100; ++j)
|
|
||||||
{
|
|
||||||
ulog.log_info("thread %, line %", n, j);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "end of thread " << n << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int geti(int i)
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
class foo
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int bar(int n)
|
|
||||||
{
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void run_threadpool_demo()
|
|
||||||
{
|
|
||||||
threadpool pool(4);
|
|
||||||
std::vector<std::future<int>> vec;
|
|
||||||
|
|
||||||
foo f;
|
|
||||||
for (std::size_t i = 0; i < 100; ++i)
|
|
||||||
{
|
|
||||||
//std::future<int> fut = pool.add_task<int>([i] { return i; });
|
|
||||||
std::future<int> fut = pool.add_task(&foo::bar, &f, (int)i);
|
|
||||||
vec.push_back(std::move(fut));
|
|
||||||
}
|
|
||||||
|
|
||||||
for(std::size_t i = 0; i < 100; ++i)
|
|
||||||
{
|
|
||||||
std::cout << "res[" << i << "] = " << vec[i].get() << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
|
||||||
return RUN_ALL_TESTS();
|
|
||||||
}
|
|
||||||
10
test/server/main.cpp
Normal file
10
test/server/main.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "server.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
server srv("0.0.0.0", "12345");
|
||||||
|
srv.run();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
41
test/server/server.cpp
Normal file
41
test/server/server.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include "server.h"
|
||||||
|
#include <boost/asio/yield.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
server::server(const std::string& address, const std::string& port)
|
||||||
|
{
|
||||||
|
tcp::resolver resolver(_io_service);
|
||||||
|
tcp::resolver::query query(address, port);
|
||||||
|
_acceptor = new tcp::acceptor(_io_service, *resolver.resolve(query));
|
||||||
|
}
|
||||||
|
|
||||||
|
void server::run()
|
||||||
|
{
|
||||||
|
accept();
|
||||||
|
_io_service.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void server::accept(boost::system::error_code ec)
|
||||||
|
{
|
||||||
|
if(!ec)
|
||||||
|
{
|
||||||
|
reenter(this) for(;;)
|
||||||
|
{
|
||||||
|
_session = new session(_io_service);
|
||||||
|
yield _acceptor->async_accept(_session->_socket, std::bind(&server::accept, this, std::placeholders::_1));
|
||||||
|
std::cout << "new connection started" << std::endl;
|
||||||
|
_session->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "error: " << ec.message() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server::~server() {
|
||||||
|
if(_socket) delete _socket;
|
||||||
|
if(_acceptor) delete _acceptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <boost/asio/unyield.hpp>
|
||||||
29
test/server/server.h
Normal file
29
test/server/server.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef _SERVER_H_
|
||||||
|
#define _SERVER_H_
|
||||||
|
|
||||||
|
#include "session.h"
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
|
class server: boost::asio::coroutine
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef boost::asio::ip::tcp tcp;
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::asio::io_service _io_service;
|
||||||
|
tcp::acceptor* _acceptor;
|
||||||
|
tcp::socket* _socket;
|
||||||
|
session* _session;
|
||||||
|
|
||||||
|
public:
|
||||||
|
server() = delete ;
|
||||||
|
server(server& srv) = delete;
|
||||||
|
server(const std::string& address, const std::string& port);
|
||||||
|
void run();
|
||||||
|
~server();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void accept(boost::system::error_code ec = boost::system::error_code());
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _SERVER_H_
|
||||||
41
test/server/session.cpp
Normal file
41
test/server/session.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include "session.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <boost/asio/yield.hpp>
|
||||||
|
|
||||||
|
session::session(boost::asio::io_service &io_service): boost::asio::coroutine(), _socket(io_service)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
session::~session()
|
||||||
|
{
|
||||||
|
std::cout << "session destructor" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void session::start(boost::system::error_code ec, std::size_t bytes_transferred)
|
||||||
|
{
|
||||||
|
if(!ec)
|
||||||
|
{
|
||||||
|
reenter(this) for(;;)
|
||||||
|
{
|
||||||
|
std::memset(_data, 0, 128);
|
||||||
|
yield _socket.async_read_some(boost::asio::buffer(_data, 128), std::bind(&session::start, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
std::cout << "async_read " << bytes_transferred << " bytes" << std::endl;
|
||||||
|
std::cout << "number: " << std::atoi(_data) << std::endl;
|
||||||
|
|
||||||
|
// yield _pool<int>.add_task([this]{
|
||||||
|
// return 42;
|
||||||
|
// });
|
||||||
|
|
||||||
|
yield _socket.async_write_some(boost::asio::buffer(_data, 128), std::bind(&session::start, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
|
std::cout << "async_write" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "error: " << ec.message() << std::endl;
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <boost/asio/unyield.hpp>
|
||||||
27
test/server/session.h
Normal file
27
test/server/session.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef _SESSION_H_
|
||||||
|
#define _SESSION_H_
|
||||||
|
|
||||||
|
#include "threadpool.h"
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
|
class session: boost::asio::coroutine
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef boost::asio::ip::tcp tcp;
|
||||||
|
friend class server;
|
||||||
|
|
||||||
|
private:
|
||||||
|
tcp::socket _socket;
|
||||||
|
char _data[128];
|
||||||
|
threadpool _pool;
|
||||||
|
|
||||||
|
public:
|
||||||
|
session() = delete;
|
||||||
|
session(session&) = delete;
|
||||||
|
session(boost::asio::io_service& io_service);
|
||||||
|
void start(boost::system::error_code ec = boost::system::error_code(), std::size_t bytes_transferred = 0);
|
||||||
|
~session();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _SESSION_H_
|
||||||
Loading…
Reference in New Issue
Block a user