feat:replace boost library with C++11 std library

This commit is contained in:
Livox-SDK
2020-04-01 20:53:55 +08:00
parent 559ffbf712
commit 47389056be
1936 changed files with 241862 additions and 60153 deletions
+80
View File
@@ -0,0 +1,80 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Usage Notes:
*
* this module, and the misc/win32/utf8.c modules must be
* compiled APR_EXPORT_STATIC and linked to an application with
* the /entry:wmainCRTStartup flag (which this module kindly
* provides to the developer who links to libaprapp-1.lib).
* This module becomes the true wmain entry point, and passes
* utf-8 reformatted argv and env arrays to the application's
* main() function as if nothing happened.
*
* This module is only compatible with Unicode operating systems.
* Mixed (Win9x backwards compatible) binaries should refer instead
* to the apr_startup.c module.
*
* _dbg_malloc/realloc is used in place of the usual API, in order
* to convince the MSVCRT that it created these entities. If we
* do not create them as _CRT_BLOCK entities, the crt will fault
* on an assert. We are not worrying about the crt's locks here,
* since we are single threaded [so far].
*/
#include "apr_general.h"
#include "ShellAPI.h"
#include "wchar.h"
#include "apr_arch_file_io.h"
#include "assert.h"
#include "apr_private.h"
#include "apr_arch_misc.h"
#pragma comment(linker,"/ENTRY:wmainCRTStartup")
extern int main(int argc, const char **argv, const char **env);
int wmain(int argc, const wchar_t **wargv, const wchar_t **wenv)
{
char **argv;
char **env;
int dupenv;
(void)apr_wastrtoastr(&argv, wargv, argc);
dupenv = apr_wastrtoastr(&env, wenv, -1);
_environ = apr_malloc_dbg((dupenv + 1) * sizeof (char *),
__FILE__, __LINE__ );
memcpy(_environ, env, (dupenv + 1) * sizeof (char *));
/* MSVCRT will attempt to maintain the wide environment calls
* on _putenv(), which is bogus if we've passed a non-ascii
* string to _putenv(), since they use MultiByteToWideChar
* and breaking the implicit utf-8 assumption we've built.
*
* Reset _wenviron for good measure.
*/
if (_wenviron) {
wenv = _wenviron;
_wenviron = NULL;
free((wchar_t **)wenv);
}
apr_app_init_complete = 1;
return main(argc, argv, env);
}
+55
View File
@@ -0,0 +1,55 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "apr.h"
#include "apr_strings.h"
#include "apr_portable.h"
APR_DECLARE(const char*) apr_os_default_encoding (apr_pool_t *pool)
{
return apr_psprintf(pool, "CP%u", (unsigned) GetACP());
}
APR_DECLARE(const char*) apr_os_locale_encoding (apr_pool_t *pool)
{
#ifdef _UNICODE
int i;
#endif
#if defined(_WIN32_WCE)
LCID locale = GetUserDefaultLCID();
#else
LCID locale = GetThreadLocale();
#endif
int len = GetLocaleInfo(locale, LOCALE_IDEFAULTANSICODEPAGE, NULL, 0);
char *cp = apr_palloc(pool, (len * sizeof(TCHAR)) + 2);
if (0 < GetLocaleInfo(locale, LOCALE_IDEFAULTANSICODEPAGE, (TCHAR*) (cp + 2), len))
{
/* Fix up the returned number to make a valid codepage name of
the form "CPnnnn". */
cp[0] = 'C';
cp[1] = 'P';
#ifdef _UNICODE
for(i = 0; i < len; i++) {
cp[i + 2] = (char) ((TCHAR*) (cp + 2))[i];
}
#endif
return cp;
}
return apr_os_default_encoding(pool);
}
+192
View File
@@ -0,0 +1,192 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define APR_WANT_STRFUNC
#include "apr_want.h"
#include "apr.h"
#include "apr_arch_misc.h"
#include "apr_arch_utf8.h"
#include "apr_env.h"
#include "apr_errno.h"
#include "apr_pools.h"
#include "apr_strings.h"
#if APR_HAS_UNICODE_FS && !defined(_WIN32_WCE)
static apr_status_t widen_envvar_name (apr_wchar_t *buffer,
apr_size_t bufflen,
const char *envvar)
{
apr_size_t inchars;
apr_status_t status;
inchars = strlen(envvar) + 1;
status = apr_conv_utf8_to_ucs2(envvar, &inchars, buffer, &bufflen);
if (status == APR_INCOMPLETE)
status = APR_ENAMETOOLONG;
return status;
}
#endif
APR_DECLARE(apr_status_t) apr_env_get(char **value,
const char *envvar,
apr_pool_t *pool)
{
#if defined(_WIN32_WCE)
return APR_ENOTIMPL;
#else
char *val = NULL;
DWORD size;
#if APR_HAS_UNICODE_FS
IF_WIN_OS_IS_UNICODE
{
apr_wchar_t wenvvar[APR_PATH_MAX];
apr_size_t inchars, outchars;
apr_wchar_t *wvalue, dummy;
apr_status_t status;
status = widen_envvar_name(wenvvar, APR_PATH_MAX, envvar);
if (status)
return status;
SetLastError(0);
size = GetEnvironmentVariableW(wenvvar, &dummy, 0);
if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
/* The environment variable doesn't exist. */
return APR_ENOENT;
if (size == 0) {
/* The environment value exists, but is zero-length. */
*value = apr_pstrdup(pool, "");
return APR_SUCCESS;
}
wvalue = apr_palloc(pool, size * sizeof(*wvalue));
size = GetEnvironmentVariableW(wenvvar, wvalue, size);
inchars = wcslen(wvalue) + 1;
outchars = 3 * inchars; /* Enough for any UTF-8 representation */
val = apr_palloc(pool, outchars);
status = apr_conv_ucs2_to_utf8(wvalue, &inchars, val, &outchars);
if (status)
return status;
}
#endif
#if APR_HAS_ANSI_FS
ELSE_WIN_OS_IS_ANSI
{
char dummy;
SetLastError(0);
size = GetEnvironmentVariableA(envvar, &dummy, 0);
if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
/* The environment variable doesn't exist. */
return APR_ENOENT;
if (size == 0) {
/* The environment value exists, but is zero-length. */
*value = apr_pstrdup(pool, "");
return APR_SUCCESS;
}
val = apr_palloc(pool, size);
size = GetEnvironmentVariableA(envvar, val, size);
if (size == 0)
/* Mid-air collision?. Somebody must've changed the env. var. */
return APR_INCOMPLETE;
}
#endif
*value = val;
return APR_SUCCESS;
#endif
}
APR_DECLARE(apr_status_t) apr_env_set(const char *envvar,
const char *value,
apr_pool_t *pool)
{
#if defined(_WIN32_WCE)
return APR_ENOTIMPL;
#else
#if APR_HAS_UNICODE_FS
IF_WIN_OS_IS_UNICODE
{
apr_wchar_t wenvvar[APR_PATH_MAX];
apr_wchar_t *wvalue;
apr_size_t inchars, outchars;
apr_status_t status;
status = widen_envvar_name(wenvvar, APR_PATH_MAX, envvar);
if (status)
return status;
outchars = inchars = strlen(value) + 1;
wvalue = apr_palloc(pool, outchars * sizeof(*wvalue));
status = apr_conv_utf8_to_ucs2(value, &inchars, wvalue, &outchars);
if (status)
return status;
if (!SetEnvironmentVariableW(wenvvar, wvalue))
return apr_get_os_error();
}
#endif
#if APR_HAS_ANSI_FS
ELSE_WIN_OS_IS_ANSI
{
if (!SetEnvironmentVariableA(envvar, value))
return apr_get_os_error();
}
#endif
return APR_SUCCESS;
#endif
}
APR_DECLARE(apr_status_t) apr_env_delete(const char *envvar, apr_pool_t *pool)
{
#if defined(_WIN32_WCE)
return APR_ENOTIMPL;
#else
#if APR_HAS_UNICODE_FS
IF_WIN_OS_IS_UNICODE
{
apr_wchar_t wenvvar[APR_PATH_MAX];
apr_status_t status;
status = widen_envvar_name(wenvvar, APR_PATH_MAX, envvar);
if (status)
return status;
if (!SetEnvironmentVariableW(wenvvar, NULL))
return apr_get_os_error();
}
#endif
#if APR_HAS_ANSI_FS
ELSE_WIN_OS_IS_ANSI
{
if (!SetEnvironmentVariableA(envvar, NULL))
return apr_get_os_error();
}
#endif
return APR_SUCCESS;
#endif
}
+101
View File
@@ -0,0 +1,101 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "apr_private.h"
#include "apr_arch_misc.h"
#include "apr_arch_file_io.h"
#include <assert.h>
/* This module is the source of -static- helper functions that are
* entirely internal to apr. If the fn is exported - it does not
* belong here.
*
* Namespace decoration is still required to protect us from symbol
* clashes in static linkages.
*/
/* Shared by apr_app.c and start.c
*
* An internal apr function to convert an array of strings (either
* a counted or NULL terminated list, such as an argv[argc] or env[]
* list respectively) from wide Unicode strings to narrow utf-8 strings.
* These are allocated from the MSVCRT's _CRT_BLOCK to trick the system
* into trusting our store.
*/
int apr_wastrtoastr(char const * const * *retarr,
wchar_t const * const *arr, int args)
{
apr_size_t elesize = 0;
char **newarr;
char *elements;
char *ele;
int arg;
if (args < 0) {
for (args = 0; arr[args]; ++args)
;
}
newarr = apr_malloc_dbg((args + 1) * sizeof(char *),
__FILE__, __LINE__);
for (arg = 0; arg < args; ++arg) {
newarr[arg] = (void*)(wcslen(arr[arg]) + 1);
elesize += (apr_size_t)newarr[arg];
}
/* This is a safe max allocation, we will realloc after
* processing and return the excess to the free store.
* 3 ucs bytes hold any single wchar_t value (16 bits)
* 4 ucs bytes will hold a wchar_t pair value (20 bits)
*/
elesize = elesize * 3 + 1;
ele = elements = apr_malloc_dbg(elesize * sizeof(char),
__FILE__, __LINE__);
for (arg = 0; arg < args; ++arg) {
apr_size_t len = (apr_size_t)newarr[arg];
apr_size_t newlen = elesize;
newarr[arg] = ele;
(void)apr_conv_ucs2_to_utf8(arr[arg], &len,
newarr[arg], &elesize);
newlen -= elesize;
ele += newlen;
assert(elesize && (len == 0));
}
newarr[arg] = NULL;
*(ele++) = '\0';
/* Return to the free store if the heap realloc is the least bit optimized
*/
ele = apr_realloc_dbg(elements, ele - elements,
__FILE__, __LINE__);
if (ele != elements) {
apr_size_t diff = ele - elements;
for (arg = 0; arg < args; ++arg) {
newarr[arg] += diff;
}
}
*retarr = (char const * const *)newarr;
return args;
}
+266
View File
@@ -0,0 +1,266 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "apr_private.h"
#include "apr_arch_misc.h"
#include "apr_arch_file_io.h"
#include "assert.h"
#include "apr_lib.h"
#include "tchar.h"
APR_DECLARE_DATA apr_oslevel_e apr_os_level = APR_WIN_UNK;
apr_status_t apr_get_oslevel(apr_oslevel_e *level)
{
if (apr_os_level == APR_WIN_UNK)
{
static OSVERSIONINFO oslev;
oslev.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&oslev);
if (oslev.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
static unsigned int servpack = 0;
TCHAR *pservpack;
if ((pservpack = oslev.szCSDVersion)) {
while (*pservpack && !apr_isdigit(*pservpack)) {
pservpack++;
}
if (*pservpack)
#ifdef _UNICODE
servpack = _wtoi(pservpack);
#else
servpack = atoi(pservpack);
#endif
}
if (oslev.dwMajorVersion < 3) {
apr_os_level = APR_WIN_UNSUP;
}
else if (oslev.dwMajorVersion == 3) {
if (oslev.dwMajorVersion < 50) {
apr_os_level = APR_WIN_UNSUP;
}
else if (oslev.dwMajorVersion == 50) {
apr_os_level = APR_WIN_NT_3_5;
}
else {
apr_os_level = APR_WIN_NT_3_51;
}
}
else if (oslev.dwMajorVersion == 4) {
if (servpack < 2)
apr_os_level = APR_WIN_NT_4;
else if (servpack <= 2)
apr_os_level = APR_WIN_NT_4_SP2;
else if (servpack <= 3)
apr_os_level = APR_WIN_NT_4_SP3;
else if (servpack <= 4)
apr_os_level = APR_WIN_NT_4_SP4;
else if (servpack <= 5)
apr_os_level = APR_WIN_NT_4_SP5;
else
apr_os_level = APR_WIN_NT_4_SP6;
}
else if (oslev.dwMajorVersion == 5) {
if (oslev.dwMinorVersion == 0) {
if (servpack == 0)
apr_os_level = APR_WIN_2000;
else if (servpack == 1)
apr_os_level = APR_WIN_2000_SP1;
else
apr_os_level = APR_WIN_2000_SP2;
}
else if (oslev.dwMinorVersion == 2) {
apr_os_level = APR_WIN_2003;
}
else {
if (servpack < 1)
apr_os_level = APR_WIN_XP;
else if (servpack == 1)
apr_os_level = APR_WIN_XP_SP1;
else
apr_os_level = APR_WIN_XP_SP2;
}
}
else if (oslev.dwMajorVersion == 6) {
if (oslev.dwMinorVersion == 0)
apr_os_level = APR_WIN_VISTA;
else
apr_os_level = APR_WIN_7;
}
else {
apr_os_level = APR_WIN_XP;
}
}
#ifndef WINNT
else if (oslev.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
TCHAR *prevision;
if (prevision = oslev.szCSDVersion) {
while (*prevision && !apr_isupper(*prevision)) {
prevision++;
}
}
else prevision = _T("");
if (oslev.dwMinorVersion < 10) {
if (*prevision < _T('C'))
apr_os_level = APR_WIN_95;
else
apr_os_level = APR_WIN_95_OSR2;
}
else if (oslev.dwMinorVersion < 90) {
if (*prevision < _T('A'))
apr_os_level = APR_WIN_98;
else
apr_os_level = APR_WIN_98_SE;
}
else {
apr_os_level = APR_WIN_ME;
}
}
#endif
#ifdef _WIN32_WCE
else if (oslev.dwPlatformId == VER_PLATFORM_WIN32_CE)
{
if (oslev.dwMajorVersion < 3) {
apr_os_level = APR_WIN_UNSUP;
}
else {
apr_os_level = APR_WIN_CE_3;
}
}
#endif
else {
apr_os_level = APR_WIN_UNSUP;
}
}
*level = apr_os_level;
if (apr_os_level < APR_WIN_UNSUP) {
return APR_EGENERAL;
}
return APR_SUCCESS;
}
/* This is the helper code to resolve late bound entry points
* missing from one or more releases of the Win32 API
*/
static const char* const lateDllName[DLL_defined] = {
"kernel32", "advapi32", "mswsock", "ws2_32", "shell32", "ntdll.dll" };
static HMODULE lateDllHandle[DLL_defined] = {
NULL, NULL, NULL, NULL, NULL, NULL };
FARPROC apr_load_dll_func(apr_dlltoken_e fnLib, char* fnName, int ordinal)
{
if (!lateDllHandle[fnLib]) {
lateDllHandle[fnLib] = LoadLibraryA(lateDllName[fnLib]);
if (!lateDllHandle[fnLib])
return NULL;
}
#if defined(_WIN32_WCE)
if (ordinal)
return GetProcAddressA(lateDllHandle[fnLib], (const char *)
(apr_ssize_t)ordinal);
else
return GetProcAddressA(lateDllHandle[fnLib], fnName);
#else
if (ordinal)
return GetProcAddress(lateDllHandle[fnLib], (const char *)
(apr_ssize_t)ordinal);
else
return GetProcAddress(lateDllHandle[fnLib], fnName);
#endif
}
/* Declared in include/arch/win32/apr_dbg_win32_handles.h
*/
APR_DECLARE_NONSTD(HANDLE) apr_dbg_log(char* fn, HANDLE ha, char* fl, int ln,
int nh, /* HANDLE hv, char *dsc */...)
{
static DWORD tlsid = 0xFFFFFFFF;
static HANDLE fh = NULL;
static long ctr = 0;
static CRITICAL_SECTION cs;
long seq;
DWORD wrote;
char *sbuf;
seq = (InterlockedIncrement)(&ctr);
if (tlsid == 0xFFFFFFFF) {
tlsid = (TlsAlloc)();
}
sbuf = (TlsGetValue)(tlsid);
if (!fh || !sbuf) {
sbuf = (malloc)(1024);
(TlsSetValue)(tlsid, sbuf);
sbuf[1023] = '\0';
if (!fh) {
(GetModuleFileNameA)(NULL, sbuf, 250);
sprintf(strchr(sbuf, '\0'), ".%u",
(unsigned int)(GetCurrentProcessId)());
fh = (CreateFileA)(sbuf, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, 0, NULL);
(InitializeCriticalSection)(&cs);
}
}
if (!nh) {
(sprintf)(sbuf, "%p %08x %08x %s() %s:%d\n",
ha, (unsigned int)seq, (unsigned int)GetCurrentThreadId(),
fn, fl, ln);
(EnterCriticalSection)(&cs);
(WriteFile)(fh, sbuf, (DWORD)strlen(sbuf), &wrote, NULL);
(LeaveCriticalSection)(&cs);
}
else {
va_list a;
va_start(a,nh);
(EnterCriticalSection)(&cs);
do {
HANDLE *hv = va_arg(a, HANDLE*);
char *dsc = va_arg(a, char*);
if (strcmp(dsc, "Signaled") == 0) {
if ((apr_ssize_t)ha >= STATUS_WAIT_0
&& (apr_ssize_t)ha < STATUS_ABANDONED_WAIT_0) {
hv += (apr_ssize_t)ha;
}
else if ((apr_ssize_t)ha >= STATUS_ABANDONED_WAIT_0
&& (apr_ssize_t)ha < STATUS_USER_APC) {
hv += (apr_ssize_t)ha - STATUS_ABANDONED_WAIT_0;
dsc = "Abandoned";
}
else if ((apr_ssize_t)ha == WAIT_TIMEOUT) {
dsc = "Timed Out";
}
}
(sprintf)(sbuf, "%p %08x %08x %s(%s) %s:%d\n",
*hv, (unsigned int)seq,
(unsigned int)GetCurrentThreadId(),
fn, dsc, fl, ln);
(WriteFile)(fh, sbuf, (DWORD)strlen(sbuf), &wrote, NULL);
} while (--nh);
(LeaveCriticalSection)(&cs);
va_end(a);
}
return ha;
}
+69
View File
@@ -0,0 +1,69 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "apr.h"
#include <rpc.h>
#include <wincrypt.h>
#include "apr_private.h"
#include "apr_general.h"
#include "apr_portable.h"
#include "apr_arch_misc.h"
APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char * buf,
apr_size_t length)
{
HCRYPTPROV hProv;
apr_status_t res = APR_SUCCESS;
/* 0x40 bit = CRYPT_SILENT, only introduced in more recent PSDKs
* and will only work for Win2K and later.
*/
DWORD flags = CRYPT_VERIFYCONTEXT
| ((apr_os_level >= APR_WIN_2000) ? 0x40 : 0);
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, flags)) {
return apr_get_os_error();
}
/* XXX: An ugly hack for Win64, randomness is such that noone should
* ever expect > 2^31 bytes of data at once without the prng
* coming to a complete halt.
*/
if (!CryptGenRandom(hProv, (DWORD)length, buf)) {
res = apr_get_os_error();
}
CryptReleaseContext(hProv, 0);
return res;
}
APR_DECLARE(apr_status_t) apr_os_uuid_get(unsigned char *uuid_data)
{
/* Note: this call doesn't actually require CoInitialize() first
*
* XXX: we should scramble the bytes or some such to eliminate the
* possible misuse/abuse since uuid is based on the NIC address, and
* is therefore not only a uniqifier, but an identity (which might not
* be appropriate in all cases.
*
* Note that Win2000, XP and later no longer suffer from this problem,
* a scrambling fix is only needed for (apr_os_level < APR_WIN_2000)
*/
if (FAILED(UuidCreate((UUID *)uuid_data))) {
return APR_EGENERAL;
}
return APR_SUCCESS;
}
+232
View File
@@ -0,0 +1,232 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "apr_private.h"
#include "apr_general.h"
#include "apr_pools.h"
#include "apr_signal.h"
#include "shellapi.h"
#include "apr_arch_misc.h" /* for WSAHighByte / WSALowByte */
#include "wchar.h"
#include "apr_arch_file_io.h" /* bring in unicode-ness */
#include "apr_arch_threadproc.h" /* bring in apr_threadproc_init */
#include "assert.h"
/* This symbol is _private_, although it must be exported.
*/
int APR_DECLARE_DATA apr_app_init_complete = 0;
#if !defined(_WIN32_WCE)
/* Used by apr_app_initialize to reprocess the environment
*
* An internal apr function to convert a double-null terminated set
* of single-null terminated strings from wide Unicode to narrow utf-8
* as a list of strings. These are allocated from the MSVCRT's
* _CRT_BLOCK to trick the system into trusting our store.
*/
static int warrsztoastr(const char * const * *retarr,
const wchar_t * arrsz)
{
const apr_wchar_t *wch;
apr_size_t totlen;
apr_size_t newlen;
apr_size_t wsize;
char **env;
char *pstrs;
char *strs;
int arg, args;
for (args = 1, wch = arrsz; wch[0] || wch[1]; ++wch)
if (!*wch)
++args;
wsize = 1 + wch - arrsz;
/* This is a safe max allocation, we will alloc each
* string exactly after processing and return this
* temporary buffer to the free store.
* 3 ucs bytes hold any single wchar_t value (16 bits)
* 4 ucs bytes will hold a wchar_t pair value (20 bits)
*/
newlen = totlen = wsize * 3 + 1;
pstrs = strs = apr_malloc_dbg(newlen * sizeof(char),
__FILE__, __LINE__);
(void)apr_conv_ucs2_to_utf8(arrsz, &wsize, strs, &newlen);
assert(newlen && !wsize);
*retarr = env = apr_malloc_dbg((args + 1) * sizeof(char*),
__FILE__, __LINE__);
for (arg = 0; arg < args; ++arg) {
char* p = pstrs;
int len = 0;
while (*p++)
++len;
len += 1;
*env = apr_malloc_dbg(len * sizeof(char),
__FILE__, __LINE__);
memcpy(*env, pstrs, len * sizeof(char));
pstrs += len;
++env;
}
*env = NULL;
free(strs);
return args;
}
#endif
/* Reprocess the arguments to main() for a completely apr-ized application
*/
APR_DECLARE(apr_status_t) apr_app_initialize(int *argc,
const char * const * *argv,
const char * const * *env)
{
apr_status_t rv = apr_initialize();
if (rv != APR_SUCCESS) {
return rv;
}
#if defined(_WIN32_WCE)
apr_app_init_complete = 1;
#elif APR_HAS_UNICODE_FS
IF_WIN_OS_IS_UNICODE
{
apr_wchar_t **wstrs;
apr_wchar_t *sysstr;
int wstrc;
int dupenv;
if (apr_app_init_complete) {
return rv;
}
apr_app_init_complete = 1;
sysstr = GetCommandLineW();
if (sysstr) {
wstrs = CommandLineToArgvW(sysstr, &wstrc);
if (wstrs) {
*argc = apr_wastrtoastr(argv, wstrs, wstrc);
GlobalFree(wstrs);
}
}
sysstr = GetEnvironmentStringsW();
dupenv = warrsztoastr(&_environ, sysstr);
if (env) {
*env = apr_malloc_dbg((dupenv + 1) * sizeof (char *),
__FILE__, __LINE__ );
memcpy((void*)*env, _environ, (dupenv + 1) * sizeof (char *));
}
else {
}
FreeEnvironmentStringsW(sysstr);
/* MSVCRT will attempt to maintain the wide environment calls
* on _putenv(), which is bogus if we've passed a non-ascii
* string to _putenv(), since they use MultiByteToWideChar
* and breaking the implicit utf-8 assumption we've built.
*
* Reset _wenviron for good measure.
*/
if (_wenviron) {
apr_wchar_t **wenv = _wenviron;
_wenviron = NULL;
free(wenv);
}
}
#endif
return rv;
}
static int initialized = 0;
/* Provide to win32/thread.c */
extern DWORD tls_apr_thread;
APR_DECLARE(apr_status_t) apr_initialize(void)
{
apr_pool_t *pool;
apr_status_t status;
int iVersionRequested;
WSADATA wsaData;
int err;
apr_oslevel_e osver;
if (initialized++) {
return APR_SUCCESS;
}
/* Initialize apr_os_level global */
if (apr_get_oslevel(&osver) != APR_SUCCESS) {
return APR_EEXIST;
}
tls_apr_thread = TlsAlloc();
if ((status = apr_pool_initialize()) != APR_SUCCESS)
return status;
if (apr_pool_create(&pool, NULL) != APR_SUCCESS) {
return APR_ENOPOOL;
}
apr_pool_tag(pool, "apr_initialize");
iVersionRequested = MAKEWORD(WSAHighByte, WSALowByte);
err = WSAStartup((WORD) iVersionRequested, &wsaData);
if (err) {
return err;
}
if (LOBYTE(wsaData.wVersion) != WSAHighByte ||
HIBYTE(wsaData.wVersion) != WSALowByte) {
WSACleanup();
return APR_EEXIST;
}
apr_signal_init(pool);
apr_threadproc_init(pool);
return APR_SUCCESS;
}
APR_DECLARE_NONSTD(void) apr_terminate(void)
{
initialized--;
if (initialized) {
return;
}
apr_pool_terminate();
WSACleanup();
TlsFree(tls_apr_thread);
}
APR_DECLARE(void) apr_terminate2(void)
{
apr_terminate();
}
+259
View File
@@ -0,0 +1,259 @@
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "apr.h"
#include "apr_private.h"
#include "apr_errno.h"
#include "apr_arch_utf8.h"
/* Implementation of RFC 3629, "UTF-8, a transformation format of ISO 10646"
* with particular attention to canonical translation forms (see section 10
* "Security Considerations" of the RFC for more info).
*
* Since several architectures including Windows support unicode, with UCS2
* used as the actual storage conventions by that archicture, these functions
* exist to transform or validate UCS2 strings into APR's 'char' type
* convention. It is left up to the operating system to determine the
* validitity of the string, e.g. normative forms, in the context of
* its native language support. Other file systems which support filename
* characters of 0x80-0xff but have no explicit requirement for Unicode
* will find this function useful only for validating the character sequences
* and rejecting poorly encoded UTF8 sequences.
*
* Len UCS-4 range (hex) UTF-8 octet sequence (binary)
* 1:2 00000000-0000007F 0xxxxxxx
* 2:2 00000080-000007FF 110XXXXx 10xxxxxx
* 3:2 00000800-0000FFFF 1110XXXX 10Xxxxxx 10xxxxxx
* 4:4 00010000-001FFFFF 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx
* 00200000-03FFFFFF 111110XX 10XXXxxx 10xxxxxx 10xxxxxx 10xxxxxx
* 04000000-7FFFFFFF 1111110X 10XXXXxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*
* One of the X bits must be 1 to avoid overlong representation of ucs2 values.
*
* For conversion into ucs2, the 4th form is limited in range to 0010 FFFF,
* and the final two forms are used only by full ucs4, per RFC 3629;
*
* "Pairs of UCS-2 values between D800 and DFFF (surrogate pairs in
* Unicode parlance), being actually UCS-4 characters transformed
* through UTF-16, need special treatment: the UTF-16 transformation
* must be undone, yielding a UCS-4 character that is then transformed
* as above."
*
* From RFC2781 UTF-16: the compressed ISO 10646 encoding bitmask
*
* U' = U - 0x10000
* U' = 00000000 0000yyyy yyyyyyxx xxxxxxxx
* W1 = 110110yy yyyyyyyy
* W2 = 110111xx xxxxxxxx
* Max U' = 0000 00001111 11111111 11111111
* Max U = 0000 00010000 11111111 11111111
*
* Len is the table above is a mapping of bytes used for utf8:ucs2 values,
* which results in these conclusions of maximum allocations;
*
* apr_conv_utf8_to_ucs2 out bytes:sizeof(in) * 1 <= Req <= sizeof(in) * 2
* apr_conv_ucs2_to_utf8 out words:sizeof(in) / 2 <= Req <= sizeof(in) * 3 / 2
*/
APR_DECLARE(apr_status_t) apr_conv_utf8_to_ucs2(const char *in,
apr_size_t *inbytes,
apr_wchar_t *out,
apr_size_t *outwords)
{
apr_int64_t newch, mask;
apr_size_t expect, eating;
int ch;
while (*inbytes && *outwords)
{
ch = (unsigned char)(*in++);
if (!(ch & 0200)) {
/* US-ASCII-7 plain text
*/
--*inbytes;
--*outwords;
*(out++) = ch;
}
else
{
if ((ch & 0300) != 0300) {
/* Multibyte Continuation is out of place
*/
return APR_EINVAL;
}
else
{
/* Multibyte Sequence Lead Character
*
* Compute the expected bytes while adjusting
* or lead byte and leading zeros mask.
*/
mask = 0340;
expect = 1;
while ((ch & mask) == mask) {
mask |= mask >> 1;
if (++expect > 3) /* (truly 5 for ucs-4) */
return APR_EINVAL;
}
newch = ch & ~mask;
eating = expect + 1;
if (*inbytes <= expect)
return APR_INCOMPLETE;
/* Reject values of excessive leading 0 bits
* utf-8 _demands_ the shortest possible byte length
*/
if (expect == 1) {
if (!(newch & 0036))
return APR_EINVAL;
}
else {
/* Reject values of excessive leading 0 bits
*/
if (!newch && !((unsigned char)*in & 0077 & (mask << 1)))
return APR_EINVAL;
if (expect == 2) {
/* Reject values D800-DFFF when not utf16 encoded
* (may not be an appropriate restriction for ucs-4)
*/
if (newch == 0015 && ((unsigned char)*in & 0040))
return APR_EINVAL;
}
else if (expect == 3) {
/* Short circuit values > 110000
*/
if (newch > 4)
return APR_EINVAL;
if (newch == 4 && ((unsigned char)*in & 0060))
return APR_EINVAL;
}
}
/* Where the boolean (expect > 2) is true, we will need
* an extra word for the output.
*/
if (*outwords < (apr_size_t)(expect > 2) + 1)
break; /* buffer full */
while (expect--)
{
/* Multibyte Continuation must be legal */
if (((ch = (unsigned char)*(in++)) & 0300) != 0200)
return APR_EINVAL;
newch <<= 6;
newch |= (ch & 0077);
}
*inbytes -= eating;
/* newch is now a true ucs-4 character
*
* now we need to fold to ucs-2
*/
if (newch < 0x10000)
{
--*outwords;
*(out++) = (apr_wchar_t) newch;
}
else
{
*outwords -= 2;
newch -= 0x10000;
*(out++) = (apr_wchar_t) (0xD800 | (newch >> 10));
*(out++) = (apr_wchar_t) (0xDC00 | (newch & 0x03FF));
}
}
}
}
/* Buffer full 'errors' aren't errors, the client must inspect both
* the inbytes and outwords values
*/
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_conv_ucs2_to_utf8(const apr_wchar_t *in,
apr_size_t *inwords,
char *out,
apr_size_t *outbytes)
{
apr_int64_t newch, require;
apr_size_t need;
char *invout;
int ch;
while (*inwords && *outbytes)
{
ch = (unsigned short)(*in++);
if (ch < 0x80)
{
--*inwords;
--*outbytes;
*(out++) = (unsigned char) ch;
}
else
{
if ((ch & 0xFC00) == 0xDC00) {
/* Invalid Leading ucs-2 Multiword Continuation Character
*/
return APR_EINVAL;
}
if ((ch & 0xFC00) == 0xD800) {
/* Leading ucs-2 Multiword Character
*/
if (*inwords < 2) {
/* Missing ucs-2 Multiword Continuation Character
*/
return APR_INCOMPLETE;
}
if (((unsigned short)(*in) & 0xFC00) != 0xDC00) {
/* Invalid ucs-2 Multiword Continuation Character
*/
return APR_EINVAL;
}
newch = (ch & 0x03FF) << 10 | ((unsigned short)(*in++) & 0x03FF);
newch += 0x10000;
}
else {
/* ucs-2 Single Word Character
*/
newch = ch;
}
/* Determine the absolute minimum utf-8 bytes required
*/
require = newch >> 11;
need = 1;
while (require)
require >>= 5, ++need;
if (need >= *outbytes)
break; /* Insufficient buffer */
*inwords -= (need > 2) + 1;
*outbytes -= need + 1;
/* Compute the utf-8 characters in last to first order,
* calculating the lead character length bits along the way.
*/
ch = 0200;
out += need + 1;
invout = out;
while (need--) {
ch |= ch >> 1;
*(--invout) = (unsigned char)(0200 | (newch & 0077));
newch >>= 6;
}
/* Compute the lead utf-8 character and move the dest offset
*/
*(--invout) = (unsigned char)(ch | newch);
}
}
/* Buffer full 'errors' aren't errors, the client must inspect both
* the inwords and outbytes values
*/
return APR_SUCCESS;
}