mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-18 19:48:44 +02:00
Merge branch 'poco-1.9.1' of https://github.com/pocoproject/poco into poco-1.9.1
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -41,6 +41,10 @@ coverage/
|
|||||||
config.build
|
config.build
|
||||||
config.make
|
config.make
|
||||||
|
|
||||||
|
# CLion #
|
||||||
|
########
|
||||||
|
.idea/
|
||||||
|
|
||||||
# CMake #
|
# CMake #
|
||||||
########
|
########
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
@@ -50,6 +54,7 @@ CMakeCache.txt
|
|||||||
CPackConfig.cmake
|
CPackConfig.cmake
|
||||||
CPackSourceConfig.cmake
|
CPackSourceConfig.cmake
|
||||||
cmake_*
|
cmake_*
|
||||||
|
cmake-build-*
|
||||||
|
|
||||||
# Packages #
|
# Packages #
|
||||||
############
|
############
|
||||||
|
@@ -93,5 +93,7 @@ private:
|
|||||||
#define CppUnit_addTest(suite, cls, mth) \
|
#define CppUnit_addTest(suite, cls, mth) \
|
||||||
suite->addTest(new CppUnit::TestCaller<cls>(#mth, &cls::mth))
|
suite->addTest(new CppUnit::TestCaller<cls>(#mth, &cls::mth))
|
||||||
|
|
||||||
|
#define CppUnit_addQualifiedTest(suite, cls, mth) \
|
||||||
|
suite->addTest(new CppUnit::TestCaller<cls>(#cls"::"#mth, &cls::mth))
|
||||||
|
|
||||||
#endif // CppUnit_TestCaller_INCLUDED
|
#endif // CppUnit_TestCaller_INCLUDED
|
||||||
|
@@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
/* The current PCRE version information. */
|
/* The current PCRE version information. */
|
||||||
|
|
||||||
#define PCRE_MAJOR 8
|
#define PCRE_MAJOR 8
|
||||||
#define PCRE_MINOR 41
|
#define PCRE_MINOR 42
|
||||||
#define PCRE_PRERELEASE
|
#define PCRE_PRERELEASE
|
||||||
#define PCRE_DATE 2017-07-05
|
#define PCRE_DATE 2018-03-20
|
||||||
|
|
||||||
/* When an application links to a PCRE DLL in Windows, the symbols that are
|
/* When an application links to a PCRE DLL in Windows, the symbols that are
|
||||||
imported have to be identified as such. When building PCRE, the appropriate
|
imported have to be identified as such. When building PCRE, the appropriate
|
||||||
|
@@ -8062,7 +8062,7 @@ for (;; ptr++)
|
|||||||
single group (i.e. not to a duplicated name. */
|
single group (i.e. not to a duplicated name. */
|
||||||
|
|
||||||
HANDLE_REFERENCE:
|
HANDLE_REFERENCE:
|
||||||
if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
|
if (firstcharflags == REQ_UNSET) zerofirstcharflags = firstcharflags = REQ_NONE;
|
||||||
previous = code;
|
previous = code;
|
||||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||||
*code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
|
*code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
|
||||||
|
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language (but see
|
|||||||
below for why this module is different).
|
below for why this module is different).
|
||||||
|
|
||||||
Written by Philip Hazel
|
Written by Philip Hazel
|
||||||
Copyright (c) 1997-2014 University of Cambridge
|
Copyright (c) 1997-2017 University of Cambridge
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -2286,12 +2286,14 @@ for (;;)
|
|||||||
case OP_NOTI:
|
case OP_NOTI:
|
||||||
if (clen > 0)
|
if (clen > 0)
|
||||||
{
|
{
|
||||||
unsigned int otherd;
|
pcre_uint32 otherd;
|
||||||
#ifdef SUPPORT_UTF
|
#ifdef SUPPORT_UTF
|
||||||
if (utf && d >= 128)
|
if (utf && d >= 128)
|
||||||
{
|
{
|
||||||
#ifdef SUPPORT_UCP
|
#ifdef SUPPORT_UCP
|
||||||
otherd = UCD_OTHERCASE(d);
|
otherd = UCD_OTHERCASE(d);
|
||||||
|
#else
|
||||||
|
otherd = d;
|
||||||
#endif /* SUPPORT_UCP */
|
#endif /* SUPPORT_UCP */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
and semantics are as close as possible to those of the Perl 5 language.
|
and semantics are as close as possible to those of the Perl 5 language.
|
||||||
|
|
||||||
Written by Philip Hazel
|
Written by Philip Hazel
|
||||||
Copyright (c) 1997-2014 University of Cambridge
|
Copyright (c) 1997-2018 University of Cambridge
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -2306,7 +2306,7 @@ for (;;)
|
|||||||
case OP_ANY:
|
case OP_ANY:
|
||||||
if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
|
if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
|
||||||
if (md->partial != 0 &&
|
if (md->partial != 0 &&
|
||||||
eptr + 1 >= md->end_subject &&
|
eptr == md->end_subject - 1 &&
|
||||||
NLBLOCK->nltype == NLTYPE_FIXED &&
|
NLBLOCK->nltype == NLTYPE_FIXED &&
|
||||||
NLBLOCK->nllen == 2 &&
|
NLBLOCK->nllen == 2 &&
|
||||||
UCHAR21TEST(eptr) == NLBLOCK->nl[0])
|
UCHAR21TEST(eptr) == NLBLOCK->nl[0])
|
||||||
@@ -3054,7 +3054,7 @@ for (;;)
|
|||||||
{
|
{
|
||||||
RMATCH(eptr, ecode, offset_top, md, eptrb, RM18);
|
RMATCH(eptr, ecode, offset_top, md, eptrb, RM18);
|
||||||
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
|
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
|
||||||
if (eptr-- == pp) break; /* Stop if tried at original pos */
|
if (eptr-- <= pp) break; /* Stop if tried at original pos */
|
||||||
BACKCHAR(eptr);
|
BACKCHAR(eptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3211,7 +3211,7 @@ for (;;)
|
|||||||
{
|
{
|
||||||
RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
|
RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
|
||||||
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
|
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
|
||||||
if (eptr-- == pp) break; /* Stop if tried at original pos */
|
if (eptr-- <= pp) break; /* Stop if tried at original pos */
|
||||||
#ifdef SUPPORT_UTF
|
#ifdef SUPPORT_UTF
|
||||||
if (utf) BACKCHAR(eptr);
|
if (utf) BACKCHAR(eptr);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -163,7 +163,6 @@ typedef struct jit_arguments {
|
|||||||
const pcre_uchar *begin;
|
const pcre_uchar *begin;
|
||||||
const pcre_uchar *end;
|
const pcre_uchar *end;
|
||||||
int *offsets;
|
int *offsets;
|
||||||
pcre_uchar *uchar_ptr;
|
|
||||||
pcre_uchar *mark_ptr;
|
pcre_uchar *mark_ptr;
|
||||||
void *callout_data;
|
void *callout_data;
|
||||||
/* Everything else after. */
|
/* Everything else after. */
|
||||||
@@ -213,7 +212,7 @@ enum control_types {
|
|||||||
type_then_trap = 1
|
type_then_trap = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
|
typedef int (SLJIT_FUNC *jit_function)(jit_arguments *args);
|
||||||
|
|
||||||
/* The following structure is the key data type for the recursive
|
/* The following structure is the key data type for the recursive
|
||||||
code generator. It is allocated by compile_matchingpath, and contains
|
code generator. It is allocated by compile_matchingpath, and contains
|
||||||
@@ -488,9 +487,24 @@ typedef struct compare_context {
|
|||||||
/* Used for accessing the elements of the stack. */
|
/* Used for accessing the elements of the stack. */
|
||||||
#define STACK(i) ((i) * (int)sizeof(sljit_sw))
|
#define STACK(i) ((i) * (int)sizeof(sljit_sw))
|
||||||
|
|
||||||
|
#ifdef SLJIT_PREF_SHIFT_REG
|
||||||
|
#if SLJIT_PREF_SHIFT_REG == SLJIT_R2
|
||||||
|
/* Nothing. */
|
||||||
|
#elif SLJIT_PREF_SHIFT_REG == SLJIT_R3
|
||||||
|
#define SHIFT_REG_IS_R3
|
||||||
|
#else
|
||||||
|
#error "Unsupported shift register"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TMP1 SLJIT_R0
|
#define TMP1 SLJIT_R0
|
||||||
|
#ifdef SHIFT_REG_IS_R3
|
||||||
|
#define TMP2 SLJIT_R3
|
||||||
|
#define TMP3 SLJIT_R2
|
||||||
|
#else
|
||||||
#define TMP2 SLJIT_R2
|
#define TMP2 SLJIT_R2
|
||||||
#define TMP3 SLJIT_R3
|
#define TMP3 SLJIT_R3
|
||||||
|
#endif
|
||||||
#define STR_PTR SLJIT_S0
|
#define STR_PTR SLJIT_S0
|
||||||
#define STR_END SLJIT_S1
|
#define STR_END SLJIT_S1
|
||||||
#define STACK_TOP SLJIT_R1
|
#define STACK_TOP SLJIT_R1
|
||||||
@@ -519,13 +533,10 @@ the start pointers when the end of the capturing group has not yet reached. */
|
|||||||
|
|
||||||
#if defined COMPILE_PCRE8
|
#if defined COMPILE_PCRE8
|
||||||
#define MOV_UCHAR SLJIT_MOV_U8
|
#define MOV_UCHAR SLJIT_MOV_U8
|
||||||
#define MOVU_UCHAR SLJIT_MOVU_U8
|
|
||||||
#elif defined COMPILE_PCRE16
|
#elif defined COMPILE_PCRE16
|
||||||
#define MOV_UCHAR SLJIT_MOV_U16
|
#define MOV_UCHAR SLJIT_MOV_U16
|
||||||
#define MOVU_UCHAR SLJIT_MOVU_U16
|
|
||||||
#elif defined COMPILE_PCRE32
|
#elif defined COMPILE_PCRE32
|
||||||
#define MOV_UCHAR SLJIT_MOV_U32
|
#define MOV_UCHAR SLJIT_MOV_U32
|
||||||
#define MOVU_UCHAR SLJIT_MOVU_U32
|
|
||||||
#else
|
#else
|
||||||
#error Unsupported compiling mode
|
#error Unsupported compiling mode
|
||||||
#endif
|
#endif
|
||||||
@@ -2381,14 +2392,27 @@ if (length < 8)
|
|||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), SLJIT_R0, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), SLJIT_R0, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw)) == SLJIT_SUCCESS)
|
||||||
{
|
{
|
||||||
GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
|
GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
|
||||||
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
|
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
|
||||||
loop = LABEL();
|
loop = LABEL();
|
||||||
OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw), SLJIT_R0, 0);
|
sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw));
|
||||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
|
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
|
||||||
JUMPTO(SLJIT_NOT_ZERO, loop);
|
JUMPTO(SLJIT_NOT_ZERO, loop);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START + sizeof(sljit_sw));
|
||||||
|
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
|
||||||
|
loop = LABEL();
|
||||||
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), 0, SLJIT_R0, 0);
|
||||||
|
OP2(SLJIT_ADD, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, sizeof(sljit_sw));
|
||||||
|
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
|
||||||
|
JUMPTO(SLJIT_NOT_ZERO, loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static SLJIT_INLINE void reset_fast_fail(compiler_common *common)
|
static SLJIT_INLINE void reset_fast_fail(compiler_common *common)
|
||||||
@@ -2419,14 +2443,27 @@ if (length < 8)
|
|||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), TMP1, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), TMP1, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw)) == SLJIT_SUCCESS)
|
||||||
{
|
{
|
||||||
GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
|
GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
|
||||||
loop = LABEL();
|
loop = LABEL();
|
||||||
OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
|
sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
|
||||||
OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
|
OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
|
||||||
JUMPTO(SLJIT_NOT_ZERO, loop);
|
JUMPTO(SLJIT_NOT_ZERO, loop);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + 2 * sizeof(sljit_sw));
|
||||||
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
|
||||||
|
loop = LABEL();
|
||||||
|
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP1, 0);
|
||||||
|
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(sljit_sw));
|
||||||
|
OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
|
||||||
|
JUMPTO(SLJIT_NOT_ZERO, loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
|
OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
|
||||||
if (common->mark_ptr != 0)
|
if (common->mark_ptr != 0)
|
||||||
@@ -2435,10 +2472,10 @@ if (common->control_head_ptr != 0)
|
|||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, end));
|
||||||
}
|
}
|
||||||
|
|
||||||
static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
|
static sljit_sw SLJIT_FUNC do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
|
||||||
{
|
{
|
||||||
while (current != NULL)
|
while (current != NULL)
|
||||||
{
|
{
|
||||||
@@ -2459,7 +2496,7 @@ while (current != NULL)
|
|||||||
SLJIT_ASSERT(current[0] == 0 || current < (sljit_sw*)current[0]);
|
SLJIT_ASSERT(current[0] == 0 || current < (sljit_sw*)current[0]);
|
||||||
current = (sljit_sw*)current[0];
|
current = (sljit_sw*)current[0];
|
||||||
}
|
}
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
|
static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
|
||||||
@@ -2467,6 +2504,7 @@ static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
|
|||||||
DEFINE_COMPILER;
|
DEFINE_COMPILER;
|
||||||
struct sljit_label *loop;
|
struct sljit_label *loop;
|
||||||
struct sljit_jump *early_quit;
|
struct sljit_jump *early_quit;
|
||||||
|
BOOL has_pre;
|
||||||
|
|
||||||
/* At this point we can freely use all registers. */
|
/* At this point we can freely use all registers. */
|
||||||
OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
|
OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
|
||||||
@@ -2480,32 +2518,60 @@ if (common->mark_ptr != 0)
|
|||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);
|
||||||
OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
|
OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
|
||||||
OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin));
|
OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin));
|
||||||
GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START);
|
|
||||||
|
has_pre = sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw)) == SLJIT_SUCCESS;
|
||||||
|
GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START - (has_pre ? sizeof(sljit_sw) : 0));
|
||||||
|
|
||||||
/* Unlikely, but possible */
|
/* Unlikely, but possible */
|
||||||
early_quit = CMP(SLJIT_EQUAL, SLJIT_R1, 0, SLJIT_IMM, 0);
|
early_quit = CMP(SLJIT_EQUAL, SLJIT_R1, 0, SLJIT_IMM, 0);
|
||||||
loop = LABEL();
|
loop = LABEL();
|
||||||
OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0);
|
|
||||||
|
if (has_pre)
|
||||||
|
sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0);
|
||||||
OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
|
OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
|
||||||
|
}
|
||||||
|
|
||||||
|
OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, sizeof(int));
|
||||||
|
OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_R0, 0);
|
||||||
/* Copy the integer value to the output buffer */
|
/* Copy the integer value to the output buffer */
|
||||||
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
|
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
|
||||||
OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
|
OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
|
||||||
#endif
|
#endif
|
||||||
OP1(SLJIT_MOVU_S32, SLJIT_MEM1(SLJIT_R2), sizeof(int), SLJIT_S1, 0);
|
|
||||||
|
OP1(SLJIT_MOV_S32, SLJIT_MEM1(SLJIT_R2), 0, SLJIT_S1, 0);
|
||||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
|
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
|
||||||
JUMPTO(SLJIT_NOT_ZERO, loop);
|
JUMPTO(SLJIT_NOT_ZERO, loop);
|
||||||
JUMPHERE(early_quit);
|
JUMPHERE(early_quit);
|
||||||
|
|
||||||
/* Calculate the return value, which is the maximum ovector value. */
|
/* Calculate the return value, which is the maximum ovector value. */
|
||||||
if (topbracket > 1)
|
if (topbracket > 1)
|
||||||
|
{
|
||||||
|
if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw))) == SLJIT_SUCCESS)
|
||||||
{
|
{
|
||||||
GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
|
GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
|
||||||
OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
|
OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
|
||||||
|
|
||||||
/* OVECTOR(0) is never equal to SLJIT_S2. */
|
/* OVECTOR(0) is never equal to SLJIT_S2. */
|
||||||
loop = LABEL();
|
loop = LABEL();
|
||||||
OP1(SLJIT_MOVU, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw)));
|
sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw)));
|
||||||
OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
|
OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
|
||||||
CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
|
CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + (topbracket - 1) * 2 * sizeof(sljit_sw));
|
||||||
|
OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
|
||||||
|
|
||||||
|
/* OVECTOR(0) is never equal to SLJIT_S2. */
|
||||||
|
loop = LABEL();
|
||||||
|
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), 0);
|
||||||
|
OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 2 * (sljit_sw)sizeof(sljit_sw));
|
||||||
|
OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
|
||||||
|
CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
|
||||||
|
}
|
||||||
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
|
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -5166,93 +5232,190 @@ OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
|
|||||||
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
|
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHAR1 STR_END
|
|
||||||
#define CHAR2 STACK_TOP
|
|
||||||
|
|
||||||
static void do_casefulcmp(compiler_common *common)
|
static void do_casefulcmp(compiler_common *common)
|
||||||
{
|
{
|
||||||
DEFINE_COMPILER;
|
DEFINE_COMPILER;
|
||||||
struct sljit_jump *jump;
|
struct sljit_jump *jump;
|
||||||
struct sljit_label *label;
|
struct sljit_label *label;
|
||||||
|
int char1_reg;
|
||||||
|
int char2_reg;
|
||||||
|
|
||||||
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
|
if (sljit_get_register_index(TMP3) < 0)
|
||||||
|
{
|
||||||
|
char1_reg = STR_END;
|
||||||
|
char2_reg = STACK_TOP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char1_reg = TMP3;
|
||||||
|
char2_reg = RETURN_ADDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
|
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
|
||||||
OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
|
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR2, 0);
|
|
||||||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
|
|
||||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
|
||||||
|
|
||||||
|
if (char1_reg == STR_END)
|
||||||
|
{
|
||||||
|
OP1(SLJIT_MOV, TMP3, 0, char1_reg, 0);
|
||||||
|
OP1(SLJIT_MOV, RETURN_ADDR, 0, char2_reg, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
|
||||||
|
{
|
||||||
label = LABEL();
|
label = LABEL();
|
||||||
OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
|
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
|
||||||
OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
|
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
|
||||||
jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
|
jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
|
||||||
OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
|
OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
JUMPTO(SLJIT_NOT_ZERO, label);
|
JUMPTO(SLJIT_NOT_ZERO, label);
|
||||||
|
|
||||||
JUMPHERE(jump);
|
JUMPHERE(jump);
|
||||||
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
|
}
|
||||||
|
else if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
|
||||||
|
{
|
||||||
|
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
|
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
|
|
||||||
|
label = LABEL();
|
||||||
|
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
|
||||||
|
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
|
||||||
|
jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
|
||||||
|
OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
|
JUMPTO(SLJIT_NOT_ZERO, label);
|
||||||
|
|
||||||
|
JUMPHERE(jump);
|
||||||
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
|
}
|
||||||
OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
else
|
||||||
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
|
{
|
||||||
|
label = LABEL();
|
||||||
|
OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);
|
||||||
|
OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);
|
||||||
|
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
|
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
|
jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
|
||||||
|
OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
|
JUMPTO(SLJIT_NOT_ZERO, label);
|
||||||
|
|
||||||
|
JUMPHERE(jump);
|
||||||
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LCC_TABLE STACK_LIMIT
|
if (char1_reg == STR_END)
|
||||||
|
{
|
||||||
|
OP1(SLJIT_MOV, char1_reg, 0, TMP3, 0);
|
||||||
|
OP1(SLJIT_MOV, char2_reg, 0, RETURN_ADDR, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
sljit_emit_fast_return(compiler, TMP1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void do_caselesscmp(compiler_common *common)
|
static void do_caselesscmp(compiler_common *common)
|
||||||
{
|
{
|
||||||
DEFINE_COMPILER;
|
DEFINE_COMPILER;
|
||||||
struct sljit_jump *jump;
|
struct sljit_jump *jump;
|
||||||
struct sljit_label *label;
|
struct sljit_label *label;
|
||||||
|
int char1_reg = STR_END;
|
||||||
|
int char2_reg;
|
||||||
|
int lcc_table;
|
||||||
|
int opt_type = 0;
|
||||||
|
|
||||||
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
|
if (sljit_get_register_index(TMP3) < 0)
|
||||||
|
{
|
||||||
|
char2_reg = STACK_TOP;
|
||||||
|
lcc_table = STACK_LIMIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char2_reg = RETURN_ADDR;
|
||||||
|
lcc_table = TMP3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
|
||||||
|
opt_type = 1;
|
||||||
|
else if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
|
||||||
|
opt_type = 2;
|
||||||
|
|
||||||
|
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
|
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
|
||||||
|
|
||||||
OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, char1_reg, 0);
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR1, 0);
|
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, CHAR2, 0);
|
if (char2_reg == STACK_TOP)
|
||||||
OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
|
{
|
||||||
|
OP1(SLJIT_MOV, TMP3, 0, char2_reg, 0);
|
||||||
|
OP1(SLJIT_MOV, RETURN_ADDR, 0, lcc_table, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
OP1(SLJIT_MOV, lcc_table, 0, SLJIT_IMM, common->lcc);
|
||||||
|
|
||||||
|
if (opt_type == 1)
|
||||||
|
{
|
||||||
|
label = LABEL();
|
||||||
|
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
|
||||||
|
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
|
||||||
|
}
|
||||||
|
else if (opt_type == 2)
|
||||||
|
{
|
||||||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
|
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
|
|
||||||
label = LABEL();
|
label = LABEL();
|
||||||
OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
|
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
|
||||||
OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
|
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
label = LABEL();
|
||||||
|
OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);
|
||||||
|
OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);
|
||||||
|
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef COMPILE_PCRE8
|
#ifndef COMPILE_PCRE8
|
||||||
jump = CMP(SLJIT_GREATER, CHAR1, 0, SLJIT_IMM, 255);
|
jump = CMP(SLJIT_GREATER, char1_reg, 0, SLJIT_IMM, 255);
|
||||||
#endif
|
#endif
|
||||||
OP1(SLJIT_MOV_U8, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
|
OP1(SLJIT_MOV_U8, char1_reg, 0, SLJIT_MEM2(lcc_table, char1_reg), 0);
|
||||||
#ifndef COMPILE_PCRE8
|
#ifndef COMPILE_PCRE8
|
||||||
JUMPHERE(jump);
|
JUMPHERE(jump);
|
||||||
jump = CMP(SLJIT_GREATER, CHAR2, 0, SLJIT_IMM, 255);
|
jump = CMP(SLJIT_GREATER, char2_reg, 0, SLJIT_IMM, 255);
|
||||||
#endif
|
#endif
|
||||||
OP1(SLJIT_MOV_U8, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
|
OP1(SLJIT_MOV_U8, char2_reg, 0, SLJIT_MEM2(lcc_table, char2_reg), 0);
|
||||||
#ifndef COMPILE_PCRE8
|
#ifndef COMPILE_PCRE8
|
||||||
JUMPHERE(jump);
|
JUMPHERE(jump);
|
||||||
#endif
|
#endif
|
||||||
jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
|
|
||||||
|
if (opt_type == 0)
|
||||||
|
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
|
|
||||||
|
jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
|
||||||
OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
|
OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
JUMPTO(SLJIT_NOT_ZERO, label);
|
JUMPTO(SLJIT_NOT_ZERO, label);
|
||||||
|
|
||||||
JUMPHERE(jump);
|
JUMPHERE(jump);
|
||||||
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
|
|
||||||
|
if (opt_type == 2)
|
||||||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||||
OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
|
|
||||||
OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
if (char2_reg == STACK_TOP)
|
||||||
OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
|
{
|
||||||
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
|
OP1(SLJIT_MOV, char2_reg, 0, TMP3, 0);
|
||||||
|
OP1(SLJIT_MOV, lcc_table, 0, RETURN_ADDR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef LCC_TABLE
|
OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
|
||||||
#undef CHAR1
|
sljit_emit_fast_return(compiler, TMP1, 0);
|
||||||
#undef CHAR2
|
}
|
||||||
|
|
||||||
#if defined SUPPORT_UTF && defined SUPPORT_UCP
|
#if defined SUPPORT_UTF && defined SUPPORT_UCP
|
||||||
|
|
||||||
static const pcre_uchar * SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
|
static const pcre_uchar * SLJIT_FUNC do_utf_caselesscmp(pcre_uchar *src1, pcre_uchar *src2, pcre_uchar *end1, pcre_uchar *end2)
|
||||||
{
|
{
|
||||||
/* This function would be ineffective to do in JIT level. */
|
/* This function would be ineffective to do in JIT level. */
|
||||||
sljit_u32 c1, c2;
|
sljit_u32 c1, c2;
|
||||||
const pcre_uchar *src2 = args->uchar_ptr;
|
|
||||||
const pcre_uchar *end2 = args->end;
|
|
||||||
const ucd_record *ur;
|
const ucd_record *ur;
|
||||||
const sljit_u32 *pp;
|
const sljit_u32 *pp;
|
||||||
|
|
||||||
@@ -6775,32 +6938,37 @@ else
|
|||||||
#if defined SUPPORT_UTF && defined SUPPORT_UCP
|
#if defined SUPPORT_UTF && defined SUPPORT_UCP
|
||||||
if (common->utf && *cc == OP_REFI)
|
if (common->utf && *cc == OP_REFI)
|
||||||
{
|
{
|
||||||
SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1 && TMP2 == SLJIT_R2);
|
SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1);
|
||||||
if (ref)
|
if (ref)
|
||||||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
|
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
|
||||||
else
|
else
|
||||||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
|
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
|
||||||
|
|
||||||
if (withchecks)
|
if (withchecks)
|
||||||
jump = CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0);
|
jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_R2, 0);
|
||||||
|
|
||||||
/* Needed to save important temporary registers. */
|
/* No free saved registers so save data on stack. */
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
|
||||||
OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
|
OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0);
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
|
OP1(SLJIT_MOV, SLJIT_R3, 0, STR_END, 0);
|
||||||
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
|
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
|
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
|
||||||
|
|
||||||
if (common->mode == JIT_COMPILE)
|
if (common->mode == JIT_COMPILE)
|
||||||
add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
|
add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
|
OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_LESS, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
|
||||||
nopartial = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
|
|
||||||
|
add_jump(compiler, backtracks, JUMP(SLJIT_LESS));
|
||||||
|
|
||||||
|
nopartial = JUMP(SLJIT_NOT_EQUAL);
|
||||||
|
OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
|
||||||
check_partial(common, FALSE);
|
check_partial(common, FALSE);
|
||||||
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
|
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
|
||||||
JUMPHERE(nopartial);
|
JUMPHERE(nopartial);
|
||||||
}
|
}
|
||||||
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* SUPPORT_UTF && SUPPORT_UCP */
|
#endif /* SUPPORT_UTF && SUPPORT_UCP */
|
||||||
@@ -7124,7 +7292,7 @@ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IM
|
|||||||
return cc + 1 + LINK_SIZE;
|
return cc + 1 + LINK_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int SLJIT_CALL do_callout(struct jit_arguments *arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
|
static sljit_s32 SLJIT_FUNC do_callout(struct jit_arguments *arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
|
||||||
{
|
{
|
||||||
const pcre_uchar *begin = arguments->begin;
|
const pcre_uchar *begin = arguments->begin;
|
||||||
int *offset_vector = arguments->offsets;
|
int *offset_vector = arguments->offsets;
|
||||||
@@ -7206,18 +7374,17 @@ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
|
|||||||
/* SLJIT_R0 = arguments */
|
/* SLJIT_R0 = arguments */
|
||||||
OP1(SLJIT_MOV, SLJIT_R1, 0, STACK_TOP, 0);
|
OP1(SLJIT_MOV, SLJIT_R1, 0, STACK_TOP, 0);
|
||||||
GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);
|
GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);
|
||||||
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
|
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(S32) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
|
||||||
OP1(SLJIT_MOV_S32, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
|
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
|
free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
|
||||||
|
|
||||||
/* Check return value. */
|
/* Check return value. */
|
||||||
OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
OP2(SLJIT_SUB32 | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
||||||
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER));
|
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER32));
|
||||||
if (common->forced_quit_label == NULL)
|
if (common->forced_quit_label == NULL)
|
||||||
add_jump(compiler, &common->forced_quit, JUMP(SLJIT_NOT_EQUAL) /* SIG_LESS */);
|
add_jump(compiler, &common->forced_quit, JUMP(SLJIT_NOT_EQUAL32) /* SIG_LESS */);
|
||||||
else
|
else
|
||||||
JUMPTO(SLJIT_NOT_EQUAL /* SIG_LESS */, common->forced_quit_label);
|
JUMPTO(SLJIT_NOT_EQUAL32 /* SIG_LESS */, common->forced_quit_label);
|
||||||
return cc + 2 + 2 * LINK_SIZE;
|
return cc + 2 + 2 * LINK_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10438,11 +10605,11 @@ if (opcode == OP_SKIP_ARG)
|
|||||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
|
||||||
sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
|
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
|
|
||||||
OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
|
OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
|
||||||
add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
|
add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11030,7 +11197,7 @@ if (!compiler)
|
|||||||
common->compiler = compiler;
|
common->compiler = compiler;
|
||||||
|
|
||||||
/* Main pcre_jit_exec entry. */
|
/* Main pcre_jit_exec entry. */
|
||||||
sljit_emit_enter(compiler, 0, 1, 5, 5, 0, 0, private_data_size);
|
sljit_emit_enter(compiler, 0, SLJIT_ARG1(SW), 5, 5, 0, 0, private_data_size);
|
||||||
|
|
||||||
/* Register init. */
|
/* Register init. */
|
||||||
reset_ovector(common, (re->top_bracket + 1) * 2);
|
reset_ovector(common, (re->top_bracket + 1) * 2);
|
||||||
@@ -11043,8 +11210,8 @@ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str))
|
|||||||
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
|
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
|
||||||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||||
OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
|
OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, end));
|
||||||
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
|
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, start));
|
||||||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
|
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
|
||||||
|
|
||||||
@@ -11250,20 +11417,22 @@ common->quit_label = quit_label;
|
|||||||
set_jumps(common->stackalloc, LABEL());
|
set_jumps(common->stackalloc, LABEL());
|
||||||
/* RETURN_ADDR is not a saved register. */
|
/* RETURN_ADDR is not a saved register. */
|
||||||
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
|
|
||||||
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
|
|
||||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
|
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
|
|
||||||
OP2(SLJIT_SUB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
|
|
||||||
|
|
||||||
sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
|
SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1);
|
||||||
jump = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
|
||||||
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STACK_TOP, 0);
|
||||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
|
OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
|
OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_LIMIT, 0, SLJIT_IMM, STACK_GROWTH_RATE);
|
||||||
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
|
OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
|
OP1(SLJIT_MOV, STACK_LIMIT, 0, TMP2, 0);
|
||||||
sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
|
||||||
|
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
|
||||||
|
jump = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
||||||
|
OP1(SLJIT_MOV, TMP2, 0, STACK_LIMIT, 0);
|
||||||
|
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_RETURN_REG, 0);
|
||||||
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
|
||||||
|
sljit_emit_fast_return(compiler, TMP1, 0);
|
||||||
|
|
||||||
/* Allocation failed. */
|
/* Allocation failed. */
|
||||||
JUMPHERE(jump);
|
JUMPHERE(jump);
|
||||||
@@ -11408,9 +11577,9 @@ union {
|
|||||||
sljit_u8 local_space[MACHINE_STACK_SIZE];
|
sljit_u8 local_space[MACHINE_STACK_SIZE];
|
||||||
struct sljit_stack local_stack;
|
struct sljit_stack local_stack;
|
||||||
|
|
||||||
local_stack.max_limit = local_space;
|
local_stack.min_start = local_space;
|
||||||
local_stack.limit = local_space;
|
local_stack.start = local_space;
|
||||||
local_stack.base = local_space + MACHINE_STACK_SIZE;
|
local_stack.end = local_space + MACHINE_STACK_SIZE;
|
||||||
local_stack.top = local_space + MACHINE_STACK_SIZE;
|
local_stack.top = local_space + MACHINE_STACK_SIZE;
|
||||||
arguments->stack = &local_stack;
|
arguments->stack = &local_stack;
|
||||||
convert_executable_func.executable_func = executable_func;
|
convert_executable_func.executable_func = executable_func;
|
||||||
@@ -11528,7 +11697,7 @@ if ((options & PCRE_PARTIAL_HARD) != 0)
|
|||||||
else if ((options & PCRE_PARTIAL_SOFT) != 0)
|
else if ((options & PCRE_PARTIAL_SOFT) != 0)
|
||||||
mode = JIT_PARTIAL_SOFT_COMPILE;
|
mode = JIT_PARTIAL_SOFT_COMPILE;
|
||||||
|
|
||||||
if (functions->executable_funcs[mode] == NULL)
|
if (functions == NULL || functions->executable_funcs[mode] == NULL)
|
||||||
return PCRE_ERROR_JIT_BADOPTION;
|
return PCRE_ERROR_JIT_BADOPTION;
|
||||||
|
|
||||||
/* Sanity checks should be handled by pcre_exec. */
|
/* Sanity checks should be handled by pcre_exec. */
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
and semantics are as close as possible to those of the Perl 5 language.
|
and semantics are as close as possible to those of the Perl 5 language.
|
||||||
|
|
||||||
Written by Philip Hazel
|
Written by Philip Hazel
|
||||||
Copyright (c) 1997-2012 University of Cambridge
|
Copyright (c) 1997-2017 University of Cambridge
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
@@ -125,11 +125,11 @@ void WebSocketTest::testWebSocket()
|
|||||||
|
|
||||||
std::string payload("x");
|
std::string payload("x");
|
||||||
ws.sendFrame(payload.data(), (int) payload.size());
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
char buffer[1024];
|
char buffer[1024] = {};
|
||||||
int flags;
|
int flags;
|
||||||
int n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
int n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
assertTrue (n == payload.size());
|
assertTrue (n == payload.size());
|
||||||
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
assertTrue (payload.compare(0, payload.size(), buffer, n) == 0);
|
||||||
assertTrue (flags == WebSocket::FRAME_TEXT);
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
|
|
||||||
for (int i = 2; i < 20; i++)
|
for (int i = 2; i < 20; i++)
|
||||||
@@ -138,14 +138,16 @@ void WebSocketTest::testWebSocket()
|
|||||||
ws.sendFrame(payload.data(), (int) payload.size());
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
assertTrue (n == payload.size());
|
assertTrue (n == payload.size());
|
||||||
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
assertTrue (payload.compare(0, payload.size(), buffer, n) == 0);
|
||||||
assertTrue (flags == WebSocket::FRAME_TEXT);
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
|
|
||||||
ws.sendFrame(payload.data(), (int) payload.size());
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
Poco::Buffer<char> pocobuffer(0);
|
Poco::Buffer<char> pocobuffer(0);
|
||||||
|
assertTrue(0 == pocobuffer.size());
|
||||||
n = ws.receiveFrame(pocobuffer, flags);
|
n = ws.receiveFrame(pocobuffer, flags);
|
||||||
assertTrue (n == payload.size());
|
assertTrue (n == payload.size());
|
||||||
assertTrue (payload.compare(0, payload.size(), pocobuffer.begin(), 0, n) == 0);
|
assertTrue (n == pocobuffer.size());
|
||||||
|
assertTrue (payload.compare(0, payload.size(), pocobuffer.begin(), n) == 0);
|
||||||
assertTrue (flags == WebSocket::FRAME_TEXT);
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,14 +157,14 @@ void WebSocketTest::testWebSocket()
|
|||||||
ws.sendFrame(payload.data(), (int) payload.size());
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
assertTrue (n == payload.size());
|
assertTrue (n == payload.size());
|
||||||
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
assertTrue (payload.compare(0, payload.size(), buffer, n) == 0);
|
||||||
assertTrue (flags == WebSocket::FRAME_TEXT);
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
|
|
||||||
ws.sendFrame(payload.data(), (int) payload.size());
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
Poco::Buffer<char> pocobuffer(0);
|
Poco::Buffer<char> pocobuffer(0);
|
||||||
n = ws.receiveFrame(pocobuffer, flags);
|
n = ws.receiveFrame(pocobuffer, flags);
|
||||||
assertTrue (n == payload.size());
|
assertTrue (n == payload.size());
|
||||||
assertTrue (payload.compare(0, payload.size(), pocobuffer.begin(), 0, n) == 0);
|
assertTrue (payload.compare(0, payload.size(), pocobuffer.begin(), n) == 0);
|
||||||
assertTrue (flags == WebSocket::FRAME_TEXT);
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,14 +172,14 @@ void WebSocketTest::testWebSocket()
|
|||||||
ws.sendFrame(payload.data(), (int) payload.size());
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
assertTrue (n == payload.size());
|
assertTrue (n == payload.size());
|
||||||
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
assertTrue (payload.compare(0, payload.size(), buffer, n) == 0);
|
||||||
assertTrue (flags == WebSocket::FRAME_TEXT);
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
|
|
||||||
payload = "Hello, universe!";
|
payload = "Hello, universe!";
|
||||||
ws.sendFrame(payload.data(), (int) payload.size(), WebSocket::FRAME_BINARY);
|
ws.sendFrame(payload.data(), (int) payload.size(), WebSocket::FRAME_BINARY);
|
||||||
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
assertTrue (n == payload.size());
|
assertTrue (n == payload.size());
|
||||||
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
assertTrue (payload.compare(0, payload.size(), buffer, n) == 0);
|
||||||
assertTrue (flags == WebSocket::FRAME_BINARY);
|
assertTrue (flags == WebSocket::FRAME_BINARY);
|
||||||
|
|
||||||
ws.shutdown();
|
ws.shutdown();
|
||||||
@@ -210,7 +212,7 @@ void WebSocketTest::testWebSocketLarge()
|
|||||||
sstr << payload;
|
sstr << payload;
|
||||||
sstr.flush();
|
sstr.flush();
|
||||||
|
|
||||||
char buffer[msgSize + 1];
|
char buffer[msgSize + 1] = {};
|
||||||
int flags;
|
int flags;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
do
|
do
|
||||||
@@ -219,7 +221,7 @@ void WebSocketTest::testWebSocketLarge()
|
|||||||
} while (n > 0 && n < msgSize);
|
} while (n > 0 && n < msgSize);
|
||||||
|
|
||||||
assertTrue (n == payload.size());
|
assertTrue (n == payload.size());
|
||||||
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
assertTrue (payload.compare(0, payload.size(), buffer, n) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -247,7 +249,7 @@ void WebSocketTest::testOneLargeFrame(int msgSize)
|
|||||||
|
|
||||||
n = ws.receiveFrame(buffer.begin(), buffer.size(), flags);
|
n = ws.receiveFrame(buffer.begin(), buffer.size(), flags);
|
||||||
assertTrue (n == payload.size());
|
assertTrue (n == payload.size());
|
||||||
assertTrue (payload.compare(0, payload.size(), buffer.begin(), 0, n) == 0);
|
assertTrue (payload.compare(0, payload.size(), buffer.begin(), n) == 0);
|
||||||
|
|
||||||
ws.sendFrame(payload.data(), msgSize);
|
ws.sendFrame(payload.data(), msgSize);
|
||||||
|
|
||||||
@@ -255,7 +257,7 @@ void WebSocketTest::testOneLargeFrame(int msgSize)
|
|||||||
|
|
||||||
n = ws.receiveFrame(pocobuffer, flags);
|
n = ws.receiveFrame(pocobuffer, flags);
|
||||||
assertTrue (n == payload.size());
|
assertTrue (n == payload.size());
|
||||||
assertTrue (payload.compare(0, payload.size(), pocobuffer.begin(), 0, n) == 0);
|
assertTrue (payload.compare(0, payload.size(), pocobuffer.begin(), n) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -15,7 +15,8 @@ endif
|
|||||||
|
|
||||||
objects = NetSSLTestSuite Driver \
|
objects = NetSSLTestSuite Driver \
|
||||||
HTTPSClientSessionTest HTTPSClientTestSuite HTTPSServerTest HTTPSServerTestSuite \
|
HTTPSClientSessionTest HTTPSClientTestSuite HTTPSServerTest HTTPSServerTestSuite \
|
||||||
HTTPSStreamFactoryTest HTTPSTestServer TCPServerTest TCPServerTestSuite
|
HTTPSStreamFactoryTest HTTPSTestServer TCPServerTest TCPServerTestSuite \
|
||||||
|
WebSocketTest WebSocketTestSuite
|
||||||
|
|
||||||
target = testrunner
|
target = testrunner
|
||||||
target_version = 1
|
target_version = 1
|
||||||
|
@@ -428,7 +428,6 @@ void HTTPSClientSessionTest::testUnknownContentLength()
|
|||||||
assertTrue (ostr.str() == HTTPSTestServer::SMALL_BODY);
|
assertTrue (ostr.str() == HTTPSTestServer::SMALL_BODY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void HTTPSClientSessionTest::testServerAbort()
|
void HTTPSClientSessionTest::testServerAbort()
|
||||||
{
|
{
|
||||||
HTTPSTestServer srv;
|
HTTPSTestServer srv;
|
||||||
|
@@ -13,16 +13,17 @@
|
|||||||
#include "HTTPSClientTestSuite.h"
|
#include "HTTPSClientTestSuite.h"
|
||||||
#include "TCPServerTestSuite.h"
|
#include "TCPServerTestSuite.h"
|
||||||
#include "HTTPSServerTestSuite.h"
|
#include "HTTPSServerTestSuite.h"
|
||||||
|
#include "WebSocketTestSuite.h"
|
||||||
|
|
||||||
|
|
||||||
CppUnit::Test* NetSSLTestSuite::suite()
|
CppUnit::Test* NetSSLTestSuite::suite()
|
||||||
{
|
{
|
||||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("OpenSSLTestSuite");
|
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("OpenSSLTestSuite");
|
||||||
|
|
||||||
|
|
||||||
pSuite->addTest(HTTPSClientTestSuite::suite());
|
pSuite->addTest(HTTPSClientTestSuite::suite());
|
||||||
pSuite->addTest(TCPServerTestSuite::suite());
|
pSuite->addTest(TCPServerTestSuite::suite());
|
||||||
pSuite->addTest(HTTPSServerTestSuite::suite());
|
pSuite->addTest(HTTPSServerTestSuite::suite());
|
||||||
|
pSuite->addTest(WebSocketTestSuite::suite());
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
237
NetSSL_OpenSSL/testsuite/src/WebSocketTest.cpp
Normal file
237
NetSSL_OpenSSL/testsuite/src/WebSocketTest.cpp
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
//
|
||||||
|
// WebSocketTest.cpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "WebSocketTest.h"
|
||||||
|
#include "Poco/CppUnit/TestCaller.h"
|
||||||
|
#include "Poco/CppUnit/TestSuite.h"
|
||||||
|
#include "Poco/Net/WebSocket.h"
|
||||||
|
#include "Poco/Net/SocketStream.h"
|
||||||
|
#include "Poco/Net/HTTPSClientSession.h"
|
||||||
|
#include "Poco/Net/HTTPServer.h"
|
||||||
|
#include "Poco/Net/HTTPServerParams.h"
|
||||||
|
#include "Poco/Net/HTTPRequestHandler.h"
|
||||||
|
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||||
|
#include "Poco/Net/HTTPServerRequest.h"
|
||||||
|
#include "Poco/Net/HTTPServerResponse.h"
|
||||||
|
#include "Poco/Net/SecureServerSocket.h"
|
||||||
|
#include "Poco/Net/NetException.h"
|
||||||
|
#include "Poco/Thread.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using Poco::Net::HTTPSClientSession;
|
||||||
|
using Poco::Net::HTTPRequest;
|
||||||
|
using Poco::Net::HTTPResponse;
|
||||||
|
using Poco::Net::HTTPServerRequest;
|
||||||
|
using Poco::Net::HTTPServerResponse;
|
||||||
|
using Poco::Net::SocketStream;
|
||||||
|
using Poco::Net::WebSocket;
|
||||||
|
using Poco::Net::WebSocketException;
|
||||||
|
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class WebSocketRequestHandler: public Poco::Net::HTTPRequestHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WebSocketRequestHandler(std::size_t bufSize = 1024): _bufSize(bufSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
WebSocket ws(request, response);
|
||||||
|
#ifndef POCO_ENABLE_CPP11
|
||||||
|
std::auto_ptr<char> pBuffer(new char[_bufSize]);
|
||||||
|
#else
|
||||||
|
std::unique_ptr<char[]> pBuffer(new char[_bufSize]);
|
||||||
|
#endif // POCO_ENABLE_CPP11
|
||||||
|
int flags;
|
||||||
|
int n;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
n = ws.receiveFrame(pBuffer.get(), static_cast<int>(_bufSize), flags);
|
||||||
|
if (n == 0)
|
||||||
|
break;
|
||||||
|
ws.sendFrame(pBuffer.get(), n, flags);
|
||||||
|
}
|
||||||
|
while ((flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
|
||||||
|
}
|
||||||
|
catch (WebSocketException& exc)
|
||||||
|
{
|
||||||
|
switch (exc.code())
|
||||||
|
{
|
||||||
|
case WebSocket::WS_ERR_HANDSHAKE_UNSUPPORTED_VERSION:
|
||||||
|
response.set("Sec-WebSocket-Version", WebSocket::WEBSOCKET_VERSION);
|
||||||
|
// fallthrough
|
||||||
|
case WebSocket::WS_ERR_NO_HANDSHAKE:
|
||||||
|
case WebSocket::WS_ERR_HANDSHAKE_NO_VERSION:
|
||||||
|
case WebSocket::WS_ERR_HANDSHAKE_NO_KEY:
|
||||||
|
response.setStatusAndReason(HTTPResponse::HTTP_BAD_REQUEST);
|
||||||
|
response.setContentLength(0);
|
||||||
|
response.send();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t _bufSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WebSocketRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WebSocketRequestHandlerFactory(std::size_t bufSize = 1024): _bufSize(bufSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Poco::Net::HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
|
||||||
|
{
|
||||||
|
return new WebSocketRequestHandler(_bufSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t _bufSize;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WebSocketTest::WebSocketTest(const std::string& name): CppUnit::TestCase(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WebSocketTest::~WebSocketTest()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WebSocketTest::testWebSocket()
|
||||||
|
{
|
||||||
|
Poco::Net::SecureServerSocket ss(0);
|
||||||
|
Poco::Net::HTTPServer server(new WebSocketRequestHandlerFactory, ss, new Poco::Net::HTTPServerParams);
|
||||||
|
server.start();
|
||||||
|
|
||||||
|
Poco::Thread::sleep(200);
|
||||||
|
|
||||||
|
HTTPSClientSession cs("127.0.0.1", ss.address().port());
|
||||||
|
HTTPRequest request(HTTPRequest::HTTP_GET, "/ws");
|
||||||
|
HTTPResponse response;
|
||||||
|
WebSocket ws(cs, request, response);
|
||||||
|
|
||||||
|
std::string payload("x");
|
||||||
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
|
char buffer[1024] = {};
|
||||||
|
int flags;
|
||||||
|
int n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
assertTrue (n == payload.size());
|
||||||
|
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||||
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
|
|
||||||
|
for (int i = 2; i < 20; i++)
|
||||||
|
{
|
||||||
|
payload.assign(i, 'x');
|
||||||
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
assertTrue (n == payload.size());
|
||||||
|
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||||
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 125; i < 129; i++)
|
||||||
|
{
|
||||||
|
payload.assign(i, 'x');
|
||||||
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
assertTrue (n == payload.size());
|
||||||
|
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||||
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = "Hello, world!";
|
||||||
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
assertTrue (n == payload.size());
|
||||||
|
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||||
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
|
|
||||||
|
payload = "Hello, universe!";
|
||||||
|
ws.sendFrame(payload.data(), (int) payload.size(), WebSocket::FRAME_BINARY);
|
||||||
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
assertTrue (n == payload.size());
|
||||||
|
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||||
|
assertTrue (flags == WebSocket::FRAME_BINARY);
|
||||||
|
|
||||||
|
ws.shutdown();
|
||||||
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
assertTrue (n == 2);
|
||||||
|
assertTrue ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_CLOSE);
|
||||||
|
|
||||||
|
server.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WebSocketTest::testWebSocketLarge()
|
||||||
|
{
|
||||||
|
const int msgSize = 64000;
|
||||||
|
|
||||||
|
Poco::Net::SecureServerSocket ss(0);
|
||||||
|
Poco::Net::HTTPServer server(new WebSocketRequestHandlerFactory(msgSize), ss, new Poco::Net::HTTPServerParams);
|
||||||
|
server.start();
|
||||||
|
|
||||||
|
Poco::Thread::sleep(200);
|
||||||
|
|
||||||
|
HTTPSClientSession cs("127.0.0.1", ss.address().port());
|
||||||
|
HTTPRequest request(HTTPRequest::HTTP_GET, "/ws");
|
||||||
|
HTTPResponse response;
|
||||||
|
WebSocket ws(cs, request, response);
|
||||||
|
ws.setSendBufferSize(msgSize);
|
||||||
|
ws.setReceiveBufferSize(msgSize);
|
||||||
|
std::string payload(msgSize, 'x');
|
||||||
|
SocketStream sstr(ws);
|
||||||
|
sstr << payload;
|
||||||
|
sstr.flush();
|
||||||
|
|
||||||
|
char buffer[msgSize + 1] = {};
|
||||||
|
int flags;
|
||||||
|
int n = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
n += ws.receiveFrame(buffer + n, sizeof(buffer) - n, flags);
|
||||||
|
} while (n > 0 && n < msgSize);
|
||||||
|
|
||||||
|
assertTrue (n == payload.size());
|
||||||
|
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||||
|
|
||||||
|
server.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WebSocketTest::setUp()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WebSocketTest::tearDown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CppUnit::Test* WebSocketTest::suite()
|
||||||
|
{
|
||||||
|
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("WebSocketTest");
|
||||||
|
|
||||||
|
CppUnit_addTest(pSuite, WebSocketTest, testWebSocket);
|
||||||
|
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketLarge);
|
||||||
|
|
||||||
|
return pSuite;
|
||||||
|
}
|
39
NetSSL_OpenSSL/testsuite/src/WebSocketTest.h
Normal file
39
NetSSL_OpenSSL/testsuite/src/WebSocketTest.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// WebSocketTest.h
|
||||||
|
//
|
||||||
|
// Definition of the WebSocketTest class.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef WebSocketTest_INCLUDED
|
||||||
|
#define WebSocketTest_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Net/Net.h"
|
||||||
|
#include "Poco/CppUnit/TestCase.h"
|
||||||
|
|
||||||
|
|
||||||
|
class WebSocketTest: public CppUnit::TestCase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WebSocketTest(const std::string& name);
|
||||||
|
~WebSocketTest();
|
||||||
|
|
||||||
|
void testWebSocket();
|
||||||
|
void testWebSocketLarge();
|
||||||
|
|
||||||
|
void setUp();
|
||||||
|
void tearDown();
|
||||||
|
|
||||||
|
static CppUnit::Test* suite();
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // WebSocketTest_INCLUDED
|
22
NetSSL_OpenSSL/testsuite/src/WebSocketTestSuite.cpp
Normal file
22
NetSSL_OpenSSL/testsuite/src/WebSocketTestSuite.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// WebSocketTestSuite.cpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "WebSocketTestSuite.h"
|
||||||
|
#include "WebSocketTest.h"
|
||||||
|
|
||||||
|
|
||||||
|
CppUnit::Test* WebSocketTestSuite::suite()
|
||||||
|
{
|
||||||
|
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("WebSocketTestSuite");
|
||||||
|
|
||||||
|
pSuite->addTest(WebSocketTest::suite());
|
||||||
|
|
||||||
|
return pSuite;
|
||||||
|
}
|
27
NetSSL_OpenSSL/testsuite/src/WebSocketTestSuite.h
Normal file
27
NetSSL_OpenSSL/testsuite/src/WebSocketTestSuite.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// WebSocketTestSuite.h
|
||||||
|
//
|
||||||
|
// Definition of the WebSocketTestSuite class.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef WebSocketTestSuite_INCLUDED
|
||||||
|
#define WebSocketTestSuite_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "CppUnit/TestSuite.h"
|
||||||
|
|
||||||
|
|
||||||
|
class WebSocketTestSuite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static CppUnit::Test* suite();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // WebSocketTestSuite_INCLUDED
|
231
NetSSL_Win/testsuite/src/WebSocketTest.cpp
Normal file
231
NetSSL_Win/testsuite/src/WebSocketTest.cpp
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
//
|
||||||
|
// WebSocketTest.cpp
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "WebSocketTest.h"
|
||||||
|
#include "Poco/CppUnit/TestCaller.h"
|
||||||
|
#include "Poco/CppUnit/TestSuite.h"
|
||||||
|
#include "Poco/Net/WebSocket.h"
|
||||||
|
#include "Poco/Net/SocketStream.h"
|
||||||
|
#include "Poco/Net/HTTPSClientSession.h"
|
||||||
|
#include "Poco/Net/HTTPServer.h"
|
||||||
|
#include "Poco/Net/HTTPServerParams.h"
|
||||||
|
#include "Poco/Net/HTTPRequestHandler.h"
|
||||||
|
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||||
|
#include "Poco/Net/HTTPServerRequest.h"
|
||||||
|
#include "Poco/Net/HTTPServerResponse.h"
|
||||||
|
#include "Poco/Net/SecureServerSocket.h"
|
||||||
|
#include "Poco/Net/NetException.h"
|
||||||
|
#include "Poco/Thread.h"
|
||||||
|
|
||||||
|
|
||||||
|
using Poco::Net::HTTPSClientSession;
|
||||||
|
using Poco::Net::HTTPRequest;
|
||||||
|
using Poco::Net::HTTPResponse;
|
||||||
|
using Poco::Net::HTTPServerRequest;
|
||||||
|
using Poco::Net::HTTPServerResponse;
|
||||||
|
using Poco::Net::SocketStream;
|
||||||
|
using Poco::Net::WebSocket;
|
||||||
|
using Poco::Net::WebSocketException;
|
||||||
|
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class WebSocketRequestHandler: public Poco::Net::HTTPRequestHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WebSocketRequestHandler(std::size_t bufSize = 1024): _bufSize(bufSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
WebSocket ws(request, response);
|
||||||
|
std::unique_ptr<char[]> pBuffer(new char[_bufSize]);
|
||||||
|
int flags;
|
||||||
|
int n;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
n = ws.receiveFrame(pBuffer.get(), static_cast<int>(_bufSize), flags);
|
||||||
|
if (n == 0)
|
||||||
|
break;
|
||||||
|
ws.sendFrame(pBuffer.get(), n, flags);
|
||||||
|
}
|
||||||
|
while ((flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
|
||||||
|
}
|
||||||
|
catch (WebSocketException& exc)
|
||||||
|
{
|
||||||
|
switch (exc.code())
|
||||||
|
{
|
||||||
|
case WebSocket::WS_ERR_HANDSHAKE_UNSUPPORTED_VERSION:
|
||||||
|
response.set("Sec-WebSocket-Version", WebSocket::WEBSOCKET_VERSION);
|
||||||
|
// fallthrough
|
||||||
|
case WebSocket::WS_ERR_NO_HANDSHAKE:
|
||||||
|
case WebSocket::WS_ERR_HANDSHAKE_NO_VERSION:
|
||||||
|
case WebSocket::WS_ERR_HANDSHAKE_NO_KEY:
|
||||||
|
response.setStatusAndReason(HTTPResponse::HTTP_BAD_REQUEST);
|
||||||
|
response.setContentLength(0);
|
||||||
|
response.send();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t _bufSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WebSocketRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WebSocketRequestHandlerFactory(std::size_t bufSize = 1024): _bufSize(bufSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Poco::Net::HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request)
|
||||||
|
{
|
||||||
|
return new WebSocketRequestHandler(_bufSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::size_t _bufSize;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WebSocketTest::WebSocketTest(const std::string& name): CppUnit::TestCase(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WebSocketTest::~WebSocketTest()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WebSocketTest::testWebSocket()
|
||||||
|
{
|
||||||
|
Poco::Net::SecureServerSocket ss(0);
|
||||||
|
Poco::Net::HTTPServer server(new WebSocketRequestHandlerFactory, ss, new Poco::Net::HTTPServerParams);
|
||||||
|
server.start();
|
||||||
|
|
||||||
|
Poco::Thread::sleep(200);
|
||||||
|
|
||||||
|
HTTPSClientSession cs("127.0.0.1", ss.address().port());
|
||||||
|
HTTPRequest request(HTTPRequest::HTTP_GET, "/ws");
|
||||||
|
HTTPResponse response;
|
||||||
|
WebSocket ws(cs, request, response);
|
||||||
|
|
||||||
|
std::string payload("x");
|
||||||
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
|
char buffer[1024] = {};
|
||||||
|
int flags;
|
||||||
|
int n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
assertTrue (n == payload.size());
|
||||||
|
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||||
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
|
|
||||||
|
for (int i = 2; i < 20; i++)
|
||||||
|
{
|
||||||
|
payload.assign(i, 'x');
|
||||||
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
assertTrue (n == payload.size());
|
||||||
|
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||||
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 125; i < 129; i++)
|
||||||
|
{
|
||||||
|
payload.assign(i, 'x');
|
||||||
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
assertTrue (n == payload.size());
|
||||||
|
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||||
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
payload = "Hello, world!";
|
||||||
|
ws.sendFrame(payload.data(), (int) payload.size());
|
||||||
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
assertTrue (n == payload.size());
|
||||||
|
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||||
|
assertTrue (flags == WebSocket::FRAME_TEXT);
|
||||||
|
|
||||||
|
payload = "Hello, universe!";
|
||||||
|
ws.sendFrame(payload.data(), (int) payload.size(), WebSocket::FRAME_BINARY);
|
||||||
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
assertTrue (n == payload.size());
|
||||||
|
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||||
|
assertTrue (flags == WebSocket::FRAME_BINARY);
|
||||||
|
|
||||||
|
ws.shutdown();
|
||||||
|
n = ws.receiveFrame(buffer, sizeof(buffer), flags);
|
||||||
|
assertTrue (n == 2);
|
||||||
|
assertTrue ((flags & WebSocket::FRAME_OP_BITMASK) == WebSocket::FRAME_OP_CLOSE);
|
||||||
|
|
||||||
|
server.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WebSocketTest::testWebSocketLarge()
|
||||||
|
{
|
||||||
|
const int msgSize = 64000;
|
||||||
|
|
||||||
|
Poco::Net::SecureServerSocket ss(0);
|
||||||
|
Poco::Net::HTTPServer server(new WebSocketRequestHandlerFactory(msgSize), ss, new Poco::Net::HTTPServerParams);
|
||||||
|
server.start();
|
||||||
|
|
||||||
|
Poco::Thread::sleep(200);
|
||||||
|
|
||||||
|
HTTPSClientSession cs("127.0.0.1", ss.address().port());
|
||||||
|
HTTPRequest request(HTTPRequest::HTTP_GET, "/ws");
|
||||||
|
HTTPResponse response;
|
||||||
|
WebSocket ws(cs, request, response);
|
||||||
|
ws.setSendBufferSize(msgSize);
|
||||||
|
ws.setReceiveBufferSize(msgSize);
|
||||||
|
std::string payload(msgSize, 'x');
|
||||||
|
SocketStream sstr(ws);
|
||||||
|
sstr << payload;
|
||||||
|
sstr.flush();
|
||||||
|
|
||||||
|
char buffer[msgSize + 1] = {};
|
||||||
|
int flags;
|
||||||
|
int n = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
n += ws.receiveFrame(buffer + n, sizeof(buffer) - n, flags);
|
||||||
|
} while (n > 0 && n < msgSize);
|
||||||
|
|
||||||
|
assertTrue (n == payload.size());
|
||||||
|
assertTrue (payload.compare(0, payload.size(), buffer, 0, n) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WebSocketTest::setUp()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WebSocketTest::tearDown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CppUnit::Test* WebSocketTest::suite()
|
||||||
|
{
|
||||||
|
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("WebSocketTest");
|
||||||
|
|
||||||
|
CppUnit_addTest(pSuite, WebSocketTest, testWebSocket);
|
||||||
|
CppUnit_addTest(pSuite, WebSocketTest, testWebSocketLarge);
|
||||||
|
|
||||||
|
return pSuite;
|
||||||
|
}
|
39
NetSSL_Win/testsuite/src/WebSocketTest.h
Normal file
39
NetSSL_Win/testsuite/src/WebSocketTest.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// WebSocketTest.h
|
||||||
|
//
|
||||||
|
// Definition of the WebSocketTest class.
|
||||||
|
//
|
||||||
|
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||||
|
// and Contributors.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef WebSocketTest_INCLUDED
|
||||||
|
#define WebSocketTest_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "Poco/Net/Net.h"
|
||||||
|
#include "Poco/CppUnit/TestCase.h"
|
||||||
|
|
||||||
|
|
||||||
|
class WebSocketTest: public CppUnit::TestCase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WebSocketTest(const std::string& name);
|
||||||
|
~WebSocketTest();
|
||||||
|
|
||||||
|
void testWebSocket();
|
||||||
|
void testWebSocketLarge();
|
||||||
|
|
||||||
|
void setUp();
|
||||||
|
void tearDown();
|
||||||
|
|
||||||
|
static CppUnit::Test* suite();
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // WebSocketTest_INCLUDED
|
@@ -830,7 +830,7 @@ PocoDoc.version=${version}-all
|
|||||||
javaWDK = javaWDK.replace('\\','/')
|
javaWDK = javaWDK.replace('\\','/')
|
||||||
|
|
||||||
file.text += """
|
file.text += """
|
||||||
Includes=-I${postgres32Home}/include,-I${mysql32Home}/include,-ICppParser/include,-ICppUnit/include,-ICrypto/include,-IData/include,-IData/include,-IData/MySQL/include,-IData/ODBC/include,-IData/PostgreSQL/include,-IData/SQLite/include, -IData/SQLite/src,-IFoundation/include,-IJSON/include,-IMongoDB/include,-INet/include,-INetSSL_OpenSSL/include,-INetSSL_Win/include,-IRedis/include,-IUtil/include,-IXML/include,-IZip/include,-ISevenZip/include,-IPDF/include
|
Includes=-I${postgres32Home}/include,-I${mysql32Home}/include,-ICppParser/include,-ICppUnit/include,-ICrypto/include,-IEncodings/include,-IData/include,-IData/include,-IData/MySQL/include,-IData/ODBC/include,-IData/PostgreSQL/include,-IData/SQLite/include, -IData/SQLite/src,-IFoundation/include,-IJSON/include,-IMongoDB/include,-INet/include,-INetSSL_OpenSSL/include,-INetSSL_Win/include,-IRedis/include,-IUtil/include,-IXML/include,-IZip/include,-ISevenZip/include,-IPDF/include
|
||||||
VCH=${javaVCH}
|
VCH=${javaVCH}
|
||||||
WDK=${javaWDK}
|
WDK=${javaWDK}
|
||||||
CLP=${javaCLP}
|
CLP=${javaCLP}
|
||||||
|
Reference in New Issue
Block a user