summaryrefslogtreecommitdiffstats
path: root/include/rtl
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /include/rtl
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'include/rtl')
-rw-r--r--include/rtl/alloc.h334
-rw-r--r--include/rtl/bootstrap.h224
-rw-r--r--include/rtl/bootstrap.hxx231
-rw-r--r--include/rtl/byteseq.h331
-rw-r--r--include/rtl/byteseq.hxx144
-rw-r--r--include/rtl/character.hxx526
-rw-r--r--include/rtl/cipher.h284
-rw-r--r--include/rtl/crc.h56
-rw-r--r--include/rtl/digest.h643
-rw-r--r--include/rtl/instance.hxx643
-rw-r--r--include/rtl/locale.h139
-rw-r--r--include/rtl/malformeduriexception.hxx72
-rw-r--r--include/rtl/math.h509
-rw-r--r--include/rtl/math.hxx511
-rw-r--r--include/rtl/process.h83
-rw-r--r--include/rtl/random.h102
-rw-r--r--include/rtl/ref.hxx316
-rw-r--r--include/rtl/strbuf.h143
-rw-r--r--include/rtl/strbuf.hxx1116
-rw-r--r--include/rtl/string.h1454
-rw-r--r--include/rtl/string.hxx2451
-rw-r--r--include/rtl/stringconcat.hxx394
-rw-r--r--include/rtl/stringutils.hxx398
-rw-r--r--include/rtl/tencinfo.h284
-rw-r--r--include/rtl/textcvt.h194
-rw-r--r--include/rtl/textenc.h269
-rw-r--r--include/rtl/unload.h96
-rw-r--r--include/rtl/uri.h362
-rw-r--r--include/rtl/uri.hxx173
-rw-r--r--include/rtl/ustrbuf.h218
-rw-r--r--include/rtl/ustrbuf.hxx1801
-rw-r--r--include/rtl/ustring.h2405
-rw-r--r--include/rtl/ustring.hxx3613
-rw-r--r--include/rtl/uuid.h186
34 files changed, 20705 insertions, 0 deletions
diff --git a/include/rtl/alloc.h b/include/rtl/alloc.h
new file mode 100644
index 0000000000..4ce01cf1bc
--- /dev/null
+++ b/include/rtl/alloc.h
@@ -0,0 +1,334 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_ALLOC_H
+#define INCLUDED_RTL_ALLOC_H
+
+#include "sal/config.h"
+
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Allocate memory.
+
+ A call to this function will return NULL upon the requested
+ memory size being either zero or larger than currently allocatable.
+
+ @param[in] Bytes memory size.
+ @return pointer to the allocated memory.
+ */
+SAL_DLLPUBLIC void * SAL_CALL rtl_allocateMemory (
+ sal_Size Bytes
+) SAL_THROW_EXTERN_C();
+
+
+/** Reallocate memory.
+
+ A call to this function with parameter 'Ptr' being NULL
+ is equivalent to a rtl_allocateMemory() call.
+ A call to this function with parameter 'Bytes' being 0
+ is equivalent to a rtl_freeMemory() call.
+
+ @see rtl_allocateMemory()
+ @see rtl_freeMemory()
+
+ @param[in] Ptr pointer to the previously allocated memory.
+ @param[in] Bytes new memory size.
+ @return pointer to the reallocated memory. May differ from Ptr.
+ */
+SAL_DLLPUBLIC void * SAL_CALL rtl_reallocateMemory (
+ void * Ptr,
+ sal_Size Bytes
+) SAL_THROW_EXTERN_C();
+
+
+/** Free memory.
+
+ Memory is released, and the pointer is invalidated.
+
+ @param[in] Ptr pointer to the previously allocated memory.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_freeMemory (
+ void * Ptr
+) SAL_THROW_EXTERN_C();
+
+/** Allocate and zero memory.
+
+ A call to this function will return NULL upon the requested
+ memory size being either zero or larger than currently allocatable.
+
+ @param[in] Bytes memory size.
+ @return pointer to the allocated and zero'ed memory.
+ */
+SAL_DLLPUBLIC void * SAL_CALL rtl_allocateZeroMemory (
+ sal_Size Bytes
+) SAL_THROW_EXTERN_C();
+
+/** Zero memory
+
+ Fills a block of memory with zeros in a way that is guaranteed to be secure
+
+ @param[in] Ptr pointer to the previously allocated memory.
+ @param[in] Bytes memory size.
+
+ @since LibreOffice 5.0
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_secureZeroMemory (
+ void * Ptr,
+ sal_Size Bytes
+) SAL_THROW_EXTERN_C();
+
+
+/** Zero and free memory.
+
+ Memory is zero'ed with rtl_secureZeroMemory() and released.
+ The original pointer is no longer valid.
+
+ @param[in] Ptr pointer to the previously allocated memory.
+ @param[in] Bytes memory size.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_freeZeroMemory (
+ void * Ptr,
+ sal_Size Bytes
+) SAL_THROW_EXTERN_C();
+
+/** Allocate aligned memory.
+
+ A call to this function will return NULL upon the requested
+ memory size being either zero or larger than currently allocatable.
+
+ Memory obtained through this function must be freed with
+ rtl_freeAlignedMemory().
+
+ @param[in] Alignment alignment in bytes, must be a power of two multiple of
+ sizeof(void*).
+ @param[in] Bytes memory size.
+ @return pointer to the allocated memory.
+
+ @since LibreOffice 4.3
+ */
+SAL_DLLPUBLIC void* SAL_CALL rtl_allocateAlignedMemory (
+ sal_Size Alignment,
+ sal_Size Bytes
+) SAL_THROW_EXTERN_C();
+
+
+/** Free memory allocated with rtl_allocateAlignedMemory().
+
+ Memory is released, and the pointer invalidated.
+
+ @param[in] Ptr pointer to the previously allocated memory.
+
+ @since LibreOffice 4.3
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_freeAlignedMemory (
+ void * Ptr
+) SAL_THROW_EXTERN_C();
+
+
+/** Opaque rtl_arena_type.
+ */
+typedef struct SAL_DLLPUBLIC_RTTI rtl_arena_st rtl_arena_type;
+
+#define RTL_ARENA_NAME_LENGTH 31
+
+
+/**
+ * @param[in] pName descriptive name; for debugging purposes.
+ * @param[in] quantum resource allocation unit / granularity; rounded up to next power of 2.
+ * @param[in] quantum_cache_max no longer used, should be 0.
+ * @param[in] source_arena passed as argument to source_alloc, source_free; usually NULL.
+ * @param[in] source_alloc function to allocate resources; usually rtl_arena_alloc.
+ * @param[in] source_free function to free resources; usually rtl_arena_free.
+ * @param[in] nFlags flags; usually 0.
+ *
+ * @return pointer to rtl_arena_type, or NULL upon failure.
+ *
+ * @see rtl_arena_destroy()
+ */
+SAL_DLLPUBLIC rtl_arena_type * SAL_CALL rtl_arena_create (
+ const char * pName,
+ sal_Size quantum,
+ sal_Size quantum_cache_max,
+ rtl_arena_type * source_arena,
+ void * (SAL_CALL * source_alloc)(rtl_arena_type *, sal_Size *),
+ void (SAL_CALL * source_free) (rtl_arena_type *, void *, sal_Size),
+ int nFlags
+) SAL_THROW_EXTERN_C();
+
+
+/**
+ * @param[in] pArena the arena to destroy.
+ *
+ * @see rtl_arena_create()
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_arena_destroy (
+ rtl_arena_type * pArena
+) SAL_THROW_EXTERN_C();
+
+
+/**
+ * @param[in] pArena arena from which resource is allocated.
+ * @param[in,out] pBytes size of resource to allocate.
+ *
+ * @return allocated resource, or NULL upon failure.
+ *
+ * @see rtl_arena_free()
+ */
+SAL_DLLPUBLIC void * SAL_CALL rtl_arena_alloc (
+ rtl_arena_type * pArena,
+ sal_Size * pBytes
+) SAL_THROW_EXTERN_C();
+
+
+/**
+ * @param[in] pArena arena from which resource was allocated.
+ * @param[in] pAddr resource to free.
+ * @param[in] nBytes size of resource.
+ *
+ * @see rtl_arena_alloc()
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_arena_free (
+ rtl_arena_type * pArena,
+ void * pAddr,
+ sal_Size nBytes
+) SAL_THROW_EXTERN_C();
+
+
+/** Opaque rtl_cache_type.
+ */
+typedef struct rtl_cache_st rtl_cache_type;
+
+#define RTL_CACHE_NAME_LENGTH 31
+
+#define RTL_CACHE_FLAG_BULKDESTROY 1 /* obsolete */
+
+/**
+ * @param[in] pName descriptive name; for debugging purposes.
+ * @param[in] nObjSize object size.
+ * @param[in] nObjAlign object alignment; usually 0 for suitable default.
+ * @param[in] constructor object constructor callback function; returning 1 for success or 0 for failure.
+ * @param[in] destructor object destructor callback function.
+ * @param[in] reclaim reclaim callback function.
+ * @param[in] pUserArg opaque argument passed to callback functions.
+ * @param[in] pSource unused argument (should be null).
+ * @param[in] nFlags flags (unused).
+ *
+ * @return pointer to rtl_cache_type, or NULL upon failure.
+ *
+ * @see rtl_cache_destroy()
+ */
+SAL_DLLPUBLIC rtl_cache_type * SAL_CALL rtl_cache_create (
+ const char * pName,
+ sal_Size nObjSize,
+ sal_Size nObjAlign,
+ int (SAL_CALL * constructor)(void * pObj, void * pUserArg),
+ void (SAL_CALL * destructor) (void * pObj, void * pUserArg),
+ void (SAL_CALL * reclaim) (void * pUserArg),
+ void * pUserArg,
+ rtl_arena_type * pSource,
+ int nFlags
+) SAL_THROW_EXTERN_C();
+
+
+/**
+ * @param[in] pCache the cache to destroy.
+ *
+ * @see rtl_cache_create()
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_cache_destroy (
+ rtl_cache_type * pCache
+) SAL_THROW_EXTERN_C();
+
+
+/**
+ * @param[in] pCache cache from which object is allocated.
+ *
+ * @return pointer to the allocated object, or NULL upon failure.
+ */
+SAL_DLLPUBLIC void * SAL_CALL rtl_cache_alloc (
+ rtl_cache_type * pCache
+) SAL_THROW_EXTERN_C();
+
+
+/**
+ * @param[in] pCache cache from which object was allocated.
+ * @param[in] pObj object to free.
+ *
+ * @see rtl_cache_alloc()
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_cache_free (
+ rtl_cache_type * pCache,
+ void * pObj
+) SAL_THROW_EXTERN_C();
+
+
+#ifdef LIBO_INTERNAL_ONLY
+
+/** @cond INTERNAL */
+/** rtl_alloc_preInit
+ *
+ * This function, is called at the beginning and again
+ * at the end of LibreOfficeKit pre-initialization to enable
+ * various optimizations.
+ *
+ * Its function is to annotate a section @start = true
+ * to end (@start = false) via. two calls. Inside this
+ * section string allocators are replaced with ones which cause the
+ * strings to be staticized at the end of the section.
+ *
+ * This brings a number of constraints - in particular no
+ * string allocated outside the section should be freed
+ * inside it, practically this means starting the section
+ * as early as possible. No string allocated inside the
+ * section will be freed subsequently as they are
+ * staticized.
+ *
+ * This method is not thread-safe, nor intended for use in
+ * a threaded context, cf. previous constraints.
+ *
+ * It is almost certainly not the method that you want,
+ * use with extraordinary care referring to the
+ * implementation.
+ *
+ * @since LibreOffice 6.1
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_alloc_preInit (
+ sal_Bool start
+) SAL_THROW_EXTERN_C();
+/** @endcond */
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_RTL_ALLOC_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/bootstrap.h b/include/rtl/bootstrap.h
new file mode 100644
index 0000000000..e532cd0e3d
--- /dev/null
+++ b/include/rtl/bootstrap.h
@@ -0,0 +1,224 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+#ifndef INCLUDED_RTL_BOOTSTRAP_H
+#define INCLUDED_RTL_BOOTSTRAP_H
+
+#include "sal/config.h"
+
+#include "rtl/ustring.h"
+#include "sal/saldllapi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ @file
+
+ The described concept provides a platform independent way to access
+ minimum bootstrap settings for every application by explicitly or
+ implicitly passing the values to the application.
+
+ <strong>MULTI-LEVEL STRATEGY FOR RETRIEVAL OF BOOTSTRAP VALUES:</strong>
+
+ The 1st level is tried first. On failure,
+ the next level is tried. Every query starts at the first level again, so
+ that one setting may be taken from the 3rd and one from the 1st level.
+
+ 1st level: explicitly set variables via rtl_bootstrap_set()
+
+ 2nd level: command line arguments. A `-env:SETTINGNAME=value` is given on
+ command line. This allows giving an application a certain setting, even
+ if an ini-file exists (especially useful for e.g. daemons that want to
+ start an executable with dynamical changing settings).
+
+ 3rd level: environment variables. The application tries to get the
+ setting from the environment.
+
+ 4th level: executable ini-file. Every application looks for an ini-file.
+ The filename defaults to `/absolute/path/to/executable[rc|.ini]`
+ without .bin or .exe suffix. The ini-filename can be
+ set by the special command line parameter
+ `-env:INIFILENAME=/absolute/path/to/inifile` at runtime or it may
+ be set at compile time by an API-call.
+
+ 5th level: URE_BOOTSTRAP ini-file. If the bootstrap variable URE_BOOTSTRAP
+ expands to the URL of an ini-file, that ini-file is searched.
+
+ 6th level: default. An application can have some default settings decided
+ at compile time, which allow the application to run even with no
+ deployment settings.
+
+ If neither of the above levels leads to a successful retrieval of the value
+ (no default possible), the application may fail to start.
+
+ <strong>NAMING CONVENTIONS</strong>
+
+ Naming conventions for names of bootstrap values:
+ Names may only include characters, that are allowed characters for
+ environment variables. This excludes '.', ' ', ';', ':' and any non-ascii
+ character. Names are case insensitive.
+
+ An ini-file is only allowed to have one section, which must be named
+ `[Bootstrap]` with the square brackets.
+ The section may be omitted.
+ The section name does not appear in the name of the corresponding
+ environment variable or commandline arg.
+ Values may be arbitrary unicode strings, they must be encoded in UTF8.
+
+ <em>Example:</em>
+
+ in an ini-file:
+ <code>
+ [Sectionname]
+ Name=value
+ </code>
+
+ as commandline arg:
+ <code>-env:Name=value</code>
+
+ as environment:
+ - <code>setenv Name value</code>
+ - <code>set Name=value</code>
+
+ <strong>SPECIAL VARIABLES:</strong>
+
+ - INIFILENAME<br>
+ This variable allows to set the inifilename. This makes only sense, if the filename
+ is different than the executable file name. It must be given on command line. If it is
+ given the executable ini-file is ignored.
+*/
+
+/** may be called by an application to set an ini-filename.
+
+ Must be called before rtl_bootstrap_get(). May not be called twice.
+ If it is never called, the filename is based on the name of the executable,
+ with the suffix ".ini" on Windows or "rc" on Unix.
+
+ @param pFileUri URL of the inifile with path but WITHOUT suffix (.ini or rc)
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_bootstrap_setIniFileName( rtl_uString *pFileUri );
+
+/**
+ @param pName
+ The name of the bootstrap setting to be retrieved.
+ @param[out] ppValue
+ Contains always a valid rtl_uString pointer.
+ @param pDefault
+ maybe <code>NULL</code>. If once the default is
+ returned, successive calls always return this
+ default value, even when called with different
+ defaults.
+
+ @retval sal_True when a value could be retrieved successfully.
+ When a <code>pDefault</code> value is given,
+ the function always returns <code>sal_True</code>.
+ @retval sal_False when none of the 4 methods gave a value.
+ <code>ppValue</code> then contains an empty string.
+*/
+SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_bootstrap_get(
+ rtl_uString *pName, rtl_uString **ppValue, rtl_uString *pDefault );
+
+/** Sets a bootstrap parameter.
+
+ @param pName
+ name of bootstrap parameter
+ @param pValue
+ value of bootstrap parameter
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_bootstrap_set(
+ rtl_uString * pName, rtl_uString * pValue );
+
+
+typedef void * rtlBootstrapHandle;
+
+/**
+ Opens a bootstrap argument container.
+ @param[in] pIniName The name of the ini-file to use, if <code>NULL</code> defaults
+ to the executables name
+ @return Handle for a bootstrap argument container
+*/
+SAL_DLLPUBLIC rtlBootstrapHandle SAL_CALL rtl_bootstrap_args_open(rtl_uString * pIniName);
+
+/**
+ Closes a bootstrap argument container.
+ @param[in] handle The handle got by rtl_bootstrap_args_open()
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_bootstrap_args_close(rtlBootstrapHandle handle)
+ SAL_THROW_EXTERN_C();
+
+/**
+ @param[in] handle The handle got by rtl_bootstrap_args_open()
+ @param[in] pName The name of the variable to be retrieved
+ @param[out] ppValue The result of the retrieval. *ppValue may be null in case of failure.
+ @param[in] pDefault The default value for the retrieval, may be <code>NULL</code>
+
+ @return The status of the retrieval, <code>sal_True</code> on success.
+*/
+SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_bootstrap_get_from_handle(
+ rtlBootstrapHandle handle, rtl_uString *pName, rtl_uString **ppValue, rtl_uString *pDefault);
+
+
+/** Returns the name of the inifile associated with this handle.
+
+ @param[in] handle The handle got by rtl_bootstrap_args_open()
+ @param[out] ppIniName contains after the call the name of the ini-filename.
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_bootstrap_get_iniName_from_handle(
+ rtlBootstrapHandle handle, rtl_uString ** ppIniName);
+
+/** Expands a macro using bootstrap variables.
+
+ @param[in] handle The handle got by rtl_bootstrap_args_open()
+ @param[in,out] macro The macro to be expanded
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_bootstrap_expandMacros_from_handle(
+ rtlBootstrapHandle handle, rtl_uString ** macro );
+
+/** Expands a macro using default bootstrap variables.
+
+ @param[in,out] macro The macro to be expanded
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_bootstrap_expandMacros(
+ rtl_uString ** macro);
+
+/** Escapes special characters ("$" and "\").
+
+ @param value
+ an arbitrary, non-NULL value
+
+ @param[out] encoded
+ the given value with all occurrences of special characters ("$" and "\") escaped
+
+ @since UDK 3.2.9
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_bootstrap_encode(
+ rtl_uString const * value, rtl_uString ** encoded );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/bootstrap.hxx b/include/rtl/bootstrap.hxx
new file mode 100644
index 0000000000..4d8db0690e
--- /dev/null
+++ b/include/rtl/bootstrap.hxx
@@ -0,0 +1,231 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+#ifndef INCLUDED_RTL_BOOTSTRAP_HXX
+#define INCLUDED_RTL_BOOTSTRAP_HXX
+
+#include "sal/config.h"
+
+#include <cstddef>
+
+#include "rtl/ustring.hxx"
+#include "rtl/bootstrap.h"
+
+namespace rtl
+{
+ class Bootstrap
+ {
+ void * _handle;
+
+ Bootstrap( Bootstrap const & ) SAL_DELETED_FUNCTION;
+ Bootstrap & operator = ( Bootstrap const & ) SAL_DELETED_FUNCTION;
+
+ public:
+ /**
+ * @see rtl_bootstrap_setIniFileName()
+ */
+ static inline void SAL_CALL setIniFilename( const ::rtl::OUString &sFileUri );
+
+ /** Retrieves a bootstrap parameter
+ @param sName name of the bootstrap value. case insensitive.
+ @param[out] outValue On success contains the value, otherwise
+ an empty string.
+ @return false, if no value could be retrieved, otherwise true
+ @see rtl_bootstrap_get()
+ */
+ static inline bool get(
+ const ::rtl::OUString &sName,
+ ::rtl::OUString &outValue );
+
+ /** Retrieves a bootstrap parameter
+
+ @param sName name of the bootstrap value. case insensitive.
+ @param[out] outValue Contains the value associated with <code>sName</code>.
+ @param aDefault if none of the other methods retrieved a value,
+ <code>outValue</code> is assigned to <code>aDefault</code>.
+
+ @see rtl_bootstrap_get()
+ */
+ static inline void get(
+ const ::rtl::OUString &sName,
+ ::rtl::OUString &outValue,
+ const ::rtl::OUString &aDefault );
+
+ /** Sets a bootstrap parameter.
+
+ @param name
+ name of bootstrap parameter
+ @param value
+ value of bootstrap parameter
+
+ @see rtl_bootstrap_set()
+ */
+ static inline void set( ::rtl::OUString const & name, ::rtl::OUString const & value );
+
+ /** default ctor.
+ */
+ inline Bootstrap();
+
+ /** Opens a bootstrap argument container
+ @see rtl_bootstrap_args_open()
+ */
+ inline Bootstrap(const rtl::OUString & iniName);
+
+ /** Closes a bootstrap argument container
+ @see rtl_bootstrap_args_close()
+ */
+ inline ~Bootstrap();
+
+ /** Retrieves a bootstrap argument.
+
+ It is first tried to retrieve the value via the global function
+ and second via the special bootstrap container.
+ @see rtl_bootstrap_get_from_handle()
+ */
+
+ inline bool getFrom(const ::rtl::OUString &sName,
+ ::rtl::OUString &outValue) const;
+
+ /** Retrieves a bootstrap argument.
+
+ It is first tried to retrieve the value via the global function
+ and second via the special bootstrap container.
+ @see rtl_bootstrap_get_from_handle()
+ */
+ inline void getFrom(const ::rtl::OUString &sName,
+ ::rtl::OUString &outValue,
+ const ::rtl::OUString &aDefault) const;
+
+ /** Retrieves the name of the underlying ini-file.
+ @see rtl_bootstrap_get_iniName_from_handle()
+ */
+ inline void getIniName(::rtl::OUString & iniName) const;
+
+ /** Expands a macro using bootstrap variables.
+
+ @param[in,out] macro The macro to be expanded
+ */
+ void expandMacrosFrom( ::rtl::OUString & macro ) const
+ { rtl_bootstrap_expandMacros_from_handle( _handle, &macro.pData ); }
+
+ /** Expands a macro using default bootstrap variables.
+
+ @param[in,out] macro The macro to be expanded
+ */
+ static void expandMacros( ::rtl::OUString & macro )
+ { rtl_bootstrap_expandMacros( &macro.pData ); }
+
+ /** Provides the bootstrap internal handle.
+
+ @return bootstrap handle
+ */
+ rtlBootstrapHandle getHandle() const
+ { return _handle; }
+
+ /** Escapes special characters ("$" and "\").
+
+ @param value
+ an arbitrary value
+
+ @return
+ the given value, with all occurrences of special characters ("$" and
+ "\") escaped
+
+ @since UDK 3.2.9
+ */
+ static inline ::rtl::OUString encode( ::rtl::OUString const & value );
+ };
+
+
+ // IMPLEMENTATION
+
+ inline void Bootstrap::setIniFilename( const ::rtl::OUString &sFile )
+ {
+ rtl_bootstrap_setIniFileName( sFile.pData );
+ }
+
+ inline bool Bootstrap::get( const ::rtl::OUString &sName,
+ ::rtl::OUString & outValue )
+ {
+ return rtl_bootstrap_get( sName.pData , &(outValue.pData) , NULL );
+ }
+
+ inline void Bootstrap::get( const ::rtl::OUString &sName,
+ ::rtl::OUString & outValue,
+ const ::rtl::OUString & sDefault )
+ {
+ rtl_bootstrap_get( sName.pData , &(outValue.pData) , sDefault.pData );
+ }
+
+ inline void Bootstrap::set( ::rtl::OUString const & name, ::rtl::OUString const & value )
+ {
+ rtl_bootstrap_set( name.pData, value.pData );
+ }
+
+ inline Bootstrap::Bootstrap()
+ {
+ _handle = NULL;
+ }
+
+ inline Bootstrap::Bootstrap(const rtl::OUString & iniName)
+ {
+ if(!iniName.isEmpty())
+ _handle = rtl_bootstrap_args_open(iniName.pData);
+
+ else
+ _handle = NULL;
+ }
+
+ inline Bootstrap::~Bootstrap()
+ {
+ rtl_bootstrap_args_close(_handle);
+ }
+
+
+ inline bool Bootstrap::getFrom(const ::rtl::OUString &sName,
+ ::rtl::OUString &outValue) const
+ {
+ return rtl_bootstrap_get_from_handle(_handle, sName.pData, &outValue.pData, NULL);
+ }
+
+ inline void Bootstrap::getFrom(const ::rtl::OUString &sName,
+ ::rtl::OUString &outValue,
+ const ::rtl::OUString &aDefault) const
+ {
+ rtl_bootstrap_get_from_handle(_handle, sName.pData, &outValue.pData, aDefault.pData);
+ }
+
+ inline void Bootstrap::getIniName(::rtl::OUString & iniName) const
+ {
+ rtl_bootstrap_get_iniName_from_handle(_handle, &iniName.pData);
+ }
+
+ inline ::rtl::OUString Bootstrap::encode( ::rtl::OUString const & value )
+ {
+ ::rtl::OUString encoded;
+ rtl_bootstrap_encode(value.pData, &encoded.pData);
+ return encoded;
+ }
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/byteseq.h b/include/rtl/byteseq.h
new file mode 100644
index 0000000000..2acb9b745d
--- /dev/null
+++ b/include/rtl/byteseq.h
@@ -0,0 +1,331 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+#ifndef INCLUDED_RTL_BYTESEQ_H
+#define INCLUDED_RTL_BYTESEQ_H
+
+#include "sal/config.h"
+
+#include "rtl/alloc.h"
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/** Assures that the reference count of the given byte sequence is one. Otherwise a new copy
+ of the sequence is created with a reference count of one.
+
+ @param ppSequence sequence
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_byte_sequence_reference2One(
+ sal_Sequence ** ppSequence )
+ SAL_THROW_EXTERN_C();
+
+/** Reallocates length of byte sequence.
+
+ @param ppSequence sequence
+ @param nSize new size of sequence
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_byte_sequence_realloc(
+ sal_Sequence ** ppSequence, sal_Int32 nSize )
+ SAL_THROW_EXTERN_C();
+
+/** Acquires the byte sequence
+
+ @param pSequence sequence, that is to be acquired
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_byte_sequence_acquire(
+ sal_Sequence *pSequence )
+ SAL_THROW_EXTERN_C();
+
+/** Releases the byte sequence. If the refcount drops to zero, the sequence is freed.
+
+ @param pSequence sequence, that is to be released; invalid after call
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_byte_sequence_release(
+ sal_Sequence *pSequence )
+ SAL_THROW_EXTERN_C();
+
+/** Constructs a bytes sequence with length nLength. All bytes are set to zero.
+
+ @param ppSequence inout sequence; on entry *ppSequence may be null, otherwise it is released;
+ after the call, *ppSequence contains the newly constructed sequence
+ @param nLength length of new sequence
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_byte_sequence_construct(
+ sal_Sequence **ppSequence , sal_Int32 nLength )
+ SAL_THROW_EXTERN_C();
+
+/** Constructs a bytes sequence with length nLength. The data is not initialized.
+
+ @param ppSequence inout sequence; on entry *ppSequence may be null, otherwise it is released;
+ after the call, *ppSequence contains the newly constructed sequence
+ @param nLength length of new sequence
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_byte_sequence_constructNoDefault(
+ sal_Sequence **ppSequence , sal_Int32 nLength )
+ SAL_THROW_EXTERN_C();
+
+/** Constructs a byte sequence with length nLength and copies nLength bytes from pData.
+
+ @param ppSequence inout sequence; on entry *ppSequence may be null, otherwise it is released;
+ after the call, *ppSequence contains the newly constructed sequence
+ @param pData initial data
+ @param nLength length of new sequence
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_byte_sequence_constructFromArray(
+ sal_Sequence **ppSequence, const sal_Int8 *pData , sal_Int32 nLength )
+ SAL_THROW_EXTERN_C();
+
+/** Assigns the byte sequence pSequence to *ppSequence.
+
+ @param ppSequence inout sequence; on entry *ppSequence may be null, otherwise it is released;
+ after the call, *ppSequence references pSequence
+ @param pSequence the source sequence
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_byte_sequence_assign(
+ sal_Sequence **ppSequence , sal_Sequence *pSequence )
+ SAL_THROW_EXTERN_C();
+
+/** Compares two byte sequences.
+
+ @return true, if the data within the sequences are identical; false otherwise
+*/
+SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_byte_sequence_equals(
+ sal_Sequence *pSequence1 , sal_Sequence *pSequence2 )
+ SAL_THROW_EXTERN_C();
+
+/** Returns the data array pointer of the sequence.
+
+ @return read-pointer to the data array of the sequence. If rtl_byte_sequence_reference2One()
+ has been called before, the pointer may be casted to a non const pointer and
+ the sequence may be modified
+*/
+SAL_DLLPUBLIC const sal_Int8 *SAL_CALL rtl_byte_sequence_getConstArray(
+ sal_Sequence *pSequence )
+ SAL_THROW_EXTERN_C();
+
+/** Returns the length of the sequence
+
+ @param pSequence sequence handle
+ @return length of the sequence
+*/
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_byte_sequence_getLength(
+ sal_Sequence *pSequence )
+ SAL_THROW_EXTERN_C();
+
+#ifdef __cplusplus
+}
+namespace rtl
+{
+
+enum __ByteSequence_NoDefault
+{
+ /** This enum value can be used to create a bytesequence with uninitialized data
+ */
+ BYTESEQ_NODEFAULT = 0xcafe
+};
+
+enum __ByteSequence_NoAcquire
+{
+ /** This enum value can be used to create a bytesequence from a C-Handle without
+ acquiring the handle.
+ */
+ BYTESEQ_NOACQUIRE =
+#if defined _MSC_VER
+ int(0xcafebabe)
+#else
+ 0xcafebabe
+#endif
+};
+
+/** C++ class representing a SAL byte sequence.
+ C++ Sequences are reference counted and shared, so the sequence keeps a handle to its data.
+ To keep value semantics, copies are only generated if the sequence is to be modified
+ (new handle).
+*/
+class SAL_WARN_UNUSED ByteSequence
+{
+ /** sequence handle
+ */
+ sal_Sequence * _pSequence;
+
+public:
+ /// @cond INTERNAL
+ // these are here to force memory de/allocation to sal lib.
+ static void * SAL_CALL operator new ( size_t nSize )
+ { return ::rtl_allocateMemory( nSize ); }
+ static void SAL_CALL operator delete ( void * pMem )
+ { ::rtl_freeMemory( pMem ); }
+ static void * SAL_CALL operator new ( size_t, void * pMem )
+ { return pMem; }
+ static void SAL_CALL operator delete ( void *, void * )
+ {}
+ /// @endcond
+
+ /** Default constructor: Creates an empty sequence.
+ */
+ inline ByteSequence();
+ /** Copy constructor: Creates a copy of given sequence.
+
+ @param rSeq another byte sequence
+ */
+ inline ByteSequence( const ByteSequence & rSeq );
+#if defined LIBO_INTERNAL_ONLY
+ inline ByteSequence( ByteSequence && rSeq ) noexcept;
+#endif
+ /** Copy constructor Creates a copy from the C-Handle.
+
+ @param pSequence another byte sequence handle
+ */
+ inline ByteSequence( sal_Sequence *pSequence );
+ /** Constructor: Creates a copy of given data bytes.
+
+ @param pElements an array of bytes
+ @param len number of bytes
+ */
+ inline ByteSequence( const sal_Int8 * pElements, sal_Int32 len );
+ /** Constructor: Creates sequence of given length and initializes all bytes to 0.
+
+ @param len initial sequence length
+ */
+ inline ByteSequence( sal_Int32 len );
+ /** Constructor: Creates sequence of given length and does NOT initialize data.
+ Use this ctor for performance optimization only.
+
+ @param len initial sequence length
+ @param nodefault dummy parameter forcing explicit BYTESEQ_NODEFAULT
+ */
+ inline ByteSequence( sal_Int32 len , enum __ByteSequence_NoDefault nodefault );
+ /** Constructor:
+ Creates a sequence from a C-Handle without acquiring the handle, thus taking
+ over ownership. Eitherway the handle is released by the destructor.
+ This ctor is useful, when working with a c-interface (it safes a pair of
+ acquire and release call and is thus a performance optimization only).
+
+ @param pSequence sequence handle to be taken over
+ @param noacquire dummy parameter forcing explicit BYTESEQ_NOACQUIRE
+ */
+ inline ByteSequence( sal_Sequence *pSequence , enum __ByteSequence_NoAcquire noacquire );
+ /** Destructor: Releases sequence handle. Last handle will free memory.
+ */
+ inline ~ByteSequence();
+
+ /** Assignment operator: Acquires given sequence handle and releases a previously set handle.
+
+ @param rSeq another byte sequence
+ @return this sequence
+ */
+ inline ByteSequence & SAL_CALL operator = ( const ByteSequence & rSeq );
+#if defined LIBO_INTERNAL_ONLY
+ inline ByteSequence & operator = ( ByteSequence && rSeq ) noexcept;
+#endif
+
+ /** Gets the length of sequence.
+
+ @return length of sequence
+ */
+ sal_Int32 SAL_CALL getLength() const
+ { return _pSequence->nElements; }
+
+ /** Gets a pointer to byte array for READING. If the sequence has a length of 0, then the
+ returned pointer is undefined.
+
+ @return pointer to byte array
+ */
+ const sal_Int8 * SAL_CALL getConstArray() const
+ { return reinterpret_cast<sal_Int8 *>(_pSequence->elements); }
+ /** Gets a pointer to elements array for READING AND WRITING. In general if the sequence
+ has a handle acquired by other sequences (reference count > 1), then a new sequence is
+ created copying all bytes to keep value semantics!
+ If the sequence has a length of 0, then the returned pointer is undefined.
+
+ @return pointer to elements array
+ */
+ inline sal_Int8 * SAL_CALL getArray();
+
+ /** Non-const index operator:
+ Obtains a reference to byte indexed at given position.
+ In general if the sequence has a handle acquired by other
+ sequences (reference count > 1), then a new sequence is created
+ copying all bytes to keep value semantics!
+
+ @attention
+ The implementation does NOT check for array bounds!
+
+ @param nIndex index
+ @return non-const C++ reference to element at index nIndex
+ */
+ inline sal_Int8 & SAL_CALL operator [] ( sal_Int32 nIndex );
+
+ /** Const index operator: Obtains a reference to byte indexed at given position.
+ The implementation does NOT check for array bounds!
+
+ @param nIndex index
+ @return const C++ reference to byte at element of index nIndex
+ */
+ const sal_Int8 & SAL_CALL operator [] ( sal_Int32 nIndex ) const
+ { return getConstArray()[ nIndex ]; }
+
+ /** Equality operator: Compares two sequences.
+
+ @param rSeq another byte sequence (right side)
+ @return true if both sequences are equal, false otherwise
+ */
+ inline bool SAL_CALL operator == ( const ByteSequence & rSeq ) const;
+ /** Unequality operator: Compares two sequences.
+
+ @param rSeq another byte sequence (right side)
+ @return false if both sequences are equal, true otherwise
+ */
+ inline bool SAL_CALL operator != ( const ByteSequence & rSeq ) const;
+
+ /** Reallocates sequence to new length. If the sequence has a handle acquired by other sequences
+ (reference count > 1), then the remaining elements are copied to a new sequence handle to
+ keep value semantics!
+
+ @param nSize new size of sequence
+ */
+ inline void SAL_CALL realloc( sal_Int32 nSize );
+
+ /** Returns the UNacquired C handle of the sequence
+
+ @return UNacquired handle of the sequence
+ */
+ sal_Sequence * SAL_CALL getHandle() const
+ { return _pSequence; }
+ /** Returns the UNacquired C handle of the sequence (for compatibility reasons)
+
+ @return UNacquired handle of the sequence
+ */
+ sal_Sequence * SAL_CALL get() const
+ { return _pSequence; }
+};
+
+}
+#endif
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/byteseq.hxx b/include/rtl/byteseq.hxx
new file mode 100644
index 0000000000..33118cd8b4
--- /dev/null
+++ b/include/rtl/byteseq.hxx
@@ -0,0 +1,144 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+#ifndef INCLUDED_RTL_BYTESEQ_HXX
+#define INCLUDED_RTL_BYTESEQ_HXX
+
+#include "rtl/byteseq.h"
+
+#include <cstddef>
+#include <new>
+
+namespace rtl
+{
+
+
+inline ByteSequence::ByteSequence()
+ : _pSequence( NULL )
+{
+ ::rtl_byte_sequence_construct( &_pSequence, 0 );
+}
+
+inline ByteSequence::ByteSequence( const ByteSequence & rSeq )
+ : _pSequence( NULL )
+{
+ ::rtl_byte_sequence_assign( &_pSequence, rSeq._pSequence );
+}
+
+#if defined LIBO_INTERNAL_ONLY
+inline ByteSequence::ByteSequence( ByteSequence && rSeq ) noexcept
+ : _pSequence(rSeq._pSequence)
+{
+ rSeq._pSequence = nullptr;
+}
+#endif
+
+inline ByteSequence::ByteSequence( sal_Sequence *pSequence)
+ : _pSequence( pSequence )
+{
+ ::rtl_byte_sequence_acquire( pSequence );
+}
+
+inline ByteSequence::ByteSequence( const sal_Int8 * pElements, sal_Int32 len )
+ : _pSequence( NULL )
+{
+ ::rtl_byte_sequence_constructFromArray( &_pSequence, pElements, len );
+ if (_pSequence == NULL)
+ throw ::std::bad_alloc();
+}
+
+inline ByteSequence::ByteSequence( sal_Int32 len, enum __ByteSequence_NoDefault )
+ : _pSequence( NULL )
+{
+ ::rtl_byte_sequence_constructNoDefault( &_pSequence, len );
+ if (_pSequence == NULL)
+ throw ::std::bad_alloc();
+}
+
+inline ByteSequence::ByteSequence( sal_Sequence *pSequence, enum __ByteSequence_NoAcquire )
+ : _pSequence( pSequence )
+{
+}
+
+inline ByteSequence::ByteSequence( sal_Int32 len )
+ : _pSequence( NULL )
+{
+ ::rtl_byte_sequence_construct( &_pSequence, len );
+ if (_pSequence == NULL)
+ throw ::std::bad_alloc();
+}
+
+inline ByteSequence::~ByteSequence()
+{
+ ::rtl_byte_sequence_release( _pSequence );
+}
+
+inline ByteSequence & ByteSequence::operator = ( const ByteSequence & rSeq )
+{
+ ::rtl_byte_sequence_assign( &_pSequence, rSeq._pSequence );
+ return *this;
+}
+
+#if defined LIBO_INTERNAL_ONLY
+inline ByteSequence & ByteSequence::operator = ( ByteSequence && rSeq ) noexcept
+{
+ ::rtl_byte_sequence_release(_pSequence);
+ _pSequence = rSeq._pSequence;
+ rSeq._pSequence = nullptr;
+ return *this;
+}
+#endif
+
+inline bool ByteSequence::operator == ( const ByteSequence & rSeq ) const
+{
+ return ::rtl_byte_sequence_equals( _pSequence, rSeq._pSequence );
+}
+
+inline sal_Int8 * ByteSequence::getArray()
+{
+ ::rtl_byte_sequence_reference2One( &_pSequence );
+ if (_pSequence == NULL)
+ throw ::std::bad_alloc();
+ return reinterpret_cast<sal_Int8 *>(_pSequence->elements);
+}
+
+inline void ByteSequence::realloc( sal_Int32 nSize )
+{
+ ::rtl_byte_sequence_realloc( &_pSequence, nSize );
+ if (_pSequence == NULL)
+ throw ::std::bad_alloc();
+}
+
+inline sal_Int8 & ByteSequence::operator [] ( sal_Int32 nIndex )
+{
+ return getArray()[ nIndex ];
+}
+
+inline bool ByteSequence::operator != ( const ByteSequence & rSeq ) const
+{
+ return (! operator == ( rSeq ));
+}
+
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/character.hxx b/include/rtl/character.hxx
new file mode 100644
index 0000000000..5801063532
--- /dev/null
+++ b/include/rtl/character.hxx
@@ -0,0 +1,526 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_CHARACTER_HXX
+#define INCLUDED_RTL_CHARACTER_HXX
+
+#include "sal/config.h"
+
+#include <cassert>
+#include <cstddef>
+
+#include "sal/types.h"
+
+#if defined LIBO_INTERNAL_ONLY
+#include <type_traits>
+#endif
+
+namespace rtl
+{
+/** Check for Unicode code point.
+
+ @param code An integer.
+
+ @return True if code is a Unicode code point.
+
+ @since LibreOffice 5.2
+*/
+inline SAL_CONSTEXPR bool isUnicodeCodePoint(sal_uInt32 code) { return code <= 0x10FFFF; }
+
+/** Check for ASCII character.
+
+ @param code A Unicode code point.
+
+ @return True if code is an ASCII character (0x00--0x7F).
+
+ @since LibreOffice 4.1
+ */
+inline SAL_CONSTEXPR bool isAscii(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return code <= 0x7F;
+}
+
+#if defined LIBO_INTERNAL_ONLY
+bool isAscii(char) = delete;
+bool isAscii(signed char) = delete;
+template <typename T>
+inline constexpr std::enable_if_t<std::is_integral_v<T> && sizeof(T) <= sizeof(sal_uInt32), bool>
+isAscii(T code)
+{
+ return isAscii(sal_uInt32(code));
+}
+#endif
+
+/** Check for ASCII lower case character.
+
+ @param code A Unicode code point.
+
+ @return True if code is an ASCII lower case alphabetic character (ASCII
+ 'a'--'z').
+
+ @since LibreOffice 4.1
+ */
+inline SAL_CONSTEXPR bool isAsciiLowerCase(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return code >= 'a' && code <= 'z';
+}
+
+#if defined LIBO_INTERNAL_ONLY
+bool isAsciiLowerCase(char) = delete;
+bool isAsciiLowerCase(signed char) = delete;
+template <typename T>
+inline constexpr std::enable_if_t<std::is_integral_v<T> && sizeof(T) <= sizeof(sal_uInt32), bool>
+isAsciiLowerCase(T code)
+{
+ return isAsciiLowerCase(sal_uInt32(code));
+}
+#endif
+
+/** Check for ASCII upper case character.
+
+ @param code A Unicode code point.
+
+ @return True if code is an ASCII upper case alphabetic character (ASCII
+ 'A'--'Z').
+
+ @since LibreOffice 4.1
+ */
+inline SAL_CONSTEXPR bool isAsciiUpperCase(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return code >= 'A' && code <= 'Z';
+}
+
+#if defined LIBO_INTERNAL_ONLY
+bool isAsciiUpperCase(char) = delete;
+bool isAsciiUpperCase(signed char) = delete;
+template <typename T>
+inline constexpr std::enable_if_t<std::is_integral_v<T> && sizeof(T) <= sizeof(sal_uInt32), bool>
+isAsciiUpperCase(T code)
+{
+ return isAsciiUpperCase(sal_uInt32(code));
+}
+#endif
+
+/** Check for ASCII alphabetic character.
+
+ @param code A Unicode code point.
+
+ @return True if code is an ASCII alphabetic character (ASCII 'A'--'Z' or
+ 'a'--'z').
+
+ @since LibreOffice 4.1
+ */
+inline SAL_CONSTEXPR bool isAsciiAlpha(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return isAsciiLowerCase(code) || isAsciiUpperCase(code);
+}
+
+#if defined LIBO_INTERNAL_ONLY
+bool isAsciiAlpha(char) = delete;
+bool isAsciiAlpha(signed char) = delete;
+template <typename T>
+inline constexpr std::enable_if_t<std::is_integral_v<T> && sizeof(T) <= sizeof(sal_uInt32), bool>
+isAsciiAlpha(T code)
+{
+ return isAsciiAlpha(sal_uInt32(code));
+}
+#endif
+
+/** Check for ASCII digit character.
+
+ @param code A Unicode code point.
+
+ @return True if code is an ASCII (decimal) digit character (ASCII
+ '0'--'9').
+
+ @since LibreOffice 4.1
+ */
+inline SAL_CONSTEXPR bool isAsciiDigit(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return code >= '0' && code <= '9';
+}
+
+#if defined LIBO_INTERNAL_ONLY
+bool isAsciiDigit(char) = delete;
+bool isAsciiDigit(signed char) = delete;
+template <typename T>
+inline constexpr std::enable_if_t<std::is_integral_v<T> && sizeof(T) <= sizeof(sal_uInt32), bool>
+isAsciiDigit(T code)
+{
+ return isAsciiDigit(sal_uInt32(code));
+}
+#endif
+
+/** Check for ASCII alphanumeric character.
+
+ @param code A Unicode code point.
+
+ @return True if code is an ASCII alphanumeric character (ASCII '0'--'9',
+ 'A'--'Z', or 'a'--'z').
+
+ @since LibreOffice 4.1
+ */
+inline SAL_CONSTEXPR bool isAsciiAlphanumeric(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return isAsciiDigit(code) || isAsciiAlpha(code);
+}
+
+#if defined LIBO_INTERNAL_ONLY
+bool isAsciiAlphanumeric(char) = delete;
+bool isAsciiAlphanumeric(signed char) = delete;
+template <typename T>
+inline constexpr std::enable_if_t<std::is_integral_v<T> && sizeof(T) <= sizeof(sal_uInt32), bool>
+isAsciiAlphanumeric(T code)
+{
+ return isAsciiAlphanumeric(sal_uInt32(code));
+}
+#endif
+
+/** Check for ASCII canonic hexadecimal digit character.
+
+ @param code A Unicode code point.
+
+ @return True if code is an ASCII canonic (i.e., upper case) hexadecimal
+ digit character (ASCII '0'--'9' or 'A'--'F').
+
+ @since LibreOffice 4.1
+ */
+inline SAL_CONSTEXPR bool isAsciiCanonicHexDigit(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return isAsciiDigit(code) || (code >= 'A' && code <= 'F');
+}
+
+#if defined LIBO_INTERNAL_ONLY
+bool isAsciiCanonicHexDigit(char) = delete;
+bool isAsciiCanonicHexDigit(signed char) = delete;
+template <typename T>
+inline constexpr std::enable_if_t<std::is_integral_v<T> && sizeof(T) <= sizeof(sal_uInt32), bool>
+isAsciiCanonicHexDigit(T code)
+{
+ return isAsciiCanonicHexDigit(sal_uInt32(code));
+}
+#endif
+
+/** Check for ASCII hexadecimal digit character.
+
+ @param code A Unicode code point.
+
+ @return True if code is an ASCII hexadecimal digit character (ASCII
+ '0'--'9', 'A'--'F', or 'a'--'f').
+
+ @since LibreOffice 4.1
+ */
+inline SAL_CONSTEXPR bool isAsciiHexDigit(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return isAsciiCanonicHexDigit(code) || (code >= 'a' && code <= 'f');
+}
+
+#if defined LIBO_INTERNAL_ONLY
+bool isAsciiHexDigit(char) = delete;
+bool isAsciiHexDigit(signed char) = delete;
+template <typename T>
+inline constexpr std::enable_if_t<std::is_integral_v<T> && sizeof(T) <= sizeof(sal_uInt32), bool>
+isAsciiHexDigit(T code)
+{
+ return isAsciiHexDigit(sal_uInt32(code));
+}
+#endif
+
+/** Check for ASCII octal digit character.
+
+ @param code A Unicode code point.
+
+ @return True if code is an ASCII octal digit character (ASCII '0'--'7').
+
+ @since LibreOffice 5.0
+ */
+inline SAL_CONSTEXPR bool isAsciiOctalDigit(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return code >= '0' && code <= '7';
+}
+
+#if defined LIBO_INTERNAL_ONLY
+bool isAsciiOctalDigit(char) = delete;
+bool isAsciiOctalDigit(signed char) = delete;
+template <typename T>
+inline constexpr std::enable_if_t<std::is_integral_v<T> && sizeof(T) <= sizeof(sal_uInt32), bool>
+isAsciiOctalDigit(T code)
+{
+ return isAsciiOctalDigit(sal_uInt32(code));
+}
+#endif
+
+/** Check for ASCII white space character.
+
+ @param code A Unicode code point.
+
+ @return True if code is an ASCII white space character as defined by C for
+ isspace in the "C" locale (ASCII ' ', '\\f', '\\n', '\\r', '\\t' '\\v').
+
+ @since LibreOffice 5.4
+*/
+inline SAL_CONSTEXPR bool isAsciiWhiteSpace(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return code == ' ' || code == '\f' || code == '\n' || code == '\r' || code == '\t'
+ || code == '\v';
+}
+
+#if defined LIBO_INTERNAL_ONLY
+bool isAsciiWhiteSpace(char) = delete;
+bool isAsciiWhiteSpace(signed char) = delete;
+template <typename T>
+inline constexpr std::enable_if_t<std::is_integral_v<T> && sizeof(T) <= sizeof(sal_uInt32), bool>
+isAsciiWhiteSpace(T code)
+{
+ return isAsciiWhiteSpace(sal_uInt32(code));
+}
+#endif
+
+/** Convert a character, if ASCII, to upper case.
+
+ @param code A Unicode code point.
+
+ @return code converted to ASCII upper case.
+
+ @since LibreOffice 4.2
+*/
+inline SAL_CONSTEXPR sal_uInt32 toAsciiUpperCase(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return isAsciiLowerCase(code) ? code - 32 : code;
+}
+
+#if defined LIBO_INTERNAL_ONLY
+sal_uInt32 toAsciiUpperCase(char) = delete;
+sal_uInt32 toAsciiUpperCase(signed char) = delete;
+template <typename T>
+inline constexpr std::enable_if_t<std::is_integral_v<T> && sizeof(T) <= sizeof(sal_uInt32),
+ sal_uInt32>
+toAsciiUpperCase(T code)
+{
+ return toAsciiUpperCase(sal_uInt32(code));
+}
+#endif
+
+/** Convert a character, if ASCII, to lower case.
+
+ @param code A Unicode code point.
+
+ @return code converted to ASCII lower case.
+
+ @since LibreOffice 4.2
+*/
+inline SAL_CONSTEXPR sal_uInt32 toAsciiLowerCase(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return isAsciiUpperCase(code) ? code + 32 : code;
+}
+
+#if defined LIBO_INTERNAL_ONLY
+sal_uInt32 toAsciiLowerCase(char) = delete;
+sal_uInt32 toAsciiLowerCase(signed char) = delete;
+template <typename T>
+inline constexpr std::enable_if_t<std::is_integral_v<T> && sizeof(T) <= sizeof(sal_uInt32),
+ sal_uInt32>
+toAsciiLowerCase(T code)
+{
+ return toAsciiLowerCase(sal_uInt32(code));
+}
+#endif
+
+/** Compare two characters ignoring ASCII case.
+
+ @param code1 A Unicode code point.
+
+ @param code2 A unicode code point.
+
+ @return 0 if both code points are equal,
+ < 0 if code1 is less than code2,
+ > 0 if code1 is greater than code2.
+
+ @since LibreOffice 4.2
+ */
+inline SAL_CONSTEXPR sal_Int32 compareIgnoreAsciiCase(sal_uInt32 code1, sal_uInt32 code2)
+{
+ assert(isUnicodeCodePoint(code1));
+ assert(isUnicodeCodePoint(code2));
+ return static_cast<sal_Int32>(toAsciiLowerCase(code1))
+ - static_cast<sal_Int32>(toAsciiLowerCase(code2));
+}
+
+/// @cond INTERNAL
+namespace detail
+{
+sal_uInt32 const surrogatesHighFirst = 0xD800;
+sal_uInt32 const surrogatesHighLast = 0xDBFF;
+sal_uInt32 const surrogatesLowFirst = 0xDC00;
+sal_uInt32 const surrogatesLowLast = 0xDFFF;
+}
+/// @endcond
+
+/** Check for surrogate.
+
+ @param code A Unicode code point.
+
+ @return True if code is a surrogate code point (0xD800--0xDFFF).
+
+ @since LibreOffice 6.0
+*/
+inline SAL_CONSTEXPR bool isSurrogate(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return code >= detail::surrogatesHighFirst && code <= detail::surrogatesLowLast;
+}
+
+/** Check for high surrogate.
+
+ @param code A Unicode code point.
+
+ @return True if code is a high surrogate code point (0xD800--0xDBFF).
+
+ @since LibreOffice 5.0
+*/
+inline SAL_CONSTEXPR bool isHighSurrogate(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return code >= detail::surrogatesHighFirst && code <= detail::surrogatesHighLast;
+}
+
+/** Check for low surrogate.
+
+ @param code A Unicode code point.
+
+ @return True if code is a low surrogate code point (0xDC00--0xDFFF).
+
+ @since LibreOffice 5.0
+*/
+inline SAL_CONSTEXPR bool isLowSurrogate(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ return code >= detail::surrogatesLowFirst && code <= detail::surrogatesLowLast;
+}
+
+/** Get high surrogate half of a non-BMP Unicode code point.
+
+ @param code A non-BMP Unicode code point.
+
+ @return The UTF-16 high surrogate half for the give code point.
+
+ @since LibreOffice 5.0
+ */
+inline SAL_CONSTEXPR sal_Unicode getHighSurrogate(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ assert(code >= 0x10000);
+ return static_cast<sal_Unicode>(((code - 0x10000) >> 10) | detail::surrogatesHighFirst);
+}
+
+/** Get low surrogate half of a non-BMP Unicode code point.
+
+ @param code A non-BMP Unicode code point.
+
+ @return The UTF-16 low surrogate half for the give code point.
+
+ @since LibreOffice 5.0
+ */
+inline SAL_CONSTEXPR sal_Unicode getLowSurrogate(sal_uInt32 code)
+{
+ assert(isUnicodeCodePoint(code));
+ assert(code >= 0x10000);
+ return static_cast<sal_Unicode>(((code - 0x10000) & 0x3FF) | detail::surrogatesLowFirst);
+}
+
+/** Combine surrogates to form a code point.
+
+ @param high A high surrogate code point.
+
+ @param low A low surrogate code point.
+
+ @return The code point represented by the surrogate pair.
+
+ @since LibreOffice 5.0
+*/
+inline SAL_CONSTEXPR sal_uInt32 combineSurrogates(sal_uInt32 high, sal_uInt32 low)
+{
+ assert(isHighSurrogate(high));
+ assert(isLowSurrogate(low));
+ return ((high - detail::surrogatesHighFirst) << 10) + (low - detail::surrogatesLowFirst)
+ + 0x10000;
+}
+
+/** Split a Unicode code point into UTF-16 code units.
+
+ @param code A Unicode code point.
+
+ @param output A non-null pointer to an array with space for at least two
+ sal_Unicode UTF-16 code units.
+
+ @return The number of UTF-16 code units placed into the output (either one
+ or two).
+
+ @since LibreOffice 5.3
+*/
+inline SAL_CONSTEXPR std::size_t splitSurrogates(sal_uInt32 code, sal_Unicode* output)
+{
+ assert(isUnicodeCodePoint(code));
+ assert(output != NULL);
+ if (code < 0x10000)
+ {
+ output[0] = code;
+ return 1;
+ }
+ else
+ {
+ output[0] = getHighSurrogate(code);
+ output[1] = getLowSurrogate(code);
+ return 2;
+ }
+}
+
+/** Check for Unicode scalar value.
+
+ @param code An integer.
+
+ @return True if code is a Unicode scalar value.
+
+ @since LibreOffice 6.0
+*/
+inline SAL_CONSTEXPR bool isUnicodeScalarValue(sal_uInt32 code)
+{
+ return isUnicodeCodePoint(code) && !isSurrogate(code);
+}
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/cipher.h b/include/rtl/cipher.h
new file mode 100644
index 0000000000..928f71ba97
--- /dev/null
+++ b/include/rtl/cipher.h
@@ -0,0 +1,284 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_CIPHER_H
+#define INCLUDED_RTL_CIPHER_H
+
+#include "sal/config.h"
+
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Cipher Handle opaque type.
+ */
+typedef void* rtlCipher;
+
+/** Cipher Algorithm enumeration.
+ @see rtl_cipher_create()
+ */
+enum __rtl_CipherAlgorithm
+{
+ rtl_Cipher_AlgorithmBF,
+ rtl_Cipher_AlgorithmARCFOUR,
+ rtl_Cipher_AlgorithmInvalid,
+ rtl_Cipher_Algorithm_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+};
+
+/** Cipher Algorithm type.
+ */
+typedef enum __rtl_CipherAlgorithm rtlCipherAlgorithm;
+
+/** Cipher Mode enumeration.
+ @see rtl_cipher_create()
+ */
+enum __rtl_CipherMode
+{
+ rtl_Cipher_ModeECB,
+ rtl_Cipher_ModeCBC,
+ rtl_Cipher_ModeStream,
+ rtl_Cipher_ModeInvalid,
+ rtl_Cipher_Mode_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+};
+
+/** Cipher Mode type.
+ */
+typedef enum __rtl_CipherMode rtlCipherMode;
+
+/** Cipher Direction enumeration.
+ @see rtl_cipher_init()
+ */
+enum __rtl_CipherDirection
+{
+ rtl_Cipher_DirectionBoth,
+ rtl_Cipher_DirectionDecode,
+ rtl_Cipher_DirectionEncode,
+ rtl_Cipher_DirectionInvalid,
+ rtl_Cipher_Direction_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+};
+
+/** Cipher Direction type.
+ */
+typedef enum __rtl_CipherDirection rtlCipherDirection;
+
+
+/** Error Code enumeration.
+ */
+enum __rtl_CipherError
+{
+ rtl_Cipher_E_None,
+ rtl_Cipher_E_Argument,
+ rtl_Cipher_E_Algorithm,
+ rtl_Cipher_E_Direction,
+ rtl_Cipher_E_Mode,
+ rtl_Cipher_E_BufferSize,
+ rtl_Cipher_E_Memory,
+ rtl_Cipher_E_Unknown,
+ rtl_Cipher_E_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+};
+
+/** Error Code type.
+ */
+typedef enum __rtl_CipherError rtlCipherError;
+
+
+/** Create a cipher handle for the given algorithm and mode.
+ @see rtlCipherAlgorithm
+ @see rtlCipherMode
+
+ @param[in] Algorithm cipher algorithm.
+ @param[in] Mode cipher mode.
+ @return Cipher handle, or 0 upon failure.
+ */
+SAL_DLLPUBLIC rtlCipher SAL_CALL rtl_cipher_create (
+ rtlCipherAlgorithm Algorithm,
+ rtlCipherMode Mode
+) SAL_THROW_EXTERN_C();
+
+/** Inititialize a cipher for the given direction.
+ @see rtlCipherDirection
+
+ @param[in] Cipher cipher handle.
+ @param[in] Direction cipher direction.
+ @param[in] pKeyData key material buffer.
+ @param[in] nKeyLen key material length in bytes.
+ @param[in] pArgData initialization vector buffer.
+ @param[in] nArgLen initialization vector length in bytes.
+ @retval rtl_Cipher_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlCipherError SAL_CALL rtl_cipher_init (
+ rtlCipher Cipher,
+ rtlCipherDirection Direction,
+ const sal_uInt8 *pKeyData, sal_Size nKeyLen,
+ const sal_uInt8 *pArgData, sal_Size nArgLen
+) SAL_THROW_EXTERN_C();
+
+/** Encode a buffer under a given cipher algorithm.
+ @pre Initialized for a compatible cipher direction.
+ @see rtl_cipher_init()
+
+ @param[in] Cipher cipher handle.
+ @param[in] pData plaintext buffer.
+ @param[in] nDatLen plaintext length in bytes.
+ @param[out] pBuffer ciphertext buffer.
+ @param[in] nBufLen ciphertext length in bytes.
+ @retval rtl_Cipher_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlCipherError SAL_CALL rtl_cipher_encode (
+ rtlCipher Cipher,
+ const void *pData, sal_Size nDatLen,
+ sal_uInt8 *pBuffer, sal_Size nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Decode a buffer under a given cipher algorithm.
+ @pre Initialized for a compatible cipher direction.
+ @see rtl_cipher_init()
+
+ @param[in] Cipher cipher handle.
+ @param[in] pData ciphertext buffer.
+ @param[in] nDatLen ciphertext length in bytes.
+ @param[out] pBuffer plaintext buffer.
+ @param[in] nBufLen plaintext length in bytes.
+ @retval rtl_Cipher_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlCipherError SAL_CALL rtl_cipher_decode (
+ rtlCipher Cipher,
+ const void *pData, sal_Size nDatLen,
+ sal_uInt8 *pBuffer, sal_Size nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Destroy a cipher handle.
+
+ Cipher handle destroyed and invalid.
+
+ @param[in] Cipher cipher handle to be destroyed.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_cipher_destroy (
+ rtlCipher Cipher
+) SAL_THROW_EXTERN_C();
+
+/** Create a Blowfish cipher handle for the given mode.
+
+ The Blowfish block cipher algorithm is specified in
+ Bruce Schneier: Applied Cryptography, 2nd edition, ch. 14.3
+
+ @see rtl_cipher_create()
+ */
+SAL_DLLPUBLIC rtlCipher SAL_CALL rtl_cipher_createBF (
+ rtlCipherMode Mode
+) SAL_THROW_EXTERN_C();
+
+/** Inititialize a Blowfish cipher for the given direction.
+ @see rtl_cipher_init()
+ */
+SAL_DLLPUBLIC rtlCipherError SAL_CALL rtl_cipher_initBF (
+ rtlCipher Cipher,
+ rtlCipherDirection Direction,
+ const sal_uInt8 *pKeyData, sal_Size nKeyLen,
+ const sal_uInt8 *pArgData, sal_Size nArgLen
+) SAL_THROW_EXTERN_C();
+
+/** Encode a buffer under the Blowfish cipher algorithm.
+ @see rtl_cipher_encode()
+ */
+SAL_DLLPUBLIC rtlCipherError SAL_CALL rtl_cipher_encodeBF (
+ rtlCipher Cipher,
+ const void *pData, sal_Size nDatLen,
+ sal_uInt8 *pBuffer, sal_Size nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Decode a buffer under the Blowfish cipher algorithm.
+ @see rtl_cipher_decode()
+ */
+SAL_DLLPUBLIC rtlCipherError SAL_CALL rtl_cipher_decodeBF (
+ rtlCipher Cipher,
+ const void *pData, sal_Size nDatLen,
+ sal_uInt8 *pBuffer, sal_Size nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Destroy a Blowfish cipher handle.
+ @see rtl_cipher_destroy()
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_cipher_destroyBF (
+ rtlCipher Cipher
+) SAL_THROW_EXTERN_C();
+
+/** Create a RC4 cipher handle for the given mode.
+
+ The RC4 symmetric stream cipher algorithm is specified in
+ Bruce Schneier: Applied Cryptography, 2nd edition, ch. 17.1
+
+ @see rtl_cipher_create()
+
+ @param[in] Mode cipher mode. Must be <code>rtl_Cipher_ModeStream</code>.
+ @return Cipher handle, or 0 upon failure.
+ */
+SAL_DLLPUBLIC rtlCipher SAL_CALL rtl_cipher_createARCFOUR (
+ rtlCipherMode Mode
+) SAL_THROW_EXTERN_C();
+
+/** Inititialize a RC4 cipher for the given direction.
+ @see rtl_cipher_init()
+ */
+SAL_DLLPUBLIC rtlCipherError SAL_CALL rtl_cipher_initARCFOUR (
+ rtlCipher Cipher,
+ rtlCipherDirection Direction,
+ const sal_uInt8 *pKeyData, sal_Size nKeyLen,
+ const sal_uInt8 *pArgData, sal_Size nArgLen
+) SAL_THROW_EXTERN_C();
+
+/** Encode a buffer under the RC4 cipher algorithm.
+ @see rtl_cipher_encode()
+ */
+SAL_DLLPUBLIC rtlCipherError SAL_CALL rtl_cipher_encodeARCFOUR (
+ rtlCipher Cipher,
+ const void *pData, sal_Size nDatLen,
+ sal_uInt8 *pBuffer, sal_Size nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Decode a buffer under the RC4 cipher algorithm.
+ @see rtl_cipher_decode()
+ */
+SAL_DLLPUBLIC rtlCipherError SAL_CALL rtl_cipher_decodeARCFOUR (
+ rtlCipher Cipher,
+ const void *pData, sal_Size nDatLen,
+ sal_uInt8 *pBuffer, sal_Size nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Destroy a RC4 cipher handle.
+ @see rtl_cipher_destroy()
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_cipher_destroyARCFOUR (
+ rtlCipher Cipher
+) SAL_THROW_EXTERN_C();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! INCLUDED_RTL_CIPHER_H */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/crc.h b/include/rtl/crc.h
new file mode 100644
index 0000000000..d081140f55
--- /dev/null
+++ b/include/rtl/crc.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_CRC_H
+#define INCLUDED_RTL_CRC_H
+
+#include "sal/config.h"
+
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Evaluate CRC32 over given data.
+
+ This function evaluates the CRC polynomial 0xEDB88320.
+
+ @param[in] Crc CRC32 over previous data or zero.
+ @param[in] Data data buffer.
+ @param[in] DatLen data buffer length.
+ @return new CRC32 value.
+ */
+SAL_DLLPUBLIC sal_uInt32 SAL_CALL rtl_crc32 (
+ sal_uInt32 Crc,
+ const void *Data, sal_uInt32 DatLen
+) SAL_THROW_EXTERN_C();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_RTL_CRC_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/digest.h b/include/rtl/digest.h
new file mode 100644
index 0000000000..f649d8b594
--- /dev/null
+++ b/include/rtl/digest.h
@@ -0,0 +1,643 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_DIGEST_H
+#define INCLUDED_RTL_DIGEST_H
+
+#include "sal/config.h"
+
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Digest Handle opaque type.
+ */
+typedef void* rtlDigest;
+
+
+/** Digest Algorithm enumeration.
+ @see rtl_digest_create()
+ */
+enum __rtl_DigestAlgorithm
+{
+ rtl_Digest_AlgorithmMD2,
+ rtl_Digest_AlgorithmMD5,
+ rtl_Digest_AlgorithmSHA,
+ rtl_Digest_AlgorithmSHA1,
+
+ rtl_Digest_AlgorithmHMAC_MD5,
+ rtl_Digest_AlgorithmHMAC_SHA1,
+
+ rtl_Digest_AlgorithmInvalid,
+ rtl_Digest_Algorithm_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+};
+
+/** Digest Algorithm type.
+ */
+typedef enum __rtl_DigestAlgorithm rtlDigestAlgorithm;
+
+
+/** Error Code enumeration.
+ */
+enum __rtl_DigestError
+{
+ rtl_Digest_E_None,
+ rtl_Digest_E_Argument,
+ rtl_Digest_E_Algorithm,
+ rtl_Digest_E_BufferSize,
+ rtl_Digest_E_Memory,
+ rtl_Digest_E_Unknown,
+ rtl_Digest_E_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+};
+
+/** Error Code type.
+ */
+typedef enum __rtl_DigestError rtlDigestError;
+
+
+/** Create a digest handle for the given algorithm.
+ @see rtlDigestAlgorithm
+
+ @param[in] Algorithm digest algorithm.
+ @return Digest handle, or 0 upon failure.
+ */
+SAL_DLLPUBLIC rtlDigest SAL_CALL rtl_digest_create (
+ rtlDigestAlgorithm Algorithm
+) SAL_THROW_EXTERN_C();
+
+
+/** Destroy a digest handle.
+ @post Digest handle destroyed and invalid.
+ @param[in] Digest digest handle to be destroyed.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_digest_destroy (
+ rtlDigest Digest
+) SAL_THROW_EXTERN_C();
+
+
+/** Query the algorithm of a given digest.
+ @param[in] Digest digest handle.
+ @return digest algorithm, or <code>rtl_Digest_AlgorithmInvalid</code> upon failure.
+ */
+SAL_DLLPUBLIC rtlDigestAlgorithm SAL_CALL rtl_digest_queryAlgorithm (
+ rtlDigest Digest
+) SAL_THROW_EXTERN_C();
+
+
+/** Query the length of a given digest.
+ @param[in] Digest digest handle.
+ @return digest length, or 0 upon failure.
+ */
+SAL_DLLPUBLIC sal_uInt32 SAL_CALL rtl_digest_queryLength (
+ rtlDigest Digest
+) SAL_THROW_EXTERN_C();
+
+
+/** Initialize a digest with given data.
+ @param[in] Digest digest handle.
+ @param[in] pData data buffer.
+ @param[in] nDatLen data length.
+
+ @retval rtl_Digest_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_init (
+ rtlDigest Digest,
+ const sal_uInt8 *pData, sal_uInt32 nDatLen
+) SAL_THROW_EXTERN_C();
+
+
+/** Update a digest with given data.
+ @param[in] Digest digest handle.
+ @param[in] pData data buffer.
+ @param[in] nDatLen data length.
+
+ @retval rtl_Digest_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_update (
+ rtlDigest Digest,
+ const void *pData, sal_uInt32 nDatLen
+) SAL_THROW_EXTERN_C();
+
+
+/** Finalize a digest and retrieve the digest value.
+ @pre Digest value length must not be less than digest length.
+ @post Digest initialized to accept another update sequence.
+ @see rtl_digest_queryLength()
+ @see rtl_digest_update()
+
+ @param[in] Digest digest handle.
+ @param[in] pBuffer digest value buffer.
+ @param[in] nBufLen digest value length.
+
+ @retval rtl_Digest_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_get (
+ rtlDigest Digest,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+#define RTL_DIGEST_LENGTH_MD2 16
+
+/** Create a MD2 digest handle.
+
+ The MD2 digest algorithm is specified in
+ RFC 1319 (Informational)
+ The MD2 Message-Digest Algorithm
+
+ @see rtl_digest_create()
+ */
+SAL_DLLPUBLIC rtlDigest SAL_CALL rtl_digest_createMD2 (void) SAL_THROW_EXTERN_C();
+
+
+/** Destroy a MD2 digest handle.
+ @see rtl_digest_destroy()
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_digest_destroyMD2 (
+ rtlDigest Digest
+) SAL_THROW_EXTERN_C();
+
+/** Update a MD2 digest with given data.
+ @see rtl_digest_update()
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_updateMD2 (
+ rtlDigest Digest,
+ const void *pData, sal_uInt32 nDatLen
+) SAL_THROW_EXTERN_C();
+
+/** Finalize a MD2 digest and retrieve the digest value.
+ @see rtl_digest_get()
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_getMD2 (
+ rtlDigest Digest,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Evaluate a MD2 digest value from given data.
+
+ This function performs an optimized call sequence on a
+ single data buffer, avoiding digest creation and destruction.
+
+ @see rtl_digest_updateMD2()
+ @see rtl_digest_getMD2()
+
+ @param[in] pData data buffer.
+ @param[in] nDatLen data length.
+ @param[in] pBuffer digest value buffer.
+ @param[in] nBufLen digest value length.
+
+ @retval rtl_Digest_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_MD2 (
+ const void *pData, sal_uInt32 nDatLen,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+#define RTL_DIGEST_LENGTH_MD5 16
+
+/** Create a MD5 digest handle.
+
+ The MD5 digest algorithm is specified in
+ RFC 1321 (Informational)
+ The MD5 Message-Digest Algorithm
+
+ @see rtl_digest_create()
+ */
+SAL_DLLPUBLIC rtlDigest SAL_CALL rtl_digest_createMD5 (void) SAL_THROW_EXTERN_C();
+
+/** Destroy a MD5 digest handle.
+ @see rtl_digest_destroy()
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_digest_destroyMD5 (
+ rtlDigest Digest
+) SAL_THROW_EXTERN_C();
+
+/** Update a MD5 digest with given data.
+ @see rtl_digest_update()
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_updateMD5 (
+ rtlDigest Digest,
+ const void *pData, sal_uInt32 nDatLen
+) SAL_THROW_EXTERN_C();
+
+/** Finalize a MD5 digest and retrieve the digest value.
+ @see rtl_digest_get()
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_getMD5 (
+ rtlDigest Digest,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Retrieve the raw (not finalized) MD5 digest value.
+
+ This function is a non-standard replacement for
+ rtl_digest_getMD5() and must be used with caution.
+
+ @post Digest initialized to accept another update sequence.
+ @see rtl_digest_get()
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_rawMD5 (
+ rtlDigest Digest,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Evaluate a MD5 digest value from given data.
+
+ This function performs an optimized call sequence on a
+ single data buffer, avoiding digest creation and destruction.
+
+ @see rtl_digest_updateMD5()
+ @see rtl_digest_getMD5()
+
+ @param[in] pData data buffer.
+ @param[in] nDatLen data length.
+ @param[in] pBuffer digest value buffer.
+ @param[in] nBufLen digest value length.
+
+ @retval rtl_Digest_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_MD5 (
+ const void *pData, sal_uInt32 nDatLen,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+#define RTL_DIGEST_LENGTH_SHA 20
+
+/** Create a SHA digest handle.
+
+ The SHA digest algorithm is specified in
+ FIPS PUB 180 (Superseded by FIPS PUB 180-1)
+ Secure Hash Standard
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_create()
+ */
+SAL_DLLPUBLIC rtlDigest SAL_CALL rtl_digest_createSHA (void) SAL_THROW_EXTERN_C();
+
+/** Destroy a SHA digest handle.
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_destroy()
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_digest_destroySHA (
+ rtlDigest Digest
+) SAL_THROW_EXTERN_C();
+
+
+/** Update a SHA digest with given data.
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_update()
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_updateSHA (
+ rtlDigest Digest,
+ const void *pData, sal_uInt32 nDatLen
+) SAL_THROW_EXTERN_C();
+
+/** Finalize a SHA digest and retrieve the digest value.
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_get()
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_getSHA (
+ rtlDigest Digest,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Evaluate a SHA digest value from given data.
+
+ This function performs an optimized call sequence on a
+ single data buffer, avoiding digest creation and destruction.
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_updateSHA()
+ @see rtl_digest_getSHA()
+
+ @param[in] pData data buffer.
+ @param[in] nDatLen data length.
+ @param[in] pBuffer digest value buffer.
+ @param[in] nBufLen digest value length.
+
+ @retval rtl_Digest_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_SHA (
+ const void *pData, sal_uInt32 nDatLen,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+/*========================================================================
+ *
+ * rtl_digest_SHA1 interface.
+ *
+ *======================================================================*/
+#define RTL_DIGEST_LENGTH_SHA1 20
+
+/** Create a SHA1 digest handle.
+
+ The SHA1 digest algorithm is specified in
+ FIPS PUB 180-1 (Supersedes FIPS PUB 180)
+ Secure Hash Standard
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_create()
+ */
+SAL_DLLPUBLIC rtlDigest SAL_CALL rtl_digest_createSHA1 (void) SAL_THROW_EXTERN_C();
+
+/** Destroy a SHA1 digest handle.
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_destroy()
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_digest_destroySHA1 (
+ rtlDigest Digest
+) SAL_THROW_EXTERN_C();
+
+/** Update a SHA1 digest with given data.
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_update()
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_updateSHA1 (
+ rtlDigest Digest,
+ const void *pData, sal_uInt32 nDatLen
+) SAL_THROW_EXTERN_C();
+
+/** Finalize a SHA1 digest and retrieve the digest value.
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_get()
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_getSHA1 (
+ rtlDigest Digest,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Evaluate a SHA1 digest value from given data.
+
+ This function performs an optimized call sequence on a
+ single data buffer, avoiding digest creation and destruction.
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_updateSHA1()
+ @see rtl_digest_getSHA1()
+
+ @param[in] pData data buffer.
+ @param[in] nDatLen data length.
+ @param[in] pBuffer digest value buffer.
+ @param[in] nBufLen digest value length.
+
+ @retval rtl_Digest_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_SHA1 (
+ const void *pData, sal_uInt32 nDatLen,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+#define RTL_DIGEST_LENGTH_HMAC_MD5 RTL_DIGEST_LENGTH_MD5
+
+/** Create a HMAC_MD5 digest handle.
+
+ The HMAC_MD5 digest algorithm is specified in
+
+ RFC 2104 (Informational)
+ HMAC: Keyed-Hashing for Message Authentication
+
+ @see rtl_digest_create()
+ */
+SAL_DLLPUBLIC rtlDigest SAL_CALL rtl_digest_createHMAC_MD5 (void) SAL_THROW_EXTERN_C();
+
+/** Destroy a HMAC_MD5 digest handle.
+ @see rtl_digest_destroy()
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_digest_destroyHMAC_MD5 (
+ rtlDigest Digest
+) SAL_THROW_EXTERN_C();
+
+/** Initialize a HMAC_MD5 digest.
+ @see rtl_digest_init()
+
+ @param[in] Digest digest handle.
+ @param[in] pKeyData key material buffer.
+ @param[in] nKeyLen key material length.
+
+ @retval rtl_Digest_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_initHMAC_MD5 (
+ rtlDigest Digest,
+ const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen
+) SAL_THROW_EXTERN_C();
+
+/** Update a HMAC_MD5 digest with given data.
+ @see rtl_digest_update()
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_updateHMAC_MD5 (
+ rtlDigest Digest,
+ const void *pData, sal_uInt32 nDatLen
+) SAL_THROW_EXTERN_C();
+
+/** Finalize a HMAC_MD5 digest and retrieve the digest value.
+ @see rtl_digest_get()
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_getHMAC_MD5 (
+ rtlDigest Digest,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Evaluate a HMAC_MD5 digest value from given data.
+
+ This function performs an optimized call sequence on a
+ single data buffer, avoiding digest creation and destruction.
+
+ @see rtl_digest_initHMAC_MD5()
+ @see rtl_digest_updateHMAC_MD5()
+ @see rtl_digest_getHMAC_MD5()
+
+ @param[in] pKeyData key material buffer.
+ @param[in] nKeyLen key material length.
+ @param[in] pData data buffer.
+ @param[in] nDatLen data length.
+ @param[in] pBuffer digest value buffer.
+ @param[in] nBufLen digest value length.
+
+ @retval rtl_Digest_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_HMAC_MD5 (
+ const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen,
+ const void *pData, sal_uInt32 nDatLen,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+#define RTL_DIGEST_LENGTH_HMAC_SHA1 RTL_DIGEST_LENGTH_SHA1
+
+/** Create a HMAC_SHA1 digest handle.
+
+ The HMAC_SHA1 digest algorithm is specified in
+ RFC 2104 (Informational)
+ HMAC: Keyed-Hashing for Message Authentication
+ RFC 2898 (Informational)
+ PKCS #5: Password-Based Cryptography Specification Version 2.0
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_create()
+ */
+SAL_DLLPUBLIC rtlDigest SAL_CALL rtl_digest_createHMAC_SHA1 (void) SAL_THROW_EXTERN_C();
+
+/** Destroy a HMAC_SHA1 digest handle.
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_destroy()
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_digest_destroyHMAC_SHA1 (
+ rtlDigest Digest
+) SAL_THROW_EXTERN_C();
+
+/** Initialize a HMAC_SHA1 digest.
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_init()
+
+ @param[in] Digest digest handle.
+ @param[in] pKeyData key material buffer.
+ @param[in] nKeyLen key material length.
+
+ @retval rtl_Digest_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_initHMAC_SHA1 (
+ rtlDigest Digest,
+ const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen
+) SAL_THROW_EXTERN_C();
+
+/** Update a HMAC_SHA1 digest with given data.
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_update()
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_updateHMAC_SHA1 (
+ rtlDigest Digest,
+ const void *pData, sal_uInt32 nDatLen
+) SAL_THROW_EXTERN_C();
+
+/** Finalize a HMAC_SHA1 digest and retrieve the digest value.
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_get()
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_getHMAC_SHA1 (
+ rtlDigest Digest,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Evaluate a HMAC_SHA1 digest value from given data.
+
+ This function performs an optimized call sequence on a
+ single data buffer, avoiding digest creation and destruction.
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility.
+
+ @see rtl_digest_initHMAC_SHA1()
+ @see rtl_digest_updateHMAC_SHA1()
+ @see rtl_digest_getHMAC_SHA1()
+
+ @param[in] pKeyData key material buffer.
+ @param[in] nKeyLen key material length.
+ @param[in] pData data buffer.
+ @param[in] nDatLen data length.
+ @param[in] pBuffer digest value buffer.
+ @param[in] nBufLen digest value length.
+
+ @retval rtl_Digest_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_HMAC_SHA1 (
+ const sal_uInt8 *pKeyData, sal_uInt32 nKeyLen,
+ const void *pData, sal_uInt32 nDatLen,
+ sal_uInt8 *pBuffer, sal_uInt32 nBufLen
+) SAL_THROW_EXTERN_C();
+
+/** Password-Based Key Derivation Function.
+
+ The PBKDF2 key derivation function is specified in
+ RFC 2898 (Informational)
+ PKCS #5: Password-Based Cryptography Specification Version 2.0
+
+ @deprecated The implementation is buggy and generates incorrect results
+ for 52 <= (len % 64) <= 55; use only for bug-compatibility
+ or if the input is guaranteed to have a good length
+ by a start-key derivation round.
+
+ @param[out] pKeyData derived key
+ @param[in] nKeyLen derived key length
+ @param[in] pPassData password
+ @param[in] nPassLen password length
+ @param[in] pSaltData salt
+ @param[in] nSaltLen salt length
+ @param[in] nCount iteration count
+
+ @retval rtl_Digest_E_None upon success.
+*/
+SAL_DLLPUBLIC rtlDigestError SAL_CALL rtl_digest_PBKDF2 (
+ sal_uInt8 *pKeyData , sal_uInt32 nKeyLen,
+ const sal_uInt8 *pPassData, sal_uInt32 nPassLen,
+ const sal_uInt8 *pSaltData, sal_uInt32 nSaltLen,
+ sal_uInt32 nCount
+) SAL_THROW_EXTERN_C();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_RTL_DIGEST_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/instance.hxx b/include/rtl/instance.hxx
new file mode 100644
index 0000000000..0d7d8f3fca
--- /dev/null
+++ b/include/rtl/instance.hxx
@@ -0,0 +1,643 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_INSTANCE_HXX
+#define INCLUDED_RTL_INSTANCE_HXX
+
+#include "sal/config.h"
+
+#include <cstddef>
+
+#include "osl/doublecheckedlocking.h"
+#include "osl/getglobalmutex.hxx"
+
+namespace {
+
+/** A non-broken version of the double-checked locking pattern.
+
+ See
+ <http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html>
+ for a description of double-checked locking, why it is broken, and how it
+ can be fixed. Always use this template instead of spelling out the
+ double-checked locking pattern explicitly, and only in those rare cases
+ where that is not possible and you have to spell it out explicitly, at
+ least call OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER() at the right
+ places. That way, all platform-dependent code to make double-checked
+ locking work can be kept in one place.
+
+ Usage scenarios:
+
+ 1 Static instance (most common case)
+
+ Pattern:
+
+ T * getInstance()
+ {
+ static T * pInstance = 0;
+ if (!pInstance)
+ {
+ ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex());
+ if (!pInstance)
+ {
+ static T aInstance;
+ pInstance = &aInstance;
+ }
+ }
+ return pInstance;
+ }
+
+ Code:
+
+ #include <rtl/instance.hxx>
+ #include <osl/getglobalmutex.hxx>
+
+ namespace {
+ struct Init
+ {
+ T * operator()()
+ {
+ static T aInstance;
+ return &aInstance;
+ }
+ };
+ }
+
+ T * getInstance()
+ {
+ return rtl_Instance< T, Init, ::osl::MutexGuard,
+ ::osl::GetGlobalMutex >::create(
+ Init(), ::osl::GetGlobalMutex());
+ }
+
+ 2 Dynamic instance
+
+ Pattern:
+
+ T * getInstance()
+ {
+ static T * pInstance = 0;
+ if (!pInstance)
+ {
+ ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex());
+ if (!pInstance)
+ pInstance = new T;
+ }
+ return pInstance;
+ }
+
+ Code:
+
+ #include <rtl/instance.hxx>
+ #include <osl/getglobalmutex.hxx>
+
+ namespace {
+ struct Init
+ {
+ T * operator()()
+ {
+ return new T;
+ }
+ };
+ }
+
+ T * getInstance()
+ {
+ return rtl_Instance< T, Init, ::osl::MutexGuard,
+ ::osl::GetGlobalMutex >::create(
+ Init(), ::osl::GetGlobalMutex());
+ }
+
+ 3 Other guard/mutex
+
+ Pattern:
+
+ T * getInstance()
+ {
+ static T * pInstance = 0;
+ if (!pInstance)
+ {
+ SomeGuard aGuard(pSomeMutex);
+ if (!pInstance)
+ {
+ static T aInstance;
+ pInstance = &aInstance;
+ }
+ }
+ return pInstance;
+ }
+
+ Code:
+
+ #include <rtl/instance.hxx>
+
+ namespace {
+ struct InitInstance
+ {
+ T * operator()()
+ {
+ static T aInstance;
+ return &aInstance;
+ }
+ };
+
+ struct InitGuard
+ {
+ SomeMutex * operator()()
+ {
+ return pSomeMutex;
+ }
+ };
+ }
+
+ T * getInstance()
+ {
+ return rtl_Instance< T, InitInstance,
+ SomeGuard, InitGuard >::create(
+ InitInstance(), InitMutex());
+ }
+
+ 4 Calculate extra data
+
+ Pattern:
+
+ T * getInstance()
+ {
+ static T * pInstance = 0;
+ if (!pInstance)
+ {
+ Data aData(...);
+ ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex());
+ if (!pInstance)
+ {
+ static T aInstance(aData);
+ pInstance = &aInstance;
+ }
+ }
+ return pInstance;
+ }
+
+ Code:
+
+ #include <rtl/instance.hxx>
+ #include <osl/getglobalmutex.hxx>
+
+ namespace {
+ struct InitInstance
+ {
+ T * operator()()
+ {
+ static T aInstance;
+ return &aInstance;
+ }
+ }
+
+ struct InitData
+ {
+ Data const & operator()()
+ {
+ return ...;
+ }
+ }
+ }
+
+ T * getInstance()
+ {
+ return rtl_Instance< T, InitInstance,
+ ::osl::MutexGuard, ::osl::GetGlobalMutex,
+ Data, InitData >::create(
+ InitInstance(), ::osl::GetGlobalMutex(), InitData());
+ }
+
+ Some comments:
+
+ For any instantiation of rtl_Instance, at most one call to a create method
+ may occur in the program code: Each occurrence of a create method within
+ the program code is supposed to return a fresh object instance on the
+ first call, and that same object instance on subsequent calls; but
+ independent occurrences of create methods are supposed to return
+ independent object instances. Since there is a one-to-one correspondence
+ between object instances and instantiations of rtl_Instance, the
+ requirement should be clear. One measure to enforce the requirement is
+ that rtl_Instance lives in an unnamed namespace, so that instantiations of
+ rtl_Instance in different translation units will definitely be different
+ instantiations. A drawback of that measure is that the name of the class
+ needs a funny "hand coded" prefix "rtl_" instead of a proper namespace
+ prefix like "::rtl::".
+
+ A known problem with this template is when two occurrences of calls to
+ create methods with identical template arguments appear in one translation
+ unit. Those two places will share a single object instance. This can be
+ avoided by using different Init structs (see the above code samples) in
+ the two places.
+
+ There is no need to make m_pInstance volatile, in order to avoid usage of
+ stale copies of m_pInstance: At the first check, a thread will see that
+ m_pInstance contains either 0 or a valid pointer. If it contains a valid
+ pointer, it cannot be stale, and that pointer is used. If it contains 0,
+ acquiring the mutex will ensure that the second check sees a non-stale
+ value in all cases.
+
+ On some compilers, the create methods would not be inlined if they
+ contained any static variables, so m_pInstance is made a class member
+ instead (and the create methods are inlined). But on MSC, the definition
+ of the class member m_pInstance would cause compilation to fail with an
+ internal compiler error. Since MSC is able to inline methods containing
+ static variables, m_pInstance is moved into the methods there. Note that
+ this only works well because for any instantiation of rtl_Instance at most
+ one call to a create method should be present, anyway.
+ */
+template< typename Inst, typename InstCtor,
+ typename Guard, typename GuardCtor,
+ typename Data = int, typename DataCtor = int >
+class rtl_Instance
+{
+public:
+ static Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor)
+ {
+#if defined _MSC_VER
+ static Inst * m_pInstance = NULL;
+#endif // _MSC_VER
+ Inst * p = m_pInstance;
+ if (!p)
+ {
+ Guard aGuard(aGuardCtor());
+ p = m_pInstance;
+ if (!p)
+ {
+ p = aInstCtor();
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ m_pInstance = p;
+ }
+ }
+ else
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ return p;
+ }
+
+ static Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor,
+ DataCtor aDataCtor)
+ {
+#if defined _MSC_VER
+ static Inst * m_pInstance = NULL;
+#endif // _MSC_VER
+ Inst * p = m_pInstance;
+ if (!p)
+ {
+ Data aData(aDataCtor());
+ Guard aGuard(aGuardCtor());
+ p = m_pInstance;
+ if (!p)
+ {
+ p = aInstCtor(aData);
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ m_pInstance = p;
+ }
+ }
+ else
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ return p;
+ }
+
+ static Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor,
+ const Data &rData)
+ {
+#if defined _MSC_VER
+ static Inst * m_pInstance = 0;
+#endif // _MSC_VER
+ Inst * p = m_pInstance;
+ if (!p)
+ {
+ Guard aGuard(aGuardCtor());
+ p = m_pInstance;
+ if (!p)
+ {
+ p = aInstCtor(rData);
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ m_pInstance = p;
+ }
+ }
+ else
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ return p;
+ }
+
+private:
+#if !defined _MSC_VER
+ static Inst * m_pInstance;
+#endif // _MSC_VER
+};
+
+#if !defined _MSC_VER
+template< typename Inst, typename InstCtor,
+ typename Guard, typename GuardCtor,
+ typename Data, typename DataCtor >
+Inst *
+rtl_Instance< Inst, InstCtor, Guard, GuardCtor, Data, DataCtor >::m_pInstance
+= NULL;
+#endif // _MSC_VER
+
+}
+
+namespace rtl {
+
+/** Helper base class for a late-initialized (default-constructed)
+ static variable, implementing the double-checked locking pattern correctly.
+
+ @derive
+ Derive from this class (common practice), e.g.
+ <pre>
+ struct MyStatic : public rtl::Static<MyType, MyStatic> {};
+ ...
+ MyType & rStatic = MyStatic::get();
+ ...
+ </pre>
+
+ @tparam T
+ variable's type
+ @tparam Unique
+ Implementation trick to make the inner static holder unique,
+ using the outer class
+ (the one that derives from this base class)
+*/
+#if defined LIBO_INTERNAL_ONLY
+template<typename T, typename Unique>
+class Static {
+public:
+ /** Gets the static. Mutual exclusion is implied by a functional
+ -fthreadsafe-statics
+
+ @return
+ static variable
+ */
+ static T & get() {
+ static T instance;
+ return instance;
+ }
+};
+#else
+template<typename T, typename Unique>
+class Static {
+public:
+ /** Gets the static. Mutual exclusion is performed using the
+ osl global mutex.
+
+ @return
+ static variable
+ */
+ static T & get() {
+ return *rtl_Instance<
+ T, StaticInstance,
+ ::osl::MutexGuard, ::osl::GetGlobalMutex >::create(
+ StaticInstance(), ::osl::GetGlobalMutex() );
+ }
+private:
+ struct StaticInstance {
+ T * operator () () {
+ static T instance;
+ return &instance;
+ }
+ };
+};
+#endif
+
+/** Helper base class for a late-initialized (default-constructed)
+ static variable, implementing the double-checked locking pattern correctly.
+
+ @derive
+ Derive from this class (common practice), e.g.
+ <pre>
+ struct MyStatic : public rtl::Static<MyType, MyStatic> {};
+ ...
+ MyType & rStatic = MyStatic::get();
+ ...
+ </pre>
+
+ @tparam T
+ variable's type
+ @tparam Unique
+ Implementation trick to make the inner static holder unique,
+ using the outer class
+ (the one that derives from this base class)
+*/
+#if defined LIBO_INTERNAL_ONLY
+template<typename T, typename Data, typename Unique>
+class StaticWithArg {
+public:
+ /** Gets the static. Mutual exclusion is implied by a functional
+ -fthreadsafe-statics
+
+ @return
+ static variable
+ */
+ static T & get(const Data& rData) {
+ static T instance(rData);
+ return instance;
+ }
+
+ /** Gets the static. Mutual exclusion is implied by a functional
+ -fthreadsafe-statics
+
+ @return
+ static variable
+ */
+ static T & get(Data& rData) {
+ static T instance(rData);
+ return instance;
+ }
+};
+#else
+template<typename T, typename Data, typename Unique>
+class StaticWithArg {
+public:
+ /** Gets the static. Mutual exclusion is performed using the
+ osl global mutex.
+
+ @return
+ static variable
+ */
+ static T & get(const Data& rData) {
+ return *rtl_Instance<
+ T, StaticInstanceWithArg,
+ ::osl::MutexGuard, ::osl::GetGlobalMutex,
+ Data >::create( StaticInstanceWithArg(),
+ ::osl::GetGlobalMutex(),
+ rData );
+ }
+
+ /** Gets the static. Mutual exclusion is performed using the
+ osl global mutex.
+
+ @return
+ static variable
+ */
+ static T & get(Data& rData) {
+ return *rtl_Instance<
+ T, StaticInstanceWithArg,
+ ::osl::MutexGuard, ::osl::GetGlobalMutex,
+ Data >::create( StaticInstanceWithArg(),
+ ::osl::GetGlobalMutex(),
+ rData );
+ }
+private:
+ struct StaticInstanceWithArg {
+ T * operator () (const Data& rData) {
+ static T instance(rData);
+ return &instance;
+ }
+
+ T * operator () (Data& rData) {
+ static T instance(rData);
+ return &instance;
+ }
+ };
+};
+#endif
+
+/** Helper class for a late-initialized static aggregate, e.g. an array,
+ implementing the double-checked locking pattern correctly.
+
+ @tparam T
+ aggregate's element type
+ @tparam InitAggregate
+ initializer functor class
+*/
+#if defined LIBO_INTERNAL_ONLY
+template<typename T, typename InitAggregate>
+class StaticAggregate {
+public:
+ /** Gets the static aggregate, late-initializing.
+ Mutual exclusion is implied by a functional
+ -fthreadsafe-statics
+
+ @return
+ aggregate
+ */
+ static T * get() {
+ static T *instance = InitAggregate()();
+ return instance;
+ }
+};
+#else
+template<typename T, typename InitAggregate>
+class StaticAggregate {
+public:
+ /** Gets the static aggregate, late-initializing.
+ Mutual exclusion is performed using the osl global mutex.
+
+ @return
+ aggregate
+ */
+ static T * get() {
+ return rtl_Instance<
+ T, InitAggregate,
+ ::osl::MutexGuard, ::osl::GetGlobalMutex >::create(
+ InitAggregate(), ::osl::GetGlobalMutex() );
+ }
+};
+#endif
+/** Helper base class for a late-initialized static variable,
+ implementing the double-checked locking pattern correctly.
+
+ @derive
+ Derive from this class (common practice),
+ providing an initializer functor class, e.g.
+ <pre>
+ struct MyStatic : public rtl::StaticWithInit<MyType, MyStatic> {
+ MyType operator () () {
+ ...
+ return MyType( ... );
+ }
+ };
+ ...
+ MyType & rStatic = MyStatic::get();
+ ...
+ </pre>
+
+ @tparam T
+ variable's type
+ @tparam InitData
+ initializer functor class
+ @tparam Unique
+ Implementation trick to make the inner static holder unique,
+ using the outer class
+ (the one that derives from this base class).
+ Default is InitData (common practice).
+ @tparam Data
+ Initializer functor's return type.
+ Default is T (common practice).
+*/
+#if defined LIBO_INTERNAL_ONLY
+template<typename T, typename InitData,
+ typename Unique = InitData, typename Data = T>
+class StaticWithInit {
+public:
+ /** Gets the static. Mutual exclusion is implied by a functional
+ -fthreadsafe-statics
+
+ @return
+ static variable
+ */
+ static T & get() {
+ static T instance = InitData()();
+ return instance;
+ }
+};
+#else
+template<typename T, typename InitData,
+ typename Unique = InitData, typename Data = T>
+class StaticWithInit {
+public:
+ /** Gets the static. Mutual exclusion is performed using the
+ osl global mutex.
+
+ @return
+ static variable
+ */
+ static T & get() {
+ return *rtl_Instance<
+ T, StaticInstanceWithInit,
+ ::osl::MutexGuard, ::osl::GetGlobalMutex,
+ Data, InitData >::create( StaticInstanceWithInit(),
+ ::osl::GetGlobalMutex(),
+ InitData() );
+ }
+private:
+ struct StaticInstanceWithInit {
+ T * operator () ( Data d ) {
+ static T instance(d);
+ return &instance;
+ }
+ };
+};
+#endif
+} // namespace rtl
+
+#endif // INCLUDED_RTL_INSTANCE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/locale.h b/include/rtl/locale.h
new file mode 100644
index 0000000000..141ff87683
--- /dev/null
+++ b/include/rtl/locale.h
@@ -0,0 +1,139 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_LOCALE_H
+#define INCLUDED_RTL_LOCALE_H
+
+#include "sal/config.h"
+
+#include "rtl/ustring.h"
+#include "sal/saldllapi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN32
+# pragma pack(push, 8)
+#endif
+
+/**
+ The implementation structure of a locale. Do not create this structure
+ direct. Only use the functions rtl_locale_register and
+ rtl_locale_setDefault. The strings Language, Country and Variant
+ are constants, so it is not necessary to acquire and release them.
+ */
+typedef struct _rtl_Locale
+{
+ /**
+ Lowercase two-letter ISO 639-1 or three-letter ISO 639-3 code.
+ */
+ rtl_uString * Language;
+ /**
+ uppercase two-letter ISO-3166 code.
+ */
+ rtl_uString * Country;
+ /**
+ Lowercase vendor and browser specific code.
+ */
+ rtl_uString * Variant;
+ /**
+ The merged hash value of the Language, Country and Variant strings.
+ */
+ sal_Int32 HashCode;
+} rtl_Locale;
+
+#if defined( _WIN32)
+#pragma pack(pop)
+#endif
+
+/**
+ Register a locale from language, country and variant.
+ @param language lowercase two-letter ISO 639-1 or three-letter ISO 639-3 code.
+ @param country uppercase two-letter ISO-3166 code. May be null.
+ @param variant vendor and browser specific code. May be null.
+ */
+SAL_DLLPUBLIC rtl_Locale * SAL_CALL rtl_locale_register(
+ const sal_Unicode * language, const sal_Unicode * country, const sal_Unicode * variant );
+
+/**
+ Common method of getting the current default Locale.
+
+ @deprecated LibreOffice itself does not use this anymore, and client code
+ should not have good use for it either. It may eventually be removed.
+ */
+SAL_DLLPUBLIC rtl_Locale * SAL_CALL rtl_locale_getDefault(void);
+
+/**
+ Sets the default.
+
+ <code>setDefault</code> does not reset the host locale.
+
+ @param language lowercase two-letter ISO 639-1 or three-letter ISO 639-3 code.
+ @param country uppercase two-letter ISO-3166 code.
+ @param variant vendor and browser specific code. See class description.
+
+ @deprecated LibreOffice itself does not use this anymore, and client code
+ should not have good use for it either. It may eventually be removed.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_locale_setDefault(
+ const sal_Unicode * language, const sal_Unicode * country, const sal_Unicode * variant );
+
+/**
+ Getter for programmatic name of field,
+ a lowercase two-letter ISO 639-1 or three-letter ISO 639-3 code.
+ @see getDisplayLanguage
+ */
+SAL_DLLPUBLIC rtl_uString * SAL_CALL rtl_locale_getLanguage( rtl_Locale * This );
+
+/**
+ Getter for programmatic name of field,
+ an uppercased two-letter ISO-3166 code.
+ @see getDisplayCountry
+ */
+SAL_DLLPUBLIC rtl_uString * SAL_CALL rtl_locale_getCountry( rtl_Locale * This );
+
+/**
+ Getter for programmatic name of field.
+ @see getDisplayVariant
+ */
+SAL_DLLPUBLIC rtl_uString * SAL_CALL rtl_locale_getVariant( rtl_Locale * This );
+
+/**
+ Returns the hash code of the locale This.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_locale_hashCode( rtl_Locale * This );
+
+/**
+ Returns true if the locals are equal, otherwise false.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_locale_equals( rtl_Locale * This, rtl_Locale * obj );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_RTL_LOCALE_H
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/malformeduriexception.hxx b/include/rtl/malformeduriexception.hxx
new file mode 100644
index 0000000000..7186563111
--- /dev/null
+++ b/include/rtl/malformeduriexception.hxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_MALFORMEDURIEXCEPTION_HXX
+#define INCLUDED_RTL_MALFORMEDURIEXCEPTION_HXX
+
+#include "rtl/ustring.hxx"
+
+namespace rtl {
+
+/** An exception indicating a malformed URI.
+
+ <P>Used when parsing (part of) a URI fails for syntactical reasons.</P>
+ */
+class SAL_EXCEPTION_DLLPUBLIC_EXPORT MalformedUriException
+{
+public:
+ /** Create a MalformedUriException.
+
+ @param rMessage
+ A message containing any details about the exception.
+ */
+ SAL_EXCEPTION_DLLPRIVATE MalformedUriException(
+ rtl::OUString const & rMessage): m_aMessage(rMessage) {}
+
+ SAL_EXCEPTION_DLLPRIVATE MalformedUriException(
+ MalformedUriException const & other): m_aMessage(other.m_aMessage) {}
+
+ SAL_EXCEPTION_DLLPRIVATE ~MalformedUriException() {}
+
+ SAL_EXCEPTION_DLLPRIVATE MalformedUriException operator =(
+ MalformedUriException const & rOther)
+ { m_aMessage = rOther.m_aMessage; return *this; }
+
+ /** Get the message.
+
+ @return
+ A reference to the message. The reference is valid for the lifetime of
+ this MalformedUriException.
+ */
+ SAL_EXCEPTION_DLLPRIVATE rtl::OUString const & getMessage() const
+ { return m_aMessage; }
+
+private:
+ rtl::OUString m_aMessage;
+};
+
+}
+
+#endif // INCLUDED_RTL_MALFORMEDURIEXCEPTION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/math.h b/include/rtl/math.h
new file mode 100644
index 0000000000..1938f037c7
--- /dev/null
+++ b/include/rtl/math.h
@@ -0,0 +1,509 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_MATH_H
+#define INCLUDED_RTL_MATH_H
+
+#include "sal/config.h"
+
+#include "rtl/ustring.h"
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** Formatting modes for rtl_math_doubleToString and rtl_math_doubleToUString
+ and rtl_math_doubleToUStringBuffer.
+ */
+enum rtl_math_StringFormat
+{
+ /** Like sprintf() %E.
+ */
+ rtl_math_StringFormat_E,
+
+ /** Like sprintf() %f.
+ */
+ rtl_math_StringFormat_F,
+
+ /** Like sprintf() %G, 'F' or 'E' format is used depending on which one is
+ more compact.
+ */
+ rtl_math_StringFormat_G,
+
+ /** Automatic, 'F' or 'E' format is used depending on the numeric value to
+ be formatted.
+ */
+ rtl_math_StringFormat_Automatic,
+
+ /** Same 'E', but with only 1 minimum digits in exponent.
+ @since LibreOffice 5.0
+ */
+ rtl_math_StringFormat_E1,
+
+ /** Same 'E', but with only 2 minimum digits in exponent.
+ @since LibreOffice 5.0
+ */
+ rtl_math_StringFormat_E2,
+
+ /** Same 'G', but with only 1 minimum digits in exponent.
+ @since LibreOffice 5.0
+ */
+ rtl_math_StringFormat_G1,
+
+ /** Same 'G', but with only 2 minimum digits in exponent.
+ @since LibreOffice 5.0
+ */
+ rtl_math_StringFormat_G2,
+
+ /** @cond INTERNAL */
+ rtl_math_StringFormat_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+ /** @endcond */
+};
+
+/** Status for rtl_math_stringToDouble and rtl_math_uStringToDouble.
+ */
+enum rtl_math_ConversionStatus
+{
+ /** Conversion was successful.
+ */
+ rtl_math_ConversionStatus_Ok,
+
+ /** Conversion caused overflow or underflow.
+ */
+ rtl_math_ConversionStatus_OutOfRange,
+
+ /** @cond INTERNAL */
+ rtl_math_ConversionStatus_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+ /** @endcond */
+};
+
+/** Rounding modes for rtl_math_round.
+ */
+enum rtl_math_RoundingMode
+{
+ /** Like HalfUp, but corrects roundoff errors, preferred.
+ */
+ rtl_math_RoundingMode_Corrected,
+
+ /** Floor of absolute value, signed return (commercial).
+ */
+ rtl_math_RoundingMode_Down,
+
+ /** Ceil of absolute value, signed return (commercial).
+ */
+ rtl_math_RoundingMode_Up,
+
+ /** Floor of signed value.
+ */
+ rtl_math_RoundingMode_Floor,
+
+ /** Ceil of signed value.
+ */
+ rtl_math_RoundingMode_Ceiling,
+
+ /** Frac <= 0.5 ? floor of abs : ceil of abs, signed return.
+ */
+ rtl_math_RoundingMode_HalfDown,
+
+ /** Frac < 0.5 ? floor of abs : ceil of abs, signed return (mathematical).
+ */
+ rtl_math_RoundingMode_HalfUp,
+
+ /** IEEE rounding mode (statistical).
+ */
+ rtl_math_RoundingMode_HalfEven,
+
+ /** @cond INTERNAL */
+ rtl_math_RoundingMode_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+ /** @endcond */
+};
+
+/** Special decimal places constants for rtl_math_doubleToString and
+ rtl_math_doubleToUString and rtl_math_doubleToUStringBuffer.
+ */
+enum rtl_math_DecimalPlaces
+{
+ /** Value to be used with rtl_math_StringFormat_Automatic.
+ */
+ rtl_math_DecimalPlaces_Max = 0x7ffffff,
+
+ /** Value to be used with rtl_math_StringFormat_G.
+ In fact the same value as rtl_math_DecimalPlaces_Max, just an alias for
+ better understanding.
+ */
+ rtl_math_DecimalPlaces_DefaultSignificance = rtl_math_DecimalPlaces_Max
+};
+
+
+/** Conversions analogous to sprintf() using internal rounding.
+
+ +/-HUGE_VAL are converted to "INF" and "-INF", NAN values are
+ converted to "NaN".
+
+ @param pResult
+ Returns the resulting byte string. Must itself not be null, and must point
+ to either null or a valid string.
+
+ @param pResultCapacity
+ If null, pResult is considered to point to immutable strings, and a new
+ string will be allocated in pResult.
+ If non-null, it points to the current capacity of pResult, which is
+ considered to point to a string buffer (pResult must not itself be null in
+ this case, and must point to a string that has room for the given capacity).
+ The string representation of the given double value is inserted into pResult
+ at position nResultOffset. If pResult's current capacity is too small, a
+ new string buffer will be allocated in pResult as necessary, and
+ pResultCapacity will contain the new capacity on return.
+
+ @param nResultOffset
+ If pResult is used as a string buffer (i.e., pResultCapacity is non-null),
+ nResultOffset specifies the insertion offset within the buffer. Ignored
+ otherwise.
+
+ @param fValue
+ The value to convert.
+
+ @param eFormat
+ The format to use, one of rtl_math_StringFormat.
+
+ @param nDecPlaces
+ The number of decimals to be generated. Effectively fValue is rounded at
+ this position, specifying nDecPlaces <= 0 accordingly rounds the value
+ before the decimal point and fills with zeros.
+ If eFormat == rtl_math_StringFormat_Automatic and nDecPlaces ==
+ rtl_math_DecimalPlaces_Max, the highest number of significant decimals
+ possible is generated.
+ If eFormat == rtl_math_StringFormat_G, nDecPlaces specifies the number of
+ significant digits instead. If nDecPlaces ==
+ rtl_math_DecimalPlaces_DefaultSignificance, the default number (currently 6
+ as implemented by most libraries) of significant digits is generated.
+ According to the ANSI C90 standard the E style will be used only if the
+ exponent resulting from the conversion is less than -4 or greater than or
+ equal to the precision. However, as opposed to the ANSI standard, trailing
+ zeros are not necessarily removed from the fractional portion of the result
+ unless bEraseTrailingDecZeros == true was specified.
+
+ @param cDecSeparator
+ The decimal separator.
+
+ @param pGroups
+ Either null (no grouping is used), or a null-terminated list of group
+ lengths. Each group length must be strictly positive. If the number of
+ digits in a conversion exceeds the specified range, the last (highest) group
+ length is repeated as needed. Values are applied from right to left, for a
+ grouping of 1,00,00,000 you'd have to specify pGroups={3,2,0}.
+
+ @param cGroupSeparator
+ The group separator. Ignored if pGroups is null.
+
+ @param bEraseTrailingDecZeros
+ Trailing zeros in decimal places are erased.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_math_doubleToString(rtl_String ** pResult,
+ sal_Int32 * pResultCapacity,
+ sal_Int32 nResultOffset, double fValue,
+ enum rtl_math_StringFormat eFormat,
+ sal_Int32 nDecPlaces,
+ char cDecSeparator,
+ sal_Int32 const * pGroups,
+ char cGroupSeparator,
+ sal_Bool bEraseTrailingDecZeros)
+ SAL_THROW_EXTERN_C();
+
+/** Conversions analogous to sprintf() using internal rounding.
+
+ +/-HUGE_VAL are converted to "INF" and "-INF", NAN values are
+ converted to "NaN".
+
+ @param pResult
+ Returns the resulting Unicode string. Must itself not be null, and must
+ point to either null or a valid string.
+
+ @param pResultCapacity
+ If null, pResult is considered to point to immutable strings, and a new
+ string will be allocated in pResult.
+ If non-null, it points to the current capacity of pResult, which is
+ considered to point to a string buffer (pResult must not itself be null in
+ this case, and must point to a string that has room for the given capacity).
+ The string representation of the given double value is inserted into pResult
+ at position nResultOffset. If pResult's current capacity is too small, a
+ new string buffer will be allocated in pResult as necessary, and
+ pResultCapacity will contain the new capacity on return.
+
+ @param nResultOffset
+ If pResult is used as a string buffer (i.e., pResultCapacity is non-null),
+ nResultOffset specifies the insertion offset within the buffer. Ignored
+ otherwise.
+
+ @param fValue
+ The value to convert.
+
+ @param eFormat
+ The format to use, one of rtl_math_StringFormat.
+
+ @param nDecPlaces
+ The number of decimals to be generated. Effectively fValue is rounded at
+ this position, specifying nDecPlaces <= 0 accordingly rounds the value
+ before the decimal point and fills with zeros.
+ If eFormat == rtl_math_StringFormat_Automatic and nDecPlaces ==
+ rtl_math_DecimalPlaces_Max, the highest number of significant decimals
+ possible is generated.
+ If eFormat == rtl_math_StringFormat_G, nDecPlaces specifies the number of
+ significant digits instead. If nDecPlaces ==
+ rtl_math_DecimalPlaces_DefaultSignificance, the default number (currently 6
+ as implemented by most libraries) of significant digits is generated.
+ According to the ANSI C90 standard the E style will be used only if the
+ exponent resulting from the conversion is less than -4 or greater than or
+ equal to the precision. However, as opposed to the ANSI standard, trailing
+ zeros are not necessarily removed from the fractional portion of the result
+ unless bEraseTrailingDecZeros == true was specified.
+
+ @param cDecSeparator
+ The decimal separator.
+
+ @param pGroups
+ Either null (no grouping is used), or a null-terminated list of group
+ lengths. Each group length must be strictly positive. If the number of
+ digits in a conversion exceeds the specified range, the last (highest) group
+ length is repeated as needed. Values are applied from right to left, for a
+ grouping of 1,00,00,000 you'd have to specify pGroups={3,2,0}.
+
+ @param cGroupSeparator
+ The group separator. Ignored if pGroups is null.
+
+ @param bEraseTrailingDecZeros
+ Trailing zeros in decimal places are erased.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_math_doubleToUString(rtl_uString ** pResult,
+ sal_Int32 * pResultCapacity,
+ sal_Int32 nResultOffset, double fValue,
+ enum rtl_math_StringFormat eFormat,
+ sal_Int32 nDecPlaces,
+ sal_Unicode cDecSeparator,
+ sal_Int32 const * pGroups,
+ sal_Unicode cGroupSeparator,
+ sal_Bool bEraseTrailingDecZeros)
+ SAL_THROW_EXTERN_C();
+
+/** Conversion analogous to strtod(), convert a string representing a
+ decimal number into a double value.
+
+ Leading tabs (0x09) and spaces (0x20) are eaten. Overflow returns
+ +/-HUGE_VAL, underflow 0. In both cases pStatus is set to
+ rtl_math_ConversionStatus_OutOfRange, otherwise to
+ rtl_math_ConversionStatus_Ok. "INF", "-INF" and "+/-1.#INF" are
+ recognized as +/-HUGE_VAL, pStatus is set to
+ rtl_math_ConversionStatus_OutOfRange. "NaN" and "+/-1.#NAN" are
+ recognized and the value is set to +/-NAN, pStatus is set to
+ rtl_math_ConversionStatus_Ok.
+
+ @param pBegin
+ Points to the start of the byte string to convert. Must not be null.
+
+ @param pEnd
+ Points one past the end of the byte string to convert. The condition
+ pEnd >= pBegin must hold.
+
+ @param cDecSeparator
+ The decimal separator.
+
+ @param cGroupSeparator
+ The group (aka thousands) separator.
+
+ @param pStatus
+ If non-null, returns the status of the conversion.
+
+ @param pParsedEnd
+ If non-null, returns one past the position of the last character parsed
+ away. Thus if [pBegin..pEnd) only contains the numerical string to be
+ parsed, *pParsedEnd == pEnd on return. If no numerical (sub-)string is
+ found, *pParsedEnd == pBegin on return, even if there was leading
+ whitespace.
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_math_stringToDouble(
+ char const * pBegin, char const * pEnd, char cDecSeparator,
+ char cGroupSeparator, enum rtl_math_ConversionStatus * pStatus,
+ char const ** pParsedEnd) SAL_THROW_EXTERN_C();
+
+/** Conversion analogous to strtod(), convert a string representing a
+ decimal number into a double value.
+
+ Leading tabs (U+0009) and spaces (U+0020) are eaten. Overflow returns
+ +/-HUGE_VAL, underflow 0. In both cases pStatus is set to
+ rtl_math_ConversionStatus_OutOfRange, otherwise to
+ rtl_math_ConversionStatus_Ok. "INF", "-INF" and "+/-1.#INF" are
+ recognized as +/-HUGE_VAL, pStatus is set to
+ rtl_math_ConversionStatus_OutOfRange. "NaN" and "+/-1.#NAN" are
+ recognized and the value is set to +/-NAN, pStatus is set to
+ rtl_math_ConversionStatus_Ok.
+
+ @param pBegin
+ Points to the start of the Unicode string to convert. Must not be null.
+
+ @param pEnd
+ Points one past the end of the Unicode string to convert. The condition
+ pEnd >= pBegin must hold.
+
+ @param cDecSeparator
+ The decimal separator.
+
+ @param cGroupSeparator
+ The group (aka thousands) separator.
+
+ @param pStatus
+ If non-null, returns the status of the conversion.
+
+ @param pParsedEnd
+ If non-null, returns one past the position of the last character parsed
+ away. Thus if [pBegin..pEnd) only contains the numerical string to be
+ parsed, *pParsedEnd == pEnd on return. If no numerical (sub-)string is
+ found, *pParsedEnd == pBegin on return, even if there was leading
+ whitespace.
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_math_uStringToDouble(
+ sal_Unicode const * pBegin, sal_Unicode const * pEnd,
+ sal_Unicode cDecSeparator, sal_Unicode cGroupSeparator,
+ enum rtl_math_ConversionStatus * pStatus, sal_Unicode const ** pParsedEnd)
+ SAL_THROW_EXTERN_C();
+
+/** Rounds a double value.
+
+ @param fValue
+ Specifies the value to be rounded.
+
+ @param nDecPlaces
+ Specifies the decimal place where rounding occurs. Must be in the range
+ -20 to +20, inclusive. Negative if rounding occurs before the decimal
+ point.
+
+ @param eMode
+ Specifies the rounding mode.
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_math_round(double fValue, int nDecPlaces,
+ enum rtl_math_RoundingMode eMode)
+ SAL_THROW_EXTERN_C();
+
+/** Scales fVal to a power of 10 without calling pow() or div() for nExp values
+ between -16 and +16, providing a faster method.
+
+ @param fValue
+ The value to be raised.
+
+ @param nExp
+ The exponent.
+
+ @return
+ fVal * pow(10.0, nExp)
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_math_pow10Exp(double fValue, int nExp) SAL_THROW_EXTERN_C();
+
+/** Rounds value to 15 significant decimal digits.
+
+ @param fValue
+ The value to be rounded.
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_math_approxValue(double fValue) SAL_THROW_EXTERN_C();
+
+/** Test equality of two values with an accuracy of the magnitude of the
+ given values scaled by 2^-48 (4 bits roundoff stripped).
+
+ @attention
+ approxEqual( value!=0.0, 0.0 ) _never_ yields true.
+
+ @since LibreOffice 5.3
+ */
+SAL_DLLPUBLIC bool SAL_CALL rtl_math_approxEqual(double a, double b) SAL_THROW_EXTERN_C();
+
+/** Returns more accurate e^x-1 for x near 0 than calculating directly.
+
+ expm1 is part of the C99 standard, but not provided by some compilers.
+
+ @param fValue
+ The value x in the term e^x-1.
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_math_expm1(double fValue) SAL_THROW_EXTERN_C();
+
+/** Returns more accurate log(1+x) for x near 0 than calculating directly.
+
+ log1p is part of the C99 standard, but not provided by some compilers.
+
+ @param fValue
+ The value x in the term log(1+x).
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_math_log1p(double fValue) SAL_THROW_EXTERN_C();
+
+/** Returns more accurate atanh(x) for x near 0 than calculating
+ 0.5*log((1+x)/(1-x)).
+
+ atanh is part of the C99 standard, but not provided by some compilers.
+
+ @param fValue
+ The value x in the term atanh(x).
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_math_atanh(double fValue) SAL_THROW_EXTERN_C();
+
+/** Returns values of the Errorfunction erf.
+
+ erf is part of the C99 standard, but not provided by some compilers.
+
+ @param fValue
+ The value x in the term erf(x).
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_math_erf(double fValue) SAL_THROW_EXTERN_C();
+
+/** Returns values of the complement Errorfunction erfc.
+
+ erfc is part of the C99 standard, but not provided by some compilers.
+
+ @param fValue
+ The value x in the term erfc(x).
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_math_erfc(double fValue) SAL_THROW_EXTERN_C();
+
+/** Returns values of the inverse hyperbolic sine.
+
+ asinh is part of the C99 standard, but not provided by some compilers.
+
+ @param fValue
+ The value x in the term asinh(x).
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_math_asinh(double fValue) SAL_THROW_EXTERN_C();
+
+/** Returns values of the inverse hyperbolic cosine.
+
+ acosh is part of the C99 standard, but not provided by some compilers.
+
+ @param fValue
+ The value x in the term acosh(x).
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_math_acosh(double fValue) SAL_THROW_EXTERN_C();
+
+#if defined __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* INCLUDED_RTL_MATH_H */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/math.hxx b/include/rtl/math.hxx
new file mode 100644
index 0000000000..661ddf1d13
--- /dev/null
+++ b/include/rtl/math.hxx
@@ -0,0 +1,511 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_MATH_HXX
+#define INCLUDED_RTL_MATH_HXX
+
+#include "rtl/math.h"
+#include "rtl/strbuf.hxx"
+#include "rtl/string.hxx"
+#include "rtl/ustring.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "sal/mathconf.h"
+#include "sal/types.h"
+
+#include <cstddef>
+#include <math.h>
+
+namespace rtl {
+
+namespace math {
+
+/** A wrapper around rtl_math_doubleToString.
+ */
+inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
+ sal_Int32 nDecPlaces,
+ char cDecSeparator,
+ sal_Int32 const * pGroups,
+ char cGroupSeparator,
+ bool bEraseTrailingDecZeros = false)
+{
+ rtl::OString aResult;
+ rtl_math_doubleToString(&aResult.pData, NULL, 0, fValue, eFormat, nDecPlaces,
+ cDecSeparator, pGroups, cGroupSeparator,
+ bEraseTrailingDecZeros);
+ return aResult;
+}
+
+/** A wrapper around rtl_math_doubleToString, with no grouping.
+ */
+inline rtl::OString doubleToString(double fValue, rtl_math_StringFormat eFormat,
+ sal_Int32 nDecPlaces,
+ char cDecSeparator,
+ bool bEraseTrailingDecZeros = false)
+{
+ rtl::OString aResult;
+ rtl_math_doubleToString(&aResult.pData, NULL, 0, fValue, eFormat, nDecPlaces,
+ cDecSeparator, NULL, 0, bEraseTrailingDecZeros);
+ return aResult;
+}
+
+/** A wrapper around rtl_math_doubleToString that appends to an
+ rtl::OStringBuffer.
+
+ @since LibreOffice 5.4
+*/
+inline void doubleToStringBuffer(
+ rtl::OStringBuffer& rBuffer, double fValue, rtl_math_StringFormat eFormat,
+ sal_Int32 nDecPlaces, char cDecSeparator, sal_Int32 const * pGroups,
+ char cGroupSeparator, bool bEraseTrailingDecZeros = false)
+{
+ rtl_String ** pData;
+ sal_Int32 * pCapacity;
+ rBuffer.accessInternals(&pData, &pCapacity);
+ rtl_math_doubleToString(
+ pData, pCapacity, rBuffer.getLength(), fValue, eFormat, nDecPlaces,
+ cDecSeparator, pGroups, cGroupSeparator, bEraseTrailingDecZeros);
+}
+
+/** A wrapper around rtl_math_doubleToString that appends to an
+ rtl::OStringBuffer, with no grouping.
+
+ @since LibreOffice 5.4
+*/
+inline void doubleToStringBuffer(
+ rtl::OStringBuffer& rBuffer, double fValue, rtl_math_StringFormat eFormat,
+ sal_Int32 nDecPlaces, char cDecSeparator,
+ bool bEraseTrailingDecZeros = false)
+{
+ rtl_String ** pData;
+ sal_Int32 * pCapacity;
+ rBuffer.accessInternals(&pData, &pCapacity);
+ rtl_math_doubleToString(
+ pData, pCapacity, rBuffer.getLength(), fValue, eFormat, nDecPlaces,
+ cDecSeparator, NULL, 0, bEraseTrailingDecZeros);
+}
+
+/** A wrapper around rtl_math_doubleToUString.
+ */
+inline rtl::OUString doubleToUString(double fValue,
+ rtl_math_StringFormat eFormat,
+ sal_Int32 nDecPlaces,
+ sal_Unicode cDecSeparator,
+ sal_Int32 const * pGroups,
+ sal_Unicode cGroupSeparator,
+ bool bEraseTrailingDecZeros = false)
+{
+ rtl::OUString aResult;
+ rtl_math_doubleToUString(&aResult.pData, NULL, 0, fValue, eFormat, nDecPlaces,
+ cDecSeparator, pGroups, cGroupSeparator,
+ bEraseTrailingDecZeros);
+ return aResult;
+}
+
+/** A wrapper around rtl_math_doubleToUString, with no grouping.
+ */
+inline rtl::OUString doubleToUString(double fValue,
+ rtl_math_StringFormat eFormat,
+ sal_Int32 nDecPlaces,
+ sal_Unicode cDecSeparator,
+ bool bEraseTrailingDecZeros = false)
+{
+ rtl::OUString aResult;
+ rtl_math_doubleToUString(&aResult.pData, NULL, 0, fValue, eFormat, nDecPlaces,
+ cDecSeparator, NULL, 0, bEraseTrailingDecZeros);
+ return aResult;
+}
+
+/** A wrapper around rtl_math_doubleToUString that appends to an
+ rtl::OUStringBuffer.
+ */
+inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
+ rtl_math_StringFormat eFormat,
+ sal_Int32 nDecPlaces,
+ sal_Unicode cDecSeparator,
+ sal_Int32 const * pGroups,
+ sal_Unicode cGroupSeparator,
+ bool bEraseTrailingDecZeros = false)
+{
+ rtl_uString ** pData;
+ sal_Int32 * pCapacity;
+ rBuffer.accessInternals( &pData, &pCapacity );
+ rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
+ eFormat, nDecPlaces, cDecSeparator, pGroups,
+ cGroupSeparator, bEraseTrailingDecZeros);
+}
+
+/** A wrapper around rtl_math_doubleToUString that appends to an
+ rtl::OUStringBuffer, with no grouping.
+ */
+inline void doubleToUStringBuffer( rtl::OUStringBuffer& rBuffer, double fValue,
+ rtl_math_StringFormat eFormat,
+ sal_Int32 nDecPlaces,
+ sal_Unicode cDecSeparator,
+ bool bEraseTrailingDecZeros = false)
+{
+ rtl_uString ** pData;
+ sal_Int32 * pCapacity;
+ rBuffer.accessInternals( &pData, &pCapacity );
+ rtl_math_doubleToUString( pData, pCapacity, rBuffer.getLength(), fValue,
+ eFormat, nDecPlaces, cDecSeparator, NULL, 0,
+ bEraseTrailingDecZeros);
+}
+
+/** A wrapper around rtl_math_stringToDouble.
+ */
+#ifdef LIBO_INTERNAL_ONLY
+inline double stringToDouble(std::string_view aString,
+ char cDecSeparator, char cGroupSeparator,
+ rtl_math_ConversionStatus * pStatus = NULL,
+ sal_Int32 * pParsedEnd = NULL)
+{
+ char const * pBegin = aString.data();
+ char const * pEnd;
+ double fResult = rtl_math_stringToDouble(pBegin,
+ pBegin + aString.size(),
+ cDecSeparator, cGroupSeparator,
+ pStatus, &pEnd);
+ if (pParsedEnd != NULL)
+ *pParsedEnd = static_cast<sal_Int32>(pEnd - pBegin);
+ return fResult;
+}
+#else
+inline double stringToDouble(rtl::OString const & rString,
+ char cDecSeparator, char cGroupSeparator,
+ rtl_math_ConversionStatus * pStatus = NULL,
+ sal_Int32 * pParsedEnd = NULL)
+{
+ char const * pBegin = rString.getStr();
+ char const * pEnd;
+ double fResult = rtl_math_stringToDouble(pBegin,
+ pBegin + rString.getLength(),
+ cDecSeparator, cGroupSeparator,
+ pStatus, &pEnd);
+ if (pParsedEnd != NULL)
+ *pParsedEnd = static_cast<sal_Int32>(pEnd - pBegin);
+ return fResult;
+}
+#endif
+
+
+/** A wrapper around rtl_math_uStringToDouble.
+ */
+#ifdef LIBO_INTERNAL_ONLY
+inline double stringToDouble(std::u16string_view aString,
+ sal_Unicode cDecSeparator,
+ sal_Unicode cGroupSeparator,
+ rtl_math_ConversionStatus * pStatus = NULL,
+ sal_Int32 * pParsedEnd = NULL)
+{
+ sal_Unicode const * pBegin = aString.data();
+ sal_Unicode const * pEnd;
+ double fResult = rtl_math_uStringToDouble(pBegin,
+ pBegin + aString.size(),
+ cDecSeparator, cGroupSeparator,
+ pStatus, &pEnd);
+ if (pParsedEnd != NULL)
+ *pParsedEnd = static_cast<sal_Int32>(pEnd - pBegin);
+ return fResult;
+}
+#else
+inline double stringToDouble(rtl::OUString const & rString,
+ sal_Unicode cDecSeparator,
+ sal_Unicode cGroupSeparator,
+ rtl_math_ConversionStatus * pStatus = NULL,
+ sal_Int32 * pParsedEnd = NULL)
+{
+ sal_Unicode const * pBegin = rString.getStr();
+ sal_Unicode const * pEnd;
+ double fResult = rtl_math_uStringToDouble(pBegin,
+ pBegin + rString.getLength(),
+ cDecSeparator, cGroupSeparator,
+ pStatus, &pEnd);
+ if (pParsedEnd != NULL)
+ *pParsedEnd = static_cast<sal_Int32>(pEnd - pBegin);
+ return fResult;
+}
+#endif
+
+/** A wrapper around rtl_math_round.
+ */
+inline double round(
+ double fValue, int nDecPlaces = 0,
+ rtl_math_RoundingMode eMode = rtl_math_RoundingMode_Corrected)
+{
+ return rtl_math_round(fValue, nDecPlaces, eMode);
+}
+
+/** A wrapper around rtl_math_pow10Exp.
+ */
+inline double pow10Exp(double fValue, int nExp)
+{
+ return rtl_math_pow10Exp(fValue, nExp);
+}
+
+/** A wrapper around rtl_math_approxValue.
+ */
+inline double approxValue(double fValue)
+{
+ return rtl_math_approxValue(fValue);
+}
+
+/** A wrapper around rtl_math_expm1.
+ */
+inline double expm1(double fValue)
+{
+ return rtl_math_expm1(fValue);
+}
+
+/** A wrapper around rtl_math_log1p.
+ */
+inline double log1p(double fValue)
+{
+ return rtl_math_log1p(fValue);
+}
+
+/** A wrapper around rtl_math_atanh.
+ */
+inline double atanh(double fValue)
+{
+ return rtl_math_atanh(fValue);
+}
+
+/** A wrapper around rtl_math_erf.
+ */
+inline double erf(double fValue)
+{
+ return rtl_math_erf(fValue);
+}
+
+/** A wrapper around rtl_math_erfc.
+ */
+inline double erfc(double fValue)
+{
+ return rtl_math_erfc(fValue);
+}
+
+/** A wrapper around rtl_math_asinh.
+ */
+inline double asinh(double fValue)
+{
+ return rtl_math_asinh(fValue);
+}
+
+/** A wrapper around rtl_math_acosh.
+ */
+inline double acosh(double fValue)
+{
+ return rtl_math_acosh(fValue);
+}
+
+/** A wrapper around rtl_math_approxEqual.
+ */
+inline bool approxEqual(double a, double b)
+{
+ return rtl_math_approxEqual( a, b );
+}
+
+/** Test equality of two values with an accuracy defined by nPrec
+
+ @attention
+ approxEqual( value!=0.0, 0.0 ) _never_ yields true.
+ */
+inline bool approxEqual(double a, double b, sal_Int16 nPrec)
+{
+ if ( a == b )
+ return true;
+ double x = a - b;
+ return (x < 0.0 ? -x : x)
+ < ((a < 0.0 ? -a : a) * (1.0 / (pow(2.0, nPrec))));
+}
+
+/** Add two values.
+
+ If signs differ and the absolute values are equal according to approxEqual()
+ the method returns 0.0 instead of calculating the sum.
+
+ If you wanted to sum up multiple values it would be convenient not to call
+ approxAdd() for each value but instead remember the first value not equal to
+ 0.0, add all other values using normal + operator, and with the result and
+ the remembered value call approxAdd().
+ */
+inline double approxAdd(double a, double b)
+{
+ if ( ((a < 0.0 && b > 0.0) || (b < 0.0 && a > 0.0))
+ && approxEqual( a, -b ) )
+ return 0.0;
+ return a + b;
+}
+
+/** Subtract two values (a-b).
+
+ If signs are identical and the values are equal according to approxEqual()
+ the method returns 0.0 instead of calculating the subtraction.
+ */
+inline double approxSub(double a, double b)
+{
+ if ( ((a < 0.0 && b < 0.0) || (a > 0.0 && b > 0.0)) && approxEqual( a, b ) )
+ return 0.0;
+ return a - b;
+}
+
+/** floor() method taking approxValue() into account.
+
+ Use for expected integer values being calculated by double functions.
+ */
+inline double approxFloor(double a)
+{
+ return floor( approxValue( a ));
+}
+
+/** ceil() method taking approxValue() into account.
+
+ Use for expected integer values being calculated by double functions.
+ */
+inline double approxCeil(double a)
+{
+ return ceil( approxValue( a ));
+}
+
+/** Tests whether a value is neither INF nor NAN.
+ */
+inline bool isFinite(double d)
+{
+ return SAL_MATH_FINITE(d);
+}
+
+/** If a value represents +INF or -INF.
+
+ The sign bit may be queried with isSignBitSet().
+
+ If isFinite(d)==false and isInf(d)==false then NAN.
+ */
+inline bool isInf(double d)
+{
+ // exponent==0x7ff fraction==0
+ return !SAL_MATH_FINITE(d) &&
+ (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi == 0)
+ && (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
+ == 0);
+}
+
+/** Test on any QNAN or SNAN.
+ */
+inline bool isNan(double d)
+{
+ // exponent==0x7ff fraction!=0
+ return !SAL_MATH_FINITE(d) && (
+ (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_hi != 0)
+ || (reinterpret_cast< sal_math_Double * >(&d)->inf_parts.fraction_lo
+ != 0) );
+}
+
+/** If the sign bit is set.
+ */
+inline bool isSignBitSet(double d)
+{
+ return reinterpret_cast< sal_math_Double * >(&d)->inf_parts.sign != 0;
+}
+
+/** Set to +INF if bNegative==false or -INF if bNegative==true.
+ */
+inline void setInf(double * pd, bool bNegative)
+{
+ union
+ {
+ double sd;
+ sal_math_Double md;
+ };
+ md.w32_parts.msw = bNegative ? 0xFFF00000 : 0x7FF00000;
+ md.w32_parts.lsw = 0;
+ *pd = sd;
+}
+
+/** Set a QNAN.
+ */
+inline void setNan(double * pd)
+{
+ union
+ {
+ double sd;
+ sal_math_Double md;
+ };
+ md.w32_parts.msw = 0x7FFFFFFF;
+ md.w32_parts.lsw = 0xFFFFFFFF;
+ *pd = sd;
+}
+
+/** If a value is a valid argument for sin(), cos(), tan().
+
+ IEEE 754 specifies that absolute values up to 2^64 (=1.844e19) for the
+ radian must be supported by trigonometric functions. Unfortunately, at
+ least on x86 architectures, the FPU doesn't generate an error pattern for
+ values >2^64 but produces erroneous results instead and sets only the
+ "invalid operation" (IM) flag in the status word :-( Thus the application
+ has to handle it itself.
+ */
+inline bool isValidArcArg(double d)
+{
+ return fabs(d)
+ <= (static_cast< double >(static_cast< unsigned long >(0x80000000))
+ * static_cast< double >(static_cast< unsigned long >(0x80000000))
+ * 4);
+}
+
+/** Safe sin(), returns NAN if not valid.
+ */
+inline double sin(double d)
+{
+ if ( isValidArcArg( d ) )
+ return ::sin( d );
+ setNan( &d );
+ return d;
+}
+
+/** Safe cos(), returns NAN if not valid.
+ */
+inline double cos(double d)
+{
+ if ( isValidArcArg( d ) )
+ return ::cos( d );
+ setNan( &d );
+ return d;
+}
+
+/** Safe tan(), returns NAN if not valid.
+ */
+inline double tan(double d)
+{
+ if ( isValidArcArg( d ) )
+ return ::tan( d );
+ setNan( &d );
+ return d;
+}
+
+}
+
+}
+
+#endif // INCLUDED_RTL_MATH_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/process.h b/include/rtl/process.h
new file mode 100644
index 0000000000..0a28338631
--- /dev/null
+++ b/include/rtl/process.h
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+#ifndef INCLUDED_RTL_PROCESS_H
+#define INCLUDED_RTL_PROCESS_H
+
+#include "sal/config.h"
+
+#include "osl/process.h"
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ gets a 16-byte fixed size identifier which is guaranteed not to change
+ during the current process.
+
+ The current implementation creates a 16-byte uuid without using
+ the ethernet address of system. Thus the
+ identifier is different from identifiers created
+ in other processes with a very probability.
+
+ @param pTargetUUID 16 byte of memory
+ @see rtl_createUuid()
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_getGlobalProcessId( sal_uInt8 *pTargetUUID );
+
+/** Get the nArg-th command-line argument passed to the main-function of this process.
+
+ This function differs from osl_getCommandArg() in filtering any bootstrap values
+ given by command args, that means that all arguments starting with "-env:" will be
+ ignored by this function.
+
+ @param[in] nArg The number of the argument to return.
+ @param[out] strCommandArg The string receives the nArg-th command-line argument.
+ @retval osl_Process_E_None or does not return.
+ @see osl_getCommandArg()
+ @see rtl_getAppCommandArgCount()
+*/
+SAL_DLLPUBLIC oslProcessError SAL_CALL rtl_getAppCommandArg(sal_uInt32 nArg, rtl_uString **strCommandArg);
+
+/** Returns the number of command line arguments at process start.
+
+ This function differs from osl_getCommandArg() in filtering any bootstrap values
+ given by command args, that means that all arguments starting with "-env:" will be
+ ignored by this function.
+
+ @return the number of commandline arguments passed to the main-function of this process.
+ @see osl_getCommandArgCount()
+ @see rtl_getAppCommandArg()
+*/
+SAL_DLLPUBLIC sal_uInt32 SAL_CALL rtl_getAppCommandArgCount(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/random.h b/include/rtl/random.h
new file mode 100644
index 0000000000..cc7cf79435
--- /dev/null
+++ b/include/rtl/random.h
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_RANDOM_H
+#define INCLUDED_RTL_RANDOM_H
+
+#include "sal/config.h"
+
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Random Pool opaque type.
+ */
+typedef void* rtlRandomPool;
+
+
+/** Error Code enumeration.
+ */
+enum __rtl_RandomError
+{
+ rtl_Random_E_None,
+ rtl_Random_E_Argument,
+ rtl_Random_E_Memory,
+ rtl_Random_E_Unknown,
+ rtl_Random_E_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+};
+
+/** Error Code type.
+ */
+typedef enum __rtl_RandomError rtlRandomError;
+
+
+/** Create a Random Pool.
+ @return initialized Random Pool, or NULL upon failure.
+ */
+SAL_DLLPUBLIC rtlRandomPool SAL_CALL rtl_random_createPool (void) SAL_THROW_EXTERN_C();
+
+
+/** Destroy a Random Pool.
+ @param[in] Pool a Random Pool.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_random_destroyPool (
+ rtlRandomPool Pool
+) SAL_THROW_EXTERN_C();
+
+
+/** Add bytes to a Random Pool.
+ @param[in] Pool a Random Pool.
+ @param[in] Buffer a buffer containing the bytes to add.
+ @param[in] Bytes the number of bytes to read from the buffer.
+ @retval rtl_Random_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlRandomError SAL_CALL rtl_random_addBytes (
+ rtlRandomPool Pool,
+ const void *Buffer,
+ sal_Size Bytes
+) SAL_THROW_EXTERN_C();
+
+
+/** Retrieve bytes from a Random Pool.
+ @param[in] Pool a Random Pool.
+ @param[in,out] Buffer a buffer to receive the random bytes.
+ @param[in] Bytes the number of bytes to write to the buffer.
+ @retval rtl_Random_E_None upon success.
+ */
+SAL_DLLPUBLIC rtlRandomError SAL_CALL rtl_random_getBytes (
+ rtlRandomPool Pool,
+ void *Buffer,
+ sal_Size Bytes
+) SAL_THROW_EXTERN_C();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_RTL_RANDOM_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/ref.hxx b/include/rtl/ref.hxx
new file mode 100644
index 0000000000..38dfe3769e
--- /dev/null
+++ b/include/rtl/ref.hxx
@@ -0,0 +1,316 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_REF_HXX
+#define INCLUDED_RTL_REF_HXX
+
+#include "sal/config.h"
+
+#include <cassert>
+#include <cstddef>
+#include <functional>
+#ifdef LIBO_INTERNAL_ONLY
+#include <type_traits>
+#include "com/sun/star/uno/Reference.h"
+#endif
+
+#include "sal/types.h"
+
+namespace rtl
+{
+
+/** Template reference class for reference type.
+*/
+template <class reference_type>
+class Reference
+{
+ /** The <b>reference_type</b> body pointer.
+ */
+ reference_type * m_pBody;
+
+
+public:
+ /** Constructor...
+ */
+ Reference()
+ : m_pBody (NULL)
+ {}
+
+
+ /** Constructor...
+ */
+ Reference (reference_type * pBody, __sal_NoAcquire)
+ : m_pBody (pBody)
+ {
+ }
+
+ /** Constructor...
+ */
+ Reference (reference_type * pBody)
+ : m_pBody (pBody)
+ {
+ if (m_pBody)
+ m_pBody->acquire();
+ }
+
+ /** Copy constructor...
+ */
+ Reference (const Reference<reference_type> & handle)
+ : m_pBody (handle.m_pBody)
+ {
+ if (m_pBody)
+ m_pBody->acquire();
+ }
+
+#ifdef LIBO_INTERNAL_ONLY
+ /** Move constructor...
+ */
+ Reference (Reference<reference_type> && handle) noexcept
+ : m_pBody (handle.m_pBody)
+ {
+ handle.m_pBody = nullptr;
+ }
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+ /** Up-casting conversion constructor: Copies interface reference.
+
+ Does not work for up-casts to ambiguous bases.
+
+ @param rRef another reference
+ */
+ template< class derived_type >
+ inline Reference(
+ const Reference< derived_type > & rRef,
+ std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
+ : m_pBody (rRef.get())
+ {
+ if (m_pBody)
+ m_pBody->acquire();
+ }
+
+ /** Up-casting conversion operator to convert to css::uno::Interface
+
+ Does not work for up-casts to ambiguous bases.
+ */
+ template< class super_type,
+ std::enable_if_t<std::is_base_of_v<super_type, reference_type>, int> = 0 >
+ inline operator css::uno::Reference<super_type>() const
+ {
+ return css::uno::Reference<super_type>(m_pBody);
+ }
+#endif
+
+ /** Destructor...
+ */
+ ~Reference() COVERITY_NOEXCEPT_FALSE
+ {
+ if (m_pBody)
+ m_pBody->release();
+ }
+
+ /** Set...
+ Similar to assignment.
+ */
+ Reference<reference_type> &
+ SAL_CALL set (reference_type * pBody)
+ {
+ if (pBody)
+ pBody->acquire();
+ reference_type * const pOld = m_pBody;
+ m_pBody = pBody;
+ if (pOld)
+ pOld->release();
+ return *this;
+ }
+
+ /** Assignment.
+ Unbinds this instance from its body (if bound) and
+ bind it to the body represented by the handle.
+ */
+ Reference<reference_type> &
+ SAL_CALL operator= (const Reference<reference_type> & handle)
+ {
+ return set( handle.m_pBody );
+ }
+
+#ifdef LIBO_INTERNAL_ONLY
+ /** Assignment.
+ * Unbinds this instance from its body (if bound),
+ * bind it to the body represented by the handle, and
+ * set the body represented by the handle to nullptr.
+ */
+ Reference<reference_type> &
+ operator= (Reference<reference_type> && handle)
+ {
+ // self-movement guts ourself
+ if (m_pBody)
+ m_pBody->release();
+ m_pBody = handle.m_pBody;
+ handle.m_pBody = nullptr;
+ return *this;
+ }
+#endif
+
+ /** Assignment...
+ */
+ Reference<reference_type> &
+ SAL_CALL operator= (reference_type * pBody)
+ {
+ return set( pBody );
+ }
+
+ /** Unbind the body from this handle.
+ Note that for a handle representing a large body,
+ "handle.clear().set(new body());" _might_
+ perform a little bit better than "handle.set(new body());",
+ since in the second case two large objects exist in memory
+ (the old body and the new body).
+ */
+ Reference<reference_type> & SAL_CALL clear()
+ {
+ if (m_pBody)
+ {
+ reference_type * const pOld = m_pBody;
+ m_pBody = NULL;
+ pOld->release();
+ }
+ return *this;
+ }
+
+
+ /** Get the body. Can be used instead of operator->().
+ I.e. handle->someBodyOp() and handle.get()->someBodyOp()
+ are the same.
+ */
+ reference_type * SAL_CALL get() const
+ {
+ return m_pBody;
+ }
+
+
+ /** Probably most common used: handle->someBodyOp().
+ */
+ reference_type * SAL_CALL operator->() const
+ {
+ assert(m_pBody != NULL);
+ return m_pBody;
+ }
+
+
+ /** Allows (*handle).someBodyOp().
+ */
+ reference_type & SAL_CALL operator*() const
+ {
+ assert(m_pBody != NULL);
+ return *m_pBody;
+ }
+
+
+ /** Returns True if the handle does point to a valid body.
+ */
+ bool SAL_CALL is() const
+ {
+ return (m_pBody != NULL);
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /** Returns True if the handle does point to a valid body.
+ */
+ explicit operator bool() const
+ {
+ return is();
+ }
+#endif
+
+ /** Returns True if this points to pBody.
+ */
+ bool SAL_CALL operator== (const reference_type * pBody) const
+ {
+ return (m_pBody == pBody);
+ }
+
+
+ /** Returns True if handle points to the same body.
+ */
+ bool
+ SAL_CALL operator== (const Reference<reference_type> & handle) const
+ {
+ return (m_pBody == handle.m_pBody);
+ }
+
+
+ /** Needed to place References into STL collection.
+ */
+ bool
+ SAL_CALL operator!= (const Reference<reference_type> & handle) const
+ {
+ return (m_pBody != handle.m_pBody);
+ }
+
+
+ /** Needed to place References into STL collection.
+ */
+ bool
+ SAL_CALL operator< (const Reference<reference_type> & handle) const
+ {
+ return (m_pBody < handle.m_pBody);
+ }
+
+
+ /** Needed to place References into STL collection.
+ */
+ bool
+ SAL_CALL operator> (const Reference<reference_type> & handle) const
+ {
+ return (m_pBody > handle.m_pBody);
+ }
+};
+
+} // namespace rtl
+
+#if defined LIBO_INTERNAL_ONLY
+namespace std
+{
+
+/// @cond INTERNAL
+/**
+ Make rtl::Reference hashable by default for use in STL containers.
+
+ @since LibreOffice 6.3
+*/
+template<typename T>
+struct hash<::rtl::Reference<T>>
+{
+ std::size_t operator()(::rtl::Reference<T> const & s) const
+ { return std::size_t(s.get()); }
+};
+/// @endcond
+
+}
+
+#endif
+
+#endif /* ! INCLUDED_RTL_REF_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/strbuf.h b/include/rtl/strbuf.h
new file mode 100644
index 0000000000..0c6eea1dea
--- /dev/null
+++ b/include/rtl/strbuf.h
@@ -0,0 +1,143 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_STRBUF_H
+#define INCLUDED_RTL_STRBUF_H
+
+#include "sal/config.h"
+
+#include "rtl/string.h"
+#include "sal/saldllapi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Allocates a new <code>String</code> that contains characters from
+ the character array argument.
+
+ The <code>count</code> argument specifies
+ the length of the array. The initial capacity of the string buffer is
+ <code>16</code> plus the length of the string argument.
+
+ @param newStr out parameter, contains the new string. The reference count is 1.
+ @param value the initial value of the string.
+ @param count the length of value.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_stringbuffer_newFromStr_WithLength(
+ rtl_String ** newStr,
+ const char * value,
+ sal_Int32 count);
+
+/**
+ Allocates a new <code>String</code> that contains the same sequence of
+ characters as the string argument.
+
+ The initial capacity is the larger of:
+ <ul>
+ <li> The <code>bufferLen</code> argument.
+ <li> The <code>length</code> of the string argument.
+ </ul>
+
+ @param newStr out parameter, contains the new string. The reference count is 1.
+ @param capacity the initial len of the string buffer.
+ @param oldStr the initial value of the string.
+ @return the new capacity of the string buffer
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_stringbuffer_newFromStringBuffer(
+ rtl_String ** newStr,
+ sal_Int32 capacity,
+ rtl_String * oldStr );
+
+/**
+ Ensures that the capacity of the buffer is at least equal to the
+ specified minimum.
+
+ If the current capacity of this string buffer is less than the
+ argument, then a new internal buffer is allocated with greater
+ capacity. The new capacity is the larger of:
+ <ul>
+ <li>The <code>minimumCapacity</code> argument.
+ <li>Twice the old capacity, plus <code>2</code>.
+ </ul>
+ If the <code>minimumCapacity</code> argument is nonpositive, this
+ method takes no action and simply returns.
+
+ @param[in,out] This the String to operate on.
+ @param[in,out] capacity in: old capacity, out: new capacity.
+ @param[in] minimumCapacity the minimum desired capacity.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_stringbuffer_ensureCapacity(
+ rtl_String ** This,
+ sal_Int32* capacity,
+ sal_Int32 minimumCapacity);
+
+
+/**
+ Inserts the string representation of the <code>char</code> array
+ argument into this string buffer.
+
+ The characters of the array argument are inserted into the
+ contents of this string buffer at the position indicated by
+ <code>offset</code>. The length of this string buffer increases by
+ the length of the argument.
+
+ @param[in,out] This the String to operate on.
+ @param[in,out] capacity the capacity of the string buffer
+ @param[in] offset the offset.
+ @param[in] str a character array. Since LibreOffice 4.4, as a
+ special case, if str is null then the len added
+ characters are left uninitialized.
+ @param[in] len the number of characters to append.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_stringbuffer_insert(
+ rtl_String ** This,
+ sal_Int32 * capacity,
+ sal_Int32 offset,
+ const char * str,
+ sal_Int32 len);
+
+/**
+ Removes the characters in a substring of this sequence.
+
+ The substring begins at the specified <code>start</code> and
+ is <code>len</code> characters long.
+
+ start must be >= 0 && <= This->length
+
+ @param[in,out] This The String to operate on.
+ @param[in] start The beginning index, inclusive
+ @param[in] len The substring length
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_stringbuffer_remove(
+ rtl_String ** This,
+ sal_Int32 start,
+ sal_Int32 len );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_RTL_STRBUF_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/strbuf.hxx b/include/rtl/strbuf.hxx
new file mode 100644
index 0000000000..5fa7692414
--- /dev/null
+++ b/include/rtl/strbuf.hxx
@@ -0,0 +1,1116 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#pragma once
+
+#include "sal/config.h"
+
+#include <cassert>
+#include <cstring>
+#include <limits>
+
+#include "rtl/strbuf.h"
+#include "rtl/string.hxx"
+#include "rtl/stringutils.hxx"
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+#include "rtl/stringconcat.hxx"
+#include <string_view>
+#include <type_traits>
+#endif
+
+#ifdef RTL_STRING_UNITTEST
+extern bool rtl_string_unittest_const_literal;
+extern bool rtl_string_unittest_const_literal_function;
+#endif
+
+// The unittest uses slightly different code to help check that the proper
+// calls are made. The class is put into a different namespace to make
+// sure the compiler generates a different (if generating also non-inline)
+// copy of the function and does not merge them together. The class
+// is "brought" into the proper rtl namespace by a typedef below.
+#ifdef RTL_STRING_UNITTEST
+#define rtl rtlunittest
+#endif
+
+namespace rtl
+{
+
+/// @cond INTERNAL
+#ifdef RTL_STRING_UNITTEST
+#undef rtl
+// helper macro to make functions appear more readable
+#define RTL_STRING_CONST_FUNCTION rtl_string_unittest_const_literal_function = true;
+#else
+#define RTL_STRING_CONST_FUNCTION
+#endif
+/// @endcond
+
+/** A string buffer implements a mutable sequence of characters.
+ */
+class SAL_WARN_UNUSED OStringBuffer
+{
+public:
+ /**
+ Constructs a string buffer with no characters in it and an
+ initial capacity of 16 characters.
+ */
+ OStringBuffer()
+ : pData(NULL)
+ , nCapacity( 16 )
+ {
+ rtl_string_new_WithLength( &pData, nCapacity );
+ }
+
+ /**
+ Allocates a new string buffer that contains the same sequence of
+ characters as the string buffer argument.
+
+ @param value a <code>OStringBuffer</code>.
+ */
+ OStringBuffer( const OStringBuffer & value )
+ : pData(NULL)
+ , nCapacity( value.nCapacity )
+ {
+ rtl_stringbuffer_newFromStringBuffer( &pData, value.nCapacity, value.pData );
+ }
+
+ /**
+ Constructs a string buffer with no characters in it and an
+ initial capacity specified by the <code>length</code> argument.
+
+ @param length the initial capacity.
+ */
+ explicit OStringBuffer(sal_Int32 length)
+ : pData(NULL)
+ , nCapacity( length )
+ {
+ rtl_string_new_WithLength( &pData, length );
+ }
+#if defined LIBO_INTERNAL_ONLY
+ template<typename T>
+ explicit OStringBuffer(T length, std::enable_if_t<std::is_integral_v<T>, int> = 0)
+ : OStringBuffer(static_cast<sal_Int32>(length))
+ {
+ assert(
+ length >= 0
+ && static_cast<std::make_unsigned_t<T>>(length)
+ <= static_cast<std::make_unsigned_t<sal_Int32>>(
+ std::numeric_limits<sal_Int32>::max()));
+ }
+ // avoid (obvious) bugs
+ explicit OStringBuffer(bool) = delete;
+ explicit OStringBuffer(char) = delete;
+ explicit OStringBuffer(wchar_t) = delete;
+#if !(defined _MSC_VER && _MSC_VER >= 1930 && _MSC_VER <= 1939 && defined _MANAGED)
+ explicit OStringBuffer(char8_t) = delete;
+#endif
+ explicit OStringBuffer(char16_t) = delete;
+ explicit OStringBuffer(char32_t) = delete;
+#endif
+
+ /**
+ Constructs a string buffer so that it represents the same
+ sequence of characters as the string argument.
+
+ The initial
+ capacity of the string buffer is <code>16</code> plus the length
+ of the string argument.
+
+ @param value the initial string value.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ OStringBuffer(std::string_view sv)
+ : pData(nullptr)
+ , nCapacity( sv.length() + 16 )
+ {
+ if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) {
+ throw std::bad_alloc();
+ }
+ rtl_stringbuffer_newFromStr_WithLength( &pData, sv.data(), sv.length() );
+ }
+#else
+ OStringBuffer(const OString& value)
+ : pData(NULL)
+ , nCapacity( value.getLength() + 16 )
+ {
+ rtl_stringbuffer_newFromStr_WithLength( &pData, value.getStr(), value.getLength() );
+ }
+#endif
+
+ /**
+ @overload
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ OStringBuffer( const T& value, typename libreoffice_internal::CharPtrDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy())
+ : pData(NULL)
+ {
+ sal_Int32 length = rtl_str_getLength( value );
+ nCapacity = length + 16;
+ rtl_stringbuffer_newFromStr_WithLength( &pData, value, length );
+ }
+
+ template< typename T >
+ OStringBuffer( T& value, typename libreoffice_internal::NonConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy())
+ : pData(NULL)
+ {
+ sal_Int32 length = rtl_str_getLength( value );
+ nCapacity = length + 16;
+ rtl_stringbuffer_newFromStr_WithLength( &pData, value, length );
+ }
+
+#if __cplusplus > 202002L // C++23 P2266R3 "Simpler implicit move"
+ template< typename T >
+ OStringBuffer( T&& value, typename libreoffice_internal::NonConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy())
+ : pData(NULL)
+ {
+ sal_Int32 length = rtl_str_getLength( value );
+ nCapacity = length + 16;
+ rtl_stringbuffer_newFromStr_WithLength( &pData, value, length );
+ }
+#endif
+
+ /**
+ Constructs a string buffer so that it represents the same
+ sequence of characters as the string literal.
+
+ If there are any embedded \0's in the string literal, the result is undefined.
+ Use the overload that explicitly accepts length.
+
+ @since LibreOffice 3.6
+
+ @param literal a string literal
+ */
+ template< typename T >
+ OStringBuffer( T& literal, typename libreoffice_internal::ConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy())
+ : pData(NULL)
+ , nCapacity( libreoffice_internal::ConstCharArrayDetector<T>::length + 16 )
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ rtl_string_newFromLiteral(
+ &pData,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length, 16);
+#ifdef RTL_STRING_UNITTEST
+ rtl_string_unittest_const_literal = true;
+#endif
+ }
+
+ /**
+ Constructs a string buffer so that it represents the same
+ sequence of characters as the string argument.
+
+ The initial
+ capacity of the string buffer is <code>16</code> plus length
+
+ @param value a character array.
+ @param length the number of character which should be copied.
+ The character array length must be greater or
+ equal than this value.
+ */
+ OStringBuffer(const char * value, sal_Int32 length)
+ : pData(NULL)
+ , nCapacity( length + 16 )
+ {
+ rtl_stringbuffer_newFromStr_WithLength( &pData, value, length );
+ }
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ /**
+ @overload
+ @internal
+ */
+ template< typename T1, typename T2 >
+ OStringBuffer( OStringConcat< T1, T2 >&& c )
+ {
+ const sal_Int32 l = c.length();
+ nCapacity = l + 16;
+ pData = rtl_string_alloc( nCapacity );
+ char* end = c.addData( pData->buffer );
+ *end = '\0';
+ pData->length = l;
+ }
+
+ /**
+ @overload
+ @internal
+ */
+ template< std::size_t N >
+ OStringBuffer( OStringNumber< N >&& n )
+ : OStringBuffer( n.buf, n.length)
+ {}
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+ operator std::string_view() const { return {getStr(), sal_uInt32(getLength())}; }
+#endif
+
+ /** Assign to this a copy of value.
+ */
+ OStringBuffer& operator = ( const OStringBuffer& value )
+ {
+ if (this != &value)
+ {
+ rtl_stringbuffer_newFromStringBuffer(&pData,
+ value.nCapacity,
+ value.pData);
+ nCapacity = value.nCapacity;
+ }
+ return *this;
+ }
+
+ /** Assign from a string.
+
+ @since LibreOffice 5.3
+ */
+#if defined LIBO_INTERNAL_ONLY
+ OStringBuffer & operator =(std::string_view string) {
+ sal_Int32 n = string.length();
+ if (n >= nCapacity) {
+ ensureCapacity(n + 16); //TODO: check for overflow
+ }
+ std::memcpy(pData->buffer, string.data(), n);
+ pData->buffer[n] = '\0';
+ pData->length = n;
+ return *this;
+ }
+#else
+ OStringBuffer & operator =(OString const & string) {
+ sal_Int32 n = string.getLength();
+ if (n >= nCapacity) {
+ ensureCapacity(n + 16); //TODO: check for overflow
+ }
+ std::memcpy(pData->buffer, string.pData->buffer, n + 1);
+ pData->length = n;
+ return *this;
+ }
+#endif
+
+ /** Assign from a string literal.
+
+ @since LibreOffice 5.3
+ */
+ template<typename T>
+ typename
+ libreoffice_internal::ConstCharArrayDetector<T, OStringBuffer &>::Type
+ operator =(T & literal) {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ sal_Int32 const n
+ = libreoffice_internal::ConstCharArrayDetector<T>::length;
+ if (n >= nCapacity) {
+ ensureCapacity(n + 16); //TODO: check for overflow
+ }
+ std::memcpy(
+ pData->buffer,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ n + 1);
+ pData->length = n;
+ return *this;
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /** @overload @since LibreOffice 5.3 */
+ template<typename T1, typename T2>
+ OStringBuffer & operator =(OStringConcat<T1, T2> && concat) {
+ sal_Int32 const n = concat.length();
+ if (n >= nCapacity) {
+ ensureCapacity(n + 16); //TODO: check for overflow
+ }
+ *concat.addData(pData->buffer) = 0;
+ pData->length = n;
+ return *this;
+ }
+
+ /** @overload @internal */
+ template<std::size_t N>
+ OStringBuffer & operator =(OStringNumber<N> && n)
+ {
+ return operator =(std::string_view(n));
+ }
+#endif
+
+ /**
+ Release the string data.
+ */
+ ~OStringBuffer()
+ {
+ rtl_string_release( pData );
+ }
+
+ /**
+ Fill the string data in the new string and clear the buffer.
+
+ This method is more efficient than the constructor of the string. It does
+ not copy the buffer.
+
+ @return the string previously contained in the buffer.
+ */
+ SAL_WARN_UNUSED_RESULT OString makeStringAndClear()
+ {
+ OString aRet( pData );
+ rtl_string_new(&pData);
+ nCapacity = 0;
+ return aRet;
+ }
+
+ /**
+ Returns the length (character count) of this string buffer.
+
+ @return the number of characters in this string buffer.
+ */
+ sal_Int32 getLength() const
+ {
+ return pData->length;
+ }
+
+ /**
+ Checks if a string buffer is empty.
+
+ @return true if the string buffer is empty;
+ false, otherwise.
+
+ @since LibreOffice 4.1
+ */
+ bool isEmpty() const
+ {
+ return pData->length == 0;
+ }
+
+ /**
+ Returns the current capacity of the String buffer.
+
+ The capacity
+ is the amount of storage available for newly inserted
+ characters. The real buffer size is 1 byte longer, because
+ all strings are 0 terminated.
+
+ @return the current capacity of this string buffer.
+ */
+ sal_Int32 getCapacity() const
+ {
+ return nCapacity;
+ }
+
+ /**
+ Ensures that the capacity of the buffer is at least equal to the
+ specified minimum.
+
+ The new capacity will be at least as large as the maximum of the current
+ length (so that no contents of the buffer is destroyed) and the given
+ minimumCapacity. If the given minimumCapacity is negative, nothing is
+ changed.
+
+ @param minimumCapacity the minimum desired capacity.
+ */
+ void ensureCapacity(sal_Int32 minimumCapacity)
+ {
+ rtl_stringbuffer_ensureCapacity( &pData, &nCapacity, minimumCapacity );
+ }
+
+ /**
+ Sets the length of this String buffer.
+
+ If the <code>newLength</code> argument is less than the current
+ length of the string buffer, the string buffer is truncated to
+ contain exactly the number of characters given by the
+ <code>newLength</code> argument.
+ <p>
+ If the <code>newLength</code> argument is greater than or equal
+ to the current length, sufficient null characters
+ (<code>'&#92;u0000'</code>) are appended to the string buffer so that
+ length becomes the <code>newLength</code> argument.
+ <p>
+ The <code>newLength</code> argument must be greater than or equal
+ to <code>0</code>.
+
+ @param newLength the new length of the buffer.
+ */
+ void setLength(sal_Int32 newLength)
+ {
+ assert(newLength >= 0);
+ // Avoid modifications if pData points to const empty string:
+ if( newLength != pData->length )
+ {
+ if( newLength > nCapacity )
+ rtl_stringbuffer_ensureCapacity(&pData, &nCapacity, newLength);
+ else
+ pData->buffer[newLength] = '\0';
+ pData->length = newLength;
+ }
+ }
+
+ /**
+ Returns the character at a specific index in this string buffer.
+
+ The first character of a string buffer is at index
+ <code>0</code>, the next at index <code>1</code>, and so on, for
+ array indexing.
+ <p>
+ The index argument must be greater than or equal to
+ <code>0</code>, and less than the length of this string buffer.
+
+ @param index the index of the desired character.
+ @return the character at the specified index of this string buffer.
+ */
+ SAL_DEPRECATED("use rtl::OStringBuffer::operator [] instead")
+ char charAt( sal_Int32 index )
+ {
+ assert(index >= 0 && index < pData->length);
+ return pData->buffer[ index ];
+ }
+
+ /**
+ The character at the specified index of this string buffer is set
+ to <code>ch</code>.
+
+ The index argument must be greater than or equal to
+ <code>0</code>, and less than the length of this string buffer.
+
+ @param index the index of the character to modify.
+ @param ch the new character.
+ */
+ SAL_DEPRECATED("use rtl::OStringBuffer::operator [] instead")
+ OStringBuffer & setCharAt(sal_Int32 index, char ch)
+ {
+ assert(index >= 0 && index < pData->length);
+ pData->buffer[ index ] = ch;
+ return *this;
+ }
+
+ /**
+ Return a null terminated character array.
+ */
+ const char* getStr() const SAL_RETURNS_NONNULL { return pData->buffer; }
+
+ /**
+ Access to individual characters.
+
+ @param index must be non-negative and less than length.
+
+ @return a reference to the character at the given index.
+
+ @since LibreOffice 3.5
+ */
+ char & operator [](sal_Int32 index)
+ {
+ assert(index >= 0 && index < pData->length);
+ return pData->buffer[index];
+ }
+
+ /**
+ Return an OString instance reflecting the current content
+ of this OStringBuffer.
+ */
+ OString toString() const
+ {
+ return OString(pData->buffer, pData->length);
+ }
+
+#if !defined LIBO_INTERNAL_ONLY
+ /**
+ Appends the string to this string buffer.
+
+ The characters of the <code>String</code> argument are appended, in
+ order, to the contents of this string buffer, increasing the
+ length of this string buffer by the length of the argument.
+
+ @param str a string.
+ @return this string buffer.
+ */
+ OStringBuffer & append(const OString &str)
+ {
+ return insert(getLength(), str);
+ }
+#endif
+
+ /**
+ Appends the string representation of the <code>char</code> array
+ argument to this string buffer.
+
+ The characters of the array argument are appended, in order, to
+ the contents of this string buffer. The length of this string
+ buffer increases by the length of the argument.
+
+ @param str the characters to be appended.
+ @return this string buffer.
+ */
+ template< typename T >
+ typename libreoffice_internal::CharPtrDetector< T, OStringBuffer& >::Type append( const T& str )
+ {
+ return insert(getLength(), str);
+ }
+
+ template< typename T >
+ typename libreoffice_internal::NonConstCharArrayDetector< T, OStringBuffer& >::Type append( T& str )
+ {
+ return insert(getLength(), str);
+ }
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, OStringBuffer& >::Type append( T& literal )
+ {
+ return insert(getLength(), literal);
+ }
+
+ /**
+ Appends the string representation of the <code>char</code> array
+ argument to this string buffer.
+
+ Characters of the character array <code>str</code> are appended,
+ in order, to the contents of this string buffer. The length of this
+ string buffer increases by the value of <code>len</code>.
+
+ @param str the characters to be appended; must be non-null, and must
+ point to at least len characters
+ @param len the number of characters to append; must be non-negative
+ @return this string buffer.
+ */
+ OStringBuffer & append( const char * str, sal_Int32 len)
+ {
+ return insert(getLength(), str, len);
+ }
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ /**
+ @overload
+ @internal
+ */
+ template< typename T1, typename T2 >
+ OStringBuffer& append( OStringConcat< T1, T2 >&& c )
+ {
+ sal_Int32 l = c.length();
+ if (l != 0)
+ c.addData(appendUninitialized(l));
+ return *this;
+ }
+
+ /**
+ @overload
+ @internal
+ */
+ OStringBuffer& append( std::string_view s )
+ {
+ return insert(getLength(), s);
+ }
+
+#endif
+
+ /**
+ Appends the string representation of the <code>sal_Bool</code>
+ argument to the string buffer.
+
+ The argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then appended to this string buffer.
+
+ @param b a <code>sal_Bool</code>.
+ @return this string buffer.
+ */
+ OStringBuffer & append(sal_Bool b)
+ {
+ return insert(getLength(), b);
+ }
+
+ /**
+ Appends the string representation of the <code>bool</code>
+ argument to the string buffer.
+
+ The argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then appended to this string buffer.
+
+ @param b a <code>bool</code>.
+ @return this string buffer.
+
+ @since LibreOffice 4.3
+ */
+ OStringBuffer & append(bool b)
+ {
+ return insert(getLength(), b);
+ }
+
+ /// @cond INTERNAL
+ // Pointer can be automatically converted to bool, which is unwanted here.
+ // Explicitly delete all pointer append() overloads to prevent this
+ // (except for char* overload, which is handled elsewhere).
+ template< typename T >
+ typename libreoffice_internal::Enable< void,
+ !libreoffice_internal::CharPtrDetector< T* >::ok >::Type
+ append( T* ) SAL_DELETED_FUNCTION;
+ /// @endcond
+
+ /**
+ Appends the string representation of the <code>char</code>
+ argument to this string buffer.
+
+ The argument is appended to the contents of this string buffer.
+ The length of this string buffer increases by <code>1</code>.
+
+ @param c a <code>char</code>.
+ @return this string buffer.
+ */
+ OStringBuffer & append(char c)
+ {
+ return insert(getLength(), c);
+ }
+
+ /**
+ Appends the string representation of the <code>sal_Int32</code>
+ argument to this string buffer.
+
+ The argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then appended to this string buffer.
+
+ @param i an <code>sal_Int32</code>.
+ @param radix the radix
+ @return this string buffer.
+ */
+ OStringBuffer & append(sal_Int32 i, sal_Int16 radix = 10 )
+ {
+ return insert(getLength(), i, radix);
+ }
+
+ /**
+ Appends the string representation of the <code>long</code>
+ argument to this string buffer.
+
+ The argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then appended to this string buffer.
+
+ @param l a <code>long</code>.
+ @param radix the radix
+ @return this string buffer.
+ */
+ OStringBuffer & append(sal_Int64 l, sal_Int16 radix = 10 )
+ {
+ return insert(getLength(), l, radix);
+ }
+
+ /**
+ Appends the string representation of the <code>float</code>
+ argument to this string buffer.
+
+ The argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then appended to this string buffer.
+
+ @param f a <code>float</code>.
+ @return this string buffer.
+ */
+ OStringBuffer & append(float f)
+ {
+ return insert(getLength(), f);
+ }
+
+ /**
+ Appends the string representation of the <code>double</code>
+ argument to this string buffer.
+
+ The argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then appended to this string buffer.
+
+ @param d a <code>double</code>.
+ @return this string buffer.
+ */
+ OStringBuffer & append(double d)
+ {
+ return insert(getLength(), d);
+ }
+
+ /**
+ Unsafe way to make space for a fixed amount of characters to be appended
+ into this OStringBuffer.
+
+ A call to this function must immediately be followed by code that
+ completely fills the uninitialized block pointed to by the return value.
+
+ @param length the length of the uninitialized block of char entities;
+ must be non-negative
+
+ @return a pointer to the start of the uninitialized block; only valid
+ until this OStringBuffer's capacity changes
+
+ @since LibreOffice 4.4
+ */
+ char * appendUninitialized(sal_Int32 length) SAL_RETURNS_NONNULL {
+ sal_Int32 n = getLength();
+ rtl_stringbuffer_insert(&pData, &nCapacity, n, NULL, length);
+ return pData->buffer + n;
+ }
+
+ /**
+ Inserts the string into this string buffer.
+
+ The characters of the <code>String</code> argument are inserted, in
+ order, into this string buffer at the indicated offset. The length
+ of this string buffer is increased by the length of the argument.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param str a string.
+ @return this string buffer.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ OStringBuffer & insert(sal_Int32 offset, std::string_view str)
+ {
+ return insert( offset, str.data(), str.length() );
+ }
+#else
+ OStringBuffer & insert(sal_Int32 offset, const OString & str)
+ {
+ return insert( offset, str.getStr(), str.getLength() );
+ }
+#endif
+
+ /**
+ Inserts the string representation of the <code>char</code> array
+ argument into this string buffer.
+
+ The characters of the array argument are inserted into the
+ contents of this string buffer at the position indicated by
+ <code>offset</code>. The length of this string buffer increases by
+ the length of the argument.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param str a character array.
+ @return this string buffer.
+ */
+ template< typename T >
+ typename libreoffice_internal::CharPtrDetector< T, OStringBuffer& >::Type insert( sal_Int32 offset, const T& str )
+ {
+ return insert( offset, str, rtl_str_getLength( str ) );
+ }
+
+ template< typename T >
+ typename libreoffice_internal::NonConstCharArrayDetector< T, OStringBuffer& >::Type insert( sal_Int32 offset, T& str )
+ {
+ return insert( offset, str, rtl_str_getLength( str ) );
+ }
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, OStringBuffer& >::Type insert( sal_Int32 offset, T& literal )
+ {
+ RTL_STRING_CONST_FUNCTION
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return insert(
+ offset,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+
+ /**
+ Inserts the string representation of the <code>char</code> array
+ argument into this string buffer.
+
+ The characters of the array argument are inserted into the
+ contents of this string buffer at the position indicated by
+ <code>offset</code>. The length of this string buffer increases by
+ the length of the argument.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param str a character array.
+ @param len the number of characters to append.
+ @return this string buffer.
+ */
+ OStringBuffer & insert( sal_Int32 offset, const char * str, sal_Int32 len)
+ {
+ assert( len == 0 || str != NULL ); // cannot assert that in rtl_stringbuffer_insert
+ rtl_stringbuffer_insert( &pData, &nCapacity, offset, str, len );
+ return *this;
+ }
+
+ /**
+ Inserts the string representation of the <code>sal_Bool</code>
+ argument into this string buffer.
+
+ The second argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then inserted into this string buffer at the indicated
+ offset.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param b a <code>sal_Bool</code>.
+ @return this string buffer.
+ */
+ OStringBuffer & insert(sal_Int32 offset, sal_Bool b)
+ {
+ char sz[RTL_STR_MAX_VALUEOFBOOLEAN];
+ return insert( offset, sz, rtl_str_valueOfBoolean( sz, b ) );
+ }
+
+ /**
+ Inserts the string representation of the <code>bool</code>
+ argument into this string buffer.
+
+ The second argument is converted to a string as if by the method
+ <code>OString::boolean</code>, and the characters of that
+ string are then inserted into this string buffer at the indicated
+ offset.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param b a <code>bool</code>.
+ @return this string buffer.
+
+ @since LibreOffice 4.3
+ */
+ OStringBuffer & insert(sal_Int32 offset, bool b)
+ {
+ char sz[RTL_STR_MAX_VALUEOFBOOLEAN];
+ return insert( offset, sz, rtl_str_valueOfBoolean( sz, b ) );
+ }
+
+ /**
+ Inserts the string representation of the <code>char</code>
+ argument into this string buffer.
+
+ The second argument is inserted into the contents of this string
+ buffer at the position indicated by <code>offset</code>. The length
+ of this string buffer increases by one.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param c a <code>char</code>.
+ @return this string buffer.
+ */
+ OStringBuffer & insert(sal_Int32 offset, char c)
+ {
+ return insert( offset, &c, 1 );
+ }
+
+ /**
+ Inserts the string representation of the second <code>sal_Int32</code>
+ argument into this string buffer.
+
+ The second argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then inserted into this string buffer at the indicated
+ offset.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param i an <code>sal_Int32</code>.
+ @param radix the radix
+ @return this string buffer.
+ */
+ OStringBuffer & insert(sal_Int32 offset, sal_Int32 i, sal_Int16 radix = 10 )
+ {
+ char sz[RTL_STR_MAX_VALUEOFINT32];
+ return insert( offset, sz, rtl_str_valueOfInt32( sz, i, radix ) );
+ }
+
+ /**
+ Inserts the string representation of the <code>long</code>
+ argument into this string buffer.
+
+ The second argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then inserted into this string buffer at the indicated
+ offset.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param l a <code>long</code>.
+ @param radix the radix
+ @return this string buffer.
+ */
+ OStringBuffer & insert(sal_Int32 offset, sal_Int64 l, sal_Int16 radix = 10 )
+ {
+ char sz[RTL_STR_MAX_VALUEOFINT64];
+ return insert( offset, sz, rtl_str_valueOfInt64( sz, l, radix ) );
+ }
+
+ /**
+ Inserts the string representation of the <code>float</code>
+ argument into this string buffer.
+
+ The second argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then inserted into this string buffer at the indicated
+ offset.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param f a <code>float</code>.
+ @return this string buffer.
+ */
+ OStringBuffer & insert(sal_Int32 offset, float f)
+ {
+ // Same as rtl::str::valueOfFP, used for rtl_str_valueOfFloat
+ rtl_math_doubleToString(&pData, &nCapacity, offset, f, rtl_math_StringFormat_G,
+ RTL_STR_MAX_VALUEOFFLOAT - SAL_N_ELEMENTS("-x.E-xxx") + 1, '.',
+ NULL, 0, true);
+ return *this;
+ }
+
+ /**
+ Inserts the string representation of the <code>double</code>
+ argument into this string buffer.
+
+ The second argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then inserted into this string buffer at the indicated
+ offset.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param d a <code>double</code>.
+ @return this string buffer.
+ */
+ OStringBuffer & insert(sal_Int32 offset, double d)
+ {
+ // Same as rtl::str::valueOfFP, used for rtl_str_valueOfDouble
+ rtl_math_doubleToString(&pData, &nCapacity, offset, d, rtl_math_StringFormat_G,
+ RTL_STR_MAX_VALUEOFDOUBLE - SAL_N_ELEMENTS("-x.E-xxx") + 1, '.',
+ NULL, 0, true);
+ return *this;
+ }
+
+ /**
+ Removes the characters in a substring of this sequence.
+
+ The substring begins at the specified <code>start</code> and
+ is <code>len</code> characters long.
+
+ start must be >= 0 && <= getLength() && <= end
+
+ @param start The beginning index, inclusive
+ @param len The substring length
+ @return this string buffer.
+ */
+ OStringBuffer & remove( sal_Int32 start, sal_Int32 len )
+ {
+ rtl_stringbuffer_remove( &pData, start, len );
+ return *this;
+ }
+
+ /** Allows access to the internal data of this OStringBuffer, for effective
+ manipulation.
+
+ This function should be used with care. After you have called this
+ function, you may use the returned pInternalData and pInternalCapacity
+ only as long as you make no other calls on this OStringBuffer.
+
+ @param pInternalData
+ This output parameter receives a pointer to the internal data
+ (rtl_String pointer). pInternalData itself must not be null.
+
+ @param pInternalCapacity
+ This output parameter receives a pointer to the internal capacity.
+ pInternalCapacity itself must not be null.
+
+ @since LibreOffice 5.4
+ */
+ void accessInternals(
+ rtl_String *** pInternalData, sal_Int32 ** pInternalCapacity)
+ {
+ *pInternalData = &pData;
+ *pInternalCapacity = &nCapacity;
+ }
+
+private:
+ /**
+ A pointer to the data structure which contains the data.
+ */
+ rtl_String * pData;
+
+ /**
+ The len of the pData->buffer.
+ */
+ sal_Int32 nCapacity;
+};
+
+#if defined LIBO_INTERNAL_ONLY
+template<> struct ToStringHelper<OStringBuffer> {
+ static std::size_t length(OStringBuffer const & s) { return s.getLength(); }
+
+ char * operator()(char * buffer, OStringBuffer const & s) const SAL_RETURNS_NONNULL
+ { return addDataHelper(buffer, s.getStr(), s.getLength()); }
+};
+#endif
+
+}
+
+#ifdef RTL_STRING_UNITTEST
+namespace rtl
+{
+typedef rtlunittest::OStringBuffer OStringBuffer;
+}
+#undef RTL_STRING_CONST_FUNCTION
+#endif
+
+#if defined LIBO_INTERNAL_ONLY && !defined RTL_STRING_UNITTEST
+using ::rtl::OStringBuffer;
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/string.h b/include/rtl/string.h
new file mode 100644
index 0000000000..26f3615297
--- /dev/null
+++ b/include/rtl/string.h
@@ -0,0 +1,1454 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_STRING_H
+#define INCLUDED_RTL_STRING_H
+
+#include "sal/config.h"
+
+#include "osl/interlck.h"
+#include "rtl/textcvt.h"
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ======================================================================= */
+
+/** Return the length of a string.
+
+ The length is equal to the number of 8-bit characters in the string,
+ without the terminating NUL character.
+
+ @param str
+ a null-terminated string.
+
+ @return
+ the length of the sequence of characters represented by this string,
+ excluding the terminating NUL character.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_getLength(
+ const char * str ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. This function
+ cannot be used for language-specific sorting. Both strings must be
+ null-terminated.
+
+ @param first
+ the first null-terminated string to be compared.
+
+ @param second
+ the second null-terminated string which is compared with the first one.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string is
+ less than the second string, and a value greater than 0 if the first
+ string is greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_compare(
+ const char * first, const char * second ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. This function
+ cannot be used for language-specific sorting.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second string which is compared with the first one. Need not be
+ null-terminated, but must be at least as long as the specified secondLen.
+
+ @param secondLen
+ the length of the second string.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string is
+ less than the second string, and a value greater than 0 if the first
+ string is greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_compare_WithLength(
+ const char * first, sal_Int32 firstLen, const char * second, sal_Int32 secondLen ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings with a maximum count of characters.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. This function
+ cannot be used for language-specific sorting.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second string which is compared with the first one. Need not be
+ null-terminated, but must be at least as long as the specified secondLen.
+
+ @param secondLen
+ the length of the second string.
+
+ @param shortenedLen
+ the maximum number of characters to compare. This length can be greater
+ or smaller than the lengths of the two strings.
+
+ @return
+ 0 if both substrings are equal, a value less than 0 if the first substring
+ is less than the second substring, and a value greater than 0 if the first
+ substring is greater than the second substring.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_shortenedCompare_WithLength(
+ const char * first, sal_Int32 firstLen, const char * second, sal_Int32 secondLen, sal_Int32 shortenedLen ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings from back to front.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. This function
+ cannot be used for language-specific sorting.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second string which is compared with the first one. Need not be
+ null-terminated, but must be at least as long as the specified secondLen.
+
+ @param secondLen
+ the length of the second string.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string
+ compares less than the second string, and a value greater than 0 if the
+ first string compares greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_reverseCompare_WithLength(
+ const char * first, sal_Int32 firstLen, const char * second, sal_Int32 secondLen ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings, ignoring the case of ASCII characters.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. Character
+ values between 65 and 90 (ASCII A--Z) are interpreted as values between 97
+ and 122 (ASCII a--z). This function cannot be used for language-specific
+ sorting. Both strings must be null-terminated.
+
+ @param first
+ the first null-terminated string to be compared.
+
+ @param second
+ the second null-terminated string which is compared with the first one.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string is
+ less than the second string, and a value greater than 0 if the first
+ string is greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_compareIgnoreAsciiCase(
+ const char * first, const char * second ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings, ignoring the case of ASCII characters.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. Character
+ values between 65 and 90 (ASCII A--Z) are interpreted as values between 97
+ and 122 (ASCII a--z). This function cannot be used for language-specific
+ sorting.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second string which is compared with the first one. Need not be
+ null-terminated, but must be at least as long as the specified secondLen.
+
+ @param secondLen
+ the length of the second string.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string is
+ less than the second string, and a value greater than 0 if the first
+ string is greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_compareIgnoreAsciiCase_WithLength(
+ const char * first, sal_Int32 firstLen, const char * second, sal_Int32 secondLen ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings with a maximum count of characters, ignoring the case
+ of ASCII characters.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. Character
+ values between 65 and 90 (ASCII A--Z) are interpreted as values between 97
+ and 122 (ASCII a--z). This function cannot be used for language-specific
+ sorting.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second string which is compared with the first one. Need not be
+ null-terminated, but must be at least as long as the specified secondLen.
+
+ @param secondLen
+ the length of the second string.
+
+ @param shortenedLen
+ the maximum number of characters to compare. This length can be greater
+ or smaller than the lengths of the two strings.
+
+ @return
+ 0 if both substrings are equal, a value less than 0 if the first substring
+ is less than the second substring, and a value greater than 0 if the first
+ substring is greater than the second substring.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
+ const char * first, sal_Int32 firstLen, const char * second, sal_Int32 secondLen, sal_Int32 shortenedLen ) SAL_THROW_EXTERN_C();
+
+/** Return a hash code for a string.
+
+ It is not allowed to store the hash code persistently, because later
+ versions could return other hash codes. The string must be
+ null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @return
+ a hash code for the given string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_hashCode(
+ const char * str ) SAL_THROW_EXTERN_C();
+
+/** Return a hash code for a string.
+
+ It is not allowed to store the hash code persistently, because later
+ versions could return other hash codes.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+
+ @return
+ a hash code for the given string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_hashCode_WithLength(
+ const char * str, sal_Int32 len ) SAL_THROW_EXTERN_C();
+
+/** Search for the first occurrence of a character within a string.
+
+ The string must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param ch
+ the character to be searched for.
+
+ @return
+ the index (starting at 0) of the first occurrence of the character in the
+ string, or -1 if the character does not occur.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_indexOfChar(
+ const char * str, char ch ) SAL_THROW_EXTERN_C();
+
+/** Search for the first occurrence of a character within a string.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+
+ @param ch
+ the character to be searched for.
+
+ @return
+ the index (starting at 0) of the first occurrence of the character in the
+ string, or -1 if the character does not occur.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_indexOfChar_WithLength(
+ const char * str, sal_Int32 len, char ch ) SAL_THROW_EXTERN_C();
+
+/** Search for the last occurrence of a character within a string.
+
+ The string must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param ch
+ the character to be searched for.
+
+ @return
+ the index (starting at 0) of the last occurrence of the character in the
+ string, or -1 if the character does not occur. The returned value is
+ always smaller than the string length.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_lastIndexOfChar(
+ const char * str, char ch ) SAL_THROW_EXTERN_C();
+
+/** Search for the last occurrence of a character within a string.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+
+ @param ch
+ the character to be searched for.
+
+ @return
+ the index (starting at 0) of the last occurrence of the character in the
+ string, or -1 if the character does not occur. The returned value is
+ always smaller than the string length.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_lastIndexOfChar_WithLength(
+ const char * str, sal_Int32 len, char ch ) SAL_THROW_EXTERN_C();
+
+/** Search for the first occurrence of a substring within a string.
+
+ If subStr is empty, or both str and subStr are empty, -1 is returned.
+ Both strings must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param subStr
+ the null-terminated substring to be searched for.
+
+ @return
+ the index (starting at 0) of the first character of the first occurrence
+ of the substring within the string, or -1 if the substring does not occur.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_indexOfStr(
+ const char * str, const char * subStr ) SAL_THROW_EXTERN_C();
+
+/** Search for the first occurrence of a substring within a string.
+
+ If subStr is empty, or both str and subStr are empty, -1 is returned.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+
+ @param subStr
+ the substring to be searched for. Need not be null-terminated, but must
+ be at least as long as the specified subLen.
+
+ @param subLen
+ the length of the substring.
+
+ @return
+ the index (starting at 0) of the first character of the first occurrence
+ of the substring within the string, or -1 if the substring does not occur.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_indexOfStr_WithLength(
+ const char * str, sal_Int32 len, const char * subStr, sal_Int32 subLen ) SAL_THROW_EXTERN_C();
+
+/** Search for the last occurrence of a substring within a string.
+
+ If subStr is empty, or both str and subStr are empty, -1 is returned.
+ Both strings must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param subStr
+ the null-terminated substring to be searched for.
+
+ @return
+ the index (starting at 0) of the first character of the last occurrence
+ of the substring within the string, or -1 if the substring does not occur.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_lastIndexOfStr(
+ const char * str, const char * subStr ) SAL_THROW_EXTERN_C();
+
+/** Search for the last occurrence of a substring within a string.
+
+ If subStr is empty, or both str and subStr are empty, -1 is returned.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+
+ @param subStr
+ the substring to be searched for. Need not be null-terminated, but must
+ be at least as long as the specified subLen.
+
+ @param subLen
+ the length of the substring.
+
+ @return
+ the index (starting at 0) of the first character of the first occurrence
+ of the substring within the string, or -1 if the substring does not occur.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_lastIndexOfStr_WithLength(
+ const char * str, sal_Int32 len, const char * subStr, sal_Int32 subLen ) SAL_THROW_EXTERN_C();
+
+/** Replace all occurrences of a single character within a string.
+
+ If oldChar does not occur within str, then the string is not modified.
+ The string must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param oldChar
+ the old character.
+
+ @param newChar
+ the new character.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_str_replaceChar(
+ char * str, char oldChar, char newChar ) SAL_THROW_EXTERN_C();
+
+/** Replace all occurrences of a single character within a string.
+
+ If oldChar does not occur within str, then the string is not modified.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+
+ @param oldChar
+ the old character.
+
+ @param newChar
+ the new character.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_str_replaceChar_WithLength(
+ char * str, sal_Int32 len, char oldChar, char newChar ) SAL_THROW_EXTERN_C();
+
+/** Convert all ASCII uppercase letters to lowercase within a string.
+
+ The characters with values between 65 and 90 (ASCII A--Z) are replaced
+ with values between 97 and 122 (ASCII a--z). The string must be
+ null-terminated.
+
+ @param str
+ a null-terminated string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_str_toAsciiLowerCase(
+ char * str ) SAL_THROW_EXTERN_C();
+
+/** Convert all ASCII uppercase letters to lowercase within a string.
+
+ The characters with values between 65 and 90 (ASCII A--Z) are replaced
+ with values between 97 and 122 (ASCII a--z).
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_str_toAsciiLowerCase_WithLength(
+ char * str, sal_Int32 len ) SAL_THROW_EXTERN_C();
+
+/** Convert all ASCII lowercase letters to uppercase within a string.
+
+ The characters with values between 97 and 122 (ASCII a--z) are replaced
+ with values between 65 and 90 (ASCII A--Z). The string must be
+ null-terminated.
+
+ @param str
+ a null-terminated string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_str_toAsciiUpperCase(
+ char * str ) SAL_THROW_EXTERN_C();
+
+/** Convert all ASCII lowercase letters to uppercase within a string.
+
+ The characters with values between 97 and 122 (ASCII a--z) are replaced
+ with values between 65 and 90 (ASCII A--Z).
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_str_toAsciiUpperCase_WithLength(
+ char * str, sal_Int32 len ) SAL_THROW_EXTERN_C();
+
+/** Remove white space from both ends of a string.
+
+ All characters with values less than or equal to 32 (the space character)
+ are considered to be white space. This function cannot be used for
+ language-specific operations. The string must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @return
+ the new length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_trim(
+ char * str ) SAL_THROW_EXTERN_C();
+
+/** Remove white space from both ends of the string.
+
+ All characters with values less than or equal to 32 (the space character)
+ are considered to be white space. This function cannot be used for
+ language-specific operations. The string must be null-terminated.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the original length of the string.
+
+ @return
+ the new length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_trim_WithLength(
+ char * str, sal_Int32 len ) SAL_THROW_EXTERN_C();
+
+/** Create the string representation of a boolean.
+
+ If b is true, the buffer is filled with the string "true" and 4 is
+ returned. If b is false, the buffer is filled with the string "false" and
+ 5 is returned. This function cannot be used for language-specific
+ operations.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_STR_MAX_VALUEOFBOOLEAN define to create
+ a buffer that is big enough.
+
+ @param b
+ a boolean value.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_valueOfBoolean(
+ char * str, sal_Bool b ) SAL_THROW_EXTERN_C();
+#define RTL_STR_MAX_VALUEOFBOOLEAN 6
+
+/** Create the string representation of a character.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_STR_MAX_VALUEOFCHAR define to create a
+ buffer that is big enough.
+
+ @param ch
+ a character value.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_valueOfChar(
+ char * str, char ch ) SAL_THROW_EXTERN_C();
+#define RTL_STR_MAX_VALUEOFCHAR 2
+
+/** Create the string representation of an integer.
+
+ This function cannot be used for language-specific operations.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_STR_MAX_VALUEOFINT32 define to create a
+ buffer that is big enough.
+
+ @param i
+ an integer value.
+
+ @param radix
+ the radix. Must be between RTL_STR_MIN_RADIX (2) and RTL_STR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_valueOfInt32(
+ char * str, sal_Int32 i, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+#define RTL_STR_MIN_RADIX 2
+#define RTL_STR_MAX_RADIX 36
+#define RTL_STR_MAX_VALUEOFINT32 33
+
+/** Create the string representation of a long integer.
+
+ This function cannot be used for language-specific operations.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_STR_MAX_VALUEOFINT64 define to create a
+ buffer that is big enough.
+
+ @param l
+ a long integer value.
+
+ @param radix
+ the radix. Must be between RTL_STR_MIN_RADIX (2) and RTL_STR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_valueOfInt64(
+ char * str, sal_Int64 l, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+#define RTL_STR_MAX_VALUEOFINT64 65
+
+/** Create the string representation of an unsigned long integer.
+
+ This function cannot be used for language-specific operations.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_STR_MAX_VALUEOFUINT64 define to create a
+ buffer that is big enough.
+
+ @param l
+ a long integer value.
+
+ @param radix
+ the radix. Must be between RTL_STR_MIN_RADIX (2) and RTL_STR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_valueOfUInt64(
+ char * str, sal_uInt64 l, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+#define RTL_STR_MAX_VALUEOFUINT64 65
+
+/** Create the string representation of a float.
+
+ This function cannot be used for language-specific conversion.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_STR_MAX_VALUEOFFLOAT define to create a
+ buffer that is big enough.
+
+ @param f
+ a float value.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_valueOfFloat(
+ char * str, float f ) SAL_THROW_EXTERN_C();
+#define RTL_STR_MAX_VALUEOFFLOAT 15
+
+/** Create the string representation of a double.
+
+ This function cannot be used for language-specific conversion.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_STR_MAX_VALUEOFDOUBLE define to create
+ a buffer that is big enough.
+
+ @param d
+ a double value.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_valueOfDouble(
+ char * str, double d ) SAL_THROW_EXTERN_C();
+#define RTL_STR_MAX_VALUEOFDOUBLE 25
+
+/** Interpret a string as a boolean.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @return
+ true if the string is "1" or "true" in any ASCII case, false otherwise.
+ */
+SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_str_toBoolean(
+ const char * str ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as an integer.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param radix
+ the radix. Must be between RTL_STR_MIN_RADIX (2) and RTL_STR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the integer value represented by the string, or 0 if the string does not
+ represent an integer.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_toInt32(
+ const char * str, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as an unsigned integer.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param radix
+ the radix. Must be between RTL_USTR_MIN_RADIX (2) and RTL_USTR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the unsigned integer value represented by the string, or 0 if the string
+ does not represent an unsigned integer.
+
+ @since LibreOffice 4.2
+ */
+SAL_DLLPUBLIC sal_uInt32 SAL_CALL rtl_str_toUInt32(
+ const char * str, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as a long integer.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param radix
+ the radix. Must be between RTL_STR_MIN_RADIX (2) and RTL_STR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the long integer value represented by the string, or 0 if the string does
+ not represent a long integer.
+ */
+SAL_DLLPUBLIC sal_Int64 SAL_CALL rtl_str_toInt64(
+ const char * str, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as a long integer.
+
+ This function cannot be used for language-specific conversion.
+
+ @param str
+ a string.
+
+ @param radix
+ the radix. Must be between RTL_STR_MIN_RADIX (2) and RTL_STR_MAX_RADIX
+ (36), inclusive.
+
+ @param nStrLength
+ number of chars to process
+
+ @return
+ the long integer value represented by the string, or 0 if the string does
+ not represent a long integer.
+
+ @internal
+ @since LibreOffice 6.4
+*/
+SAL_DLLPUBLIC sal_Int64 SAL_CALL rtl_str_toInt64_WithLength(
+ const char * str, sal_Int16 radix, sal_Int32 nStrLength ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as an unsigned long integer.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param radix
+ the radix. Must be between RTL_USTR_MIN_RADIX (2) and RTL_USTR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the unsigned long integer value represented by the string, or 0 if the
+ string does not represent an unsigned long integer.
+
+ @since LibreOffice 4.1
+ */
+SAL_DLLPUBLIC sal_uInt64 SAL_CALL rtl_str_toUInt64(
+ const char * str, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as a float.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @return
+ the float value represented by the string, or 0.0 if the string does not
+ represent a float.
+ */
+SAL_DLLPUBLIC float SAL_CALL rtl_str_toFloat(
+ const char * str ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as a double.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @return
+ the float value represented by the string, or 0.0 if the string does not
+ represent a double.
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_str_toDouble(
+ const char * str ) SAL_THROW_EXTERN_C();
+
+/* ======================================================================= */
+
+/** @cond INTERNAL */
+/** The implementation of a byte string.
+ */
+typedef struct _rtl_String
+{
+ oslInterlockedCount refCount; /* opaque */
+ sal_Int32 length;
+ char buffer[1];
+} rtl_String;
+/** @endcond */
+
+/* ----------------------------------------------------------------------- */
+
+/** Increment the reference count of a string.
+
+ @param str
+ a string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_acquire( rtl_String * str ) SAL_THROW_EXTERN_C();
+
+/** Decrement the reference count of a string.
+
+ If the count goes to zero than the string data is deleted.
+
+ @param str
+ a string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_release( rtl_String * str ) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string containing no characters.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_new( rtl_String ** newStr ) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string containing space for a given number of characters.
+
+ The reference count of the new string will be 1. The length of the string
+ will be nLen. This function does not handle out-of-memory conditions.
+
+ For failed allocation this method returns NULL.
+
+ The characters of the capacity are not cleared, and the length is set to
+ nLen, unlike the similar method of rtl_String_new_WithLength which
+ zeros out the buffer, and sets the length to 0. So should be somewhat
+ more efficient for allocating a new string.
+
+ call rtl_String_release to release the string
+ alternatively pass ownership to an OUString with
+ rtl::OUString(newStr, SAL_NO_ACQUIRE);
+
+ @param[out] nLen the number of characters. Must be >= 0.
+
+ @return pointer to the new string.
+
+ @since LibreOffice 4.1
+ */
+SAL_DLLPUBLIC rtl_String * SAL_CALL rtl_string_alloc(sal_Int32 nLen) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string containing space for a given number of characters.
+
+ If len is greater than zero, the reference count of the new string will be
+ 1. The values of all characters are set to 0 and the length of the string
+ is 0. This function does not handle out-of-memory conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param len
+ the number of characters.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_new_WithLength( rtl_String ** newStr, sal_Int32 len ) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string that contains a copy of another string.
+
+ If the length of value is greater than zero, the reference count of the
+ new string will be 1. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param value
+ a valid string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromString( rtl_String ** newStr, const rtl_String * value ) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string that contains a copy of a character array.
+
+ If the length of value is greater than zero, the reference count of the
+ new string will be 1. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param value
+ a null-terminated character array.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromStr( rtl_String ** newStr, const char * value ) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string that contains a copy of a character array.
+
+ If the length of value is greater than zero, the reference count of the
+ new string will be 1. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param value
+ a character array. Need not be null-terminated, but must be at least as
+ long as the specified len.
+
+ @param len
+ the length of the character array.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromStr_WithLength( rtl_String ** newStr, const char * value, sal_Int32 len ) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string that is a substring of this string.
+
+ The substring begins at the specified beginIndex and contains count
+ characters. Meaningless combinations such as negative beginIndex,
+ or beginIndex + count greater than the length of the string have
+ undefined behaviour.
+
+ @param[out] newStr the specified substring.
+ @param[in] from the String to take the substring from.
+ @param[in] beginIndex the beginning index, inclusive.
+ @param[in] count the number of characters.
+
+ @since LibreOffice 4.0
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromSubString(
+ rtl_String ** newStr, const rtl_String * from,
+ sal_Int32 beginIndex, sal_Int32 count ) SAL_THROW_EXTERN_C();
+
+/**
+ @internal
+ @since LibreOffice 3.6
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromLiteral( rtl_String ** newStr, const char * value, sal_Int32 len, sal_Int32 allocExtra ) SAL_THROW_EXTERN_C();
+
+/** Assign a new value to a string.
+
+ First releases any value str might currently hold, then acquires
+ rightValue.
+
+ @param str
+ pointer to the string. The pointed-to data must be null or a valid
+ string.
+
+ @param rightValue
+ a valid string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_assign( rtl_String ** str, rtl_String * rightValue ) SAL_THROW_EXTERN_C();
+
+/** Return the length of a string.
+
+ The length is equal to the number of characters in the string.
+
+ @param str
+ a valid string.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_string_getLength( const rtl_String * str ) SAL_THROW_EXTERN_C();
+
+/** Return a pointer to the underlying character array of a string.
+
+ @param str
+ a valid string.
+
+ @return
+ a pointer to the null-terminated character array.
+ */
+SAL_DLLPUBLIC char * SAL_CALL rtl_string_getStr( rtl_String * str ) SAL_THROW_EXTERN_C();
+
+/** Create a new string that is the concatenation of two other strings.
+
+ The new string does not necessarily have a reference count of 1 (in cases
+ where one of the two other strings is empty), so it must not be modified
+ without checking the reference count. This function does not handle
+ out-of-memory conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param left
+ a valid string.
+
+ @param right
+ a valid string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newConcat( rtl_String ** newStr, rtl_String * left, rtl_String * right ) SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing a substring of another string.
+
+ The new string results from replacing a number of characters (count),
+ starting at the specified position (index) in the original string (str),
+ with some new substring (subStr). If subStr is null, then only a number
+ of characters is deleted.
+
+ The new string does not necessarily have a reference count of 1, so it
+ must not be modified without checking the reference count. This function
+ does not handle out-of-memory conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param str
+ a valid string.
+
+ @param idx
+ the index into str at which to start replacement. Must be between 0 and
+ the length of str, inclusive.
+
+ @param count
+ the number of characters to remove. Must not be negative, and the sum of
+ index and count must not exceed the length of str.
+
+ @param subStr
+ either null or a valid string to be inserted.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newReplaceStrAt(
+ rtl_String ** newStr, rtl_String * str, sal_Int32 idx, sal_Int32 count, rtl_String * subStr ) SAL_THROW_EXTERN_C();
+
+#ifdef LIBO_INTERNAL_ONLY
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newReplaceStrAt_WithLength (
+ rtl_String ** newStr, rtl_String * str, sal_Int32 idx, sal_Int32 count, char const * subStr, sal_Int32 substrLen ) SAL_THROW_EXTERN_C();
+#endif
+
+/** Create a new string by replacing all occurrences of a single character
+ within another string.
+
+ The new string results from replacing all occurrences of oldChar in str
+ with newChar.
+
+ The new string does not necessarily have a reference count of 1 (in cases
+ where oldChar does not occur in str), so it must not be modified without
+ checking the reference count. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param str
+ a valid string.
+
+ @param oldChar
+ the old character.
+
+ @param newChar
+ the new character.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newReplace(
+ rtl_String ** newStr, rtl_String * str, char oldChar, char newChar ) SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing the first occurrence of a given substring
+ with another substring.
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_String
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p fromLength bytes
+
+ @param fromLength the length of the \p from substring; must be non-negative
+
+ @param to pointer to the replacing substring; must not be null and must
+ point to memory of at least \p toLength bytes
+
+ @param toLength the length of the \p to substring; must be non-negative
+
+ @param[in,out] index pointer to a start index, must not be null; upon entry
+ to the function its value is the index into the original string at which to
+ start searching for the \p from substring, the value must be non-negative
+ and not greater than the original string's length; upon exit from the
+ function its value is the index into the original string at which the
+ replacement took place or -1 if no replacement took place
+
+ @since LibreOffice 3.6
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newReplaceFirst(
+ rtl_String ** newStr, rtl_String * str, char const * from,
+ sal_Int32 fromLength, char const * to, sal_Int32 toLength,
+ sal_Int32 * index) SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing all occurrences of a given substring with
+ another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_String
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p fromLength bytes
+
+ @param fromLength the length of the \p from substring; must be non-negative
+
+ @param to pointer to the replacing substring; must not be null and must
+ point to memory of at least \p toLength bytes
+
+ @param toLength the length of the \p to substring; must be non-negative
+
+ @since LibreOffice 3.6
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newReplaceAll(
+ rtl_String ** newStr, rtl_String * str, char const * from,
+ sal_Int32 fromLength, char const * to, sal_Int32 toLength)
+ SAL_THROW_EXTERN_C();
+
+/** Create a new string by converting all ASCII uppercase letters to lowercase
+ within another string.
+
+ The new string results from replacing all characters with values between
+ 65 and 90 (ASCII A--Z) by values between 97 and 122 (ASCII a--z).
+
+ This function cannot be used for language-specific conversion. The new
+ string does not necessarily have a reference count of 1 (in cases where
+ no characters need to be converted), so it must not be modified without
+ checking the reference count. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param str
+ a valid string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newToAsciiLowerCase(
+ rtl_String ** newStr, rtl_String * str ) SAL_THROW_EXTERN_C();
+
+/** Create a new string by converting all ASCII lowercase letters to uppercase
+ within another string.
+
+ The new string results from replacing all characters with values between
+ 97 and 122 (ASCII a--z) by values between 65 and 90 (ASCII A--Z).
+
+ This function cannot be used for language-specific conversion. The new
+ string does not necessarily have a reference count of 1 (in cases where
+ no characters need to be converted), so it must not be modified without
+ checking the reference count. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param str
+ a valid string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newToAsciiUpperCase(
+ rtl_String ** newStr, rtl_String * str ) SAL_THROW_EXTERN_C();
+
+/** Create a new string by removing white space from both ends of another
+ string.
+
+ The new string results from removing all characters with values less than
+ or equal to 32 (the space character) form both ends of str.
+
+ This function cannot be used for language-specific conversion. The new
+ string does not necessarily have a reference count of 1 (in cases where
+ no characters need to be removed), so it must not be modified without
+ checking the reference count. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param str
+ a valid string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_newTrim(
+ rtl_String ** newStr, rtl_String * str ) SAL_THROW_EXTERN_C();
+
+/** Create a new string by extracting a single token from another string.
+
+ Starting at index, the next token is searched for. If there is no
+ such token, the result is an empty string. Otherwise, all characters from
+ the start of that token and up to, but not including the next occurrence
+ of cTok make up the resulting token. The return value is the position of
+ the next token, or -1 if no more tokens follow.
+
+ Example code could look like
+ rtl_String * pToken = NULL;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ...
+ nIndex = rtl_string_getToken(&pToken, pStr, 0, ';', nIndex);
+ ...
+ }
+ while (nIndex >= 0);
+
+ The new string does not necessarily have a reference count of 1, so it
+ must not be modified without checking the reference count. This function
+ does not handle out-of-memory conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string. If either token or index is negative, an empty token is stored in
+ newStr (and -1 is returned).
+
+ @param str
+ a valid string.
+
+ @param token
+ the number of the token to return, starting at index.
+
+ @param cTok
+ the character that separates the tokens.
+
+ @param idx
+ the position at which searching for the token starts. Must not be greater
+ than the length of str.
+
+ @return
+ the index of the next token, or -1 if no more tokens follow.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_string_getToken(
+ rtl_String ** newStr , rtl_String * str, sal_Int32 token, char cTok, sal_Int32 idx ) SAL_THROW_EXTERN_C();
+
+/* ======================================================================= */
+
+/** Supply an ASCII string literal together with its length.
+
+ This macro can be used to compute (some of) the arguments in function calls
+ like rtl::OString(RTL_CONSTASCII_STRINGPARAM("foo")) or
+ rtl::OUString::equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("foo")).
+
+ @param constAsciiStr
+ must be an expression of type "(possibly cv-qualified reference to) array of
+ (possibly cv-qualified) char." Each element of the referenced array must
+ represent an ASCII value in the range 0x00--0x7F. The last element of the
+ referenced array is not considered part of the represented ASCII string, and
+ its value should be 0x00. Depending on where this macro is used, the nature
+ of the supplied expression might be further restricted.
+*/
+// The &foo[0] trick is intentional, it makes sure the type is char* or const char*
+// (plain cast to const char* would not work with non-const char foo[]="a", which seems to be allowed).
+// This is to avoid mistaken use with functions that accept string literals
+// (i.e. const char (&)[N]) where usage of this macro otherwise could match
+// the argument and a following int argument with a default value (e.g. OString::match()).
+#define RTL_CONSTASCII_STRINGPARAM( constAsciiStr ) (&(constAsciiStr)[0]), \
+ ((sal_Int32)SAL_N_ELEMENTS(constAsciiStr)-1)
+
+/** Supply the length of an ASCII string literal.
+
+ This macro can be used to compute arguments in function calls like
+ rtl::OUString::match(other, RTL_CONSTASCII_LENGTH("prefix")).
+
+ @param constAsciiStr
+ must be an expression of type "(possibly cv-qualified reference to) array of
+ (possibly cv-qualified) char." Each element of the referenced array must
+ represent an ASCII value in the range 0x00--0x7F. The last element of the
+ referenced array is not considered part of the represented ASCII string, and
+ its value should be 0x00. Depending on where this macro is used, the nature
+ of the supplied expression might be further restricted.
+*/
+#define RTL_CONSTASCII_LENGTH( constAsciiStr ) ((sal_Int32)(SAL_N_ELEMENTS(constAsciiStr)-1))
+
+/* ======================================================================= */
+
+/* predefined constants for String-Conversion */
+#define OUSTRING_TO_OSTRING_CVTFLAGS (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT |\
+ RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT |\
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE |\
+ RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0)
+
+/* ----------------------------------------------------------------------- */
+
+/** Create a new byte string by converting a Unicode string, using a specific
+ text encoding.
+
+ The lengths of the byte string and the Unicode string may differ (e.g.,
+ for double-byte encodings, UTF-7, UTF-8).
+
+ If the length of the Unicode string is greater than zero, the reference
+ count of the new string will be 1.
+
+ If an out-of-memory condition occurs, newStr will point to a null pointer
+ upon return.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param str
+ a Unicode character array. Need not be null-terminated, but must be at
+ least as long as the specified len.
+
+ @param len
+ the length of the Unicode character array.
+
+ @param encoding
+ the text encoding to use for conversion.
+
+ @param convertFlags
+ flags which control the conversion. Either use
+ OUSTRING_TO_OSTRING_CVTFLAGS, or see
+ <http://udk.openoffice.org/cpp/man/spec/textconversion.html> for more
+ details.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString2String(
+ rtl_String ** newStr, const sal_Unicode * str, sal_Int32 len, rtl_TextEncoding encoding, sal_uInt32 convertFlags ) SAL_THROW_EXTERN_C();
+
+/**
+ Converts a Unicode string to a byte string, signalling failure.
+
+ @param pTarget
+ An out parameter receiving the converted string. Must not be null itself, and
+ must contain either null or a pointer to a valid rtl_String; the contents are
+ not modified if conversion fails (rtl_convertUStringToString returns false).
+
+ @param pSource
+ The Unicode string. May only be null if nLength is zero.
+
+ @param nLength
+ The length of the Unicode string. Must be non-negative.
+
+ @param nEncoding
+ The text encoding to convert into. Must be an octet encoding (i.e.,
+ rtl_isOctetTextEncoding(nEncoding) must return true).
+
+ @param nFlags
+ A combination of RTL_UNICODETOTEXT_FLAGS that detail how to do the conversion
+ (see rtl_convertUnicodeToText). RTL_UNICODETOTEXT_FLAGS_FLUSH need not be
+ included, it is implicitly assumed. Typical uses are either
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR (fail if a Unicode character cannot be
+ converted to the target nEncoding) or OUSTRING_TO_OSTRING_CVTFLAGS (make a
+ best efforts conversion).
+
+ @return
+ True if the conversion succeeded, false otherwise.
+ */
+SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_convertUStringToString(
+ rtl_String ** pTarget,
+ sal_Unicode const * pSource,
+ sal_Int32 nLength,
+ rtl_TextEncoding nEncoding,
+ sal_uInt32 nFlags)
+ SAL_THROW_EXTERN_C();
+
+/** Ensure a string has enough space for a given number of characters.
+
+ If the given string is large enough and has refcount of 1, it is not altered in any way.
+ Otherwise it is replaced by a copy that has enough space for the given number of characters,
+ data from the source string is copied to the beginning of it, the content of the remaining
+ capacity undefined, the string has refcount of 1, and refcount of the original string is decreased.
+
+ @param str
+ pointer to the string. The pointed-to data must be a valid string.
+
+ @param size
+ the number of characters
+
+ @since LibreOffice 4.1
+ @internal
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string_ensureCapacity( rtl_String ** str, sal_Int32 size ) SAL_THROW_EXTERN_C();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_RTL_STRING_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/string.hxx b/include/rtl/string.hxx
new file mode 100644
index 0000000000..91fb155a5e
--- /dev/null
+++ b/include/rtl/string.hxx
@@ -0,0 +1,2451 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_STRING_HXX
+#define INCLUDED_RTL_STRING_HXX
+
+#include "sal/config.h"
+
+#include <cassert>
+#include <cstddef>
+#include <cstdlib>
+#include <limits>
+#include <new>
+#include <ostream>
+#include <utility>
+#include <string.h>
+
+#if defined LIBO_INTERNAL_ONLY
+#include <algorithm>
+#include <string_view>
+#include <type_traits>
+#endif
+
+#include "rtl/math.h"
+#include "rtl/textenc.h"
+#include "rtl/string.h"
+#include "rtl/stringutils.hxx"
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+#include "config_global.h"
+#include "rtl/stringconcat.hxx"
+#endif
+
+#ifdef RTL_STRING_UNITTEST
+extern bool rtl_string_unittest_const_literal;
+extern bool rtl_string_unittest_const_literal_function;
+#endif
+
+// The unittest uses slightly different code to help check that the proper
+// calls are made. The class is put into a different namespace to make
+// sure the compiler generates a different (if generating also non-inline)
+// copy of the function and does not merge them together. The class
+// is "brought" into the proper rtl namespace by a typedef below.
+#ifdef RTL_STRING_UNITTEST
+#define rtl rtlunittest
+#endif
+
+namespace rtl
+{
+
+/// @cond INTERNAL
+#ifdef RTL_STRING_UNITTEST
+#undef rtl
+// helper macro to make functions appear more readable
+#define RTL_STRING_CONST_FUNCTION rtl_string_unittest_const_literal_function = true;
+#else
+#define RTL_STRING_CONST_FUNCTION
+#endif
+/// @endcond
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+
+/**
+A wrapper dressing a string literal as a static-refcount rtl_String.
+
+This class is not part of public API and is meant to be used only in LibreOffice code.
+@since LibreOffice 4.0
+*/
+template<std::size_t N> class SAL_WARN_UNUSED OStringLiteral {
+ static_assert(N != 0);
+ static_assert(N - 1 <= std::numeric_limits<sal_Int32>::max(), "literal too long");
+
+public:
+#if HAVE_CPP_CONSTEVAL
+ consteval
+#else
+ constexpr
+#endif
+ OStringLiteral(char const (&literal)[N]) {
+ assertLayout();
+ assert(literal[N - 1] == '\0');
+ std::copy_n(literal, N, more.buffer);
+ }
+
+#if !(defined _MSC_VER && _MSC_VER >= 1930 && _MSC_VER <= 1939 && defined _MANAGED)
+#if HAVE_CPP_CONSTEVAL
+ consteval
+#else
+ constexpr
+#endif
+ OStringLiteral(char8_t const (&literal)[N]) {
+ assertLayout();
+ assert(literal[N - 1] == '\0');
+ std::copy_n(literal, N, more.buffer);
+ }
+#endif
+
+ constexpr sal_Int32 getLength() const { return more.length; }
+
+ constexpr char const * getStr() const SAL_RETURNS_NONNULL { return more.buffer; }
+
+ constexpr operator std::string_view() const { return {more.buffer, sal_uInt32(more.length)}; }
+
+private:
+ static constexpr void assertLayout() {
+ // These static_asserts verifying the layout compatibility with rtl_String cannot be class
+ // member declarations, as offsetof requires a complete type, so defer them to here:
+ static_assert(std::is_standard_layout_v<OStringLiteral>);
+ static_assert(offsetof(OStringLiteral, str.refCount) == offsetof(OStringLiteral, more.refCount));
+ static_assert(offsetof(OStringLiteral, str.length) == offsetof(OStringLiteral, more.length));
+ static_assert(offsetof(OStringLiteral, str.buffer) == offsetof(OStringLiteral, more.buffer));
+ }
+
+ struct Data {
+ Data() = default;
+
+ oslInterlockedCount refCount = 0x40000000; // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx)
+ sal_Int32 length = N - 1;
+ char buffer[N];
+ };
+
+public:
+ // (Data members must be public so that OStringLiteral is a structural type that can be used as
+ // a non-type template parameter type for operator ""_ostr and rtl::detail::OStringHolder:)
+ union {
+ rtl_String str;
+ Data more = {};
+ };
+};
+
+#if !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+
+namespace detail {
+
+template<OStringLiteral L> struct OStringHolder {
+ static constexpr auto & literal = L;
+};
+
+}
+
+#endif
+
+#endif
+
+/* ======================================================================= */
+
+/**
+ This String class provide base functionality for C++ like 8-Bit
+ character array handling. The advantage of this class is, that it
+ handle all the memory management for you - and it do it
+ more efficient. If you assign a string to another string, the
+ data of both strings are shared (without any copy operation or
+ memory allocation) as long as you do not change the string. This class
+ stores also the length of the string, so that many operations are
+ faster as the C-str-functions.
+
+ This class provides only readonly string handling. So you could create
+ a string and you could only query the content from this string.
+ It provides also functionality to change the string, but this results
+ in every case in a new string instance (in the most cases with an
+ memory allocation). You don't have functionality to change the
+ content of the string. If you want to change the string content, then
+ you should use the OStringBuffer class, which provides these
+ functionalities and avoid too much memory allocation.
+
+ The design of this class is similar to the string classes in Java
+ and so more people should have fewer understanding problems when they
+ use this class.
+*/
+
+class SAL_WARN_UNUSED SAL_DLLPUBLIC_RTTI OString
+{
+public:
+ /// @cond INTERNAL
+ rtl_String * pData;
+ /// @endcond
+
+ /**
+ New string containing no characters.
+ */
+ OString()
+ {
+ pData = NULL;
+ rtl_string_new( &pData );
+ }
+
+ /**
+ New string from OString.
+
+ @param str an OString.
+ */
+#if defined LIBO_INTERNAL_ONLY && !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ constexpr
+#endif
+ OString( const OString & str )
+ {
+ pData = str.pData;
+#if defined LIBO_INTERNAL_ONLY && !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ if (std::is_constant_evaluated()) {
+ //TODO: We would want to
+ //
+ // assert(SAL_STRING_IS_STATIC(pData));
+ //
+ // here, but that wouldn't work because read of member `str` of OUStringLiteral's
+ // anonymous union with active member `more` is not allowed in a constant expression.
+ } else
+#endif
+ rtl_string_acquire( pData );
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /**
+ Move constructor.
+
+ @param str an OString.
+ @since LibreOffice 5.2
+ */
+#if !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ constexpr
+#endif
+ OString( OString && str ) noexcept
+ {
+ pData = str.pData;
+#if !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ if (std::is_constant_evaluated()) {
+ //TODO: We would want to
+ //
+ // assert(SAL_STRING_IS_STATIC(pData));
+ //
+ // here, but that wouldn't work because read of member `str` of OUStringLiteral's
+ // anonymous union with active member `more` is not allowed in a constant expression.
+ return;
+ }
+#endif
+ str.pData = nullptr;
+ rtl_string_new( &str.pData );
+ }
+#endif
+
+ /**
+ New string from OString data.
+
+ @param str an OString data.
+ */
+ OString( rtl_String * str )
+ {
+ pData = str;
+ rtl_string_acquire( pData );
+ }
+
+ /** New string from OString data without acquiring it. Takeover of ownership.
+
+ The SAL_NO_ACQUIRE dummy parameter is only there to distinguish this
+ from other constructors.
+
+ @param str an OString data.
+ */
+ OString( rtl_String * str, __sal_NoAcquire )
+ {
+ pData = str;
+ }
+
+ /**
+ New string from a single character.
+
+ @param value a character.
+ */
+ explicit OString( char value )
+ : pData (NULL)
+ {
+ rtl_string_newFromStr_WithLength( &pData, &value, 1 );
+ }
+
+#if defined LIBO_INTERNAL_ONLY && !defined RTL_STRING_UNITTEST_CONCAT
+ // Catch inadvertent conversions to the above ctor (e.g., from sal_[u]Int8, aka [un]signed
+ // char):
+ OString(int) = delete;
+#endif
+
+ /**
+ New string from a character buffer array.
+
+ Note: The argument type is always either char* or const char*. The template is
+ used only for technical reasons, as is the second argument.
+
+ @param value a NULL-terminated character array.
+ */
+ template< typename T >
+ OString( const T& value, typename libreoffice_internal::CharPtrDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy() )
+ {
+ pData = NULL;
+ rtl_string_newFromStr( &pData, value );
+ }
+
+ template< typename T >
+ OString( T& value, typename libreoffice_internal::NonConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy() )
+ {
+ pData = NULL;
+ rtl_string_newFromStr( &pData, value );
+ }
+
+#if __cplusplus > 202002L // C++23 P2266R3 "Simpler implicit move"
+ template< typename T >
+ OString( T&& value, typename libreoffice_internal::NonConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy() )
+ {
+ pData = NULL;
+ rtl_string_newFromStr( &pData, value );
+ }
+#endif
+
+ /**
+ New string from a string literal.
+
+ If there are any embedded \0's in the string literal, the result is undefined.
+ Use the overload that explicitly accepts length.
+
+ @since LibreOffice 3.6
+
+ @param literal a string literal
+ */
+ template< typename T >
+ OString( T& literal, typename libreoffice_internal::ConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy() )
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ pData = NULL;
+ if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) {
+ rtl_string_new(&pData);
+ } else {
+ rtl_string_newFromLiteral(
+ &pData,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length, 0);
+ }
+#ifdef RTL_STRING_UNITTEST
+ rtl_string_unittest_const_literal = true;
+#endif
+ }
+
+ /**
+ New string from a character buffer array.
+
+ @param value a character array.
+ @param length the number of character which should be copied.
+ The character array length must be greater or
+ equal than this value.
+ */
+ OString( const char * value, sal_Int32 length )
+ {
+ pData = NULL;
+ rtl_string_newFromStr_WithLength( &pData, value, length );
+ }
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ /// @cond INTERNAL
+ /**
+ New string from an 8-Bit string literal.
+
+ @since LibreOffice 7.1
+ */
+ template<std::size_t N> constexpr OString(OStringLiteral<N> const & literal):
+ pData(const_cast<rtl_String *>(&literal.str)) {}
+ template<std::size_t N> OString(OStringLiteral<N> &&) = delete;
+ /// @endcond
+#endif
+
+#if defined LIBO_INTERNAL_ONLY && !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ // For operator ""_tstr:
+ template<OStringLiteral L> constexpr OString(detail::OStringHolder<L> const & holder):
+ pData(const_cast<rtl_String *>(&holder.literal.str)) {}
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+ explicit OString(std::string_view sv) {
+ if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) {
+ throw std::bad_alloc();
+ }
+ pData = nullptr;
+ rtl_string_newFromStr_WithLength(&pData, sv.data(), sv.size());
+ }
+#endif
+
+ /**
+ New string from a Unicode character buffer array.
+
+ @param value a Unicode character array.
+ @param length the number of character which should be converted.
+ The Unicode character array length must be
+ greater or equal than this value.
+ @param encoding the text encoding in which the Unicode character
+ sequence should be converted.
+ @param convertFlags flags which controls the conversion.
+ see RTL_UNICODETOTEXT_FLAGS_...
+
+ @exception std::bad_alloc is thrown if an out-of-memory condition occurs
+ */
+ OString( const sal_Unicode * value, sal_Int32 length,
+ rtl_TextEncoding encoding,
+ sal_uInt32 convertFlags = OUSTRING_TO_OSTRING_CVTFLAGS )
+ {
+ pData = NULL;
+ rtl_uString2String( &pData, value, length, encoding, convertFlags );
+ if (pData == NULL) {
+ throw std::bad_alloc();
+ }
+ }
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ /**
+ @overload
+ @internal
+ */
+ template< typename T1, typename T2 >
+ OString( OStringConcat< T1, T2 >&& c )
+ {
+ const sal_Int32 l = c.length();
+ pData = rtl_string_alloc( l );
+ if (l != 0)
+ {
+ char* end = c.addData( pData->buffer );
+ pData->length = l;
+ *end = '\0';
+ }
+ }
+
+ /**
+ @overload
+ @internal
+ */
+ template< std::size_t N >
+ OString( OStringNumber< N >&& n )
+ : OString( n.buf, n.length )
+ {}
+#endif
+
+#ifdef LIBO_INTERNAL_ONLY
+ OString(std::nullptr_t) = delete;
+#endif
+
+ /**
+ Release the string data.
+ */
+#if defined LIBO_INTERNAL_ONLY && !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ constexpr
+#endif
+ ~OString()
+ {
+#if defined LIBO_INTERNAL_ONLY && !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ if (std::is_constant_evaluated()) {
+ //TODO: We would want to
+ //
+ // assert(SAL_STRING_IS_STATIC(pData));
+ //
+ // here, but that wouldn't work because read of member `str` of OUStringLiteral's
+ // anonymous union with active member `more` is not allowed in a constant expression.
+ } else
+#endif
+ rtl_string_release( pData );
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /** Provides an OString const & passing a storage pointer of an
+ rtl_String * handle.
+ It is more convenient to use C++ OString member functions when dealing
+ with rtl_String * handles. Using this function avoids unnecessary
+ acquire()/release() calls for a temporary OString object.
+
+ @param ppHandle
+ pointer to storage
+ @return
+ OString const & based on given storage
+ */
+ static OString const & unacquired( rtl_String * const * ppHandle )
+ { return * reinterpret_cast< OString const * >( ppHandle ); }
+#endif
+
+ /**
+ Assign a new string.
+
+ @param str an OString.
+ */
+ OString & operator=( const OString & str )
+ {
+ rtl_string_assign( &pData, str.pData );
+ return *this;
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /**
+ Move assign a new string.
+
+ @param str an OString.
+ @since LibreOffice 5.2
+ */
+ OString & operator=( OString && str ) noexcept
+ {
+ rtl_string_release( pData );
+ pData = str.pData;
+ str.pData = nullptr;
+ rtl_string_new( &str.pData );
+ return *this;
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, OString& >::Type operator=( T& literal )
+ {
+ RTL_STRING_CONST_FUNCTION
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) {
+ rtl_string_new(&pData);
+ } else {
+ rtl_string_newFromLiteral(
+ &pData,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length, 0);
+ }
+ return *this;
+ }
+
+ /**
+ Append a string to this string.
+
+ @param str an OString.
+ */
+ OString & operator+=( const OString & str )
+#if defined LIBO_INTERNAL_ONLY
+ &
+#endif
+ {
+ rtl_string_newConcat( &pData, pData, str.pData );
+ return *this;
+ }
+#if defined LIBO_INTERNAL_ONLY
+ void operator+=(OString const &) && = delete;
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+ template<typename T> typename libreoffice_internal::CharPtrDetector<T, OString &>::Type
+ operator +=(T const & value) & { return operator +=(std::string_view(value)); }
+ template<typename T> typename libreoffice_internal::CharPtrDetector<T, OString &>::Type
+ operator +=(T const &) && = delete;
+
+ template<typename T>
+ typename libreoffice_internal::NonConstCharArrayDetector<T, OString &>::Type
+ operator +=(T & value) & { return operator +=(std::string_view(value)); }
+ template<typename T>
+ typename libreoffice_internal::NonConstCharArrayDetector<T, OString &>::Type operator +=(T &) &&
+ = delete;
+
+ template<typename T> typename libreoffice_internal::ConstCharArrayDetector<T, OString &>::Type
+ operator +=(T & literal) & {
+ assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return operator +=(
+ std::string_view(
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length));
+ }
+ template<typename T> typename libreoffice_internal::ConstCharArrayDetector<T, OString &>::Type
+ operator +=(T &) && = delete;
+
+ template<std::size_t N> OString & operator +=(OStringLiteral<N> const & literal) &
+ { return operator +=(std::string_view(literal.getStr(), literal.getLength())); }
+ template<std::size_t N> void operator +=(OStringLiteral<N> const &) && = delete;
+
+ OString & operator +=(std::string_view sv) & {
+ if (sv.empty()) {
+ return *this;
+ }
+ if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max() - pData->length)) {
+ throw std::bad_alloc();
+ }
+ auto const l = pData->length + sv.size();
+ rtl_string_ensureCapacity(&pData, l);
+ *addDataHelper(pData->buffer + pData->length, sv.data(), sv.size()) = '\0';
+ pData->length = l;
+ return *this;
+ }
+ void operator +=(std::string_view) && = delete;
+#endif
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ /**
+ @overload
+ @internal
+ */
+ template< typename T1, typename T2 >
+ OString& operator+=( OStringConcat< T1, T2 >&& c ) & {
+ sal_Int32 l = c.length();
+ if( l == 0 )
+ return *this;
+ l += pData->length;
+ rtl_string_ensureCapacity( &pData, l );
+ char* end = c.addData( pData->buffer + pData->length );
+ *end = '\0';
+ pData->length = l;
+ return *this;
+ }
+ template<typename T1, typename T2> void operator +=(
+ OStringConcat<T1, T2> &&) && = delete;
+
+ /**
+ @overload
+ @internal
+ */
+ template< std::size_t N >
+ OString& operator+=( OStringNumber< N >&& n ) & {
+ return operator +=(std::string_view(n.buf, n.length));
+ }
+ template<std::size_t N> void operator +=(
+ OStringNumber<N> &&) && = delete;
+#endif
+
+ /**
+ Clears the string, i.e, makes a zero-character string
+ @since LibreOffice 4.4
+ */
+ void clear()
+ {
+ rtl_string_new( &pData );
+ }
+
+ /**
+ Returns the length of this string.
+
+ The length is equal to the number of characters in this string.
+
+ @return the length of the sequence of characters represented by this
+ object.
+ */
+ sal_Int32 getLength() const { return pData->length; }
+
+ /**
+ Checks if a string is empty.
+
+ @return true if the string is empty;
+ false, otherwise.
+
+ @since LibreOffice 3.4
+ */
+ bool isEmpty() const
+ {
+ return pData->length == 0;
+ }
+
+ /**
+ Returns a pointer to the characters of this string.
+
+ <p>The returned pointer is guaranteed to point to a null-terminated byte
+ string. But note that this string object may contain embedded null
+ characters, which will thus also be embedded in the returned
+ null-terminated byte string.</p>
+
+ @return a pointer to a null-terminated byte string representing the
+ characters of this string object.
+ */
+ const char * getStr() const SAL_RETURNS_NONNULL { return pData->buffer; }
+
+ /**
+ Access to individual characters.
+
+ @param index must be non-negative and less than length.
+
+ @return the character at the given index.
+
+ @since LibreOffice 3.5
+ */
+ char operator [](sal_Int32 index) const {
+ // silence spurious -Werror=strict-overflow warnings from GCC 4.8.2
+ assert(index >= 0 && static_cast<sal_uInt32>(index) < static_cast<sal_uInt32>(getLength()));
+ return getStr()[index];
+ }
+
+ /**
+ Compares two strings.
+
+ The comparison is based on the numeric value of each character in
+ the strings and return a value indicating their relationship.
+ This function can't be used for language specific sorting.
+
+ @param str the object to be compared.
+ @return 0 - if both strings are equal
+ < 0 - if this string is less than the string argument
+ > 0 - if this string is greater than the string argument
+ */
+ sal_Int32 compareTo( const OString & str ) const
+ {
+ return rtl_str_compare_WithLength( pData->buffer, pData->length,
+ str.pData->buffer, str.pData->length );
+ }
+
+ /**
+ Compares two strings with an maximum count of characters.
+
+ The comparison is based on the numeric value of each character in
+ the strings and return a value indicating their relationship.
+ This function can't be used for language specific sorting.
+
+ @param rObj the object to be compared.
+ @param maxLength the maximum count of characters to be compared.
+ @return 0 - if both strings are equal
+ < 0 - if this string is less than the string argument
+ > 0 - if this string is greater than the string argument
+ */
+ sal_Int32 compareTo( const OString & rObj, sal_Int32 maxLength ) const
+ {
+ return rtl_str_shortenedCompare_WithLength( pData->buffer, pData->length,
+ rObj.pData->buffer, rObj.pData->length, maxLength );
+ }
+
+ /**
+ Compares two strings in reverse order.
+
+ The comparison is based on the numeric value of each character in
+ the strings and return a value indicating their relationship.
+ This function can't be used for language specific sorting.
+
+ @param str the object to be compared.
+ @return 0 - if both strings are equal
+ < 0 - if this string is less than the string argument
+ > 0 - if this string is greater than the string argument
+ */
+ sal_Int32 reverseCompareTo( const OString & str ) const
+ {
+ return rtl_str_reverseCompare_WithLength( pData->buffer, pData->length,
+ str.pData->buffer, str.pData->length );
+ }
+
+ /**
+ Perform a comparison of two strings.
+
+ The result is true if and only if second string
+ represents the same sequence of characters as the first string.
+ This function can't be used for language specific comparison.
+
+ @param str the object to be compared.
+ @return true if the strings are equal;
+ false, otherwise.
+ */
+ bool equals( const OString & str ) const
+ {
+ if ( pData->length != str.pData->length )
+ return false;
+ if ( pData == str.pData )
+ return true;
+ return rtl_str_reverseCompare_WithLength( pData->buffer, pData->length,
+ str.pData->buffer, str.pData->length ) == 0;
+ }
+
+ /**
+ Perform a comparison of two strings.
+
+ The result is true if and only if second string
+ represents the same sequence of characters as the first string.
+ The ASCII string must be greater or equal as length.
+ This function can't be used for language specific comparison.
+
+
+ @param value a character array.
+ @param length the length of the character array.
+ @return true if the strings are equal;
+ false, otherwise.
+ */
+ bool equalsL( const char* value, sal_Int32 length ) const
+ {
+ if ( pData->length != length )
+ return false;
+
+ return rtl_str_reverseCompare_WithLength( pData->buffer, pData->length,
+ value, length ) == 0;
+ }
+
+ /**
+ Perform an ASCII lowercase comparison of two strings.
+
+ The result is true if and only if second string
+ represents the same sequence of characters as the first string,
+ ignoring the case.
+ Character values between 65 and 90 (ASCII A-Z) are interpreted as
+ values between 97 and 122 (ASCII a-z).
+ This function can't be used for language specific comparison.
+
+ @param str the object to be compared.
+ @return true if the strings are equal;
+ false, otherwise.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ bool equalsIgnoreAsciiCase( std::string_view str ) const
+ {
+ if ( sal_uInt32(pData->length) != str.size() )
+ return false;
+ if ( pData->buffer == str.data() )
+ return true;
+ return rtl_str_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
+ str.data(), str.size() ) == 0;
+ }
+#else
+ bool equalsIgnoreAsciiCase( const OString & str ) const
+ {
+ if ( pData->length != str.pData->length )
+ return false;
+ if ( pData == str.pData )
+ return true;
+ return rtl_str_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
+ str.pData->buffer, str.pData->length ) == 0;
+ }
+#endif
+
+ /**
+ Perform an ASCII lowercase comparison of two strings.
+
+ The result is true if and only if second string
+ represents the same sequence of characters as the first string,
+ ignoring the case.
+ Character values between 65 and 90 (ASCII A-Z) are interpreted as
+ values between 97 and 122 (ASCII a-z).
+ Since this method is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range between 0 and
+ 127. The ASCII string must be NULL-terminated.
+ This function can't be used for language specific comparison.
+
+ Note: The argument type is always either char* or const char*, the return type is bool.
+ The template is used only for technical reasons.
+
+ @param asciiStr the 8-Bit ASCII character string to be compared.
+ @return true if the strings are equal;
+ false, otherwise.
+ */
+ template< typename T >
+ typename libreoffice_internal::CharPtrDetector< T, bool >::Type equalsIgnoreAsciiCase( const T& asciiStr ) const
+ {
+ return rtl_str_compareIgnoreAsciiCase( pData->buffer, asciiStr ) == 0;
+ }
+
+ template< typename T >
+ typename libreoffice_internal::NonConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& asciiStr ) const
+ {
+ return rtl_str_compareIgnoreAsciiCase( pData->buffer, asciiStr ) == 0;
+ }
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& literal ) const
+ {
+ RTL_STRING_CONST_FUNCTION
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return
+ (pData->length
+ == libreoffice_internal::ConstCharArrayDetector<T>::length)
+ && (rtl_str_compareIgnoreAsciiCase_WithLength(
+ pData->buffer, pData->length,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length)
+ == 0);
+ }
+
+ /**
+ Perform an ASCII lowercase comparison of two strings.
+
+ The result is true if and only if second string
+ represents the same sequence of characters as the first string,
+ ignoring the case.
+ Character values between 65 and 90 (ASCII A-Z) are interpreted as
+ values between 97 and 122 (ASCII a-z).
+ Since this method is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range between 0 and
+ 127. The ASCII string must be greater or equal in length as asciiStrLength.
+ This function can't be used for language specific comparison.
+
+ @param asciiStr the 8-Bit ASCII character string to be compared.
+ @param asciiStrLength the length of the ascii string
+ @return true if the strings are equal;
+ false, otherwise.
+ */
+ bool equalsIgnoreAsciiCaseL( const char * asciiStr, sal_Int32 asciiStrLength ) const
+ {
+ if ( pData->length != asciiStrLength )
+ return false;
+
+ return rtl_str_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
+ asciiStr, asciiStrLength ) == 0;
+ }
+
+ /**
+ Match against a substring appearing in this string.
+
+ The result is true if and only if the second string appears as a substring
+ of this string, at the given position.
+ This function can't be used for language specific comparison.
+
+ @param str the object (substring) to be compared.
+ @param fromIndex the index to start the comparison from.
+ The index must be greater or equal than 0
+ and less or equal as the string length.
+ @return true if str match with the characters in the string
+ at the given position;
+ false, otherwise.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ bool match( std::string_view str, sal_Int32 fromIndex = 0 ) const
+ {
+ return rtl_str_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
+ str.data(), str.size(), str.size() ) == 0;
+ }
+#else
+ bool match( const OString & str, sal_Int32 fromIndex = 0 ) const
+ {
+ return rtl_str_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
+ str.pData->buffer, str.pData->length, str.pData->length ) == 0;
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type match( T& literal, sal_Int32 fromIndex = 0 ) const
+ {
+ RTL_STRING_CONST_FUNCTION
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return
+ rtl_str_shortenedCompare_WithLength(
+ pData->buffer + fromIndex, pData->length - fromIndex,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length,
+ libreoffice_internal::ConstCharArrayDetector<T>::length)
+ == 0;
+ }
+
+ /**
+ Match against a substring appearing in this string.
+
+ @param str the substring to be compared; must not be null and must point
+ to memory of at least strLength bytes
+
+ @param strLength the length of the substring; must be non-negative
+
+ @param fromIndex the index into this string to start the comparison at;
+ must be non-negative and not greater than this string's length
+
+ @return true if and only if the given str is contained as a substring of
+ this string at the given fromIndex
+
+ @since LibreOffice 3.6
+ */
+ bool matchL(
+ char const * str, sal_Int32 strLength, sal_Int32 fromIndex = 0)
+ const
+ {
+ return rtl_str_shortenedCompare_WithLength(
+ pData->buffer + fromIndex, pData->length - fromIndex,
+ str, strLength, strLength) == 0;
+ }
+
+ // This overload is left undefined, to detect calls of matchL that
+ // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of
+ // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit
+ // platforms):
+#if SAL_TYPES_SIZEOFLONG == 8
+ void matchL(char const *, sal_Int32, rtl_TextEncoding) const;
+#endif
+
+ /**
+ Match against a substring appearing in this string, ignoring the case of
+ ASCII letters.
+
+ The result is true if and only if the second string appears as a substring
+ of this string, at the given position.
+ Character values between 65 and 90 (ASCII A-Z) are interpreted as
+ values between 97 and 122 (ASCII a-z).
+ This function can't be used for language specific comparison.
+
+ @param str the object (substring) to be compared.
+ @param fromIndex the index to start the comparison from.
+ The index must be greater or equal than 0
+ and less or equal as the string length.
+ @return true if str match with the characters in the string
+ at the given position;
+ false, otherwise.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ bool matchIgnoreAsciiCase( std::string_view str, sal_Int32 fromIndex = 0 ) const
+ {
+ return rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
+ str.data(), str.size(),
+ str.size() ) == 0;
+ }
+#else
+ bool matchIgnoreAsciiCase( const OString & str, sal_Int32 fromIndex = 0 ) const
+ {
+ return rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
+ str.pData->buffer, str.pData->length,
+ str.pData->length ) == 0;
+ }
+#endif
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type matchIgnoreAsciiCase( T& literal, sal_Int32 fromIndex = 0 ) const
+ {
+ RTL_STRING_CONST_FUNCTION
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return
+ rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(
+ pData->buffer+fromIndex, pData->length-fromIndex,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length,
+ libreoffice_internal::ConstCharArrayDetector<T>::length)
+ == 0;
+ }
+
+ /**
+ Check whether this string starts with a given substring.
+
+ @param str the substring to be compared
+
+ @param rest if non-null, and this function returns true, then assign a
+ copy of the remainder of this string to *rest. Available since
+ LibreOffice 4.2
+
+ @return true if and only if the given str appears as a substring at the
+ start of this string
+
+ @since LibreOffice 4.0
+ */
+#if defined LIBO_INTERNAL_ONLY
+ bool startsWith(std::string_view str, OString * rest = NULL) const {
+ bool b = match(str);
+ if (b && rest != NULL) {
+ *rest = copy(str.size());
+ }
+ return b;
+ }
+#else
+ bool startsWith(OString const & str, OString * rest = NULL) const {
+ bool b = match(str);
+ if (b && rest != NULL) {
+ *rest = copy(str.getLength());
+ }
+ return b;
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 4.0
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type startsWith(
+ T & literal, OString * rest = NULL) const
+ {
+ RTL_STRING_CONST_FUNCTION
+ bool b = match(literal, 0);
+ if (b && rest != NULL) {
+ *rest = copy(
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+ return b;
+ }
+
+ /**
+ Check whether this string starts with a given string, ignoring the case of
+ ASCII letters.
+
+ Character values between 65 and 90 (ASCII A-Z) are interpreted as
+ values between 97 and 122 (ASCII a-z).
+ This function can't be used for language specific comparison.
+
+ @param str the substring to be compared
+
+ @param rest if non-null, and this function returns true, then assign a
+ copy of the remainder of this string to *rest.
+
+ @return true if and only if the given str appears as a substring at the
+ start of this string, ignoring the case of ASCII letters ("A"--"Z" and
+ "a"--"z")
+
+ @since LibreOffice 5.1
+ */
+#if defined LIBO_INTERNAL_ONLY
+ bool startsWithIgnoreAsciiCase(std::string_view str, OString * rest = NULL)
+ const
+ {
+ bool b = matchIgnoreAsciiCase(str);
+ if (b && rest != NULL) {
+ *rest = copy(str.size());
+ }
+ return b;
+ }
+#else
+ bool startsWithIgnoreAsciiCase(OString const & str, OString * rest = NULL)
+ const
+ {
+ bool b = matchIgnoreAsciiCase(str);
+ if (b && rest != NULL) {
+ *rest = copy(str.getLength());
+ }
+ return b;
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 5.1
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type
+ startsWithIgnoreAsciiCase(T & literal, OString * rest = NULL) const
+ {
+ RTL_STRING_CONST_FUNCTION
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ bool b = matchIgnoreAsciiCase(literal);
+ if (b && rest != NULL) {
+ *rest = copy(
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+ return b;
+ }
+
+ /**
+ Check whether this string ends with a given substring.
+
+ @param str the substring to be compared
+
+ @param rest if non-null, and this function returns true, then assign a
+ copy of the remainder of this string to *rest. Available since
+ LibreOffice 4.2
+
+ @return true if and only if the given str appears as a substring at the
+ end of this string
+
+ @since LibreOffice 3.6
+ */
+#if defined LIBO_INTERNAL_ONLY
+ bool endsWith(std::string_view str, OString * rest = NULL) const {
+ bool b = str.size() <= sal_uInt32(getLength())
+ && match(str, getLength() - str.size());
+ if (b && rest != NULL) {
+ *rest = copy(0, getLength() - str.size());
+ }
+ return b;
+ }
+#else
+ bool endsWith(OString const & str, OString * rest = NULL) const {
+ bool b = str.getLength() <= getLength()
+ && match(str, getLength() - str.getLength());
+ if (b && rest != NULL) {
+ *rest = copy(0, getLength() - str.getLength());
+ }
+ return b;
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type endsWith(
+ T & literal, OString * rest = NULL) const
+ {
+ RTL_STRING_CONST_FUNCTION
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ bool b
+ = (libreoffice_internal::ConstCharArrayDetector<T>::length
+ <= sal_uInt32(getLength()))
+ && match(
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ (getLength()
+ - libreoffice_internal::ConstCharArrayDetector<T>::length));
+ if (b && rest != NULL) {
+ *rest = copy(
+ 0,
+ (getLength()
+ - libreoffice_internal::ConstCharArrayDetector<T>::length));
+ }
+ return b;
+ }
+
+ /**
+ Check whether this string ends with a given substring.
+
+ @param str the substring to be compared; must not be null and must point
+ to memory of at least strLength bytes
+
+ @param strLength the length of the substring; must be non-negative
+
+ @return true if and only if the given str appears as a substring at the
+ end of this string
+
+ @since LibreOffice 3.6
+ */
+ bool endsWithL(char const * str, sal_Int32 strLength) const {
+ return strLength <= getLength()
+ && matchL(str, strLength, getLength() - strLength);
+ }
+
+ friend bool operator == ( const OString& rStr1, const OString& rStr2 )
+ { return rStr1.equals(rStr2); }
+ friend bool operator != ( const OString& rStr1, const OString& rStr2 )
+ { return !(operator == ( rStr1, rStr2 )); }
+ friend bool operator < ( const OString& rStr1, const OString& rStr2 )
+ { return rStr1.compareTo( rStr2 ) < 0; }
+ friend bool operator > ( const OString& rStr1, const OString& rStr2 )
+ { return rStr1.compareTo( rStr2 ) > 0; }
+ friend bool operator <= ( const OString& rStr1, const OString& rStr2 )
+ { return rStr1.compareTo( rStr2 ) <= 0; }
+ friend bool operator >= ( const OString& rStr1, const OString& rStr2 )
+ { return rStr1.compareTo( rStr2 ) >= 0; }
+
+ template< typename T >
+ friend typename libreoffice_internal::CharPtrDetector< T, bool >::Type operator==( const OString& rStr1, const T& value )
+ {
+ return
+ rtl_str_compare_WithLength(
+ rStr1.getStr(), rStr1.getLength(), value, rtl_str_getLength(value))
+ == 0;
+ }
+
+ template< typename T >
+ friend typename libreoffice_internal::NonConstCharArrayDetector< T, bool >::Type operator==( const OString& rStr1, T& value )
+ {
+ return
+ rtl_str_compare_WithLength(
+ rStr1.getStr(), rStr1.getLength(), value, rtl_str_getLength(value))
+ == 0;
+ }
+
+ template< typename T >
+ friend typename libreoffice_internal::CharPtrDetector< T, bool >::Type operator==( const T& value, const OString& rStr2 )
+ {
+ return
+ rtl_str_compare_WithLength(
+ value, rtl_str_getLength(value), rStr2.getStr(), rStr2.getLength())
+ == 0;
+ }
+
+ template< typename T >
+ friend typename libreoffice_internal::NonConstCharArrayDetector< T, bool >::Type operator==( T& value, const OString& rStr2 )
+ {
+ return
+ rtl_str_compare_WithLength(
+ value, rtl_str_getLength(value), rStr2.getStr(), rStr2.getLength())
+ == 0;
+ }
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator==( const OString& rStr, T& literal )
+ {
+ RTL_STRING_CONST_FUNCTION
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return
+ (rStr.getLength()
+ == libreoffice_internal::ConstCharArrayDetector<T>::length)
+ && (rtl_str_compare_WithLength(
+ rStr.pData->buffer, rStr.pData->length,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length)
+ == 0);
+ }
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator==( T& literal, const OString& rStr )
+ {
+ RTL_STRING_CONST_FUNCTION
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return
+ (rStr.getLength()
+ == libreoffice_internal::ConstCharArrayDetector<T>::length)
+ && (rtl_str_compare_WithLength(
+ rStr.pData->buffer, rStr.pData->length,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length)
+ == 0);
+ }
+
+ template< typename T >
+ friend typename libreoffice_internal::CharPtrDetector< T, bool >::Type operator!=( const OString& rStr1, const T& value )
+ {
+ return !(operator == ( rStr1, value ));
+ }
+
+ template< typename T >
+ friend typename libreoffice_internal::NonConstCharArrayDetector< T, bool >::Type operator!=( const OString& rStr1, T& value )
+ {
+ return !(operator == ( rStr1, value ));
+ }
+
+ template< typename T >
+ friend typename libreoffice_internal::CharPtrDetector< T, bool >::Type operator!=( const T& value, const OString& rStr2 )
+ {
+ return !(operator == ( value, rStr2 ));
+ }
+
+ template< typename T >
+ friend typename libreoffice_internal::NonConstCharArrayDetector< T, bool >::Type operator!=( T& value, const OString& rStr2 )
+ {
+ return !(operator == ( value, rStr2 ));
+ }
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator!=( const OString& rStr, T& literal )
+ {
+ return !( rStr == literal );
+ }
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator!=( T& literal, const OString& rStr )
+ {
+ return !( literal == rStr );
+ }
+
+ /**
+ Returns a hashcode for this string.
+
+ @return a hash code value for this object.
+
+ @see rtl::OStringHash for convenient use of std::unordered_map
+ */
+ sal_Int32 hashCode() const
+ {
+ return rtl_str_hashCode_WithLength( pData->buffer, pData->length );
+ }
+
+ /**
+ Returns the index within this string of the first occurrence of the
+ specified character, starting the search at the specified index.
+
+ @param ch character to be located.
+ @param fromIndex the index to start the search from.
+ The index must be greater or equal than 0
+ and less or equal as the string length.
+ @return the index of the first occurrence of the character in the
+ character sequence represented by this string that is
+ greater than or equal to fromIndex, or
+ -1 if the character does not occur.
+ */
+ sal_Int32 indexOf( char ch, sal_Int32 fromIndex = 0 ) const
+ {
+ sal_Int32 ret = rtl_str_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch );
+ return (ret < 0 ? ret : ret+fromIndex);
+ }
+
+ /**
+ Returns the index within this string of the last occurrence of the
+ specified character, searching backward starting at the end.
+
+ @param ch character to be located.
+ @return the index of the last occurrence of the character in the
+ character sequence represented by this string, or
+ -1 if the character does not occur.
+ */
+ sal_Int32 lastIndexOf( char ch ) const
+ {
+ return rtl_str_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch );
+ }
+
+ /**
+ Returns the index within this string of the last occurrence of the
+ specified character, searching backward starting before the specified
+ index.
+
+ @param ch character to be located.
+ @param fromIndex the index before which to start the search.
+ @return the index of the last occurrence of the character in the
+ character sequence represented by this string that
+ is less than fromIndex, or -1
+ if the character does not occur before that point.
+ */
+ sal_Int32 lastIndexOf( char ch, sal_Int32 fromIndex ) const
+ {
+ return rtl_str_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch );
+ }
+
+ /**
+ Returns the index within this string of the first occurrence of the
+ specified substring, starting at the specified index.
+
+ If str doesn't include any character, always -1 is
+ returned. This is also the case, if both strings are empty.
+
+ @param str the substring to search for.
+ @param fromIndex the index to start the search from.
+ @return If the string argument occurs one or more times as a substring
+ within this string at the starting index, then the index
+ of the first character of the first such substring is
+ returned. If it does not occur as a substring starting
+ at fromIndex or beyond, -1 is returned.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 indexOf( std::string_view str, sal_Int32 fromIndex = 0 ) const
+ {
+ sal_Int32 ret = rtl_str_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
+ str.data(), str.size() );
+ return (ret < 0 ? ret : ret+fromIndex);
+ }
+#else
+ sal_Int32 indexOf( const OString & str, sal_Int32 fromIndex = 0 ) const
+ {
+ sal_Int32 ret = rtl_str_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
+ str.pData->buffer, str.pData->length );
+ return (ret < 0 ? ret : ret+fromIndex);
+ }
+#endif
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const
+ {
+ RTL_STRING_CONST_FUNCTION
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ sal_Int32 n = rtl_str_indexOfStr_WithLength(
+ pData->buffer + fromIndex, pData->length - fromIndex,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ return n < 0 ? n : n + fromIndex;
+ }
+
+ /**
+ Returns the index within this string of the first occurrence of the
+ specified substring, starting at the specified index.
+
+ If str doesn't include any character, always -1 is
+ returned. This is also the case, if both strings are empty.
+
+ @param str the substring to search for.
+ @param len the length of the substring.
+ @param fromIndex the index to start the search from.
+ @return If the string argument occurs one or more times as a substring
+ within this string at the starting index, then the index
+ of the first character of the first such substring is
+ returned. If it does not occur as a substring starting
+ at fromIndex or beyond, -1 is returned.
+
+ @since LibreOffice 3.6
+ */
+ sal_Int32 indexOfL(char const * str, sal_Int32 len, sal_Int32 fromIndex = 0)
+ const
+ {
+ sal_Int32 n = rtl_str_indexOfStr_WithLength(
+ pData->buffer + fromIndex, pData->length - fromIndex, str, len);
+ return n < 0 ? n : n + fromIndex;
+ }
+
+ // This overload is left undefined, to detect calls of indexOfL that
+ // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of
+ // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit
+ // platforms):
+#if SAL_TYPES_SIZEOFLONG == 8
+ void indexOfL(char const *, sal_Int32, rtl_TextEncoding) const;
+#endif
+
+ /**
+ Returns the index within this string of the last occurrence of
+ the specified substring, searching backward starting at the end.
+
+ The returned index indicates the starting index of the substring
+ in this string.
+ If str doesn't include any character, always -1 is
+ returned. This is also the case, if both strings are empty.
+
+ @param str the substring to search for.
+ @return If the string argument occurs one or more times as a substring
+ within this string, then the index of the first character of
+ the last such substring is returned. If it does not occur as
+ a substring, -1 is returned.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 lastIndexOf( std::string_view str ) const
+ {
+ return rtl_str_lastIndexOfStr_WithLength( pData->buffer, pData->length,
+ str.data(), str.size() );
+ }
+#else
+ sal_Int32 lastIndexOf( const OString & str ) const
+ {
+ return rtl_str_lastIndexOfStr_WithLength( pData->buffer, pData->length,
+ str.pData->buffer, str.pData->length );
+ }
+#endif
+
+ /**
+ Returns the index within this string of the last occurrence of
+ the specified substring, searching backward starting before the specified
+ index.
+
+ The returned index indicates the starting index of the substring
+ in this string.
+ If str doesn't include any character, always -1 is
+ returned. This is also the case, if both strings are empty.
+
+ @param str the substring to search for.
+ @param fromIndex the index before which to start the search.
+ @return If the string argument occurs one or more times as a substring
+ within this string before the starting index, then the index
+ of the first character of the last such substring is
+ returned. Otherwise, -1 is returned.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 lastIndexOf( std::string_view str, sal_Int32 fromIndex ) const
+ {
+ return rtl_str_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
+ str.data(), str.size() );
+ }
+#else
+ sal_Int32 lastIndexOf( const OString & str, sal_Int32 fromIndex ) const
+ {
+ return rtl_str_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
+ str.pData->buffer, str.pData->length );
+ }
+#endif
+
+ /**
+ Returns a new string that is a substring of this string.
+
+ The substring begins at the specified beginIndex. If
+ beginIndex is negative or be greater than the length of
+ this string, behaviour is undefined.
+
+ @param beginIndex the beginning index, inclusive.
+ @return the specified substring.
+ */
+ SAL_WARN_UNUSED_RESULT OString copy( sal_Int32 beginIndex ) const
+ {
+ return copy(beginIndex, getLength() - beginIndex);
+ }
+
+ /**
+ Returns a new string that is a substring of this string.
+
+ The substring begins at the specified beginIndex and contains count
+ characters. If either beginIndex or count are negative,
+ or beginIndex + count are greater than the length of this string
+ then behaviour is undefined.
+
+ @param beginIndex the beginning index, inclusive.
+ @param count the number of characters.
+ @return the specified substring.
+ */
+ SAL_WARN_UNUSED_RESULT OString copy( sal_Int32 beginIndex, sal_Int32 count ) const
+ {
+ rtl_String *pNew = NULL;
+ rtl_string_newFromSubString( &pNew, pData, beginIndex, count );
+ return OString( pNew, SAL_NO_ACQUIRE );
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /**
+ Returns a std::string_view that is a view of a substring of this string.
+
+ The substring begins at the specified beginIndex. If
+ beginIndex is negative or be greater than the length of
+ this string, behaviour is undefined.
+
+ @param beginIndex the beginning index, inclusive.
+ @return the specified substring.
+ */
+ SAL_WARN_UNUSED_RESULT std::string_view subView( sal_Int32 beginIndex ) const
+ {
+ assert(beginIndex >= 0);
+ assert(beginIndex <= getLength());
+ return subView(beginIndex, getLength() - beginIndex);
+ }
+
+ /**
+ Returns a std::string_view that is a view of a substring of this string.
+
+ The substring begins at the specified beginIndex and contains count
+ characters. If either beginIndex or count are negative,
+ or beginIndex + count are greater than the length of this string
+ then behaviour is undefined.
+
+ @param beginIndex the beginning index, inclusive.
+ @param count the number of characters.
+ @return the specified substring.
+ */
+ SAL_WARN_UNUSED_RESULT std::string_view subView( sal_Int32 beginIndex, sal_Int32 count ) const
+ {
+ assert(beginIndex >= 0);
+ assert(count >= 0);
+ assert(beginIndex <= getLength());
+ assert(count <= getLength() - beginIndex);
+ return std::string_view(*this).substr(beginIndex, count);
+ }
+#endif
+
+#ifndef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ /**
+ Concatenates the specified string to the end of this string.
+
+ @param str the string that is concatenated to the end
+ of this string.
+ @return a string that represents the concatenation of this string
+ followed by the string argument.
+ */
+ SAL_WARN_UNUSED_RESULT OString concat( const OString & str ) const
+ {
+ rtl_String* pNew = NULL;
+ rtl_string_newConcat( &pNew, pData, str.pData );
+ return OString( pNew, SAL_NO_ACQUIRE );
+ }
+#endif
+
+#ifndef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ friend OString operator+( const OString & str1, const OString & str2 )
+ {
+ return str1.concat( str2 );
+ }
+#endif
+
+// hide this from internal code to avoid ambiguous lookup error
+#ifndef LIBO_INTERNAL_ONLY
+ /**
+ Returns a new string resulting from replacing n = count characters
+ from position index in this string with newStr.
+
+ @param index the replacing index in str.
+ The index must be greater or equal as 0 and
+ less or equal as the length of the string.
+ @param count the count of characters that will replaced
+ The count must be greater or equal as 0 and
+ less or equal as the length of the string minus index.
+ @param newStr the new substring.
+ @return the new string.
+ */
+ SAL_WARN_UNUSED_RESULT OString replaceAt( sal_Int32 index, sal_Int32 count, const OString& newStr ) const
+ {
+ rtl_String* pNew = NULL;
+ rtl_string_newReplaceStrAt( &pNew, pData, index, count, newStr.pData );
+ return OString( pNew, SAL_NO_ACQUIRE );
+ }
+#endif
+
+#ifdef LIBO_INTERNAL_ONLY
+ SAL_WARN_UNUSED_RESULT OString replaceAt( sal_Int32 index, sal_Int32 count, std::string_view newStr ) const
+ {
+ rtl_String* pNew = NULL;
+ rtl_string_newReplaceStrAt_WithLength ( &pNew, pData, index, count, newStr.data(), newStr.size() );
+ return OString( pNew, SAL_NO_ACQUIRE );
+ }
+#endif
+
+ /**
+ Returns a new string resulting from replacing all occurrences of
+ oldChar in this string with newChar.
+
+ If the character oldChar does not occur in the character sequence
+ represented by this object, then the string is assigned with
+ str.
+
+ @param oldChar the old character.
+ @param newChar the new character.
+ @return a string derived from this string by replacing every
+ occurrence of oldChar with newChar.
+ */
+ SAL_WARN_UNUSED_RESULT OString replace( char oldChar, char newChar ) const
+ {
+ rtl_String* pNew = NULL;
+ rtl_string_newReplace( &pNew, pData, oldChar, newChar );
+ return OString( pNew, SAL_NO_ACQUIRE );
+ }
+
+ /**
+ Returns a new string resulting from replacing the first occurrence of a
+ given substring with another substring.
+
+ @param from the substring to be replaced
+
+ @param to the replacing substring
+
+ @param[in,out] index pointer to a start index; if the pointer is
+ non-null: upon entry to the function, its value is the index into the this
+ string at which to start searching for the \p from substring, the value
+ must be non-negative and not greater than this string's length; upon exit
+ from the function its value is the index into this string at which the
+ replacement took place or -1 if no replacement took place; if the pointer
+ is null, searching always starts at index 0
+
+ @since LibreOffice 3.6
+ */
+ SAL_WARN_UNUSED_RESULT OString replaceFirst(
+ OString const & from, OString const & to, sal_Int32 * index = NULL) const
+ {
+ rtl_String * s = NULL;
+ sal_Int32 i = 0;
+ rtl_string_newReplaceFirst(
+ &s, pData, from.pData->buffer, from.pData->length,
+ to.pData->buffer, to.pData->length, index == NULL ? &i : index);
+ return OString(s, SAL_NO_ACQUIRE);
+ }
+
+ /**
+ Returns a new string resulting from replacing all occurrences of a given
+ substring with another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param from the substring to be replaced
+
+ @param to the replacing substring
+
+ @since LibreOffice 3.6
+ */
+ SAL_WARN_UNUSED_RESULT OString replaceAll(OString const & from, OString const & to) const {
+ rtl_String * s = NULL;
+ rtl_string_newReplaceAll(
+ &s, pData, from.pData->buffer, from.pData->length,
+ to.pData->buffer, to.pData->length);
+ return OString(s, SAL_NO_ACQUIRE);
+ }
+
+ /**
+ Converts from this string all ASCII uppercase characters (65-90)
+ to ASCII lowercase characters (97-122).
+
+ This function can't be used for language specific conversion.
+ If the string doesn't contain characters which must be converted,
+ then the new string is assigned with str.
+
+ @return the string, converted to ASCII lowercase.
+ */
+ SAL_WARN_UNUSED_RESULT OString toAsciiLowerCase() const
+ {
+ rtl_String* pNew = NULL;
+ rtl_string_newToAsciiLowerCase( &pNew, pData );
+ return OString( pNew, SAL_NO_ACQUIRE );
+ }
+
+ /**
+ Converts from this string all ASCII lowercase characters (97-122)
+ to ASCII uppercase characters (65-90).
+
+ This function can't be used for language specific conversion.
+ If the string doesn't contain characters which must be converted,
+ then the new string is assigned with str.
+
+ @return the string, converted to ASCII uppercase.
+ */
+ SAL_WARN_UNUSED_RESULT OString toAsciiUpperCase() const
+ {
+ rtl_String* pNew = NULL;
+ rtl_string_newToAsciiUpperCase( &pNew, pData );
+ return OString( pNew, SAL_NO_ACQUIRE );
+ }
+
+ /**
+ Returns a new string resulting from removing white space from both ends
+ of the string.
+
+ All characters that have codes less than or equal to
+ 32 (the space character) are considered to be white space.
+ If the string doesn't contain white spaces at both ends,
+ then the new string is assigned with str.
+
+ @return the string, with white space removed from the front and end.
+ */
+ SAL_WARN_UNUSED_RESULT OString trim() const
+ {
+ rtl_String* pNew = NULL;
+ rtl_string_newTrim( &pNew, pData );
+ return OString( pNew, SAL_NO_ACQUIRE );
+ }
+
+ /**
+ Returns a token in the string.
+
+ Example:
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ...
+ OString aToken = aStr.getToken( 0, ';', nIndex );
+ ...
+ }
+ while ( nIndex >= 0 );
+
+ @param token the number of the token to return.
+ @param cTok the character which separate the tokens.
+ @param index the position at which the token is searched in the
+ string.
+ The index must not be greater than the length of the
+ string.
+ This param is set to the position of the
+ next token or to -1, if it is the last token.
+ @return the token; if either token or index is negative, an empty token
+ is returned (and index is set to -1)
+ */
+ OString getToken( sal_Int32 token, char cTok, sal_Int32& index ) const
+ {
+ rtl_String * pNew = NULL;
+ index = rtl_string_getToken( &pNew, pData, token, cTok, index );
+ return OString( pNew, SAL_NO_ACQUIRE );
+ }
+
+ /**
+ Returns a token from the string.
+
+ The same as getToken(sal_Int32, char, sal_Int32 &), but always passing
+ in 0 as the start index in the third argument.
+
+ @param count the number of the token to return, starting with 0
+ @param separator the character which separates the tokens
+
+ @return the given token, or an empty string
+
+ @since LibreOffice 3.6
+ */
+ OString getToken(sal_Int32 count, char separator) const {
+ sal_Int32 n = 0;
+ return getToken(count, separator, n);
+ }
+
+ /**
+ Returns the Boolean value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @return true, if the string is 1 or "True" in any ASCII case.
+ false in any other case.
+ */
+ bool toBoolean() const
+ {
+ return rtl_str_toBoolean( pData->buffer );
+ }
+
+ /**
+ Returns the first character from this string.
+
+ @return the first character from this string or 0, if this string
+ is empty.
+ */
+ char toChar() const
+ {
+ return pData->buffer[0];
+ }
+
+ /**
+ Returns the int32 value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @param radix the radix (between 2 and 36)
+ @return the int32 represented from this string.
+ 0 if this string represents no number or one of too large
+ magnitude.
+ */
+ sal_Int32 toInt32( sal_Int16 radix = 10 ) const
+ {
+ return rtl_str_toInt32( pData->buffer, radix );
+ }
+
+ /**
+ Returns the uint32 value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @param radix the radix (between 2 and 36)
+ @return the uint32 represented from this string.
+ 0 if this string represents no number or one of too large
+ magnitude.
+
+ @since LibreOffice 4.2
+ */
+ sal_uInt32 toUInt32( sal_Int16 radix = 10 ) const
+ {
+ return rtl_str_toUInt32( pData->buffer, radix );
+ }
+
+ /**
+ Returns the int64 value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @param radix the radix (between 2 and 36)
+ @return the int64 represented from this string.
+ 0 if this string represents no number or one of too large
+ magnitude.
+ */
+ sal_Int64 toInt64( sal_Int16 radix = 10 ) const
+ {
+ return rtl_str_toInt64( pData->buffer, radix );
+ }
+
+ /**
+ Returns the uint64 value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @param radix the radix (between 2 and 36)
+ @return the uint64 represented from this string.
+ 0 if this string represents no number or one of too large
+ magnitude.
+
+ @since LibreOffice 4.1
+ */
+ sal_uInt64 toUInt64( sal_Int16 radix = 10 ) const
+ {
+ return rtl_str_toUInt64( pData->buffer, radix );
+ }
+
+ /**
+ Returns the float value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @return the float represented from this string.
+ 0.0 if this string represents no number.
+ */
+ float toFloat() const
+ {
+ return rtl_str_toFloat( pData->buffer );
+ }
+
+ /**
+ Returns the double value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @return the double represented from this string.
+ 0.0 if this string represents no number.
+ */
+ double toDouble() const
+ {
+ return rtl_str_toDouble( pData->buffer );
+ }
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+
+ static auto number( int i, sal_Int16 radix = 10 )
+ {
+ return OStringNumber<RTL_STR_MAX_VALUEOFINT32>(rtl_str_valueOfInt32, i, radix);
+ }
+ static auto number( long long ll, sal_Int16 radix = 10 )
+ {
+ return OStringNumber<RTL_STR_MAX_VALUEOFINT64>(rtl_str_valueOfInt64, ll, radix);
+ }
+ static auto number( unsigned long long ll, sal_Int16 radix = 10 )
+ {
+ return OStringNumber<RTL_STR_MAX_VALUEOFUINT64>(rtl_str_valueOfUInt64, ll, radix);
+ }
+ static auto number( unsigned int i, sal_Int16 radix = 10 )
+ {
+ return number( static_cast< unsigned long long >( i ), radix );
+ }
+ static auto number( long i, sal_Int16 radix = 10)
+ {
+ return number( static_cast< long long >( i ), radix );
+ }
+ static auto number( unsigned long i, sal_Int16 radix = 10 )
+ {
+ return number( static_cast< unsigned long long >( i ), radix );
+ }
+#else
+ /**
+ Returns the string representation of the integer argument.
+
+ This function can't be used for language specific conversion.
+
+ @param i an integer value
+ @param radix the radix (between 2 and 36)
+ @return a string with the string representation of the argument.
+ @since LibreOffice 4.1
+ */
+ static OString number( int i, sal_Int16 radix = 10 )
+ {
+ char aBuf[RTL_STR_MAX_VALUEOFINT32];
+ return OString(aBuf, rtl_str_valueOfInt32(aBuf, i, radix));
+ }
+ /// @overload
+ /// @since LibreOffice 4.1
+ static OString number( unsigned int i, sal_Int16 radix = 10 )
+ {
+ return number( static_cast< unsigned long long >( i ), radix );
+ }
+ /// @overload
+ /// @since LibreOffice 4.1
+ static OString number( long i, sal_Int16 radix = 10 )
+ {
+ return number( static_cast< long long >( i ), radix );
+ }
+ /// @overload
+ /// @since LibreOffice 4.1
+ static OString number( unsigned long i, sal_Int16 radix = 10 )
+ {
+ return number( static_cast< unsigned long long >( i ), radix );
+ }
+ /// @overload
+ /// @since LibreOffice 4.1
+ static OString number( long long ll, sal_Int16 radix = 10 )
+ {
+ char aBuf[RTL_STR_MAX_VALUEOFINT64];
+ return OString(aBuf, rtl_str_valueOfInt64(aBuf, ll, radix));
+ }
+ /// @overload
+ /// @since LibreOffice 4.1
+ static OString number( unsigned long long ll, sal_Int16 radix = 10 )
+ {
+ char aBuf[RTL_STR_MAX_VALUEOFUINT64];
+ return OString(aBuf, rtl_str_valueOfUInt64(aBuf, ll, radix));
+ }
+#endif
+
+ /**
+ Returns the string representation of the float argument.
+
+ This function can't be used for language specific conversion.
+
+ @param f a float.
+ @return a string with the decimal representation of the argument.
+ @since LibreOffice 4.1
+ */
+ static OString number( float f )
+ {
+ rtl_String* pNew = NULL;
+ // Same as rtl::str::valueOfFP, used for rtl_str_valueOfFloat
+ rtl_math_doubleToString(&pNew, NULL, 0, f, rtl_math_StringFormat_G,
+ RTL_STR_MAX_VALUEOFFLOAT - SAL_N_ELEMENTS("-x.E-xxx") + 1, '.',
+ NULL, 0, true);
+ if (pNew == NULL)
+ throw std::bad_alloc();
+
+ return OString(pNew, SAL_NO_ACQUIRE);
+ }
+
+ /**
+ Returns the string representation of the double argument.
+
+ This function can't be used for language specific conversion.
+
+ @param d a double.
+ @return a string with the decimal representation of the argument.
+ @since LibreOffice 4.1
+ */
+ static OString number( double d )
+ {
+ rtl_String* pNew = NULL;
+ // Same as rtl::str::valueOfFP, used for rtl_str_valueOfDouble
+ rtl_math_doubleToString(&pNew, NULL, 0, d, rtl_math_StringFormat_G,
+ RTL_STR_MAX_VALUEOFDOUBLE - SAL_N_ELEMENTS("-x.E-xxx") + 1, '.',
+ NULL, 0, true);
+ if (pNew == NULL)
+ throw std::bad_alloc();
+
+ return OString(pNew, SAL_NO_ACQUIRE);
+ }
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ static auto boolean(bool b)
+ {
+ return OStringNumber<RTL_STR_MAX_VALUEOFBOOLEAN>(rtl_str_valueOfBoolean, b);
+ }
+#else
+ /**
+ Returns the string representation of the sal_Bool argument.
+
+ If the sal_Bool is true, the string "true" is returned.
+ If the sal_Bool is false, the string "false" is returned.
+ This function can't be used for language specific conversion.
+
+ @param b a sal_Bool.
+ @return a string with the string representation of the argument.
+ @deprecated use boolean()
+ */
+ SAL_DEPRECATED("use boolean()") static OString valueOf( sal_Bool b )
+ {
+ return boolean(b);
+ }
+
+ /**
+ Returns the string representation of the boolean argument.
+
+ If the argument is true, the string "true" is returned.
+ If the argument is false, the string "false" is returned.
+ This function can't be used for language specific conversion.
+
+ @param b a bool.
+ @return a string with the string representation of the argument.
+ @since LibreOffice 4.1
+ */
+ static OString boolean( bool b )
+ {
+ char aBuf[RTL_STR_MAX_VALUEOFBOOLEAN];
+ return OString(aBuf, rtl_str_valueOfBoolean(aBuf, b));
+ }
+#endif
+
+ /**
+ Returns the string representation of the char argument.
+
+ @param c a character.
+ @return a string with the string representation of the argument.
+ @deprecated use operator, function or constructor taking char or sal_Unicode argument
+ */
+ SAL_DEPRECATED("convert to OString or use directly") static OString valueOf( char c )
+ {
+ return OString( &c, 1 );
+ }
+
+ /**
+ Returns the string representation of the int argument.
+
+ This function can't be used for language specific conversion.
+
+ @param i a int32.
+ @param radix the radix (between 2 and 36)
+ @return a string with the string representation of the argument.
+ @deprecated use number()
+ */
+ SAL_DEPRECATED("use number()") static OString valueOf( sal_Int32 i, sal_Int16 radix = 10 )
+ {
+ return number( i, radix );
+ }
+
+ /**
+ Returns the string representation of the long argument.
+
+ This function can't be used for language specific conversion.
+
+ @param ll a int64.
+ @param radix the radix (between 2 and 36)
+ @return a string with the string representation of the argument.
+ @deprecated use number()
+ */
+ SAL_DEPRECATED("use number()") static OString valueOf( sal_Int64 ll, sal_Int16 radix = 10 )
+ {
+ return number( ll, radix );
+ }
+
+ /**
+ Returns the string representation of the float argument.
+
+ This function can't be used for language specific conversion.
+
+ @param f a float.
+ @return a string with the string representation of the argument.
+ @deprecated use number()
+ */
+ SAL_DEPRECATED("use number()") static OString valueOf( float f )
+ {
+ return number(f);
+ }
+
+ /**
+ Returns the string representation of the double argument.
+
+ This function can't be used for language specific conversion.
+
+ @param d a double.
+ @return a string with the string representation of the argument.
+ @deprecated use number()
+ */
+ SAL_DEPRECATED("use number()") static OString valueOf( double d )
+ {
+ return number(d);
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ operator std::string_view() const { return {getStr(), sal_uInt32(getLength())}; }
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+ // A wrapper for the first expression in an
+ //
+ // OString::Concat(e1) + e2 + ...
+ //
+ // concatenation chain, when neither of the first two e1, e2 is one of our rtl string-related
+ // classes (so something like
+ //
+ // OString s = "a" + (b ? std::string_view("c") : std::string_view("dd"));
+ //
+ // would not compile):
+ template<typename T> [[nodiscard]] static
+ OStringConcat<OStringConcatMarker, T>
+ Concat(T const & value) { return OStringConcat<OStringConcatMarker, T>(value); }
+
+ // This overload is needed so that an argument of type 'char const[N]' ends up as
+ // 'OStringConcat<rtl::OStringConcatMarker, char const[N]>' rather than as
+ // 'OStringConcat<rtl::OStringConcatMarker, char[N]>':
+ template<typename T, std::size_t N> [[nodiscard]] static
+ OStringConcat<OStringConcatMarker, T[N]>
+ Concat(T (& value)[N]) { return OStringConcat<OStringConcatMarker, T[N]>(value); }
+#endif
+};
+
+#if defined LIBO_INTERNAL_ONLY
+inline bool operator ==(OString const & lhs, StringConcatenation<char> const & rhs)
+{ return lhs == std::string_view(rhs); }
+inline bool operator !=(OString const & lhs, StringConcatenation<char> const & rhs)
+{ return lhs != std::string_view(rhs); }
+inline bool operator ==(StringConcatenation<char> const & lhs, OString const & rhs)
+{ return std::string_view(lhs) == rhs; }
+inline bool operator !=(StringConcatenation<char> const & lhs, OString const & rhs)
+{ return std::string_view(lhs) != rhs; }
+#endif
+
+/* ======================================================================= */
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+
+/**
+ @internal
+*/
+template<>
+struct ToStringHelper< OString >
+{
+ static std::size_t length( const OString& s ) { return s.getLength(); }
+ char* operator()( char* buffer, const OString& s ) const { return addDataHelper( buffer, s.getStr(), s.getLength()); }
+};
+
+/**
+ @internal
+*/
+template<std::size_t N>
+struct ToStringHelper< OStringLiteral<N> >
+{
+ static constexpr std::size_t length( const OStringLiteral<N>& str ) { return str.getLength(); }
+ char* operator()( char* buffer, const OStringLiteral<N>& str ) const { return addDataHelper( buffer, str.getStr(), str.getLength() ); }
+};
+
+/**
+ @internal
+*/
+template< typename charT, typename traits, typename T1, typename T2 >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, OStringConcat< T1, T2 >&& concat)
+{
+ return stream << OString( std::move(concat) );
+}
+#endif
+
+
+/** A helper to use OStrings with hash maps.
+
+ Instances of this class are unary function objects that can be used as
+ hash function arguments to std::unordered_map and similar constructs.
+ */
+struct OStringHash
+{
+ /** Compute a hash code for a string.
+
+ @param rString
+ a string.
+
+ @return
+ a hash code for the string. This hash code should not be stored
+ persistently, as its computation may change in later revisions.
+ */
+ size_t operator()( const OString& rString ) const
+ { return static_cast<size_t>(rString.hashCode()); }
+};
+
+/** Equality functor for classic c-strings (i.e., null-terminated char* strings). */
+struct CStringEqual
+{
+ bool operator()( const char* p1, const char* p2) const
+ { return rtl_str_compare(p1, p2) == 0; }
+};
+
+/** Hashing functor for classic c-strings (i.e., null-terminated char* strings). */
+struct CStringHash
+{
+ size_t operator()(const char* p) const
+ { return rtl_str_hashCode(p); }
+};
+
+/* ======================================================================= */
+
+/**
+ Support for rtl::OString in std::ostream (and thus in
+ CPPUNIT_ASSERT or SAL_INFO macros, for example).
+
+ @since LibreOffice 4.0
+ */
+template< typename charT, typename traits > std::basic_ostream<charT, traits> &
+operator <<(
+ std::basic_ostream<charT, traits> & stream, OString const & rString)
+{
+ return stream << rString.getStr();
+ // best effort; potentially loses data due to embedded null characters
+}
+
+} /* Namespace */
+
+#ifdef RTL_STRING_UNITTEST
+namespace rtl
+{
+typedef rtlunittest::OString OString;
+}
+#undef RTL_STRING_CONST_FUNCTION
+#endif
+
+#if defined LIBO_INTERNAL_ONLY && !defined RTL_STRING_UNITTEST
+using ::rtl::OString;
+using ::rtl::OStringChar;
+using ::rtl::Concat2View;
+using ::rtl::OStringHash;
+using ::rtl::OStringLiteral;
+#endif
+
+#if defined LIBO_INTERNAL_ONLY && !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+
+template<
+#if defined RTL_STRING_UNITTEST
+ rtlunittest::
+#endif
+ OStringLiteral L>
+constexpr
+#if defined RTL_STRING_UNITTEST
+ rtlunittest::
+#endif
+ OString
+operator ""_ostr() { return L; }
+
+template<
+#if defined RTL_STRING_UNITTEST
+ rtlunittest::
+#endif
+ OStringLiteral L>
+constexpr
+#if defined RTL_STRING_UNITTEST
+rtlunittest
+#else
+rtl
+#endif
+::detail::OStringHolder<L> operator ""_tstr() {
+ return
+#if defined RTL_STRING_UNITTEST
+ rtlunittest
+#else
+ rtl
+#endif
+ ::detail::OStringHolder<L>();
+}
+
+#endif
+
+/// @cond INTERNAL
+/**
+ Make OString hashable by default for use in STL containers.
+
+ @since LibreOffice 6.0
+*/
+#if defined LIBO_INTERNAL_ONLY
+namespace std {
+
+template<>
+struct hash<::rtl::OString>
+{
+ std::size_t operator()(::rtl::OString const & s) const
+ {
+ if constexpr (sizeof(std::size_t) == 8)
+ {
+ // return a hash that uses the full 64-bit range instead of a 32-bit value
+ size_t n = s.getLength();
+ for (sal_Int32 i = 0, len = s.getLength(); i < len; ++i)
+ n = 37 * n + s[i];
+ return n;
+ }
+ else
+ return std::size_t(s.hashCode());
+ }
+};
+
+}
+
+#endif
+/// @endcond
+
+#endif // INCLUDED_RTL_STRING_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/stringconcat.hxx b/include/rtl/stringconcat.hxx
new file mode 100644
index 0000000000..0bed28ac81
--- /dev/null
+++ b/include/rtl/stringconcat.hxx
@@ -0,0 +1,394 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_RTL_STRINGCONCAT_HXX
+#define INCLUDED_RTL_STRINGCONCAT_HXX
+
+// This file is only included from LIBO_INTERNAL_ONLY
+
+#include "rtl/stringutils.hxx"
+#include "rtl/string.h"
+#include "rtl/ustring.h"
+
+#include <cassert>
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <string_view>
+#include <type_traits>
+#include <utility>
+
+#include <string.h>
+
+#if defined RTL_STRING_UNITTEST_CONCAT
+extern bool rtl_string_unittest_invalid_concat;
+#endif
+
+#ifdef RTL_STRING_UNITTEST
+#define rtl rtlunittest
+#endif
+namespace rtl
+{
+#ifdef RTL_STRING_UNITTEST
+#undef rtl
+#endif
+
+/*
+Implementation of efficient string concatenation.
+
+The whole system is built around two basic template classes:
+- ToStringHelper< T > - for each T it can give the length of the resulting string representation and can write
+ this string representation to a buffer
+- O(U)StringConcat< T1, T2 > - operator+ now, instead of creating O(U)String object, returns only this helper object,
+ that keeps a reference to both operator+ operands; only when converted to O(U)String it will actually create
+ the resulting string object using ToStringHelper, creating directly the resulting object without any string
+ intermediate objects
+As all the code is inline methods, it allows for extensive optimization and will usually result in very effective code
+(even surpassing strlen/strcat and equalling handwritten), while allowing for very easy and intuitive syntax.
+*/
+
+/**
+@internal
+
+Helper class for converting a given type to a string representation.
+*/
+template< typename T >
+struct ToStringHelper
+{
+ /// Return length of the string representation of the given object.
+ // static std::size_t length( const T& );
+ /// Add 8-bit representation of the given object to the given buffer and return position right after the added data.
+ // char* operator()( char* buffer, const T& ) const SAL_RETURNS_NONNULL;
+ /// Add Unicode representation of the given object to the given buffer and return position right after the added data.
+ // sal_Unicode* operator()( sal_Unicode* buffer, const T& ) const SAL_RETURNS_NONNULL;
+};
+
+/// If true, T can be used in concatenation resulting in O(U)String.
+template<typename C, typename T, class Enable = void> constexpr bool allowStringConcat = false;
+template<typename C, typename T> constexpr bool allowStringConcat<C, T, std::enable_if_t<std::is_invocable_v<ToStringHelper<T>, C*, T>>> = true;
+
+template <typename C> inline
+C* addDataHelper( C* buffer, const C* data, std::size_t length )
+{
+ if (length != 0) {
+ memcpy( buffer, data, length * sizeof( C ));
+ }
+ return buffer + length;
+}
+
+inline
+sal_Unicode* addDataLiteral( sal_Unicode* buffer, const char* data, std::size_t length )
+{
+ for( std::size_t i = 0; i != length; ++i )
+ *buffer++ = *data++;
+ return buffer;
+}
+
+template <typename C> inline
+C* addDataString( C* buffer, const C* str )
+{
+ while( *str != '\0' )
+ *buffer++ = *str++;
+ return buffer;
+}
+
+template<>
+struct ToStringHelper< const char* >
+{
+ static std::size_t length( const char* str ) {
+ return str ? strlen( str ) : 0;
+ }
+ char* operator()( char* buffer, const char* str ) const {
+ return str ? addDataString( buffer, str ) : buffer;
+ }
+};
+
+template<>
+struct ToStringHelper< char* > : public ToStringHelper< const char* > {};
+
+template< std::size_t N >
+struct ToStringHelper< char[ N ] >
+{
+ static std::size_t length( const char str[ N ] ) {
+ return strlen( str );
+ }
+ char* operator()( char* buffer, const char str[ N ] ) const { return addDataString( buffer, str ); }
+};
+
+template< std::size_t N >
+struct ToStringHelper< const char[ N ] >
+{
+ static std::size_t length( const char str[ N ] ) { (void)str; assert( strlen( str ) == N - 1 ); return N - 1; }
+ char* operator()( char* buffer, const char str[ N ] ) const { return addDataHelper( buffer, str, N - 1 ); }
+ sal_Unicode* operator()( sal_Unicode* buffer, const char str[ N ] ) const { return addDataLiteral( buffer, str, N - 1 ); }
+};
+
+template<>
+struct ToStringHelper<OStringChar>
+{
+ static std::size_t length(OStringChar) { return 1; }
+ char* operator()(char* buffer, OStringChar data) const
+ { return addDataHelper(buffer, &data.c, 1); }
+};
+
+template<>
+struct ToStringHelper< const sal_Unicode* >
+{
+ static std::size_t length( const sal_Unicode* str ) {
+ return str ? std::char_traits<char16_t>::length( str ) : 0;
+ }
+ sal_Unicode* operator()( sal_Unicode* buffer, const sal_Unicode* str ) const {
+ return str ? addDataString( buffer, str ) : buffer;
+ }
+};
+
+template<>
+struct ToStringHelper< sal_Unicode* > : public ToStringHelper< const sal_Unicode* > {};
+
+template<std::size_t N>
+struct ToStringHelper<sal_Unicode[ N ]>
+{
+ static std::size_t length( const sal_Unicode str[ N ] ) {
+ return std::char_traits<char16_t>::length( str );
+ }
+ sal_Unicode * operator()(sal_Unicode * buffer, sal_Unicode const str[N]) const
+ { return addDataHelper(buffer, str, N - 1); }
+};
+
+template<std::size_t N>
+struct ToStringHelper<sal_Unicode const[N]>
+{
+ static std::size_t length( const sal_Unicode str[ N ] ) { (void)str; assert( std::char_traits<char16_t>::length( str ) == N - 1 ); return N - 1; }
+ sal_Unicode * operator()(sal_Unicode * buffer, sal_Unicode const str[N]) const
+ { return addDataHelper(buffer, str, N - 1); }
+};
+
+template<>
+struct ToStringHelper<OUStringChar_>
+{
+ static std::size_t length(OUStringChar_) { return 1; }
+ sal_Unicode * operator()(sal_Unicode * buffer, OUStringChar_ literal) const
+ { return addDataHelper(buffer, &literal.c, 1); }
+};
+
+/**
+@internal
+
+Objects returned by operator+, instead of O(U)String. These objects (possibly recursively) keep a representation of the whole
+concatenation operation.
+
+If you get a build error related to this class, you most probably need to explicitly convert the result of a string
+concatenation to O(U)String.
+*/
+template <typename C, typename T1, typename T2, std::enable_if_t<allowStringConcat<C, T1> && allowStringConcat<C, T2>, int> = 0 >
+struct StringConcat
+{
+public:
+ StringConcat( const T1& left_, const T2& right_ ) : left( left_ ), right( right_ ) {}
+ std::size_t length() const { return ToStringHelper< T1 >::length( left ) + ToStringHelper< T2 >::length( right ); }
+ C* addData( C* buffer ) const SAL_RETURNS_NONNULL { return ToStringHelper< T2 >()( ToStringHelper< T1 >()( buffer, left ), right ); }
+ // NOTE here could be functions that would forward to the "real" temporary O(U)String. Note however that e.g. getStr()
+ // is not so simple, as the O(U)String temporary must live long enough (i.e. can't be created here in a function, a wrapper
+ // temporary object containing it must be returned instead).
+private:
+ const T1& left;
+ const T2& right;
+};
+
+template <typename C, typename T1, typename T2> struct ToStringHelper<StringConcat<C, T1, T2>>
+{
+ static std::size_t length(const StringConcat<C, T1, T2 >& c) { return c.length(); }
+ C* operator()(C* buffer, const StringConcat<C, T1, T2>& c) const SAL_RETURNS_NONNULL { return c.addData(buffer); }
+};
+
+template <typename T1, typename T2> using OStringConcat = StringConcat<char, T1, T2>;
+template <typename T1, typename T2> using OUStringConcat = StringConcat<sal_Unicode, T1, T2>;
+
+template< typename T1, typename T2 >
+[[nodiscard]]
+inline
+OStringConcat< T1, T2 > operator+( const T1& left, const T2& right )
+{
+ return OStringConcat< T1, T2 >( left, right );
+}
+
+// char[N] and const char[N] need to be done explicitly, otherwise the compiler likes to treat them the same way for some reason
+template< typename T, std::size_t N >
+[[nodiscard]]
+inline
+OStringConcat< T, const char[ N ] > operator+( const T& left, const char (&right)[ N ] )
+{
+ return OStringConcat< T, const char[ N ] >( left, right );
+}
+
+template< typename T, std::size_t N >
+[[nodiscard]]
+inline
+OStringConcat< const char[ N ], T > operator+( const char (&left)[ N ], const T& right )
+{
+ return OStringConcat< const char[ N ], T >( left, right );
+}
+
+template< typename T, std::size_t N >
+[[nodiscard]]
+inline
+OStringConcat< T, char[ N ] > operator+( const T& left, char (&right)[ N ] )
+{
+ return OStringConcat< T, char[ N ] >( left, right );
+}
+
+template< typename T, std::size_t N >
+[[nodiscard]]
+inline
+OStringConcat< char[ N ], T > operator+( char (&left)[ N ], const T& right )
+{
+ return OStringConcat< char[ N ], T >( left, right );
+}
+
+template< typename T1, typename T2 >
+[[nodiscard]]
+inline
+OUStringConcat< T1, T2 > operator+( const T1& left, const T2& right )
+{
+ return OUStringConcat< T1, T2 >( left, right );
+}
+
+template< typename T1, typename T2 >
+[[nodiscard]]
+inline
+typename std::enable_if_t< libreoffice_internal::ConstCharArrayDetector< T1, void >::ok, OUStringConcat< T1, T2 > > operator+( T1& left, const T2& right )
+{
+ return OUStringConcat< T1, T2 >( left, right );
+}
+
+template< typename T1, typename T2 >
+[[nodiscard]]
+inline
+typename std::enable_if_t< libreoffice_internal::ConstCharArrayDetector< T2, void >::ok, OUStringConcat< T1, T2 > > operator+( const T1& left, T2& right )
+{
+ return OUStringConcat< T1, T2 >( left, right );
+}
+
+#ifdef RTL_STRING_UNITTEST_CONCAT
+// Special overload to catch the remaining invalid combinations. The helper struct must
+// be used to make this operator+ overload a worse choice than all the existing overloads above.
+struct StringConcatInvalid
+ {
+ template< typename T >
+ StringConcatInvalid( const T& ) {}
+ };
+template< typename T >
+inline
+int operator+( const StringConcatInvalid&, const T& )
+ {
+ rtl_string_unittest_invalid_concat = true;
+ return 0; // doesn't matter
+ }
+#endif
+
+// Lightweight alternative to O(U)String when a (temporary) object is needed to hold
+// an O(U)StringConcat result that can then be used as a std::(u16)string_view:
+template <typename C> class StringConcatenation {
+public:
+ template <class Concat>
+ explicit StringConcatenation(Concat const& c):
+ length_(c.length()),
+ buffer_(new C[length_])
+ {
+ auto const end = c.addData(buffer_.get());
+ assert(end == buffer_.get() + length_); (void)end;
+ }
+
+ operator std::basic_string_view<C>() const { return {buffer_.get(), length_}; }
+
+private:
+ std::size_t length_;
+ std::unique_ptr<C[]> buffer_;
+};
+
+template <typename C, typename T1, typename T2> auto Concat2View(StringConcat<C, T1, T2> const& c)
+{
+ return StringConcatenation<C>(c);
+}
+
+/**
+* O(U)StringNumber implementation
+
+Objects returned by O(U)String::number(), instead of O(U)String. These objects keep a representation of the number() operation.
+
+If you get a build error related to this class, you most probably need to explicitly convert the result of calling
+O(U)String::number() to O(U)String.
+*/
+
+template <typename C, std::size_t nBufSize> struct StringNumber
+{
+ template <typename Func, typename... Args,
+ std::enable_if_t<std::is_invocable_r_v<sal_Int32, Func, C*, Args...>, int> = 0>
+ StringNumber(Func func, Args... args) { length = func(buf, args...); }
+ // O(U)String::number(value).getStr() is very common (writing xml code, ...),
+ // so implement that one also here, to avoid having to explicitly convert
+ // to O(U)String in all such places
+ const C* getStr() const SAL_RETURNS_NONNULL { return buf; }
+ StringNumber&& toAsciiUpperCase() &&
+ {
+ if constexpr (sizeof(C) == sizeof(char))
+ rtl_str_toAsciiUpperCase_WithLength(buf, length);
+ else
+ rtl_ustr_toAsciiUpperCase_WithLength(buf, length);
+ return std::move(*this);
+ }
+ operator std::basic_string_view<C>() const { return std::basic_string_view<C>(buf, length); }
+ C buf[nBufSize];
+ sal_Int32 length;
+};
+
+template<std::size_t nBufSize> using OStringNumber = StringNumber<char, nBufSize>;
+template<std::size_t nBufSize> using OUStringNumber = StringNumber<sal_Unicode, nBufSize>;
+
+template< typename C, std::size_t nBufSize >
+struct ToStringHelper< StringNumber< C, nBufSize > >
+{
+ static std::size_t length( const StringNumber< C, nBufSize >& n ) { return n.length; }
+ C* operator()( C* buffer, const StringNumber< C, nBufSize >& n ) const SAL_RETURNS_NONNULL { return addDataHelper( buffer, n.buf, n.length ); }
+};
+
+template<typename C> struct ToStringHelper<std::basic_string_view<C>> {
+ static constexpr std::size_t length(std::basic_string_view<C> s) { return s.size(); }
+
+ C * operator()(C * buffer, std::basic_string_view<C> s) const SAL_RETURNS_NONNULL
+ { return addDataHelper(buffer, s.data(), s.size()); }
+};
+
+// An internal marker class used by O(U)String::Concat:
+template<typename C> struct StringConcatMarker {};
+
+using OStringConcatMarker = StringConcatMarker<char>;
+using OUStringConcatMarker = StringConcatMarker<sal_Unicode>;
+
+template<typename C> constexpr bool allowStringConcat<C, StringConcatMarker<C>> = true;
+
+#if defined __GNUC__ && !defined __clang__
+template <typename C, typename T2>
+struct StringConcat<C, StringConcatMarker<C>, T2>
+#else
+template <typename C, typename T2, std::enable_if_t<allowStringConcat<C, T2>, int> Dummy>
+struct StringConcat<C, StringConcatMarker<C>, T2, Dummy>
+#endif
+{
+public:
+ StringConcat( const T2& right_ ) : right( right_ ) {}
+ std::size_t length() const { return ToStringHelper< T2 >::length( right ); }
+ C* addData( C* buffer ) const SAL_RETURNS_NONNULL { return ToStringHelper< T2 >()( buffer, right ); }
+private:
+ const T2& right;
+};
+
+} // namespace
+
+#endif
diff --git a/include/rtl/stringutils.hxx b/include/rtl/stringutils.hxx
new file mode 100644
index 0000000000..622542c7da
--- /dev/null
+++ b/include/rtl/stringutils.hxx
@@ -0,0 +1,398 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_STRINGUTILS_HXX
+#define INCLUDED_RTL_STRINGUTILS_HXX
+
+#include "sal/config.h"
+
+#include <cassert>
+#include <cstddef>
+
+#if defined LIBO_INTERNAL_ONLY
+#include <type_traits>
+#endif
+
+#include "sal/types.h"
+
+// The unittest uses slightly different code to help check that the proper
+// calls are made. The class is put into a different namespace to make
+// sure the compiler generates a different (if generating also non-inline)
+// copy of the function and does not merge them together. The class
+// is "brought" into the proper rtl namespace by a typedef below.
+#ifdef RTL_STRING_UNITTEST
+#define rtl rtlunittest
+#endif
+
+namespace rtl
+{
+
+#ifdef RTL_STRING_UNITTEST
+#undef rtl
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+/// @cond INTERNAL
+
+// A simple wrapper around a single char. Can be useful in string concatenation contexts, like in
+//
+// OString s = ...;
+// char c = ...;
+// s += OStringChar(c);
+//
+struct SAL_WARN_UNUSED OStringChar {
+ constexpr OStringChar(char theC): c(theC) {}
+ template<typename T> OStringChar(
+ T, std::enable_if_t<std::is_arithmetic_v<T> || std::is_enum_v<T>, int> = 0) = delete;
+ constexpr operator std::string_view() const { return {&c, 1}; }
+ char const c;
+};
+
+/** A simple wrapper around a single sal_Unicode character.
+
+ Can be useful to pass a sal_Unicode constant into an OUString-related
+ function that is optimized for UTF-16 string literal arguments. That is,
+ instead of
+
+ sal_Unicode const WILDCARD = '%';
+ ...
+ if (s[i] == WILDCARD) ...
+ ...
+ if (s.endsWith(OUString(WILDCARD))) ...
+
+ use
+
+ sal_Unicode const WILDCARD = '%';
+ ...
+ if (s[i] == WILDCARD) ...
+ ...
+ if (s.endsWith(OUStringChar(WILDCARD))) ...
+
+ to avoid creating a temporary OUString instance, and instead pick the
+ endsWith overload actually designed to take an argument of type
+ sal_Unicode const[N].
+
+ (Because of the above use case,
+ instances of OUStringChar need to be const, as those literal-optimized
+ functions take the literal argument by non-const lvalue reference, for
+ technical reasons.
+
+ For actual arrays, it is important to distinguish string literals from other char or sal_Unicode
+ arrays, which may contain junk after the first NUL character or may be non-ASCII in the case of
+ char arrays. This is not so much a concern for single char and sal_Unicode values, where NUL is
+ assumed to always be meant as an actual character.)
+
+ Can also be useful in string concatenation contexts, like in
+
+ sal_Unicode const * s = ...;
+ sal_Unicode c = ...;
+ OUString t = s + OUStringChar(c);
+
+ @since LibreOffice 5.0
+*/
+struct SAL_WARN_UNUSED OUStringChar_ {
+ constexpr OUStringChar_(sal_Unicode theC): c(theC) {}
+ constexpr OUStringChar_(char theC): c(theC) { assert(c <= 0x7F); }
+ template<typename T> OUStringChar_(
+ T, std::enable_if_t<std::is_arithmetic_v<T> || std::is_enum_v<T>, int> = 0) = delete;
+ constexpr operator std::u16string_view() const { return {&c, 1}; }
+ sal_Unicode const c;
+};
+using OUStringChar = OUStringChar_ const;
+
+/// @endcond
+#endif
+
+namespace libreoffice_internal
+{
+/*
+These templates use SFINAE (Substitution failure is not an error) to help distinguish the various
+plain C string types: char*, const char*, char[N], const char[N], char[] and const char[].
+There are 2 cases:
+1) Only string literal (i.e. const char[N]) is wanted, not any of the others.
+ In this case it is necessary to distinguish between const char[N] and char[N], as the latter
+ would be automatically converted to the const variant, which is not wanted (not a string literal
+ with known size of the content). In this case ConstCharArrayDetector is used to ensure the function
+ is called only with const char[N] arguments. There's no other plain C string type overload.
+ (Note that OUStringChar is also covered by ConstCharArrayDetector's TypeUtf16 check, but
+ provides a pointer to a string that is not NUL-terminated, unlike the char16_t const[N] arrays
+ normally covered by that check, and which are assumed to represent NUL-terminated string
+ literals.)
+2) All plain C string types are wanted, and const char[N] needs to be handled differently.
+ In this case const char[N] would match const char* argument type (not exactly sure why, but it's
+ consistent in all of gcc, clang and msvc). Using a template with a reference to const of the type
+ avoids this problem, and CharPtrDetector ensures that the function is called only with char pointer
+ arguments. The const in the argument is necessary to handle the case when something is explicitly
+ cast to const char*. Additionally (non-const) char[N] needs to be handled, but with the reference
+ being const, it would also match const char[N], so another overload with a reference to non-const
+ and NonConstCharArrayDetector are used to ensure the function is called only with (non-const) char[N].
+Additionally, char[] and const char[] (i.e. size unknown) are rather tricky. Their usage with 'T&' would
+mean it would be 'char(&)[]', which seems to be invalid. But gcc and clang somehow manage when it is
+a template. while msvc complains about no conversion from char[] to char[1]. And the reference cannot
+be avoided, because 'const char[]' as argument type would match also 'const char[N]'
+So char[] and const char[] should always be used with their contents specified (which automatically
+turns them into char[N] or const char[N]), or char* and const char* should be used.
+*/
+struct Dummy {};
+template< typename T1, typename T2 = void >
+struct CharPtrDetector
+{
+ static const bool ok = false;
+};
+template< typename T >
+struct CharPtrDetector< const char*, T >
+{
+ typedef T Type;
+ static const bool ok = true;
+};
+template< typename T >
+struct CharPtrDetector< char*, T >
+{
+ typedef T Type;
+ static const bool ok = true;
+};
+#if defined LIBO_INTERNAL_ONLY
+template<typename T> struct CharPtrDetector<sal_Unicode *, T> { using TypeUtf16 = T; };
+template<typename T> struct CharPtrDetector<sal_Unicode const *, T> { using TypeUtf16 = T; };
+template<typename T> struct CharPtrDetector<sal_Unicode[], T> { using TypeUtf16 = T; };
+template<typename T> struct CharPtrDetector<sal_Unicode const[], T> { using TypeUtf16 = T; };
+#endif
+
+template< typename T1, typename T2 >
+struct NonConstCharArrayDetector
+{
+};
+template< typename T, int N >
+struct NonConstCharArrayDetector< char[ N ], T >
+{
+ typedef T Type;
+};
+#ifdef RTL_STRING_UNITTEST
+// never use, until all compilers handle this
+template< typename T >
+struct NonConstCharArrayDetector< char[], T >
+{
+ typedef T Type;
+};
+template< typename T >
+struct NonConstCharArrayDetector< const char[], T >
+{
+ typedef T Type;
+};
+#endif
+#if defined LIBO_INTERNAL_ONLY
+template<typename T, std::size_t N> struct NonConstCharArrayDetector<sal_Unicode[N], T> {
+ using TypeUtf16 = T;
+};
+#endif
+
+template< typename T1, typename T2 = void >
+struct ConstCharArrayDetector
+{
+ static const bool ok = false;
+};
+template< std::size_t N, typename T >
+struct ConstCharArrayDetector< const char[ N ], T >
+{
+ typedef T Type;
+ static const std::size_t length = N - 1;
+ static const bool ok = true;
+#if defined LIBO_INTERNAL_ONLY
+ constexpr
+#endif
+ static bool isValid(char const (& literal)[N]) {
+ for (std::size_t i = 0; i != N - 1; ++i) {
+ if (literal[i] == '\0') {
+ return false;
+ }
+ }
+ return literal[N - 1] == '\0';
+ }
+#if defined LIBO_INTERNAL_ONLY
+ constexpr
+#endif
+ static char const * toPointer(char const (& literal)[N]) { return literal; }
+};
+
+#if defined(__COVERITY__)
+//to silence over zealous warnings that the loop is logically dead
+//for the single char case
+template< typename T >
+struct ConstCharArrayDetector< const char[ 1 ], T >
+{
+ typedef T Type;
+ static const std::size_t length = 0;
+ static const bool ok = true;
+#if defined LIBO_INTERNAL_ONLY
+ constexpr
+#endif
+ static bool isValid(char const (& literal)[1]) {
+ return literal[0] == '\0';
+ }
+#if defined LIBO_INTERNAL_ONLY
+ constexpr
+#endif
+ static char const * toPointer(char const (& literal)[1]) { return literal; }
+};
+#endif
+
+#if defined LIBO_INTERNAL_ONLY \
+ && !(defined _MSC_VER && _MSC_VER >= 1930 && _MSC_VER <= 1939 && defined _MANAGED)
+template<std::size_t N, typename T>
+struct ConstCharArrayDetector<char8_t const [N], T> {
+ using Type = T;
+ static constexpr bool const ok = true;
+ static constexpr std::size_t const length = N - 1;
+ static constexpr bool isValid(char8_t const (& literal)[N]) {
+ for (std::size_t i = 0; i != N - 1; ++i) {
+ if (literal[i] == u8'\0') {
+ return false;
+ }
+ }
+ return literal[N - 1] == u8'\0';
+ }
+ static constexpr char const * toPointer(char8_t const (& literal)[N])
+ { return reinterpret_cast<char const *>(literal); }
+};
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+template<std::size_t N, typename T>
+struct ConstCharArrayDetector<sal_Unicode const [N], T> {
+ using TypeUtf16 = T;
+ static constexpr bool const ok = true;
+ static constexpr std::size_t const length = N - 1;
+ static constexpr bool isValid(sal_Unicode const (& literal)[N]) {
+ for (std::size_t i = 0; i != N - 1; ++i) {
+ if (literal[i] == '\0') {
+ return false;
+ }
+ }
+ return literal[N - 1] == '\0';
+ }
+ static constexpr sal_Unicode const * toPointer(
+ sal_Unicode const (& literal)[N])
+ { return literal; }
+};
+
+#if defined(__COVERITY__)
+//to silence over zealous warnings that the loop is logically dead
+//for the single char case
+template<typename T>
+struct ConstCharArrayDetector<sal_Unicode const [1], T> {
+ using TypeUtf16 = T;
+ static constexpr bool const ok = true;
+ static constexpr std::size_t const length = 0;
+ static constexpr bool isValid(sal_Unicode const (& literal)[1]) {
+ return literal[0] == '\0';
+ }
+ static constexpr sal_Unicode const * toPointer(
+ sal_Unicode const (& literal)[1])
+ { return literal; }
+};
+#endif
+
+template<typename T> struct ConstCharArrayDetector<
+ OUStringChar,
+ T>
+{
+ using TypeUtf16 = T;
+ static constexpr bool const ok = true;
+ static constexpr std::size_t const length = 1;
+ static constexpr bool isValid(OUStringChar) { return true; }
+ static constexpr sal_Unicode const * toPointer(
+ OUStringChar_ const & literal)
+ { return &literal.c; }
+};
+#endif
+
+#if defined LIBO_INTERNAL_ONLY && defined RTL_STRING_UNITTEST
+
+// this one is used to rule out only const char[N]
+template< typename T >
+struct ExceptConstCharArrayDetector
+{
+ typedef Dummy Type;
+};
+template< int N >
+struct ExceptConstCharArrayDetector< const char[ N ] >
+{
+};
+template<std::size_t N>
+struct ExceptConstCharArrayDetector<sal_Unicode const[N]> {};
+template<> struct ExceptConstCharArrayDetector<
+ OUStringChar
+ >
+{};
+
+// this one is used to rule out only const char[N]
+// (const will be brought in by 'const T&' in the function call)
+// msvc needs const char[N] here (not sure whether gcc or msvc
+// are right, it doesn't matter).
+template< typename T >
+struct ExceptCharArrayDetector
+{
+ typedef Dummy Type;
+};
+template< int N >
+struct ExceptCharArrayDetector< char[ N ] >
+{
+};
+template< int N >
+struct ExceptCharArrayDetector< const char[ N ] >
+{
+};
+template<std::size_t N> struct ExceptCharArrayDetector<sal_Unicode[N]> {};
+template<std::size_t N> struct ExceptCharArrayDetector<sal_Unicode const[N]> {};
+template<> struct ExceptCharArrayDetector<OUStringChar_> {};
+
+#endif
+
+template< typename T1, typename T2 = void >
+struct SalUnicodePtrDetector
+{
+ static const bool ok = false;
+};
+template< typename T >
+struct SalUnicodePtrDetector< const sal_Unicode*, T >
+{
+ typedef T Type;
+ static const bool ok = true;
+};
+template< typename T >
+struct SalUnicodePtrDetector< sal_Unicode*, T >
+{
+ typedef T Type;
+ static const bool ok = true;
+};
+
+// SFINAE helper class
+template< typename T, bool >
+struct Enable
+ {
+ };
+
+template< typename T >
+struct Enable< T, true >
+ {
+ typedef T Type;
+ };
+
+
+} /* Namespace */
+
+} /* Namespace */
+
+#endif // INCLUDED_RTL_STRINGUTILS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/tencinfo.h b/include/rtl/tencinfo.h
new file mode 100644
index 0000000000..6154a91289
--- /dev/null
+++ b/include/rtl/tencinfo.h
@@ -0,0 +1,284 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_TENCINFO_H
+#define INCLUDED_RTL_TENCINFO_H
+
+#include "sal/config.h"
+
+#include "rtl/textenc.h"
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// See rtl_TextEncodingInfo.Flags below for documentation on these values:
+#define RTL_TEXTENCODING_INFO_CONTEXT ((sal_uInt32)0x00000001)
+#define RTL_TEXTENCODING_INFO_ASCII ((sal_uInt32)0x00000002)
+#define RTL_TEXTENCODING_INFO_UNICODE ((sal_uInt32)0x00000004)
+#define RTL_TEXTENCODING_INFO_MULTIBYTE ((sal_uInt32)0x00000008)
+#define RTL_TEXTENCODING_INFO_R2L ((sal_uInt32)0x00000010)
+#define RTL_TEXTENCODING_INFO_7BIT ((sal_uInt32)0x00000020)
+#define RTL_TEXTENCODING_INFO_SYMBOL ((sal_uInt32)0x00000040)
+#define RTL_TEXTENCODING_INFO_MIME ((sal_uInt32)0x00000080)
+
+/** Information about a text encoding.
+ */
+typedef struct _rtl_TextEncodingInfo
+{
+ /** The size (in bytes) of this structure. Should be 12.
+ */
+ sal_uInt32 StructSize;
+
+ /** The minimum number of bytes needed to encode any character in the
+ given encoding.
+
+ Can be rather meaningless for encodings that encode global state along
+ with the characters (e.g., ISO-2022 encodings).
+ */
+ sal_uInt8 MinimumCharSize;
+
+ /** The maximum number of bytes needed to encode any character in the
+ given encoding.
+
+ Can be rather meaningless for encodings that encode global state along
+ with the characters (e.g., ISO-2022 encodings).
+ */
+ sal_uInt8 MaximumCharSize;
+
+ /** The average number of bytes needed to encode a character in the given
+ encoding.
+ */
+ sal_uInt8 AverageCharSize;
+
+ /** An unused byte, for padding.
+ */
+ sal_uInt8 Reserved;
+
+ /** Any combination of the RTL_TEXTENCODING_INFO flags.
+
+ RTL_TEXTENCODING_INFO_CONTEXT: The encoding uses some mechanism (like
+ state-changing byte sequences) to switch between different modes (e.g.,
+ to encode multiple character repertoires within the same byte ranges).
+
+ Even if an encoding does not have the CONTEXT property, interpretation
+ of certain byte values within that encoding can depend on context (e.g.,
+ a certain byte value could be either a single-byte character or a
+ subsequent byte of a multi-byte character). Likewise, the single shift
+ characters (SS2 and SS3) used by some of the EUC encodings (to denote
+ that the following bytes constitute a character from another character
+ repertoire) do not imply that encodings making use of these characters
+ have the CONTEXT property. Examples of encodings that do have the
+ CONTEXT property are the ISO-2022 encodings and UTF-7.
+
+ RTL_TEXTENCODING_INFO_ASCII: The encoding is a superset of ASCII. More
+ specifically, any appearance of a byte in the range 0x20--7F denotes the
+ corresponding ASCII character (from SPACE to DELETE); in particular,
+ such a byte cannot be part of a multi-byte character. Note that the
+ ASCII control codes 0x00--1F are not included here, as they are used for
+ special purposes in some encodings.
+
+ If an encoding has this property, it is easy to search for occurrences of
+ ASCII characters within strings of this encoding---you do not need to
+ keep track whether a byte in the range 0x20--7F really represents an
+ ASCII character or rather is part of some multi-byte character.
+
+ The guarantees when mapping between Unicode and a given encoding with
+ the ASCII property are as follows: When mapping from Unicode to the
+ given encoding, U+0020--007F map to 0x20--7F (but there can also be
+ other Unicode characters mapping into the range 0x20--7F), and when
+ mapping from the given encoding to Unicode, 0x20--7F map to U+0020--007F
+ (again, there can also be other characters mapping into the range
+ U+0020--007F). In particular, this ensures round-trip conversion for
+ the ASCII range.
+
+ In principle, the ASCII property is orthogonal to the CONTEXT property.
+ In practice, however, an encoding that has the ASCII property will most
+ likely not also have the CONTEXT property.
+
+ RTL_TEXTENCODING_INFO_UNICODE: The encoding is based on the Unicode
+ character repertoire.
+
+ RTL_TEXTENCODING_INFO_MULTIBYTE: A multi-byte encoding.
+
+ RTL_TEXTENCODING_INFO_R2L: An encoding used mainly or exclusively for
+ languages written from right to left.
+
+ RTL_TEXTENCODING_INFO_7BIT: A 7-bit instead of an 8-bit encoding.
+
+ RTL_TEXTENCODING_INFO_SYMBOL: A (generic) encoding for symbol character
+ sets.
+
+ RTL_TEXTENCODING_INFO_MIME: The encoding is registered as a MIME
+ charset.
+ */
+ sal_uInt32 Flags;
+} rtl_TextEncodingInfo;
+
+/** Determine whether a text encoding uses single octets as basic units of
+ information (and can thus be used with the conversion routines in
+ rtl/textcvt.h).
+
+ @param nEncoding
+ Any rtl_TextEncoding value.
+
+ @return
+ True if the given encoding uses single octets as basic units of
+ information, false otherwise.
+ */
+SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_isOctetTextEncoding(rtl_TextEncoding nEncoding);
+
+/** Return information about a text encoding.
+
+ @param eTextEncoding
+ Any rtl_TextEncoding value.
+
+ @param pEncInfo
+ Returns information about the given encoding. Must not be null, and the
+ StructSize member must be set correctly.
+
+ @return
+ True if information about the given encoding is available, false
+ otherwise.
+ */
+SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_getTextEncodingInfo(
+ rtl_TextEncoding eTextEncoding, rtl_TextEncodingInfo* pEncInfo );
+
+/** Map from a numeric Windows charset to a text encoding.
+
+ @param nWinCharset
+ Any numeric Windows charset.
+
+ @return
+ The corresponding rtl_TextEncoding value, or RTL_TEXTENCODING_DONTKNOW if
+ no mapping is applicable.
+ If nWinCharset is 255 (OEM_CHARSET), then return value is RTL_TEXTENCODING_IBM_850,
+ regardless of current locale.
+ */
+SAL_DLLPUBLIC rtl_TextEncoding SAL_CALL rtl_getTextEncodingFromWindowsCharset(
+ sal_uInt8 nWinCharset );
+
+/** Map from a MIME charset to a text encoding.
+
+ @param pMimeCharset
+ Any MIME charset string. Must not be null.
+
+ @return
+ The corresponding rtl_TextEncoding value, or RTL_TEXTENCODING_DONTKNOW if
+ no mapping is applicable.
+ */
+SAL_DLLPUBLIC rtl_TextEncoding SAL_CALL rtl_getTextEncodingFromMimeCharset(
+ const char* pMimeCharset );
+
+/** Map from a Unix charset to a text encoding.
+
+ @param pUnixCharset
+ Any Unix charset string. Must not be null.
+
+ @return
+ The corresponding rtl_TextEncoding value, or RTL_TEXTENCODING_DONTKNOW if
+ no mapping is applicable.
+ */
+SAL_DLLPUBLIC rtl_TextEncoding SAL_CALL rtl_getTextEncodingFromUnixCharset(
+ const char* pUnixCharset );
+
+/** Map from a text encoding to the best matching numeric Windows charset.
+
+ @param eTextEncoding
+ Any rtl_TextEncoding value.
+
+ @return
+ The best matching numeric Windows charset, or 1 if none matches.
+ */
+SAL_DLLPUBLIC sal_uInt8 SAL_CALL rtl_getBestWindowsCharsetFromTextEncoding(
+ rtl_TextEncoding eTextEncoding );
+
+/** Map from a text encoding to a corresponding MIME charset name, if
+ available (see <http://www.iana.org/assignments/character-sets>).
+
+ @param nEncoding
+ Any rtl_TextEncoding value.
+
+ @return
+ The (preferred) MIME charset name corresponding to the given encoding, or
+ NULL if none is available.
+ */
+SAL_DLLPUBLIC char const * SAL_CALL rtl_getMimeCharsetFromTextEncoding(
+ rtl_TextEncoding nEncoding );
+
+/** Map from a text encoding to the best matching MIME charset.
+
+ @param eTextEncoding
+ Any rtl_TextEncoding value.
+
+ @return
+ The best matching MIME charset string, or null if none matches.
+ */
+SAL_DLLPUBLIC const char* SAL_CALL rtl_getBestMimeCharsetFromTextEncoding(
+ rtl_TextEncoding eTextEncoding );
+
+/** Map from a text encoding to the best matching Unix charset.
+
+ @param eTextEncoding
+ Any rtl_TextEncoding value.
+
+ @return
+ The best matching Unix charset string, or null if none matches.
+ */
+SAL_DLLPUBLIC const char* SAL_CALL rtl_getBestUnixCharsetFromTextEncoding(
+ rtl_TextEncoding eTextEncoding );
+
+/** Map from a Windows code page to a text encoding.
+
+ @param nCodePage
+ Any Windows code page number.
+
+ @return
+ The corresponding rtl_TextEncoding value (which will be an octet text
+ encoding, see rtl_isOctetTextEncoding), or RTL_TEXTENCODING_DONTKNOW if no
+ mapping is applicable.
+ */
+SAL_DLLPUBLIC rtl_TextEncoding SAL_CALL
+rtl_getTextEncodingFromWindowsCodePage(sal_uInt32 nCodePage);
+
+/** Map from a text encoding to a Windows code page.
+
+ @param nEncoding
+ Any rtl_TextEncoding value.
+
+ @return
+ The corresponding Windows code page number, or 0 if no mapping is
+ applicable.
+ */
+SAL_DLLPUBLIC sal_uInt32 SAL_CALL
+rtl_getWindowsCodePageFromTextEncoding(rtl_TextEncoding nEncoding);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_RTL_TENCINFO_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/textcvt.h b/include/rtl/textcvt.h
new file mode 100644
index 0000000000..14d374c16f
--- /dev/null
+++ b/include/rtl/textcvt.h
@@ -0,0 +1,194 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_TEXTCVT_H
+#define INCLUDED_RTL_TEXTCVT_H
+
+#include "sal/config.h"
+
+#include "rtl/textenc.h"
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Documentation about this file can be found at
+ <http://udk.openoffice.org/cpp/man/spec/textconversion.html>. */
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+typedef void* rtl_TextToUnicodeConverter;
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+typedef void* rtl_TextToUnicodeContext;
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+SAL_DLLPUBLIC rtl_TextToUnicodeConverter SAL_CALL rtl_createTextToUnicodeConverter( rtl_TextEncoding eTextEncoding );
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_destroyTextToUnicodeConverter( rtl_TextToUnicodeConverter hConverter );
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+SAL_DLLPUBLIC rtl_TextToUnicodeContext SAL_CALL rtl_createTextToUnicodeContext( rtl_TextToUnicodeConverter hConverter );
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_destroyTextToUnicodeContext( rtl_TextToUnicodeConverter hConverter, rtl_TextToUnicodeContext hContext );
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_resetTextToUnicodeContext( rtl_TextToUnicodeConverter hConverter, rtl_TextToUnicodeContext hContext );
+
+#define RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR ((sal_uInt32)0x0001)
+#define RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE ((sal_uInt32)0x0002)
+#define RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MAPTOPRIVATE ((sal_uInt32)0x0003)
+#define RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT ((sal_uInt32)0x0004)
+#define RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR ((sal_uInt32)0x0010)
+#define RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_IGNORE ((sal_uInt32)0x0020)
+#define RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT ((sal_uInt32)0x0030)
+#define RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR ((sal_uInt32)0x0100)
+#define RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE ((sal_uInt32)0x0200)
+#define RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT ((sal_uInt32)0x0300)
+#define RTL_TEXTTOUNICODE_FLAGS_FLUSH ((sal_uInt32)0x8000)
+#define RTL_TEXTTOUNICODE_FLAGS_GLOBAL_SIGNATURE 0x10000
+ /* Accept any global document signatures (for example, in UTF-8, a leading
+ EF BB BF encoding the Byte Order Mark U+FEFF) */
+
+#define RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MASK ((sal_uInt32)0x000F)
+#define RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_MASK ((sal_uInt32)0x00F0)
+#define RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK ((sal_uInt32)0x0F00)
+
+#define RTL_TEXTTOUNICODE_INFO_ERROR ((sal_uInt32)0x0001)
+// Misspelled constant, kept for backwards compatibility:
+#define RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL ((sal_uInt32)0x0002)
+#define RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL ((sal_uInt32)0x0002)
+// Misspelled constant, kept for backwards compatibility:
+#define RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL ((sal_uInt32)0x0004)
+#define RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL ((sal_uInt32)0x0004)
+#define RTL_TEXTTOUNICODE_INFO_UNDEFINED ((sal_uInt32)0x0008)
+#define RTL_TEXTTOUNICODE_INFO_MBUNDEFINED ((sal_uInt32)0x0010)
+#define RTL_TEXTTOUNICODE_INFO_INVALID ((sal_uInt32)0x0020)
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+
+ Deviating from the linked specification, the behavior of
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR, RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR, and
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR is as follows: When RTL_TEXTTOUNICODE_FLAGS_FLUSH is not
+ set, the erroneous input bytes are consumed as required by the linked specification. But if
+ RTL_TEXTTOUNICODE_FLAGS_FLUSH is set, any of those erroneous input bytes that would have been
+ consumed by this invocation of rtl_convertTextToUnicode (i.e., which had not already been
+ captured in hContext from a previous invocation with RTL_TEXTTOUNICODE_FLAGS_FLUSH unset) are
+ not consumed.
+ */
+SAL_DLLPUBLIC sal_Size SAL_CALL rtl_convertTextToUnicode(
+ rtl_TextToUnicodeConverter hConverter,
+ rtl_TextToUnicodeContext hContext,
+ const char* pSrcBuf, sal_Size nSrcBytes,
+ sal_Unicode* pDestBuf, sal_Size nDestChars,
+ sal_uInt32 nFlags, sal_uInt32* pInfo,
+ sal_Size* pSrcCvtBytes );
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+typedef void* rtl_UnicodeToTextConverter;
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+typedef void* rtl_UnicodeToTextContext;
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+SAL_DLLPUBLIC rtl_UnicodeToTextConverter SAL_CALL rtl_createUnicodeToTextConverter( rtl_TextEncoding eTextEncoding );
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_destroyUnicodeToTextConverter( rtl_UnicodeToTextConverter hConverter );
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+SAL_DLLPUBLIC rtl_UnicodeToTextContext SAL_CALL rtl_createUnicodeToTextContext( rtl_UnicodeToTextConverter hConverter );
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_destroyUnicodeToTextContext( rtl_UnicodeToTextConverter hConverter, rtl_UnicodeToTextContext hContext );
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_resetUnicodeToTextContext( rtl_UnicodeToTextConverter hConverter, rtl_UnicodeToTextContext hContext );
+
+#define RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR ((sal_uInt32)0x0001)
+#define RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE ((sal_uInt32)0x0002)
+#define RTL_UNICODETOTEXT_FLAGS_UNDEFINED_0 ((sal_uInt32)0x0003)
+#define RTL_UNICODETOTEXT_FLAGS_UNDEFINED_QUESTIONMARK ((sal_uInt32)0x0004)
+#define RTL_UNICODETOTEXT_FLAGS_UNDEFINED_UNDERLINE ((sal_uInt32)0x0005)
+#define RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT ((sal_uInt32)0x0006)
+#define RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR ((sal_uInt32)0x0010)
+#define RTL_UNICODETOTEXT_FLAGS_INVALID_IGNORE ((sal_uInt32)0x0020)
+#define RTL_UNICODETOTEXT_FLAGS_INVALID_0 ((sal_uInt32)0x0030)
+#define RTL_UNICODETOTEXT_FLAGS_INVALID_QUESTIONMARK ((sal_uInt32)0x0040)
+#define RTL_UNICODETOTEXT_FLAGS_INVALID_UNDERLINE ((sal_uInt32)0x0050)
+#define RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT ((sal_uInt32)0x0060)
+#define RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE ((sal_uInt32)0x0100)
+#define RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR ((sal_uInt32)0x0200)
+#define RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 ((sal_uInt32)0x0400)
+#define RTL_UNICODETOTEXT_FLAGS_NONSPACING_IGNORE ((sal_uInt32)0x0800)
+#define RTL_UNICODETOTEXT_FLAGS_CONTROL_IGNORE ((sal_uInt32)0x1000)
+#define RTL_UNICODETOTEXT_FLAGS_PRIVATE_IGNORE ((sal_uInt32)0x2000)
+#define RTL_UNICODETOTEXT_FLAGS_NOCOMPOSITE ((sal_uInt32)0x4000) ///< has no effect @deprecated
+#define RTL_UNICODETOTEXT_FLAGS_FLUSH ((sal_uInt32)0x8000)
+#define RTL_UNICODETOTEXT_FLAGS_GLOBAL_SIGNATURE 0x10000
+ /* Write any global document signatures (for example, in UTF-8, a leading
+ EF BB BF encoding the Byte Order Mark U+FEFF) */
+
+#define RTL_UNICODETOTEXT_FLAGS_UNDEFINED_MASK ((sal_uInt32)0x000F)
+#define RTL_UNICODETOTEXT_FLAGS_INVALID_MASK ((sal_uInt32)0x00F0)
+
+#define RTL_UNICODETOTEXT_INFO_ERROR ((sal_uInt32)0x0001)
+#define RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL ((sal_uInt32)0x0002)
+#define RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL ((sal_uInt32)0x0004)
+#define RTL_UNICODETOTEXT_INFO_UNDEFINED ((sal_uInt32)0x0008)
+#define RTL_UNICODETOTEXT_INFO_INVALID ((sal_uInt32)0x0010)
+
+/** see http://udk.openoffice.org/cpp/man/spec/textconversion.html
+ */
+SAL_DLLPUBLIC sal_Size SAL_CALL rtl_convertUnicodeToText(
+ rtl_UnicodeToTextConverter hConverter,
+ rtl_UnicodeToTextContext hContext,
+ const sal_Unicode* pSrcBuf, sal_Size nSrcChars,
+ char* pDestBuf, sal_Size nDestBytes,
+ sal_uInt32 nFlags, sal_uInt32* pInfo,
+ sal_Size* pSrcCvtChars );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_RTL_TEXTCVT_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/textenc.h b/include/rtl/textenc.h
new file mode 100644
index 0000000000..af4a16e5c4
--- /dev/null
+++ b/include/rtl/textenc.h
@@ -0,0 +1,269 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_TEXTENC_H
+#define INCLUDED_RTL_TEXTENC_H
+
+#include "sal/types.h"
+
+/** The various supported text encodings.
+
+ Possible values include a wide range of single- and multi-byte encodings
+ (ranging from RTL_TEXTENCODING_MS_1252 to RTL_TEXTENCODING_GB_18030),
+ the ISO 10646 (Unicode) specific encodings RTL_TEXTENCODING_UCS4 and
+ RTL_TEXTENCODING_UCS2 (aka RTL_TEXTENCODING_UNICODE), and
+ RTL_TEXTENCODING_DONTKNOW to indicate an unknown or missing encoding.
+ */
+typedef sal_uInt16 rtl_TextEncoding;
+
+#define RTL_TEXTENC_CAST( val ) ((rtl_TextEncoding) val)
+
+#define RTL_TEXTENCODING_DONTKNOW (RTL_TEXTENC_CAST( 0 ))
+#define RTL_TEXTENCODING_MS_1252 (RTL_TEXTENC_CAST( 1 ))
+#define RTL_TEXTENCODING_APPLE_ROMAN (RTL_TEXTENC_CAST( 2 ))
+#define RTL_TEXTENCODING_IBM_437 (RTL_TEXTENC_CAST( 3 ))
+#define RTL_TEXTENCODING_IBM_850 (RTL_TEXTENC_CAST( 4 ))
+#define RTL_TEXTENCODING_IBM_860 (RTL_TEXTENC_CAST( 5 ))
+#define RTL_TEXTENCODING_IBM_861 (RTL_TEXTENC_CAST( 6 ))
+#define RTL_TEXTENCODING_IBM_863 (RTL_TEXTENC_CAST( 7 ))
+#define RTL_TEXTENCODING_IBM_865 (RTL_TEXTENC_CAST( 8 ))
+/* Reserved: RTL_TEXTENCODING_SYSTEM (RTL_TEXTENC_CAST( 9 )) */
+#define RTL_TEXTENCODING_SYMBOL (RTL_TEXTENC_CAST( 10 ))
+#define RTL_TEXTENCODING_ASCII_US (RTL_TEXTENC_CAST( 11 ))
+#define RTL_TEXTENCODING_ISO_8859_1 (RTL_TEXTENC_CAST( 12 ))
+#define RTL_TEXTENCODING_ISO_8859_2 (RTL_TEXTENC_CAST( 13 ))
+#define RTL_TEXTENCODING_ISO_8859_3 (RTL_TEXTENC_CAST( 14 ))
+#define RTL_TEXTENCODING_ISO_8859_4 (RTL_TEXTENC_CAST( 15 ))
+#define RTL_TEXTENCODING_ISO_8859_5 (RTL_TEXTENC_CAST( 16 ))
+#define RTL_TEXTENCODING_ISO_8859_6 (RTL_TEXTENC_CAST( 17 ))
+#define RTL_TEXTENCODING_ISO_8859_7 (RTL_TEXTENC_CAST( 18 ))
+#define RTL_TEXTENCODING_ISO_8859_8 (RTL_TEXTENC_CAST( 19 ))
+#define RTL_TEXTENCODING_ISO_8859_9 (RTL_TEXTENC_CAST( 20 ))
+#define RTL_TEXTENCODING_ISO_8859_14 (RTL_TEXTENC_CAST( 21 ))
+#define RTL_TEXTENCODING_ISO_8859_15 (RTL_TEXTENC_CAST( 22 ))
+#define RTL_TEXTENCODING_IBM_737 (RTL_TEXTENC_CAST( 23 ))
+#define RTL_TEXTENCODING_IBM_775 (RTL_TEXTENC_CAST( 24 ))
+#define RTL_TEXTENCODING_IBM_852 (RTL_TEXTENC_CAST( 25 ))
+#define RTL_TEXTENCODING_IBM_855 (RTL_TEXTENC_CAST( 26 ))
+#define RTL_TEXTENCODING_IBM_857 (RTL_TEXTENC_CAST( 27 ))
+#define RTL_TEXTENCODING_IBM_862 (RTL_TEXTENC_CAST( 28 ))
+#define RTL_TEXTENCODING_IBM_864 (RTL_TEXTENC_CAST( 29 ))
+#define RTL_TEXTENCODING_IBM_866 (RTL_TEXTENC_CAST( 30 ))
+#define RTL_TEXTENCODING_IBM_869 (RTL_TEXTENC_CAST( 31 ))
+#define RTL_TEXTENCODING_MS_874 (RTL_TEXTENC_CAST( 32 ))
+#define RTL_TEXTENCODING_MS_1250 (RTL_TEXTENC_CAST( 33 ))
+#define RTL_TEXTENCODING_MS_1251 (RTL_TEXTENC_CAST( 34 ))
+#define RTL_TEXTENCODING_MS_1253 (RTL_TEXTENC_CAST( 35 ))
+#define RTL_TEXTENCODING_MS_1254 (RTL_TEXTENC_CAST( 36 ))
+#define RTL_TEXTENCODING_MS_1255 (RTL_TEXTENC_CAST( 37 ))
+#define RTL_TEXTENCODING_MS_1256 (RTL_TEXTENC_CAST( 38 ))
+#define RTL_TEXTENCODING_MS_1257 (RTL_TEXTENC_CAST( 39 ))
+#define RTL_TEXTENCODING_MS_1258 (RTL_TEXTENC_CAST( 40 ))
+#define RTL_TEXTENCODING_APPLE_ARABIC (RTL_TEXTENC_CAST( 41 ))
+#define RTL_TEXTENCODING_APPLE_CENTEURO (RTL_TEXTENC_CAST( 42 ))
+#define RTL_TEXTENCODING_APPLE_CROATIAN (RTL_TEXTENC_CAST( 43 ))
+#define RTL_TEXTENCODING_APPLE_CYRILLIC (RTL_TEXTENC_CAST( 44 ))
+#define RTL_TEXTENCODING_APPLE_DEVANAGARI (RTL_TEXTENC_CAST( 45 ))
+#define RTL_TEXTENCODING_APPLE_FARSI (RTL_TEXTENC_CAST( 46 ))
+#define RTL_TEXTENCODING_APPLE_GREEK (RTL_TEXTENC_CAST( 47 ))
+#define RTL_TEXTENCODING_APPLE_GUJARATI (RTL_TEXTENC_CAST( 48 ))
+#define RTL_TEXTENCODING_APPLE_GURMUKHI (RTL_TEXTENC_CAST( 49 ))
+#define RTL_TEXTENCODING_APPLE_HEBREW (RTL_TEXTENC_CAST( 50 ))
+#define RTL_TEXTENCODING_APPLE_ICELAND (RTL_TEXTENC_CAST( 51 ))
+#define RTL_TEXTENCODING_APPLE_ROMANIAN (RTL_TEXTENC_CAST( 52 ))
+#define RTL_TEXTENCODING_APPLE_THAI (RTL_TEXTENC_CAST( 53 ))
+#define RTL_TEXTENCODING_APPLE_TURKISH (RTL_TEXTENC_CAST( 54 ))
+#define RTL_TEXTENCODING_APPLE_UKRAINIAN (RTL_TEXTENC_CAST( 55 ))
+#define RTL_TEXTENCODING_APPLE_CHINSIMP (RTL_TEXTENC_CAST( 56 ))
+#define RTL_TEXTENCODING_APPLE_CHINTRAD (RTL_TEXTENC_CAST( 57 ))
+#define RTL_TEXTENCODING_APPLE_JAPANESE (RTL_TEXTENC_CAST( 58 ))
+#define RTL_TEXTENCODING_APPLE_KOREAN (RTL_TEXTENC_CAST( 59 ))
+#define RTL_TEXTENCODING_MS_932 (RTL_TEXTENC_CAST( 60 ))
+#define RTL_TEXTENCODING_MS_936 (RTL_TEXTENC_CAST( 61 ))
+#define RTL_TEXTENCODING_MS_949 (RTL_TEXTENC_CAST( 62 ))
+#define RTL_TEXTENCODING_MS_950 (RTL_TEXTENC_CAST( 63 ))
+#define RTL_TEXTENCODING_SHIFT_JIS (RTL_TEXTENC_CAST( 64 ))
+#define RTL_TEXTENCODING_GB_2312 (RTL_TEXTENC_CAST( 65 ))
+#define RTL_TEXTENCODING_GBT_12345 (RTL_TEXTENC_CAST( 66 ))
+#define RTL_TEXTENCODING_GBK (RTL_TEXTENC_CAST( 67 ))
+#define RTL_TEXTENCODING_BIG5 (RTL_TEXTENC_CAST( 68 ))
+#define RTL_TEXTENCODING_EUC_JP (RTL_TEXTENC_CAST( 69 ))
+#define RTL_TEXTENCODING_EUC_CN (RTL_TEXTENC_CAST( 70 ))
+#define RTL_TEXTENCODING_EUC_TW (RTL_TEXTENC_CAST( 71 ))
+#define RTL_TEXTENCODING_ISO_2022_JP (RTL_TEXTENC_CAST( 72 ))
+#define RTL_TEXTENCODING_ISO_2022_CN (RTL_TEXTENC_CAST( 73 ))
+#define RTL_TEXTENCODING_KOI8_R (RTL_TEXTENC_CAST( 74 ))
+#define RTL_TEXTENCODING_UTF7 (RTL_TEXTENC_CAST( 75 ))
+#define RTL_TEXTENCODING_UTF8 (RTL_TEXTENC_CAST( 76 ))
+#define RTL_TEXTENCODING_ISO_8859_10 (RTL_TEXTENC_CAST( 77 ))
+#define RTL_TEXTENCODING_ISO_8859_13 (RTL_TEXTENC_CAST( 78 ))
+#define RTL_TEXTENCODING_EUC_KR (RTL_TEXTENC_CAST( 79 ))
+#define RTL_TEXTENCODING_ISO_2022_KR (RTL_TEXTENC_CAST( 80 ))
+#define RTL_TEXTENCODING_JIS_X_0201 (RTL_TEXTENC_CAST( 81 ))
+#define RTL_TEXTENCODING_JIS_X_0208 (RTL_TEXTENC_CAST( 82 ))
+#define RTL_TEXTENCODING_JIS_X_0212 (RTL_TEXTENC_CAST( 83 ))
+#define RTL_TEXTENCODING_MS_1361 (RTL_TEXTENC_CAST( 84 ))
+#define RTL_TEXTENCODING_GB_18030 (RTL_TEXTENC_CAST( 85 ))
+#define RTL_TEXTENCODING_BIG5_HKSCS (RTL_TEXTENC_CAST( 86 ))
+#define RTL_TEXTENCODING_TIS_620 (RTL_TEXTENC_CAST( 87 ))
+#define RTL_TEXTENCODING_KOI8_U (RTL_TEXTENC_CAST( 88 ))
+#define RTL_TEXTENCODING_ISCII_DEVANAGARI (RTL_TEXTENC_CAST( 89 ))
+#define RTL_TEXTENCODING_JAVA_UTF8 (RTL_TEXTENC_CAST( 90 ))
+#define RTL_TEXTENCODING_ADOBE_STANDARD (RTL_TEXTENC_CAST( 91 ))
+#define RTL_TEXTENCODING_ADOBE_SYMBOL (RTL_TEXTENC_CAST( 92 ))
+#define RTL_TEXTENCODING_PT154 (RTL_TEXTENC_CAST( 93 ))
+#define RTL_TEXTENCODING_ADOBE_DINGBATS (RTL_TEXTENC_CAST( 94 ))
+#define RTL_TEXTENCODING_KAMENICKY (RTL_TEXTENC_CAST( 95 ))
+#define RTL_TEXTENCODING_MAZOVIA (RTL_TEXTENC_CAST( 96 ))
+/* ATTENTION! Whenever some encoding is added here, make sure to update
+ * rtl_isOctetTextEncoding in sal/textenc/tencinfo.cxx and sal_getFullTextEncodingData in
+ * sal/textenc/tables.cxx.
+ */
+
+#define RTL_TEXTENCODING_USER_START (RTL_TEXTENC_CAST( 0x8000 ))
+#define RTL_TEXTENCODING_USER_END (RTL_TEXTENC_CAST( 0xEFFF ))
+
+#define RTL_TEXTENCODING_UCS4 (RTL_TEXTENC_CAST( 0xFFFE ))
+#define RTL_TEXTENCODING_UCS2 (RTL_TEXTENC_CAST( 0xFFFF ))
+#define RTL_TEXTENCODING_UNICODE RTL_TEXTENCODING_UCS2
+
+/****** Overview over the TextEncodings *****
+# Arabic (Apple Macintosh) RTL_TEXTENCODING_APPLE_ARABIC
+Arabic (DOS/OS2-864) RTL_TEXTENCODING_IBM_864
+Arabic (ISO-8859-6) RTL_TEXTENCODING_ISO_8859_6
+Arabic (Windows-1256) RTL_TEXTENCODING_MS_1256
+
+Baltic (DOS/OS2-775) RTL_TEXTENCODING_IBM_775
+Baltic (ISO-8859-4) RTL_TEXTENCODING_ISO_8859_4
+Baltic (Windows-1257) RTL_TEXTENCODING_MS_1257
+
+Central European (Apple Macintosh) RTL_TEXTENCODING_APPLE_CENTEURO
+Central European (Apple Macintosh/Croatian) RTL_TEXTENCODING_APPLE_CROATIAN
+Central European (Apple Macintosh/Romanian) RTL_TEXTENCODING_APPLE_ROMANIAN
+Central European (DOS/OS2-852) RTL_TEXTENCODING_IBM_852
+Central European (ISO-8859-2) RTL_TEXTENCODING_ISO_8859_2
+Central European (ISO-8859-10) RTL_TEXTENCODING_ISO_8859_10
+Central European (ISO-8859-13) RTL_TEXTENCODING_ISO_8859_13
+Central European (Windows-1250/WinLatin 2) RTL_TEXTENCODING_MS_1250
+
+Chinese Simplified (Apple Macintosh) RTL_TEXTENCODING_APPLE_CHINSIMP
+Chinese Simplified (EUC-CN) RTL_TEXTENCODING_EUC_CN
+Chinese Simplified (GB-2312) RTL_TEXTENCODING_GB_2312
+Chinese Simplified (GBK/GB-2312-80) RTL_TEXTENCODING_GBK
+# Chinese Simplified (ISO-2022-CN) RTL_TEXTENCODING_ISO_2022_CN
+Chinese Simplified (Windows-936) RTL_TEXTENCODING_MS_936
+# Chinese Simplified (GB-18030) RTL_TEXTENCODING_GB_18030
+
+Chinese Traditional (Apple Macintosh) RTL_TEXTENCODING_APPLE_CHINTRAD
+Chinese Traditional (BIG5) RTL_TEXTENCODING_BIG5
+# Chinese Traditional (EUC-TW) RTL_TEXTENCODING_EUC_TW
+Chinese Traditional (GBT-12345) RTL_TEXTENCODING_GBT_12345
+Chinese Traditional (Windows-950) RTL_TEXTENCODING_MS_950
+Chinese Traditional (BIG5-HKSCS) RTL_TEXTENCODING_BIG5_HKSCS
+
+Cyrillic (Apple Macintosh) RTL_TEXTENCODING_APPLE_CYRILLIC
+Cyrillic (Apple Macintosh/Ukrainian) RTL_TEXTENCODING_APPLE_UKRAINIAN
+Cyrillic (DOS/OS2-855) RTL_TEXTENCODING_IBM_855
+Cyrillic (DOS/OS2-866/Russian) RTL_TEXTENCODING_IBM_866
+Cyrillic (ISO-8859-5) RTL_TEXTENCODING_ISO_8859_5
+Cyrillic (KOI8-R) RTL_TEXTENCODING_KOI8_R
+Cyrillic (KOI8-U) RTL_TEXTENCODING_KOI8_U
+Cyrillic (Windows-1251) RTL_TEXTENCODING_MS_1251
+
+Greek (Apple Macintosh) RTL_TEXTENCODING_APPLE_GREEK
+Greek (DOS/OS2-737) RTL_TEXTENCODING_IBM_737
+Greek (DOS/OS2-869/Modern) RTL_TEXTENCODING_IBM_869
+Greek (ISO-8859-7) RTL_TEXTENCODING_ISO_8859_7
+Greek (Windows-1253) RTL_TEXTENCODING_MS_1253
+
+# Hebrew (Apple Macintosh) RTL_TEXTENCODING_APPLE_HEBREW
+Hebrew (DOS/OS2-862) RTL_TEXTENCODING_IBM_862
+Hebrew (ISO-8859-8) RTL_TEXTENCODING_ISO_8859_8
+Hebrew (Windows-1255) RTL_TEXTENCODING_MS_1255
+
+Korean (Apple Macintosh) RTL_TEXTENCODING_APPLE_KOREAN
+Korean (EUC-KR) RTL_TEXTENCODING_EUC_KR
+# Korean (ISO-2022-KR) RTL_TEXTENCODING_ISO_2022_KR
+Korean (Windows-Wansung-949) RTL_TEXTENCODING_MS_949
+Korean (Windows-Johab-1361) RTL_TEXTENCODING_MS_1361
+
+Latin 3 (ISO-8859-3) RTL_TEXTENCODING_ISO_8859_3
+
+Indian (ISCII Devanagari) RTL_TEXTENCODING_ISCII_DEVANAGARI
+
+Japanese (Apple Macintosh) RTL_TEXTENCODING_APPLE_JAPANESE
+Japanese (EUC-JP) RTL_TEXTENCODING_EUC_JP
+# Japanese (ISO-2022-JP) RTL_TEXTENCODING_ISO_2022_JP
+Japanese (Shift-JIS) RTL_TEXTENCODING_SHIFT_JIS
+Japanese (Windows-932) RTL_TEXTENCODING_MS_932
+
+Symbol RTL_TEXTENCODING_SYMBOL
+
+# Thai (Apple Macintosh) RTL_TEXTENCODING_APPLE_THAI
+Thai (Dos/Windows-874) RTL_TEXTENCODING_MS_874
+Thai (TIS 620) RTL_TEXTENCODING_TIS_620
+
+Turkish (Apple Macintosh) RTL_TEXTENCODING_APPLE_TURKISH
+Turkish (DOS/OS2-857) RTL_TEXTENCODING_IBM_857
+Turkish (ISO-8859-9) RTL_TEXTENCODING_ISO_8859_9
+Turkish (Windows-1254) RTL_TEXTENCODING_MS_1254
+
+Unicode (UTF-7) RTL_TEXTENCODING_UTF7
+Unicode (UTF-8) RTL_TEXTENCODING_UTF8
+Unicode (Java's modified UTF-8) RTL_TEXTENCODING_JAVA_UTF8
+
+Vietnamese (Windows-1258) RTL_TEXTENCODING_MS_1258
+
+Western (Apple Macintosh) RTL_TEXTENCODING_APPLE_ROMAN
+Western (Apple Macintosh/Icelandic) RTL_TEXTENCODING_APPLE_ICELAND
+Western (ASCII/US) RTL_TEXTENCODING_ASCII_US
+Western (DOS/OS2-437/US) RTL_TEXTENCODING_IBM_437
+Western (DOS/OS2-850/International) RTL_TEXTENCODING_IBM_850
+Western (DOS/OS2-860/Portuguese) RTL_TEXTENCODING_IBM_860
+Western (DOS/OS2-861/Icelandic) RTL_TEXTENCODING_IBM_861
+Western (DOS/OS2-863/Canadian-French) RTL_TEXTENCODING_IBM_863
+Western (DOS/OS2-865/Nordic) RTL_TEXTENCODING_IBM_865
+Western (ISO-8859-1) RTL_TEXTENCODING_ISO_8859_1
+Western (ISO-8859-14) RTL_TEXTENCODING_ISO_8859_14
+Western (ISO-8859-15/EURO) RTL_TEXTENCODING_ISO_8859_15
+Western (Window-1252/WinLatin 1) RTL_TEXTENCODING_MS_1252
+
+Not known and currently not supported
+# RTL_TEXTENCODING_APPLE_DEVANAGARI
+# RTL_TEXTENCODING_APPLE_FARSI
+# RTL_TEXTENCODING_APPLE_GUJARATI
+# RTL_TEXTENCODING_APPLE_GURMUKHI
+
+Only for internal implementations and not useful for user interface.
+These encodings are not used for text encodings, only used for
+font-/textoutput encodings.
+Japanese (JIS 0201) RTL_TEXTENCODING_JISX_0201
+Japanese (JIS 0208) RTL_TEXTENCODING_JISX_0208
+Japanese (JIS 0212) RTL_TEXTENCODING_JISX_0212
+
+# Currently not implemented
+*/
+
+#endif // INCLUDED_RTL_TEXTENC_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/unload.h b/include/rtl/unload.h
new file mode 100644
index 0000000000..23cd2fa749
--- /dev/null
+++ b/include/rtl/unload.h
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+#ifndef INCLUDED_RTL_UNLOAD_H
+#define INCLUDED_RTL_UNLOAD_H
+
+#include "sal/config.h"
+
+#include "osl/interlck.h"
+#include "osl/time.h"
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+/** @file
+ Backwards-compatibility remainders of a removed library unloading feature.
+*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/** Backwards-compatibility remainder of a removed library unloading feature.
+
+ @deprecated Do not use.
+*/
+typedef struct SAL_DLLPUBLIC_RTTI _rtl_ModuleCount
+{
+ void ( SAL_CALL * acquire ) ( struct _rtl_ModuleCount * that );
+ void ( SAL_CALL * release ) ( struct _rtl_ModuleCount * that );
+}rtl_ModuleCount;
+
+/** Backwards-compatibility remainder of a removed library unloading feature.
+
+ @deprecated Do not use.
+*/
+#define MODULE_COUNT_INIT \
+{ {rtl_moduleCount_acquire,rtl_moduleCount_release}, rtl_moduleCount_canUnload, 0, {0, 0}}
+
+/** Backwards-compatibility remainder of a removed library unloading feature.
+
+ @deprecated Do not use.
+*/
+typedef struct _rtl_StandardModuleCount
+{
+ rtl_ModuleCount modCnt;
+ sal_Bool ( *canUnload ) ( struct _rtl_StandardModuleCount* a, TimeValue* libUnused);
+ oslInterlockedCount counter;
+ TimeValue unusedSince;
+} rtl_StandardModuleCount;
+
+/** Backwards-compatibility remainder of a removed library unloading feature.
+
+ @deprecated Do not use.
+*/
+SAL_DLLPUBLIC void rtl_moduleCount_acquire(rtl_ModuleCount * that ) SAL_COLD;
+
+/** Backwards-compatibility remainder of a removed library unloading feature.
+
+ @deprecated Do not use.
+*/
+SAL_DLLPUBLIC void rtl_moduleCount_release( rtl_ModuleCount * that ) SAL_COLD;
+
+/** Backwards-compatibility remainder of a removed library unloading feature.
+
+ @deprecated Do not use.
+*/
+SAL_DLLPUBLIC sal_Bool rtl_moduleCount_canUnload( rtl_StandardModuleCount * that, TimeValue* libUnused) SAL_COLD;
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/uri.h b/include/rtl/uri.h
new file mode 100644
index 0000000000..28975060c0
--- /dev/null
+++ b/include/rtl/uri.h
@@ -0,0 +1,362 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_URI_H
+#define INCLUDED_RTL_URI_H
+
+#include "sal/config.h"
+
+#include "rtl/textenc.h"
+#include "rtl/ustring.h"
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** Various predefined URI 'char classes.'
+
+ A 'char class' defines which (ASCII) characters can be written 'as they
+ are' in a part of a Uri, and which characters have to be written using
+ escape sequences ('%' followed by two hex digits). Characters outside
+ the ASCII range are always written using escape sequences.
+
+ If there are other frequently used char classes, they can be added to
+ this enumeration; the function rtl_getUriCharClass() has to be adapted
+ then, too.
+ */
+typedef enum
+{
+ /** The empty char class.
+
+ All characters are written using escape sequences.
+ */
+ rtl_UriCharClassNone,
+
+ /** The RFC 2732 @<uric> char class.
+
+ @verbatim
+ The 'valid' characters are !$&'()*+,-./:;=?@[]_~ plus digits and
+ letters.
+
+ This differs from RFC 3986 @<fragment> in additionally allowing []
+ @endverbatim
+ */
+ rtl_UriCharClassUric,
+
+ /** The RFC 2396 @<uric_no_slash> char class.
+
+ @verbatim
+ The 'valid' characters are !$&'()*+,-.:;=?@_~ plus digits and letters.
+
+ This differs from RFC 3986 @<fragment> in additionally encoding /
+ This differs from RFC 3986 @<pchar> in additionally allowing ?
+ @endverbatim
+ */
+ rtl_UriCharClassUricNoSlash,
+
+ /** The RFC 2396 @<rel_segment> char class.
+
+ @verbatim
+ The 'valid' characters are !$&'()*+,-.;=@_~ plus digits and letters.
+
+ This is the same as RFC 3986 @<segment-nz-nc>
+ @endverbatim
+ */
+ rtl_UriCharClassRelSegment,
+
+ /** The RFC 2396 @<reg_name> char class.
+
+ @verbatim
+ The 'valid' characters are !$&'()*+,-.:;=@_~ plus digits and letters.
+
+ This differs from RFC 3986 @<reg_name> in additionally allowing @
+ @endverbatim
+ */
+ rtl_UriCharClassRegName,
+
+ /** The RFC 2396 @<userinfo> char class.
+
+ @verbatim
+ The 'valid' characters are !$&'()*+,-.:;=_~ plus digits and letters.
+
+ This is the same as RFC 3986 @<userinfo>
+ @endverbatim
+ */
+ rtl_UriCharClassUserinfo,
+
+ /** The RFC 2396 @<pchar> char class.
+
+ @verbatim
+ The 'valid' characters are !$&'()*+,-.:=@_~ plus digits and letters.
+
+ This differs from RFC 3986 @<pchar> in additionally encoding ;
+ @endverbatim
+ */
+ rtl_UriCharClassPchar,
+
+ /** The char class for the values of uno URL parameters.
+
+ @verbatim
+ The 'valid' characters are !$&'()*+-./:?@_~ plus digits and letters.
+ @endverbatim
+ */
+ rtl_UriCharClassUnoParamValue,
+
+ rtl_UriCharClass_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+}
+rtl_UriCharClass;
+
+/** The mechanism describing how escape sequences in the input of
+ rtl_uriEncode() are handled.
+ */
+typedef enum
+{
+ /** The special meaning of '%' is ignored (i.e., there are by definition
+ no escape sequences in the input).
+
+ This mechanism is useful to encode user input as part of a URI (e.g.,
+ the user-supplied password in an ftp URL---'%20abcde' is a valid
+ password, so do not assume that the '%20' is an escaped space).
+ */
+ rtl_UriEncodeIgnoreEscapes,
+
+ /** All escape sequences ('%' followed by two hex digits) are kept intact,
+ even if they represent characters that need not be escaped or if they
+ do not even map to characters in the given charset.
+
+ This mechanism is useful when passing on complete URIs more or less
+ unmodified (e.g., within an HTTP proxy): missing escape sequences are
+ added, but existing escape sequences are not touched (except that any
+ lower case hex digits are replaced by upper case hex digits).
+ */
+ rtl_UriEncodeKeepEscapes,
+
+ /** All escape sequences ('%' followed by two hex digits) are resolved in
+ a first step; only those that represent characters that need to be
+ escaped are kept intact.
+
+ This mechanism is useful to properly encode complete URIs entered by
+ the user: the URI is brought into a 'canonic form,' but care is taken
+ not to damage (valid) escape sequences the (careful) user already
+ entered as such.
+ */
+ rtl_UriEncodeCheckEscapes,
+
+ /** Like rtl_UriEncodeIgnoreEscapes, but indicating failure when converting
+ unmappable characters.
+
+ @since UDK 3.2.0
+ */
+ rtl_UriEncodeStrict,
+
+ /** Like rtl_UriEncodeKeepEscapes, but indicating failure when converting
+ unmappable characters.
+
+ Also, any escape sequences that are present are always considered to be (potentially broken)
+ UTF-8. This mechanism is meant to be used on the result of a rtl_UriDecodeToIuri decoding,
+ which will thus only contain escape sequences representing either ASCII characters or broken
+ UTF-8 sequences, and which will all be kept as-is.
+
+ @since UDK 3.2.7
+ */
+ rtl_UriEncodeStrictKeepEscapes,
+
+ rtl_UriEncode_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+}
+rtl_UriEncodeMechanism;
+
+/** The mechanism describing how rtl_uriDecode() translates (part of) a URI
+ into a Unicode string.
+ */
+typedef enum
+{
+ /** The text is returned completely unmodified.
+ */
+ rtl_UriDecodeNone,
+
+ /** The text is returned in the form of an IURI (cf.
+ draft-masinter-url-i18n-05.txt).
+
+ All escape sequences representing ASCII characters (%00--%7F) are
+ kept, all other escape sequences are interpreted as UTF-8 characters
+ and translated to Unicode, if possible.
+ */
+ rtl_UriDecodeToIuri,
+
+ /** The text is decoded.
+
+ All escape sequences representing characters from the given charset
+ are decoded and translated to Unicode, if possible.
+ */
+ rtl_UriDecodeWithCharset,
+
+ /** Like rtl_UriDecodeWithCharset, but indicating failure when converting
+ unmappable characters.
+
+ @since UDK 3.2.0
+ */
+ rtl_UriDecodeStrict,
+
+ rtl_UriDecode_FORCE_EQUAL_SIZE = SAL_MAX_ENUM
+}
+rtl_UriDecodeMechanism;
+
+/** Map a predefined rtl_UriCharClass to a form usable by rtl_uriEncode().
+
+ The function rtl_uriEncode() expects an array of 128 booleans, and this
+ function maps rtl_UriCharClass enumeration members to such arrays.
+
+ @param eCharClass
+ Any valid member of rtl_UriCharClass.
+
+ @return
+ An array of 128 booleans, to be used in calls to rtl_uriEncode().
+ */
+SAL_DLLPUBLIC sal_Bool const * SAL_CALL rtl_getUriCharClass(rtl_UriCharClass eCharClass)
+ SAL_THROW_EXTERN_C();
+
+/** Encode a text as (part of) a URI.
+
+ @param pText
+ Any Unicode string. Must not be null.
+
+ @param pCharClass
+ A char class, represented as an array of 128 booleans (true means keep the
+ corresponding ASCII character unencoded, false means encode it). Must not
+ be null, and the boolean corresponding to the percent sign (0x25) must be
+ false. (See rtl_getUriCharClass() for a function mapping from
+ rtl_UriCharClass to such arrays.)
+
+ @param eMechanism
+ The mechanism describing how escape sequences in the input text are
+ handled.
+
+ @param eCharset
+ When Unicode characters from the input text have to be written using
+ escape sequences (because they are either outside the ASCII range or do
+ not belong to the given char class), they are first translated into this
+ charset before being encoded using escape sequences.
+
+ Also, if the encode mechanism is rtl_UriEncodeCheckEscapes, all escape
+ sequences already present in the input text are interpreted as characters
+ from this charset.
+
+ @param pResult
+ Returns an encoded representation of the input text. Must itself not be
+ null, and must point to either null or a valid string.
+
+ If the encode mechanism is rtl_UriEncodeStrict, and pText cannot be
+ converted to eCharset because it contains unmappable characters (which
+ implies that pText is not empty), then an empty string is returned.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uriEncode(
+ rtl_uString * pText,
+ sal_Bool const * pCharClass,
+ rtl_UriEncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ rtl_uString ** pResult)
+ SAL_THROW_EXTERN_C();
+
+/** Decode (a part of) a URI.
+
+ @param pText
+ Any Unicode string. Must not be null. (If the input is indeed part of a
+ valid URI, this string will only contain a subset of the ASCII characters,
+ but this function also handles other Unicode characters properly.)
+
+ @param eMechanism
+ The mechanism describing how the input text is translated into a Unicode
+ string.
+
+ @param eCharset
+ When the decode mechanism is rtl_UriDecodeWithCharset, all escape
+ sequences in the input text are interpreted as characters from this
+ charset. Those characters are translated to Unicode characters in the
+ resulting output, if possible.
+
+ When the decode mechanism is rtl_UriDecodeNone or rtl_UriDecodeToIuri,
+ this parameter is ignored (and is best specified as
+ RTL_TEXTENCODING_UTF8).
+
+ @param pResult
+ Returns a decoded representation of the input text. Must itself not be
+ null, and must point to either null or a valid string.
+
+ If the decode mechanism is rtl_UriDecodeStrict, and pText cannot be
+ converted to eCharset because it contains (encodings of) unmappable
+ characters (which implies that pText is not empty), then an empty string is
+ returned.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uriDecode(
+ rtl_uString * pText,
+ rtl_UriDecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset,
+ rtl_uString ** pResult)
+ SAL_THROW_EXTERN_C();
+
+/** Convert a relative URI reference into an absolute URI.
+
+ This function uses the strict parser algorithm described in RFC 3986,
+ section 5.2.
+
+ This function signals exceptions by returning false and letting pException
+ point to a message explaining the exception.
+
+ @param pBaseUriRef
+ An absolute URI that serves as the base URI. If it has to be inspected
+ (i.e., pRelUriRef is not an absolute URI already), and it is not an absolute
+ URI (i.e., does not begin with a @<scheme ":"> part), an exception will be
+ signaled.
+
+ @param pRelUriRef
+ A URI reference that may be either absolute or relative. If it is
+ absolute, it will be returned unmodified.
+
+ @param pResult
+ Returns an absolute URI. Must itself not be null, and must point to either
+ null or a valid string. If an exception is signalled, it is left unchanged.
+
+ @param pException
+ Returns an explanatory message in case an exception is signalled. Must
+ itself not be null, and must point to either null or a valid string. If no
+ exception is signalled, it is left unchanged.
+
+ @return
+ True if no exception is signalled, otherwise false.
+ */
+SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_uriConvertRelToAbs(
+ rtl_uString * pBaseUriRef,
+ rtl_uString * pRelUriRef,
+ rtl_uString ** pResult,
+ rtl_uString ** pException)
+ SAL_THROW_EXTERN_C();
+
+#if defined __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // INCLUDED_RTL_URI_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/uri.hxx b/include/rtl/uri.hxx
new file mode 100644
index 0000000000..b0b3e9ad81
--- /dev/null
+++ b/include/rtl/uri.hxx
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_URI_HXX
+#define INCLUDED_RTL_URI_HXX
+
+#include "rtl/malformeduriexception.hxx"
+#include "rtl/uri.h"
+#include "rtl/textenc.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+#if defined LIBO_INTERNAL_ONLY
+#include <array>
+#include <cassert>
+#include <cstddef>
+#include <string_view>
+#include "config_global.h"
+#endif
+
+namespace rtl {
+
+/** A wrapper around the C functions from <rtl/uri.h>.
+ */
+class Uri
+{
+public:
+ /** A wrapper around rtl_uriEncode() from <rtl/uri.h> (see there), using
+ an array of 128 booleans as char class.
+ */
+ static inline rtl::OUString encode(rtl::OUString const & rText,
+ sal_Bool const * pCharClass,
+ rtl_UriEncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset);
+
+ /** A wrapper around rtl_uriEncode() from <rtl/uri.h> (see there), using
+ a predefined rtl_UriCharClass enumeration member.
+ */
+ static inline rtl::OUString encode(rtl::OUString const & rText,
+ rtl_UriCharClass eCharClass,
+ rtl_UriEncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset);
+
+ /** A wrapper around rtl_uriDecode() from <rtl/uri.h> (see there).
+ */
+ static inline rtl::OUString decode(rtl::OUString const & rText,
+ rtl_UriDecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset);
+
+ /** A wrapper around rtl_uriConvertRelToAbs() from <rtl/uri.h> (see there).
+
+ @exception MalformedUriException
+ Thrown in case rtl_uriConvertRelToAbs() signals an exception due to a
+ malformed base URI.
+ */
+ static inline rtl::OUString convertRelToAbs(
+ rtl::OUString const & rBaseUriRef, rtl::OUString const & rRelUriRef);
+
+private:
+ Uri() SAL_DELETED_FUNCTION;
+
+ Uri(Uri &) SAL_DELETED_FUNCTION;
+
+ ~Uri() SAL_DELETED_FUNCTION;
+
+ void operator =(Uri) SAL_DELETED_FUNCTION;
+};
+
+inline rtl::OUString Uri::encode(rtl::OUString const & rText,
+ sal_Bool const * pCharClass,
+ rtl_UriEncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ rtl::OUString aResult;
+ rtl_uriEncode(rText.pData,
+ pCharClass,
+ eMechanism,
+ eCharset,
+ &aResult.pData);
+ return aResult;
+}
+
+inline rtl::OUString Uri::encode(rtl::OUString const & rText,
+ rtl_UriCharClass eCharClass,
+ rtl_UriEncodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ rtl::OUString aResult;
+ rtl_uriEncode(rText.pData,
+ rtl_getUriCharClass(eCharClass),
+ eMechanism,
+ eCharset,
+ &aResult.pData);
+ return aResult;
+}
+
+inline rtl::OUString Uri::decode(rtl::OUString const & rText,
+ rtl_UriDecodeMechanism eMechanism,
+ rtl_TextEncoding eCharset)
+{
+ rtl::OUString aResult;
+ rtl_uriDecode(rText.pData,
+ eMechanism,
+ eCharset,
+ &aResult.pData);
+ return aResult;
+}
+
+inline rtl::OUString Uri::convertRelToAbs(rtl::OUString const & rBaseUriRef,
+ rtl::OUString const & rRelUriRef)
+{
+ rtl::OUString aResult;
+ rtl::OUString aException;
+ if (!rtl_uriConvertRelToAbs(
+ rBaseUriRef.pData,
+ rRelUriRef.pData, &aResult.pData,
+ &aException.pData))
+ throw MalformedUriException(aException);
+ return aResult;
+}
+
+#if defined LIBO_INTERNAL_ONLY
+
+constexpr std::size_t UriCharClassSize = 128;
+
+// Create a char class (for use with rtl_uriEncode and rtl::Uri::encode), represented as a
+// compile-time std::array, from an UTF-8 string literal.
+//
+// The given `unencoded` lists each ASCII character once that shall not be encoded. (It uses an
+// UTF-8 string type to emphasize that its characters' values are always interpreted as ASCII
+// values.)
+#if HAVE_CPP_CONSTEVAL
+consteval
+#else
+constexpr
+#endif
+auto createUriCharClass(std::u8string_view unencoded)
+{
+ std::array<sal_Bool, UriCharClassSize> a = {};
+ for (auto c: unencoded) {
+ assert(!a[c]); // would presumably indicate a typo in the `unencoded` argument
+ a[c] = true;
+ }
+ return a;
+}
+
+#endif
+
+}
+
+#endif // INCLUDED_RTL_URI_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/ustrbuf.h b/include/rtl/ustrbuf.h
new file mode 100644
index 0000000000..9ea590c00a
--- /dev/null
+++ b/include/rtl/ustrbuf.h
@@ -0,0 +1,218 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_USTRBUF_H
+#define INCLUDED_RTL_USTRBUF_H
+
+#include "sal/config.h"
+
+#include "rtl/ustring.h"
+#include "sal/saldllapi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Allocates a new <code>String</code> that contains characters from
+ the character array argument.
+
+ The <code>count</code> argument specifies
+ the length of the array. The initial capacity of the string buffer is
+ <code>16</code> plus the length of the string argument.
+
+ @param newStr out parameter, contains the new string. The reference count is 1.
+ @param value the initial value of the string.
+ @param count the length of value.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uStringbuffer_newFromStr_WithLength(
+ rtl_uString ** newStr,
+ const sal_Unicode * value,
+ sal_Int32 count );
+
+/**
+ Allocates a new <code>String</code> that contains the same sequence of
+ characters as the string argument.
+
+ The initial capacity is the larger of:
+ <ul>
+ <li> The <code>bufferLen</code> argument.
+ <li> The <code>length</code> of the string argument.
+ </ul>
+
+ @param newStr out parameter, contains the new string. The reference count is 1.
+ @param capacity the initial len of the string buffer.
+ @param oldStr the initial value of the string.
+ @return the new capacity of the string buffer
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_uStringbuffer_newFromStringBuffer(
+ rtl_uString ** newStr,
+ sal_Int32 capacity,
+ rtl_uString * oldStr );
+
+/**
+ Ensures that the capacity of the buffer is at least equal to the
+ specified minimum.
+
+ If the current capacity of this string buffer is less than the
+ argument, then a new internal buffer is allocated with greater
+ capacity. The new capacity is the larger of:
+ <ul>
+ <li>The <code>minimumCapacity</code> argument.
+ <li>Twice the old capacity, plus <code>2</code>.
+ </ul>
+ If the <code>minimumCapacity</code> argument is nonpositive, this
+ method takes no action and simply returns.
+
+ @param[in,out] This the String to operate on.
+ @param[in,out] capacity in: old capacity, out: new capacity.
+ @param[in] minimumCapacity the minimum desired capacity.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uStringbuffer_ensureCapacity(
+ rtl_uString ** This,
+ sal_Int32* capacity,
+ sal_Int32 minimumCapacity);
+
+/**
+ Inserts the string representation of the <code>str</code> array
+ argument into this string buffer.
+
+ The characters of the array argument are inserted into the
+ contents of this string buffer at the position indicated by
+ <code>offset</code>. The length of this string buffer increases by
+ the length of the argument.
+
+ @param This The string, on that the operation should take place
+ @param capacity the capacity of the string buffer
+ @param offset the offset.
+ @param str a character array. Since LibreOffice 4.4, as a special
+ case, if str is null then the len added characters are
+ left uninitialized.
+ @param len the number of characters to append.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uStringbuffer_insert(
+ /*inout*/rtl_uString ** This,
+ /*inout*/sal_Int32 * capacity,
+ sal_Int32 offset,
+ const sal_Unicode * str,
+ sal_Int32 len);
+
+/**
+ Inserts a single UTF-32 character into this string buffer.
+
+ <p>The single UTF-32 character will be represented within the string buffer
+ as either one or two UTF-16 code units.</p>
+
+ @param pThis the string buffer on which the operation is performed
+
+ @param capacity the capacity of the string buffer
+
+ @param offset the offset into this string buffer (from zero to the length
+ of this string buffer, inclusive)
+
+ @param c a well-formed UTF-32 code unit (that is, a value in the range
+ <code>0</code>&ndash;<code>0x10FFFF</code>, but excluding
+ <code>0xD800</code>&ndash;<code>0xDFFF</code>)
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uStringbuffer_insertUtf32(
+ rtl_uString ** pThis, sal_Int32 * capacity, sal_Int32 offset, sal_uInt32 c)
+ SAL_THROW_EXTERN_C();
+
+/**
+ Inserts the 8-Bit ASCII string representation of the <code>str</code>
+ array argument into this string buffer.
+
+ Since this function is optimized
+ for performance, the ASCII character values are not converted in any way.
+ The caller has to make sure that all ASCII characters are in the allowed
+ range between 0 and 127.
+ <p>
+ The characters of the array argument are inserted into the
+ contents of this string buffer at the position indicated by
+ <code>offset</code>. The length of this string buffer increases by
+ the length of the argument.
+
+ @param This The string, on that the operation should take place
+ @param capacity the capacity of the string buffer
+ @param offset the offset.
+ @param str a character array.
+ @param len the number of characters to append.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uStringbuffer_insert_ascii(
+ /*inout*/rtl_uString ** This,
+ /*inout*/sal_Int32 * capacity,
+ sal_Int32 offset,
+ const char * str,
+ sal_Int32 len);
+
+/**
+ Removes the characters in a substring of this sequence.
+
+ The substring begins at the specified <code>start</code> and
+ is <code>len</code> characters long.
+
+ start must be >= 0 && <= This->length
+
+ @param[in,out] This The String to operate on.
+ @param[in] start The beginning index, inclusive
+ @param[in] len The substring length
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uStringbuffer_remove(
+ rtl_uString ** This,
+ sal_Int32 start,
+ sal_Int32 len );
+
+/**
+ Returns an immutable rtl_uString object, while clearing the string buffer.
+
+ This method is primarily used to allow these completed
+ string allocation events to be traced.
+
+ @param ppThis The string, on that the operation should take place
+ @param nCapacity pointer to the capacity of the string buffer
+
+ @since LibreOffice 3.6
+ */
+SAL_DLLPUBLIC rtl_uString * SAL_CALL rtl_uStringBuffer_makeStringAndClear(
+ /*inout*/ rtl_uString ** ppThis,
+ sal_Int32 *nCapacity ) SAL_RETURNS_NONNULL;
+
+/**
+ References and returns an immutable rtl_uString object, from a mutable
+ string-buffer object.
+
+ This method is primarily used to allow legacy 'String' class
+ conversions to OUString to be accurately traced.
+
+ @param pThis The string, on that the operation should take place
+
+ @since LibreOffice 3.6
+ */
+SAL_DLLPUBLIC rtl_uString * SAL_CALL rtl_uStringBuffer_refReturn( rtl_uString *pThis );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_RTL_USTRBUF_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/ustrbuf.hxx b/include/rtl/ustrbuf.hxx
new file mode 100644
index 0000000000..30aa1959a6
--- /dev/null
+++ b/include/rtl/ustrbuf.hxx
@@ -0,0 +1,1801 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_USTRBUF_HXX
+#define INCLUDED_RTL_USTRBUF_HXX
+
+#include "sal/config.h"
+
+#include <cassert>
+#include <cstring>
+#include <limits>
+#include <new>
+
+#if defined LIBO_INTERNAL_ONLY
+#include <string_view>
+#include <type_traits>
+#include <utility>
+#endif
+
+#include "rtl/ustrbuf.h"
+#include "rtl/ustring.hxx"
+#include "rtl/stringutils.hxx"
+#include "sal/types.h"
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+#include "o3tl/safeint.hxx"
+#include "rtl/stringconcat.hxx"
+#endif
+
+#ifdef RTL_STRING_UNITTEST
+extern bool rtl_string_unittest_invalid_conversion;
+#endif
+
+// The unittest uses slightly different code to help check that the proper
+// calls are made. The class is put into a different namespace to make
+// sure the compiler generates a different (if generating also non-inline)
+// copy of the function and does not merge them together. The class
+// is "brought" into the proper rtl namespace by a typedef below.
+#ifdef RTL_STRING_UNITTEST
+#define rtl rtlunittest
+#endif
+
+namespace rtl
+{
+
+#ifdef RTL_STRING_UNITTEST
+#undef rtl
+#endif
+
+/** A string buffer implements a mutable sequence of characters.
+ */
+class SAL_WARN_UNUSED OUStringBuffer
+{
+friend class OUString;
+public:
+ /**
+ Constructs a string buffer with no characters in it and an
+ initial capacity of 16 characters.
+ */
+ OUStringBuffer()
+ : pData(NULL)
+ , nCapacity( 16 )
+ {
+ rtl_uString_new_WithLength( &pData, nCapacity );
+ }
+
+ /**
+ Allocates a new string buffer that contains the same sequence of
+ characters as the string buffer argument.
+
+ @param value a <code>OUStringBuffer</code>.
+ */
+ OUStringBuffer( const OUStringBuffer & value )
+ : pData(NULL)
+ , nCapacity( value.nCapacity )
+ {
+ rtl_uStringbuffer_newFromStringBuffer( &pData, value.nCapacity, value.pData );
+ }
+
+ /**
+ Constructs a string buffer with no characters in it and an
+ initial capacity specified by the <code>length</code> argument.
+
+ @param length the initial capacity.
+ */
+ explicit OUStringBuffer(sal_Int32 length)
+ : pData(NULL)
+ , nCapacity( length )
+ {
+ rtl_uString_new_WithLength( &pData, length );
+ }
+#if defined LIBO_INTERNAL_ONLY
+ template<typename T>
+ explicit OUStringBuffer(T length, std::enable_if_t<std::is_integral_v<T>, int> = 0)
+ : OUStringBuffer(static_cast<sal_Int32>(length))
+ {
+ assert(
+ length >= 0
+ && static_cast<std::make_unsigned_t<T>>(length)
+ <= static_cast<std::make_unsigned_t<sal_Int32>>(
+ std::numeric_limits<sal_Int32>::max()));
+ }
+ // avoid (obvious) bugs
+ explicit OUStringBuffer(bool) = delete;
+ explicit OUStringBuffer(char) = delete;
+ explicit OUStringBuffer(wchar_t) = delete;
+#if !(defined _MSC_VER && _MSC_VER >= 1930 && _MSC_VER <= 1939 && defined _MANAGED)
+ explicit OUStringBuffer(char8_t) = delete;
+#endif
+ explicit OUStringBuffer(char16_t) = delete;
+ explicit OUStringBuffer(char32_t) = delete;
+#endif
+
+ /**
+ Constructs a string buffer so that it represents the same
+ sequence of characters as the string argument.
+
+ The initial
+ capacity of the string buffer is <code>16</code> plus the length
+ of the string argument.
+
+ @param value the initial contents of the buffer.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ OUStringBuffer(std::u16string_view sv)
+ : pData(nullptr)
+ , nCapacity( sv.length() + 16 )
+ {
+ if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) {
+ throw std::bad_alloc();
+ }
+ rtl_uStringbuffer_newFromStr_WithLength( &pData, sv.data(), sv.length() );
+ }
+#else
+ OUStringBuffer(const OUString& value)
+ : pData(NULL)
+ , nCapacity( value.getLength() + 16 )
+ {
+ rtl_uStringbuffer_newFromStr_WithLength( &pData, value.getStr(), value.getLength() );
+ }
+#endif
+
+ template< typename T >
+ OUStringBuffer( T& literal, typename libreoffice_internal::ConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy() )
+ : pData(NULL)
+ , nCapacity( libreoffice_internal::ConstCharArrayDetector<T>::length + 16 )
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ rtl_uString_newFromLiteral(
+ &pData,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length, 16);
+#ifdef RTL_STRING_UNITTEST
+ rtl_string_unittest_const_literal = true;
+#endif
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /** @overload @since LibreOffice 5.3 */
+ template<typename T>
+ OUStringBuffer(
+ T & literal,
+ typename libreoffice_internal::ConstCharArrayDetector<
+ T, libreoffice_internal::Dummy>::TypeUtf16
+ = libreoffice_internal::Dummy()):
+ pData(nullptr),
+ nCapacity(libreoffice_internal::ConstCharArrayDetector<T>::length + 16)
+ {
+ rtl_uStringbuffer_newFromStr_WithLength(
+ &pData,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+#endif
+
+#if defined LIBO_INTERNAL_ONLY && defined RTL_STRING_UNITTEST
+ /// @cond INTERNAL
+ /**
+ * Only used by unittests to detect incorrect conversions.
+ * @internal
+ */
+ template< typename T >
+ OUStringBuffer( T&, typename libreoffice_internal::ExceptConstCharArrayDetector< T >::Type = libreoffice_internal::Dummy() )
+ {
+ pData = NULL;
+ nCapacity = 10;
+ rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage
+ rtl_string_unittest_invalid_conversion = true;
+ }
+ /**
+ * Only used by unittests to detect incorrect conversions.
+ * @internal
+ */
+ template< typename T >
+ OUStringBuffer( const T&, typename libreoffice_internal::ExceptCharArrayDetector< T >::Type = libreoffice_internal::Dummy() )
+ {
+ pData = NULL;
+ nCapacity = 10;
+ rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage
+ rtl_string_unittest_invalid_conversion = true;
+ }
+ /// @endcond
+#endif
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ /**
+ @overload
+ @internal
+ */
+ template< typename T1, typename T2 >
+ OUStringBuffer( OUStringConcat< T1, T2 >&& c )
+ {
+ const sal_Int32 l = c.length();
+ nCapacity = l + 16;
+ pData = rtl_uString_alloc( nCapacity );
+ sal_Unicode* end = c.addData( pData->buffer );
+ *end = '\0';
+ pData->length = l;
+ }
+
+ /**
+ @overload
+ @internal
+ */
+ template< std::size_t N >
+ OUStringBuffer( OUStringNumber< N >&& n )
+ : pData(NULL)
+ , nCapacity( n.length + 16 )
+ {
+ rtl_uStringbuffer_newFromStr_WithLength( &pData, n.buf, n.length );
+ }
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+ operator std::u16string_view() const { return {getStr(), sal_uInt32(getLength())}; }
+#endif
+
+ /** Assign to this a copy of value.
+ */
+ OUStringBuffer& operator = ( const OUStringBuffer& value )
+ {
+ if (this != &value)
+ {
+ rtl_uStringbuffer_newFromStringBuffer(&pData,
+ value.nCapacity,
+ value.pData);
+ nCapacity = value.nCapacity;
+ }
+ return *this;
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /** Move assignment
+ * @since LibreOffice 7.3
+ */
+ OUStringBuffer& operator = ( OUStringBuffer&& value ) noexcept
+ {
+ rtl_uString_release( pData );
+ pData = value.pData;
+ nCapacity = value.nCapacity;
+ value.pData = nullptr;
+ value.nCapacity = 0;
+ rtl_uString_new( &value.pData );
+ return *this;
+ }
+#endif
+
+ /** Assign from a string.
+
+ @since LibreOffice 5.3
+ */
+#if defined LIBO_INTERNAL_ONLY
+ OUStringBuffer & operator =(std::u16string_view string) {
+ sal_Int32 n = string.length();
+ if (n >= nCapacity) {
+ ensureCapacity(n + 16); //TODO: check for overflow
+ }
+ std::memcpy(
+ pData->buffer, string.data(),
+ n * sizeof (sal_Unicode));
+ pData->buffer[n] = '\0';
+ pData->length = n;
+ return *this;
+ }
+#else
+ OUStringBuffer & operator =(OUString const & string) {
+ sal_Int32 n = string.getLength();
+ if (n >= nCapacity) {
+ ensureCapacity(n + 16); //TODO: check for overflow
+ }
+ std::memcpy(
+ pData->buffer, string.pData->buffer,
+ (n + 1) * sizeof (sal_Unicode));
+ pData->length = n;
+ return *this;
+ }
+#endif
+
+ /** Assign from a string literal.
+
+ @since LibreOffice 5.3
+ */
+ template<typename T>
+ typename
+ libreoffice_internal::ConstCharArrayDetector<T, OUStringBuffer &>::Type
+ operator =(T & literal) {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ sal_Int32 const n
+ = libreoffice_internal::ConstCharArrayDetector<T>::length;
+ if (n >= nCapacity) {
+ ensureCapacity(n + 16); //TODO: check for overflow
+ }
+ char const * from
+ = libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal);
+ sal_Unicode * to = pData->buffer;
+ for (sal_Int32 i = 0; i <= n; ++i) {
+ to[i] = from[i];
+ }
+ pData->length = n;
+ return *this;
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /** @overload @since LibreOffice 5.3 */
+ template<typename T>
+ typename libreoffice_internal::ConstCharArrayDetector<
+ T, OUStringBuffer &>::TypeUtf16
+ operator =(T & literal) {
+ sal_Int32 const n
+ = libreoffice_internal::ConstCharArrayDetector<T>::length;
+ if (n >= nCapacity) {
+ ensureCapacity(n + 16); //TODO: check for overflow
+ }
+ // For OUStringChar, which is covered by this template's ConstCharArrayDetector TypeUtf16
+ // check, toPointer does not return a NUL-terminated string, so we can't just memcpy n+1
+ // elements but rather need to add the terminating NUL manually:
+ std::memcpy(
+ pData->buffer,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ n * sizeof (sal_Unicode));
+ pData->buffer[n] = '\0';
+ pData->length = n;
+ return *this;
+ }
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+ /** @overload @since LibreOffice 5.3 */
+ template<typename T1, typename T2>
+ OUStringBuffer & operator =(OUStringConcat<T1, T2> && concat) {
+ sal_Int32 const n = concat.length();
+ if (n >= nCapacity) {
+ ensureCapacity(n + 16); //TODO: check for overflow
+ }
+ *concat.addData(pData->buffer) = 0;
+ pData->length = n;
+ return *this;
+ }
+
+ /** @overload @internal */
+ template<std::size_t N>
+ OUStringBuffer & operator =(OUStringNumber<N> && n)
+ {
+ return operator =(std::u16string_view(n));
+ }
+#endif
+
+ /**
+ Release the string data.
+ */
+ ~OUStringBuffer()
+ {
+ rtl_uString_release( pData );
+ }
+
+ /**
+ Fill the string data in the new string and clear the buffer.
+
+ This method is more efficient than the constructor of the string. It does
+ not copy the buffer.
+
+ @return the string previously contained in the buffer.
+ */
+ SAL_WARN_UNUSED_RESULT OUString makeStringAndClear()
+ {
+ return OUString(
+ rtl_uStringBuffer_makeStringAndClear( &pData, &nCapacity ),
+ SAL_NO_ACQUIRE );
+ }
+
+ /**
+ Returns the length (character count) of this string buffer.
+
+ @return the number of characters in this string buffer.
+ */
+ sal_Int32 getLength() const
+ {
+ return pData->length;
+ }
+
+ /**
+ Checks if a string buffer is empty.
+
+ @return true if the string buffer is empty;
+ false, otherwise.
+
+ @since LibreOffice 4.1
+ */
+ bool isEmpty() const
+ {
+ return pData->length == 0;
+ }
+
+ /**
+ Returns the current capacity of the String buffer.
+
+ The capacity
+ is the amount of storage available for newly inserted
+ characters. The real buffer size is 2 bytes longer, because
+ all strings are 0 terminated.
+
+ @return the current capacity of this string buffer.
+ */
+ sal_Int32 getCapacity() const
+ {
+ return nCapacity;
+ }
+
+ /**
+ Ensures that the capacity of the buffer is at least equal to the
+ specified minimum.
+
+ The new capacity will be at least as large as the maximum of the current
+ length (so that no contents of the buffer is destroyed) and the given
+ minimumCapacity. If the given minimumCapacity is negative, nothing is
+ changed.
+
+ @param minimumCapacity the minimum desired capacity.
+ */
+ void ensureCapacity(sal_Int32 minimumCapacity)
+ {
+ rtl_uStringbuffer_ensureCapacity( &pData, &nCapacity, minimumCapacity );
+ }
+
+ /**
+ Sets the length of this String buffer.
+
+ If the <code>newLength</code> argument is less than the current
+ length of the string buffer, the string buffer is truncated to
+ contain exactly the number of characters given by the
+ <code>newLength</code> argument.
+ <p>
+ If the <code>newLength</code> argument is greater than or equal
+ to the current length, sufficient null characters
+ (<code>'&#92;u0000'</code>) are appended to the string buffer so that
+ length becomes the <code>newLength</code> argument.
+ <p>
+ The <code>newLength</code> argument must be greater than or equal
+ to <code>0</code>.
+
+ @param newLength the new length of the buffer.
+ */
+ void setLength(sal_Int32 newLength)
+ {
+ assert(newLength >= 0);
+ // Avoid modifications if pData points to const empty string:
+ if( newLength != pData->length )
+ {
+ if( newLength > nCapacity )
+ rtl_uStringbuffer_ensureCapacity(&pData, &nCapacity, newLength);
+ else
+ pData->buffer[newLength] = 0;
+ pData->length = newLength;
+ }
+ }
+
+ /**
+ Returns the character at a specific index in this string buffer.
+
+ The first character of a string buffer is at index
+ <code>0</code>, the next at index <code>1</code>, and so on, for
+ array indexing.
+ <p>
+ The index argument must be greater than or equal to
+ <code>0</code>, and less than the length of this string buffer.
+
+ @param index the index of the desired character.
+ @return the character at the specified index of this string buffer.
+ */
+ SAL_DEPRECATED("use rtl::OUStringBuffer::operator [] instead")
+ sal_Unicode charAt( sal_Int32 index ) const
+ {
+ assert(index >= 0 && index < pData->length);
+ return pData->buffer[ index ];
+ }
+
+ /**
+ The character at the specified index of this string buffer is set
+ to <code>ch</code>.
+
+ The index argument must be greater than or equal to
+ <code>0</code>, and less than the length of this string buffer.
+
+ @param index the index of the character to modify.
+ @param ch the new character.
+ */
+ SAL_DEPRECATED("use rtl::OUStringBuffer::operator [] instead")
+ OUStringBuffer & setCharAt(sal_Int32 index, sal_Unicode ch)
+ {
+ assert(index >= 0 && index < pData->length);
+ pData->buffer[ index ] = ch;
+ return *this;
+ }
+
+ /**
+ Return a null terminated unicode character array.
+ */
+ const sal_Unicode* getStr() const SAL_RETURNS_NONNULL { return pData->buffer; }
+
+ /**
+ Access to individual characters.
+
+ @param index must be non-negative and less than length.
+
+ @return a reference to the character at the given index.
+
+ @since LibreOffice 3.5
+ */
+ sal_Unicode & operator [](sal_Int32 index)
+ {
+ assert(index >= 0 && index < pData->length);
+ return pData->buffer[index];
+ }
+
+ /**
+ Access to individual characters.
+
+ @param index must be non-negative and less than length.
+
+ @return a reference to the character at the given index.
+
+ @since LibreOffice 4.2
+ */
+ const sal_Unicode & operator [](sal_Int32 index) const
+ {
+ assert(index >= 0 && index < pData->length);
+ return pData->buffer[index];
+ }
+
+ /**
+ Return an OUString instance reflecting the current content
+ of this OUStringBuffer.
+ */
+ OUString toString() const
+ {
+ return OUString(pData->buffer, pData->length);
+ }
+
+ /**
+ Appends the string to this string buffer.
+
+ The characters of the <code>OUString</code> argument are appended, in
+ order, to the contents of this string buffer, increasing the
+ length of this string buffer by the length of the argument.
+
+ @param str a string.
+ @return this string buffer.
+ */
+#if !defined LIBO_INTERNAL_ONLY
+ OUStringBuffer & append(const OUString &str)
+#else
+ OUStringBuffer & append(std::u16string_view str)
+#endif
+ {
+ return insert(getLength(), str);
+ }
+
+#if !defined LIBO_INTERNAL_ONLY
+ /**
+ Appends the content of a stringbuffer to this string buffer.
+
+ The characters of the <code>OUStringBuffer</code> argument are appended, in
+ order, to the contents of this string buffer, increasing the
+ length of this string buffer by the length of the argument.
+
+ @param str a string.
+ @return this string buffer.
+
+ @since LibreOffice 4.0
+ */
+ OUStringBuffer & append(const OUStringBuffer &str)
+ {
+ if(!str.isEmpty())
+ {
+ append( str.getStr(), str.getLength() );
+ }
+ return *this;
+ }
+#endif
+
+ /**
+ Appends the string representation of the <code>char</code> array
+ argument to this string buffer.
+
+ The characters of the array argument are appended, in order, to
+ the contents of this string buffer. The length of this string
+ buffer increases by the length of the argument.
+
+ @param str the characters to be appended.
+ @return this string buffer.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ template<typename T>
+ typename libreoffice_internal::CharPtrDetector<T, OUStringBuffer &>::TypeUtf16
+ append(T const & str)
+#else
+ OUStringBuffer & append( const sal_Unicode * str )
+#endif
+ {
+ return insert(getLength(), str);
+ }
+
+ /**
+ Appends the string representation of the <code>char</code> array
+ argument to this string buffer.
+
+ Characters of the character array <code>str</code> are appended,
+ in order, to the contents of this string buffer. The length of this
+ string buffer increases by the value of <code>len</code>.
+
+ @param str the characters to be appended; must be non-null, and must
+ point to at least len characters
+ @param len the number of characters to append; must be non-negative
+ @return this string buffer.
+ */
+ OUStringBuffer & append( const sal_Unicode * str, sal_Int32 len)
+ {
+ return insert(getLength(), str, len);
+ }
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type append( T& literal )
+ {
+ return insert(getLength(), literal);
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ template<typename T>
+ typename libreoffice_internal::NonConstCharArrayDetector<T, OUStringBuffer &>::TypeUtf16
+ append(T & value) { return append(static_cast<sal_Unicode *>(value)); }
+
+ /** @overload @since LibreOffice 5.3 */
+ template<typename T>
+ typename libreoffice_internal::ConstCharArrayDetector<
+ T, OUStringBuffer &>::TypeUtf16
+ append(T & literal) {
+ return insert(getLength(), literal);
+ }
+#endif
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ /**
+ @overload
+ @internal
+ */
+ template< typename T1, typename T2 >
+ OUStringBuffer& append( OUStringConcat< T1, T2 >&& c )
+ {
+ return insert(getLength(), std::move(c));
+ }
+#endif
+
+ /**
+ Appends a 8-Bit ASCII character string to this string buffer.
+
+ Since this method is optimized for performance. the ASCII
+ character values are not converted in any way. The caller
+ has to make sure that all ASCII characters are in the
+ allowed range between 0 and 127. The ASCII string must be
+ NULL-terminated.
+ <p>
+ The characters of the array argument are appended, in order, to
+ the contents of this string buffer. The length of this string
+ buffer increases by the length of the argument.
+
+ @param str the 8-Bit ASCII characters to be appended.
+ @return this string buffer.
+ */
+ OUStringBuffer & appendAscii( const char * str )
+ {
+ return appendAscii( str, rtl_str_getLength( str ) );
+ }
+
+ /**
+ Appends a 8-Bit ASCII character string to this string buffer.
+
+ Since this method is optimized for performance. the ASCII
+ character values are not converted in any way. The caller
+ has to make sure that all ASCII characters are in the
+ allowed range between 0 and 127.
+ <p>
+ Characters of the character array <code>str</code> are appended,
+ in order, to the contents of this string buffer. The length of this
+ string buffer increases by the value of <code>len</code>.
+
+ @param str the 8-Bit ASCII characters to be appended; must be non-null,
+ and must point to at least len characters
+ @param len the number of characters to append; must be non-negative
+ @return this string buffer.
+ */
+ OUStringBuffer & appendAscii( const char * str, sal_Int32 len)
+ {
+ rtl_uStringbuffer_insert_ascii( &pData, &nCapacity, getLength(), str, len );
+ return *this;
+ }
+
+ /**
+ Appends the string representation of the <code>bool</code>
+ argument to the string buffer.
+
+ The argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then appended to this string buffer.
+
+ @param b a <code>bool</code>.
+ @return this string buffer.
+
+ @since LibreOffice 4.1
+ */
+ OUStringBuffer & append(bool b)
+ {
+ return insert(getLength(), b);
+ }
+
+ /// @cond INTERNAL
+ // Pointer can be automatically converted to bool, which is unwanted here.
+ // Explicitly delete all pointer append() overloads to prevent this
+ // (except for char* and sal_Unicode* overloads, which are handled elsewhere).
+ template< typename T >
+ typename libreoffice_internal::Enable< void,
+ !libreoffice_internal::CharPtrDetector< T* >::ok && !libreoffice_internal::SalUnicodePtrDetector< T* >::ok >::Type
+ append( T* ) SAL_DELETED_FUNCTION;
+ /// @endcond
+
+ // This overload is needed because OUString has a ctor from rtl_uString*, but
+ // the bool overload above would be preferred to the conversion.
+ /**
+ @internal
+ */
+ OUStringBuffer & append(rtl_uString* str)
+ {
+ return append( OUString::unacquired( &str ));
+ }
+
+ /**
+ Appends the string representation of the <code>sal_Bool</code>
+ argument to the string buffer.
+
+ The argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then appended to this string buffer.
+
+ @param b a <code>sal_Bool</code>.
+ @return this string buffer.
+ */
+ OUStringBuffer & append(sal_Bool b)
+ {
+ return insert(getLength(), b);
+ }
+
+ /**
+ Appends the string representation of the ASCII <code>char</code>
+ argument to this string buffer.
+
+ The argument is appended to the contents of this string buffer.
+ The length of this string buffer increases by <code>1</code>.
+
+ @param c an ASCII <code>char</code>.
+ @return this string buffer.
+
+ @since LibreOffice 3.5
+ */
+ OUStringBuffer & append(char c)
+ {
+ assert(static_cast< unsigned char >(c) <= 0x7F);
+ return insert(getLength(), c);
+ }
+
+ /**
+ Appends the string representation of the <code>char</code>
+ argument to this string buffer.
+
+ The argument is appended to the contents of this string buffer.
+ The length of this string buffer increases by <code>1</code>.
+
+ @param c a <code>char</code>.
+ @return this string buffer.
+ */
+ OUStringBuffer & append(sal_Unicode c)
+ {
+ return insert(getLength(), c);
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ void append(sal_uInt16) = delete;
+#endif
+
+ /**
+ Appends the string representation of the <code>sal_Int32</code>
+ argument to this string buffer.
+
+ The argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then appended to this string buffer.
+
+ @param i an <code>sal_Int32</code>.
+ @param radix the radix
+ @return this string buffer.
+ */
+ OUStringBuffer & append(sal_Int32 i, sal_Int16 radix = 10 )
+ {
+ return insert(getLength(), i, radix);
+ }
+
+ /**
+ Appends the string representation of the <code>long</code>
+ argument to this string buffer.
+
+ The argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then appended to this string buffer.
+
+ @param l a <code>long</code>.
+ @param radix the radix
+ @return this string buffer.
+ */
+ OUStringBuffer & append(sal_Int64 l, sal_Int16 radix = 10 )
+ {
+ return insert(getLength(), l, radix);
+ }
+
+ /**
+ Appends the string representation of the <code>float</code>
+ argument to this string buffer.
+
+ The argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then appended to this string buffer.
+
+ @param f a <code>float</code>.
+ @return this string buffer.
+ */
+ OUStringBuffer & append(float f)
+ {
+ return insert(getLength(), f);
+ }
+
+ /**
+ Appends the string representation of the <code>double</code>
+ argument to this string buffer.
+
+ The argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then appended to this string buffer.
+
+ @param d a <code>double</code>.
+ @return this string buffer.
+ */
+ OUStringBuffer & append(double d)
+ {
+ return insert(getLength(), d);
+ }
+
+ /**
+ Appends a single UTF-32 character to this string buffer.
+
+ <p>The single UTF-32 character will be represented within the string
+ buffer as either one or two UTF-16 code units.</p>
+
+ @param c a well-formed UTF-32 code unit (that is, a value in the range
+ <code>0</code>&ndash;<code>0x10FFFF</code>, but excluding
+ <code>0xD800</code>&ndash;<code>0xDFFF</code>)
+
+ @return
+ this string buffer
+ */
+ OUStringBuffer & appendUtf32(sal_uInt32 c) {
+ return insertUtf32(getLength(), c);
+ }
+
+ /**
+ Unsafe way to make space for a fixed amount of characters to be appended
+ into this OUStringBuffer.
+
+ A call to this function must immediately be followed by code that
+ completely fills the uninitialized block pointed to by the return value.
+
+ @param length the length of the uninitialized block of sal_Unicode
+ entities; must be non-negative
+
+ @return a pointer to the start of the uninitialized block; only valid
+ until this OUStringBuffer's capacity changes
+
+ @since LibreOffice 4.4
+ */
+ sal_Unicode * appendUninitialized(sal_Int32 length) SAL_RETURNS_NONNULL {
+ sal_Int32 n = getLength();
+ rtl_uStringbuffer_insert(&pData, &nCapacity, n, NULL, length);
+ return pData->buffer + n;
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /**
+ "Stream" operator to append a value to this OUStringBuffer.
+
+ @internal
+ @since LibreOffice 7.5
+ */
+ template<typename T>
+ OUStringBuffer& operator<<(T&& rValue)
+ {
+ return append(std::forward<T>(rValue));
+ }
+#endif
+
+ /**
+ Inserts the string into this string buffer.
+
+ The characters of the <code>String</code> argument are inserted, in
+ order, into this string buffer at the indicated offset. The length
+ of this string buffer is increased by the length of the argument.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param str a string.
+ @return this string buffer.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ OUStringBuffer & insert(sal_Int32 offset, std::u16string_view str)
+ {
+ if (str.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) {
+ throw std::bad_alloc();
+ }
+ return insert( offset, str.data(), str.length() );
+ }
+#else
+ OUStringBuffer & insert(sal_Int32 offset, const OUString & str)
+ {
+ return insert( offset, str.getStr(), str.getLength() );
+ }
+#endif
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ /**
+ @overload
+ @internal
+ */
+ template <typename T1, typename T2>
+ OUStringBuffer& insert(sal_Int32 offset, OUStringConcat<T1, T2>&& c)
+ {
+ const size_t l = c.length();
+ if (l == 0)
+ return *this;
+ if (l > o3tl::make_unsigned(std::numeric_limits<sal_Int32>::max() - pData->length))
+ throw std::bad_alloc();
+
+ rtl_uStringbuffer_insert(&pData, &nCapacity, offset, nullptr, l);
+
+ /* insert the new characters */
+ c.addData(pData->buffer + offset);
+ return *this;
+ }
+#endif
+
+ /**
+ Inserts the string representation of the <code>char</code> array
+ argument into this string buffer.
+
+ The characters of the array argument are inserted into the
+ contents of this string buffer at the position indicated by
+ <code>offset</code>. The length of this string buffer increases by
+ the length of the argument.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param str a character array.
+ @return this string buffer.
+ */
+ OUStringBuffer & insert( sal_Int32 offset, const sal_Unicode * str )
+ {
+ return insert( offset, str, rtl_ustr_getLength( str ) );
+ }
+
+ /**
+ Inserts the string representation of the <code>char</code> array
+ argument into this string buffer.
+
+ The characters of the array argument are inserted into the
+ contents of this string buffer at the position indicated by
+ <code>offset</code>. The length of this string buffer increases by
+ the length of the argument.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param str a character array.
+ @param len the number of characters to append.
+ @return this string buffer.
+ */
+ OUStringBuffer & insert( sal_Int32 offset, const sal_Unicode * str, sal_Int32 len)
+ {
+ assert( len == 0 || str != NULL ); // cannot assert that in rtl_uStringbuffer_insert
+ rtl_uStringbuffer_insert( &pData, &nCapacity, offset, str, len );
+ return *this;
+ }
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, OUStringBuffer& >::Type insert( sal_Int32 offset, T& literal )
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ rtl_uStringbuffer_insert_ascii(
+ &pData, &nCapacity, offset,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ return *this;
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /** @overload @since LibreOffice 5.3 */
+ template<typename T>
+ typename libreoffice_internal::ConstCharArrayDetector<
+ T, OUStringBuffer &>::TypeUtf16
+ insert(sal_Int32 offset, T & literal) {
+ return insert(
+ offset,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+#endif
+
+ /**
+ Inserts the string representation of the <code>sal_Bool</code>
+ argument into this string buffer.
+
+ The second argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then inserted into this string buffer at the indicated
+ offset.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param b a <code>sal_Bool</code>.
+ @return this string buffer.
+ */
+ OUStringBuffer & insert(sal_Int32 offset, sal_Bool b)
+ {
+ sal_Unicode sz[RTL_USTR_MAX_VALUEOFBOOLEAN];
+ return insert( offset, sz, rtl_ustr_valueOfBoolean( sz, b ) );
+ }
+
+ /**
+ Inserts the string representation of the <code>bool</code>
+ argument into this string buffer.
+
+ The second argument is converted to a string as if by the method
+ <code>OUString::boolean</code>, and the characters of that
+ string are then inserted into this string buffer at the indicated
+ offset.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param b a <code>bool</code>.
+ @return this string buffer.
+
+ @since LibreOffice 4.3
+ */
+ OUStringBuffer & insert(sal_Int32 offset, bool b)
+ {
+ sal_Unicode sz[RTL_USTR_MAX_VALUEOFBOOLEAN];
+ return insert( offset, sz, rtl_ustr_valueOfBoolean( sz, b ) );
+ }
+
+ /**
+ Inserts the string representation of the <code>char</code>
+ argument into this string buffer.
+
+ The second argument is inserted into the contents of this string
+ buffer at the position indicated by <code>offset</code>. The length
+ of this string buffer increases by one.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param c a <code>char</code>.
+ @return this string buffer.
+
+ @since LibreOffice 3.6
+ */
+ OUStringBuffer & insert(sal_Int32 offset, char c)
+ {
+ sal_Unicode u = c;
+ return insert( offset, &u, 1 );
+ }
+
+ /**
+ Inserts the string representation of the <code>char</code>
+ argument into this string buffer.
+
+ The second argument is inserted into the contents of this string
+ buffer at the position indicated by <code>offset</code>. The length
+ of this string buffer increases by one.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param c a <code>char</code>.
+ @return this string buffer.
+ */
+ OUStringBuffer & insert(sal_Int32 offset, sal_Unicode c)
+ {
+ return insert( offset, &c, 1 );
+ }
+
+ /**
+ Inserts the string representation of the second <code>sal_Int32</code>
+ argument into this string buffer.
+
+ The second argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then inserted into this string buffer at the indicated
+ offset.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param i an <code>sal_Int32</code>.
+ @param radix the radix.
+ @return this string buffer.
+ @exception StringIndexOutOfBoundsException if the offset is invalid.
+ */
+ OUStringBuffer & insert(sal_Int32 offset, sal_Int32 i, sal_Int16 radix = 10 )
+ {
+ sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT32];
+ return insert( offset, sz, rtl_ustr_valueOfInt32( sz, i, radix ) );
+ }
+
+ /**
+ Inserts the string representation of the <code>long</code>
+ argument into this string buffer.
+
+ The second argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then inserted into this string buffer at the indicated
+ offset.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param l a <code>long</code>.
+ @param radix the radix.
+ @return this string buffer.
+ @exception StringIndexOutOfBoundsException if the offset is invalid.
+ */
+ OUStringBuffer & insert(sal_Int32 offset, sal_Int64 l, sal_Int16 radix = 10 )
+ {
+ sal_Unicode sz[RTL_USTR_MAX_VALUEOFINT64];
+ return insert( offset, sz, rtl_ustr_valueOfInt64( sz, l, radix ) );
+ }
+
+ /**
+ Inserts the string representation of the <code>float</code>
+ argument into this string buffer.
+
+ The second argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then inserted into this string buffer at the indicated
+ offset.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param f a <code>float</code>.
+ @return this string buffer.
+ @exception StringIndexOutOfBoundsException if the offset is invalid.
+ */
+ OUStringBuffer & insert(sal_Int32 offset, float f)
+ {
+ // Same as rtl::str::valueOfFP, used for rtl_ustr_valueOfFloat
+ rtl_math_doubleToUString(&pData, &nCapacity, offset, f, rtl_math_StringFormat_G,
+ RTL_USTR_MAX_VALUEOFFLOAT - SAL_N_ELEMENTS("-x.E-xxx") + 1, '.',
+ NULL, 0, true);
+ return *this;
+ }
+
+ /**
+ Inserts the string representation of the <code>double</code>
+ argument into this string buffer.
+
+ The second argument is converted to a string as if by the method
+ <code>String.valueOf</code>, and the characters of that
+ string are then inserted into this string buffer at the indicated
+ offset.
+ <p>
+ The offset argument must be greater than or equal to
+ <code>0</code>, and less than or equal to the length of this
+ string buffer.
+
+ @param offset the offset.
+ @param d a <code>double</code>.
+ @return this string buffer.
+ @exception StringIndexOutOfBoundsException if the offset is invalid.
+ */
+ OUStringBuffer & insert(sal_Int32 offset, double d)
+ {
+ // Same as rtl::str::valueOfFP, used for rtl_ustr_valueOfDouble
+ rtl_math_doubleToUString(&pData, &nCapacity, offset, d, rtl_math_StringFormat_G,
+ RTL_USTR_MAX_VALUEOFDOUBLE - SAL_N_ELEMENTS("-x.E-xxx") + 1, '.',
+ NULL, 0, true);
+ return *this;
+ }
+
+ /**
+ Inserts a single UTF-32 character into this string buffer.
+
+ <p>The single UTF-32 character will be represented within the string
+ buffer as either one or two UTF-16 code units.</p>
+
+ @param offset the offset into this string buffer (from zero to the length
+ of this string buffer, inclusive)
+
+ @param c a well-formed UTF-32 code unit (that is, a value in the range
+ <code>0</code>&ndash;<code>0x10FFFF</code>, but excluding
+ <code>0xD800</code>&ndash;<code>0xDFFF</code>)
+
+ @return this string buffer
+ */
+ OUStringBuffer & insertUtf32(sal_Int32 offset, sal_uInt32 c) {
+ rtl_uStringbuffer_insertUtf32(&pData, &nCapacity, offset, c);
+ return *this;
+ }
+
+ /**
+ Removes the characters in a substring of this sequence.
+
+ The substring begins at the specified <code>start</code> and
+ is <code>len</code> characters long.
+
+ start must be >= 0 && <= This->length
+
+ @param start The beginning index, inclusive
+ @param len The substring length
+ @return this string buffer.
+ */
+ OUStringBuffer & remove( sal_Int32 start, sal_Int32 len )
+ {
+ rtl_uStringbuffer_remove( &pData, start, len );
+ return *this;
+ }
+
+ /**
+ Removes the tail of a string buffer start at the indicate position
+
+ start must be >= 0 && <= This->length
+
+ @param start The beginning index, inclusive. default to 0
+ @return this string buffer.
+
+ @since LibreOffice 4.0
+ */
+ OUStringBuffer & truncate( sal_Int32 start = 0 )
+ {
+ rtl_uStringbuffer_remove( &pData, start, getLength() - start );
+ return *this;
+ }
+
+ /**
+ Replace all occurrences of
+ oldChar in this string buffer with newChar.
+
+ @since LibreOffice 4.0
+
+ @param oldChar the old character.
+ @param newChar the new character.
+ @return this string buffer
+ */
+ OUStringBuffer& replace( sal_Unicode oldChar, sal_Unicode newChar )
+ {
+ sal_Int32 index = 0;
+ while((index = indexOf(oldChar, index)) >= 0)
+ {
+ pData->buffer[ index ] = newChar;
+ }
+ return *this;
+ }
+
+ /** Allows access to the internal data of this OUStringBuffer, for effective
+ manipulation.
+
+ This method should be used with care. After you have called this
+ method, you may use the returned pInternalData or pInternalCapacity only
+ as long as you make no other method call on this OUStringBuffer.
+
+ @param pInternalData
+ This output parameter receives a pointer to the internal data
+ (rtl_uString pointer). pInternalData itself must not be null.
+
+ @param pInternalCapacity
+ This output parameter receives a pointer to the internal capacity.
+ pInternalCapacity itself must not be null.
+ */
+ void accessInternals(rtl_uString *** pInternalData,
+ sal_Int32 ** pInternalCapacity)
+ {
+ *pInternalData = &pData;
+ *pInternalCapacity = &nCapacity;
+ }
+
+
+ /**
+ Returns the index within this string of the first occurrence of the
+ specified character, starting the search at the specified index.
+
+ @since LibreOffice 4.0
+
+ @param ch character to be located.
+ @param fromIndex the index to start the search from.
+ The index must be greater or equal than 0
+ and less or equal as the string length.
+ @return the index of the first occurrence of the character in the
+ character sequence represented by this string that is
+ greater than or equal to fromIndex, or
+ -1 if the character does not occur.
+ */
+ sal_Int32 indexOf( sal_Unicode ch, sal_Int32 fromIndex = 0 ) const
+ {
+ assert( fromIndex >= 0 && fromIndex <= pData->length );
+ sal_Int32 ret = rtl_ustr_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch );
+ return (ret < 0 ? ret : ret+fromIndex);
+ }
+
+ /**
+ Returns the index within this string of the last occurrence of the
+ specified character, searching backward starting at the end.
+
+ @since LibreOffice 4.0
+
+ @param ch character to be located.
+ @return the index of the last occurrence of the character in the
+ character sequence represented by this string, or
+ -1 if the character does not occur.
+ */
+ sal_Int32 lastIndexOf( sal_Unicode ch ) const
+ {
+ return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch );
+ }
+
+ /**
+ Returns the index within this string of the last occurrence of the
+ specified character, searching backward starting before the specified
+ index.
+
+ @since LibreOffice 4.0
+
+ @param ch character to be located.
+ @param fromIndex the index before which to start the search.
+ @return the index of the last occurrence of the character in the
+ character sequence represented by this string that
+ is less than fromIndex, or -1
+ if the character does not occur before that point.
+ */
+ sal_Int32 lastIndexOf( sal_Unicode ch, sal_Int32 fromIndex ) const
+ {
+ assert( fromIndex >= 0 && fromIndex <= pData->length );
+ return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch );
+ }
+
+ /**
+ Returns the index within this string of the first occurrence of the
+ specified substring, starting at the specified index.
+
+ If str doesn't include any character, always -1 is
+ returned. This is also the case, if both strings are empty.
+
+ @since LibreOffice 4.0
+
+ @param str the substring to search for.
+ @param fromIndex the index to start the search from.
+ @return If the string argument occurs one or more times as a substring
+ within this string at the starting index, then the index
+ of the first character of the first such substring is
+ returned. If it does not occur as a substring starting
+ at fromIndex or beyond, -1 is returned.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 indexOf( std::u16string_view str, sal_Int32 fromIndex = 0 ) const
+ {
+ assert( fromIndex >= 0 && fromIndex <= pData->length );
+ sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
+ str.data(), str.length() );
+ return (ret < 0 ? ret : ret+fromIndex);
+ }
+#else
+ sal_Int32 indexOf( const OUString & str, sal_Int32 fromIndex = 0 ) const
+ {
+ assert( fromIndex >= 0 && fromIndex <= pData->length );
+ sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
+ str.pData->buffer, str.pData->length );
+ return (ret < 0 ? ret : ret+fromIndex);
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+
+ @since LibreOffice 4.0
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ sal_Int32 n = rtl_ustr_indexOfAscii_WithLength(
+ pData->buffer + fromIndex, pData->length - fromIndex,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ return n < 0 ? n : n + fromIndex;
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /** @overload @since LibreOffice 5.3 */
+ template<typename T>
+ typename
+ libreoffice_internal::ConstCharArrayDetector<T, sal_Int32>::TypeUtf16
+ indexOf(T & literal, sal_Int32 fromIndex = 0) const {
+ assert(fromIndex >= 0);
+ auto n = rtl_ustr_indexOfStr_WithLength(
+ pData->buffer + fromIndex, pData->length - fromIndex,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ return n < 0 ? n : n + fromIndex;
+ }
+#endif
+
+ /**
+ Returns the index within this string of the last occurrence of
+ the specified substring, searching backward starting at the end.
+
+ The returned index indicates the starting index of the substring
+ in this string.
+ If str doesn't include any character, always -1 is
+ returned. This is also the case, if both strings are empty.
+
+ @since LibreOffice 4.0
+
+ @param str the substring to search for.
+ @return If the string argument occurs one or more times as a substring
+ within this string, then the index of the first character of
+ the last such substring is returned. If it does not occur as
+ a substring, -1 is returned.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 lastIndexOf( std::u16string_view str ) const
+ {
+ return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length,
+ str.data(), str.length() );
+ }
+#else
+ sal_Int32 lastIndexOf( const OUString & str ) const
+ {
+ return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length,
+ str.pData->buffer, str.pData->length );
+ }
+#endif
+
+ /**
+ Returns the index within this string of the last occurrence of
+ the specified substring, searching backward starting before the specified
+ index.
+
+ The returned index indicates the starting index of the substring
+ in this string.
+ If str doesn't include any character, always -1 is
+ returned. This is also the case, if both strings are empty.
+
+ @since LibreOffice 4.0
+
+ @param str the substring to search for.
+ @param fromIndex the index before which to start the search.
+ @return If the string argument occurs one or more times as a substring
+ within this string before the starting index, then the index
+ of the first character of the last such substring is
+ returned. Otherwise, -1 is returned.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 lastIndexOf( std::u16string_view str, sal_Int32 fromIndex ) const
+ {
+ assert( fromIndex >= 0 && fromIndex <= pData->length );
+ return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
+ str.data(), str.length() );
+ }
+#else
+ sal_Int32 lastIndexOf( const OUString & str, sal_Int32 fromIndex ) const
+ {
+ assert( fromIndex >= 0 && fromIndex <= pData->length );
+ return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
+ str.pData->buffer, str.pData->length );
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 4.0
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf( T& literal ) const
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return rtl_ustr_lastIndexOfAscii_WithLength(
+ pData->buffer, pData->length,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /** @overload @since LibreOffice 5.3 */
+ template<typename T>
+ typename
+ libreoffice_internal::ConstCharArrayDetector<T, sal_Int32>::TypeUtf16
+ lastIndexOf(T & literal) const {
+ return rtl_ustr_lastIndexOfStr_WithLength(
+ pData->buffer, pData->length,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+#endif
+
+ /**
+ Strip the given character from the start of the buffer.
+
+ @since LibreOffice 4.0
+
+ @param c the character to strip
+ @return The number of characters stripped
+
+ */
+ sal_Int32 stripStart(sal_Unicode c = ' ')
+ {
+ sal_Int32 index;
+ for(index = 0; index < getLength() ; index++)
+ {
+ if(pData->buffer[ index ] != c)
+ {
+ break;
+ }
+ }
+ if(index)
+ {
+ remove(0, index);
+ }
+ return index;
+ }
+
+ /**
+ Strip the given character from the end of the buffer.
+
+ @since LibreOffice 4.0
+
+ @param c the character to strip
+ @return The number of characters stripped
+
+ */
+ sal_Int32 stripEnd(sal_Unicode c = ' ')
+ {
+ sal_Int32 result = getLength();
+ sal_Int32 index;
+ for(index = getLength(); index > 0 ; index--)
+ {
+ if(pData->buffer[ index - 1 ] != c)
+ {
+ break;
+ }
+ }
+ if(index < getLength())
+ {
+ truncate(index);
+ }
+ return result - getLength();
+ }
+ /**
+ Strip the given character from the both end of the buffer.
+
+ @since LibreOffice 4.0
+
+ @param c the character to strip
+ @return The number of characters stripped
+
+ */
+ sal_Int32 strip(sal_Unicode c = ' ')
+ {
+ return stripStart(c) + stripEnd(c);
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /**
+ Returns a std::u16string_view that is a view of a substring of this string.
+
+ The substring begins at the specified beginIndex. If
+ beginIndex is negative or be greater than the length of
+ this string, behaviour is undefined.
+
+ @param beginIndex the beginning index, inclusive.
+ @return the specified substring.
+ */
+ SAL_WARN_UNUSED_RESULT std::u16string_view subView( sal_Int32 beginIndex ) const
+ {
+ assert(beginIndex >= 0);
+ assert(beginIndex <= getLength());
+ return subView(beginIndex, getLength() - beginIndex);
+ }
+
+ /**
+ Returns a std::u16string_view that is a view of a substring of this string.
+
+ The substring begins at the specified beginIndex and contains count
+ characters. If either beginIndex or count are negative,
+ or beginIndex + count are greater than the length of this string
+ then behaviour is undefined.
+
+ @param beginIndex the beginning index, inclusive.
+ @param count the number of characters.
+ @return the specified substring.
+ */
+ SAL_WARN_UNUSED_RESULT std::u16string_view subView( sal_Int32 beginIndex, sal_Int32 count ) const
+ {
+ assert(beginIndex >= 0);
+ assert(count >= 0);
+ assert(beginIndex <= getLength());
+ assert(count <= getLength() - beginIndex);
+ return std::u16string_view(pData->buffer, sal_uInt32(pData->length)).substr(beginIndex, count);
+ }
+#endif
+
+ /**
+ Returns a new string buffer that is a substring of this string.
+
+ The substring begins at the specified beginIndex. If
+ beginIndex is negative or be greater than the length of
+ this string, behaviour is undefined.
+
+ @param beginIndex the beginning index, inclusive.
+ @return the specified substring.
+ @since LibreOffice 4.1
+ */
+ OUStringBuffer copy( sal_Int32 beginIndex ) const
+ {
+ return copy( beginIndex, getLength() - beginIndex );
+ }
+
+ /**
+ Returns a new string buffer that is a substring of this string.
+
+ The substring begins at the specified beginIndex and contains count
+ characters. If either beginIndex or count are negative,
+ or beginIndex + count are greater than the length of this string
+ then behaviour is undefined.
+
+ @param beginIndex the beginning index, inclusive.
+ @param count the number of characters.
+ @return the specified substring.
+ @since LibreOffice 4.1
+ */
+ OUStringBuffer copy( sal_Int32 beginIndex, sal_Int32 count ) const
+ {
+ assert(beginIndex >= 0 && beginIndex <= getLength());
+ assert(count >= 0 && count <= getLength() - beginIndex);
+ rtl_uString *pNew = NULL;
+ rtl_uStringbuffer_newFromStr_WithLength( &pNew, getStr() + beginIndex, count );
+ return OUStringBuffer( pNew, count + 16 );
+ }
+
+private:
+ OUStringBuffer( rtl_uString * value, const sal_Int32 capacity )
+ {
+ pData = value;
+ nCapacity = capacity;
+ }
+
+ /**
+ A pointer to the data structure which contains the data.
+ */
+ rtl_uString * pData;
+
+ /**
+ The len of the pData->buffer.
+ */
+ sal_Int32 nCapacity;
+};
+
+#if defined LIBO_INTERNAL_ONLY
+template<> struct ToStringHelper<OUStringBuffer> {
+ static std::size_t length(OUStringBuffer const & s) { return s.getLength(); }
+
+ sal_Unicode * operator()(sal_Unicode * buffer, OUStringBuffer const & s) const SAL_RETURNS_NONNULL
+ { return addDataHelper(buffer, s.getStr(), s.getLength()); }
+};
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+ // Define this here to avoid circular includes
+ inline OUString & OUString::operator+=( const OUStringBuffer & str ) &
+ {
+ // Call operator= if this is empty, otherwise rtl_uString_newConcat will attempt to
+ // acquire() the str.pData buffer, which is part of the OUStringBuffer mutable state.
+ if (isEmpty())
+ return operator=(str.toString());
+ else
+ return internalAppend(str.pData);
+ }
+
+ inline OUString const& OUString::unacquired(const OUStringBuffer& str)
+ {
+ return unacquired(&str.pData);
+ }
+#endif
+}
+
+#ifdef RTL_STRING_UNITTEST
+namespace rtl
+{
+typedef rtlunittest::OUStringBuffer OUStringBuffer;
+}
+#endif
+
+#if defined LIBO_INTERNAL_ONLY && !defined RTL_STRING_UNITTEST
+using ::rtl::OUStringBuffer;
+#endif
+
+#endif // INCLUDED_RTL_USTRBUF_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/ustring.h b/include/rtl/ustring.h
new file mode 100644
index 0000000000..303aff4460
--- /dev/null
+++ b/include/rtl/ustring.h
@@ -0,0 +1,2405 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_USTRING_H
+#define INCLUDED_RTL_USTRING_H
+
+#include "sal/config.h"
+
+#include "osl/interlck.h"
+#include "rtl/string.h"
+#include "rtl/textenc.h"
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ======================================================================= */
+
+/** Return the length of a string.
+
+ The length is equal to the number of 16-bit Unicode characters in the
+ string, without the terminating NUL character.
+
+ @param str
+ a null-terminated string.
+
+ @return
+ the length of the sequence of characters represented by this string,
+ excluding the terminating NUL character.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_getLength(
+ const sal_Unicode * str ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. This function
+ cannot be used for language-specific sorting. Both strings must be
+ null-terminated.
+
+ @param first
+ the first null-terminated string to be compared.
+
+ @param second
+ the second null-terminated string which is compared with the first one.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string is
+ less than the second string, and a value greater than 0 if the first
+ string is greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_compare(
+ const sal_Unicode * first, const sal_Unicode * second ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. This function
+ cannot be used for language-specific sorting.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second string which is compared with the first one. Need not be
+ null-terminated, but must be at least as long as the specified secondLen.
+
+ @param secondLen
+ the length of the second string.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string is
+ less than the second string, and a value greater than 0 if the first
+ string is greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_compare_WithLength(
+ const sal_Unicode * first, sal_Int32 firstLen, const sal_Unicode * second, sal_Int32 secondLen ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings with a maximum count of characters.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. This function
+ cannot be used for language-specific sorting.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second string which is compared with the first one. Need not be
+ null-terminated, but must be at least as long as the specified secondLen.
+
+ @param secondLen
+ the length of the second string.
+
+ @param shortenedLen
+ the maximum number of characters to compare. This length can be greater
+ or smaller than the lengths of the two strings.
+
+ @return
+ 0 if both substrings are equal, a value less than 0 if the first substring
+ is less than the second substring, and a value greater than 0 if the first
+ substring is greater than the second substring.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_shortenedCompare_WithLength(
+ const sal_Unicode * first, sal_Int32 firstLen, const sal_Unicode * second, sal_Int32 secondLen, sal_Int32 shortenedLen ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings from back to front.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. This function
+ cannot be used for language-specific sorting.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second string which is compared with the first one. Need not be
+ null-terminated, but must be at least as long as the specified secondLen.
+
+ @param secondLen
+ the length of the second string.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string
+ compares less than the second string, and a value greater than 0 if the
+ first string compares greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_reverseCompare_WithLength(
+ const sal_Unicode * first, sal_Int32 firstLen, const sal_Unicode * second, sal_Int32 secondLen ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings from back to front for equality.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns 'true' if, and only if, both strings are equal.
+ This function cannot be used for language-specific sorting.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified len.
+
+ @param second
+ the second string which is compared with the first one. Need not be
+ null-terminated, but must be at least as long as the specified len.
+
+ @param len
+ the length of both strings.
+
+ @return
+ true if both strings are equal, false if they are not equal.
+ */
+
+SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_ustr_asciil_reverseEquals_WithLength(
+ const sal_Unicode * first, const char * second, sal_Int32 len ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings, ignoring the case of ASCII characters.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. Character
+ values between 65 and 90 (ASCII A--Z) are interpreted as values between 97
+ and 122 (ASCII a--z). This function cannot be used for language-specific
+ sorting. Both strings must be null-terminated.
+
+ @param first
+ the first null-terminated string to be compared.
+
+ @param second
+ the second null-terminated string which is compared with the first one.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string is
+ less than the second string, and a value greater than 0 if the first
+ string is greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_compareIgnoreAsciiCase(
+ const sal_Unicode * first, const sal_Unicode * second ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings, ignoring the case of ASCII characters.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. Character
+ values between 65 and 90 (ASCII A--Z) are interpreted as values between 97
+ and 122 (ASCII a--z). This function cannot be used for language-specific
+ sorting.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second string which is compared with the first one. Need not be
+ null-terminated, but must be at least as long as the specified secondLen.
+
+ @param secondLen
+ the length of the second string.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string is
+ less than the second string, and a value greater than 0 if the first
+ string is greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_compareIgnoreAsciiCase_WithLength(
+ const sal_Unicode * first, sal_Int32 firstLen, const sal_Unicode * second, sal_Int32 secondLen ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings with a maximum count of characters, ignoring the case
+ of ASCII characters.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. Character
+ values between 65 and 90 (ASCII A--Z) are interpreted as values between 97
+ and 122 (ASCII a--z). This function cannot be used for language-specific
+ sorting.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second string which is compared with the first one. Need not be
+ null-terminated, but must be at least as long as the specified secondLen.
+
+ @param secondLen
+ the length of the second string.
+
+ @param shortenedLen
+ the maximum number of characters to compare. This length can be greater
+ or smaller than the lengths of the two strings.
+
+ @return
+ 0 if both substrings are equal, a value less than 0 if the first substring
+ is less than the second substring, and a value greater than 0 if the first
+ substring is greater than the second substring.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength(
+ const sal_Unicode * first, sal_Int32 firstLen, const sal_Unicode * second, sal_Int32 secondLen, sal_Int32 shortenedLen ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. This function
+ cannot be used for language-specific sorting. Both strings must be
+ null-terminated.
+
+ Since this function is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range of 0 and 127, inclusive.
+
+ @param first
+ the first null-terminated string to be compared.
+
+ @param second
+ the second null-terminated ASCII string which is compared with the first
+ one.
+
+ @return
+ 0 if both substrings are equal, a value less than 0 if the first substring
+ is less than the second substring, and a value greater than 0 if the first
+ substring is greater than the second substring.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_ascii_compare(
+ const sal_Unicode * first, const char * second ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. This function
+ cannot be used for language-specific sorting.
+
+ Since this function is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range of 0 and 127, inclusive.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second null-terminated ASCII string which is compared with the first
+ one.
+
+ @return
+ 0 if both substrings are equal, a value less than 0 if the first substring
+ is less than the second substring, and a value greater than 0 if the first
+ substring is greater than the second substring.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_ascii_compare_WithLength(
+ const sal_Unicode * first, sal_Int32 firstLen, const char * second ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings with a maximum count of characters.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. This function
+ cannot be used for language-specific sorting.
+
+ Since this function is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range of 0 and 127, inclusive.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second null-terminated ASCII string which is compared with the first
+ one.
+
+ @param shortenedLen
+ the maximum number of characters to compare. This length can be greater
+ or smaller than the lengths of the two strings.
+
+ @return
+ 0 if both substrings are equal, a value less than 0 if the first substring
+ is less than the second substring, and a value greater than 0 if the first
+ substring is greater than the second substring.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompare_WithLength(
+ const sal_Unicode * first, sal_Int32 firstLen, const char * second, sal_Int32 shortenedLen ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings from back to front.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. This function
+ cannot be used for language-specific sorting.
+
+ Since this function is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range of 0 and 127, inclusive.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second ASCII string which is compared with the first one. Need not be
+ null-terminated, but must be at least as long as the specified secondLen.
+
+ @param secondLen
+ the length of the second string.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string
+ compares less than the second string, and a value greater than 0 if the
+ first string compares greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_asciil_reverseCompare_WithLength(
+ const sal_Unicode * first, sal_Int32 firstLen, const char * second, sal_Int32 secondLen ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings, ignoring the case of ASCII characters.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. Character
+ values between 65 and 90 (ASCII A--Z) are interpreted as values between 97
+ and 122 (ASCII a--z). This function cannot be used for language-specific
+ sorting. Both strings must be null-terminated.
+
+ Since this function is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range of 0 and 127, inclusive.
+
+ @param first
+ the first null-terminated string to be compared.
+
+ @param second
+ the second null-terminated ASCII string which is compared with the first
+ one.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string is
+ less than the second string, and a value greater than 0 if the first
+ string is greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase(
+ const sal_Unicode * first, const char * second ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings, ignoring the case of ASCII characters.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. Character
+ values between 65 and 90 (ASCII A--Z) are interpreted as values between 97
+ and 122 (ASCII a--z). This function cannot be used for language-specific
+ sorting.
+
+ Since this function is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range of 0 and 127, inclusive.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second null-terminated ASCII string which is compared with the first
+ one.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string is
+ less than the second string, and a value greater than 0 if the first
+ string is greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength(
+ const sal_Unicode * first, sal_Int32 firstLen, const char * second ) SAL_THROW_EXTERN_C();
+
+/** Compare two strings, ignoring the case of ASCII characters.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. Character
+ values between 65 and 90 (ASCII A--Z) are interpreted as values between 97
+ and 122 (ASCII a--z). This function cannot be used for language-specific
+ sorting.
+
+ Since this function is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range of 0 and 127, inclusive.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second string which is compared with the first one. Need not be
+ null-terminated, but must be at least as long as the specified secondLen.
+
+ @param secondLen
+ the length of the second string.
+
+ @return
+ 0 if both strings are equal, a value less than 0 if the first string is
+ less than the second string, and a value greater than 0 if the first
+ string is greater than the second string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
+ sal_Unicode const * first, sal_Int32 firstLen,
+ char const * second, sal_Int32 secondLen) SAL_THROW_EXTERN_C();
+
+/** Compare two strings with a maximum count of characters, ignoring the case
+ of ASCII characters.
+
+ The comparison is based on the numeric value of each character in the
+ strings and returns a value indicating their relationship. Character
+ values between 65 and 90 (ASCII A--Z) are interpreted as values between 97
+ and 122 (ASCII a--z). This function cannot be used for language-specific
+ sorting.
+
+ Since this function is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range of 0 and 127, inclusive.
+
+ @param first
+ the first string to be compared. Need not be null-terminated, but must be
+ at least as long as the specified firstLen.
+
+ @param firstLen
+ the length of the first string.
+
+ @param second
+ the second null-terminated ASCII string which is compared with the first
+ one.
+
+ @param shortenedLen
+ the maximum number of characters to compare. This length can be greater
+ or smaller than the lengths of the two strings.
+
+ @return
+ 0 if both substrings are equal, a value less than 0 if the first substring
+ is less than the second substring, and a value greater than 0 if the first
+ substring is greater than the second substring.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength(
+ const sal_Unicode * first, sal_Int32 firstLen, const char * second, sal_Int32 shortenedLen ) SAL_THROW_EXTERN_C();
+
+/** Return a hash code for a string.
+
+ It is not allowed to store the hash code persistently, because later
+ versions could return other hash codes. The string must be
+ null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @return
+ a hash code for the given string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_hashCode(
+ const sal_Unicode * str ) SAL_THROW_EXTERN_C();
+
+/** Return a hash code for a string.
+
+ It is not allowed to store the hash code persistently, because later
+ versions could return other hash codes.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+
+ @return
+ a hash code for the given string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_hashCode_WithLength(
+ const sal_Unicode * str, sal_Int32 len ) SAL_THROW_EXTERN_C();
+
+/** Search for the first occurrence of a character within a string.
+
+ The string must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param ch
+ the character to be searched for.
+
+ @return
+ the index (starting at 0) of the first occurrence of the character in the
+ string, or -1 if the character does not occur.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_indexOfChar(
+ const sal_Unicode * str, sal_Unicode ch ) SAL_THROW_EXTERN_C();
+
+/** Search for the first occurrence of a character within a string.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+
+ @param ch
+ the character to be searched for.
+
+ @return
+ the index (starting at 0) of the first occurrence of the character in the
+ string, or -1 if the character does not occur.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_indexOfChar_WithLength(
+ const sal_Unicode * str, sal_Int32 len, sal_Unicode ch ) SAL_THROW_EXTERN_C();
+
+/** Search for the last occurrence of a character within a string.
+
+ The string must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param ch
+ the character to be searched for.
+
+ @return
+ the index (starting at 0) of the last occurrence of the character in the
+ string, or -1 if the character does not occur. The returned value is
+ always smaller than the string length.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_lastIndexOfChar(
+ const sal_Unicode * str, sal_Unicode ch ) SAL_THROW_EXTERN_C();
+
+/** Search for the last occurrence of a character within a string.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+
+ @param ch
+ the character to be searched for.
+
+ @return
+ the index (starting at 0) of the last occurrence of the character in the
+ string, or -1 if the character does not occur. The returned value is
+ always smaller than the string length.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_lastIndexOfChar_WithLength(
+ const sal_Unicode * str, sal_Int32 len, sal_Unicode ch ) SAL_THROW_EXTERN_C();
+
+/** Search for the first occurrence of a substring within a string.
+
+ If subStr is empty, or both str and subStr are empty, -1 is returned.
+ Both strings must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param subStr
+ the null-terminated substring to be searched for.
+
+ @return
+ the index (starting at 0) of the first character of the first occurrence
+ of the substring within the string, or -1 if the substring does not occur.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_indexOfStr(
+ const sal_Unicode * str, const sal_Unicode * subStr ) SAL_THROW_EXTERN_C();
+
+/** Search for the first occurrence of a substring within a string.
+
+ If subStr is empty, or both str and subStr are empty, -1 is returned.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+
+ @param subStr
+ the substring to be searched for. Need not be null-terminated, but must
+ be at least as long as the specified subLen.
+
+ @param subLen
+ the length of the substring.
+
+ @return
+ the index (starting at 0) of the first character of the first occurrence
+ of the substring within the string, or -1 if the substring does not occur.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_indexOfStr_WithLength(
+ const sal_Unicode * str, sal_Int32 len, const sal_Unicode * subStr, sal_Int32 subLen ) SAL_THROW_EXTERN_C();
+
+/** Search for the first occurrence of an ASCII substring within a string.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string; must be non-negative.
+
+ @param subStr
+ the substring to be searched for. Need not be null-terminated, but must
+ be at least as long as the specified subLen. Must only contain characters
+ in the ASCII range 0x00--7F.
+
+ @param subLen
+ the length of the substring; must be non-negative.
+
+ @return
+ the index (starting at 0) of the first character of the first occurrence
+ of the substring within the string, or -1 if the substring does not occur.
+ If subLen is zero, -1 is returned.
+
+ @since UDK 3.2.7
+*/
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_indexOfAscii_WithLength(
+ sal_Unicode const * str, sal_Int32 len,
+ char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C();
+
+/** Search for the last occurrence of a substring within a string.
+
+ If subStr is empty, or both str and subStr are empty, -1 is returned.
+ Both strings must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param subStr
+ the null-terminated substring to be searched for.
+
+ @return
+ the index (starting at 0) of the first character of the last occurrence
+ of the substring within the string, or -1 if the substring does not occur.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_lastIndexOfStr(
+ const sal_Unicode * str, const sal_Unicode * subStr ) SAL_THROW_EXTERN_C();
+
+/** Search for the last occurrence of a substring within a string.
+
+ If subStr is empty, or both str and subStr are empty, -1 is returned.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+
+ @param subStr
+ the substring to be searched for. Need not be null-terminated, but must
+ be at least as long as the specified subLen.
+
+ @param subLen
+ the length of the substring.
+
+ @return
+ the index (starting at 0) of the first character of the first occurrence
+ of the substring within the string, or -1 if the substring does not occur.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_lastIndexOfStr_WithLength(
+ const sal_Unicode * str, sal_Int32 len, const sal_Unicode * subStr, sal_Int32 subLen ) SAL_THROW_EXTERN_C();
+
+/** Search for the last occurrence of an ASCII substring within a string.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string; must be non-negative.
+
+ @param subStr
+ the substring to be searched for. Need not be null-terminated, but must
+ be at least as long as the specified subLen. Must only contain characters
+ in the ASCII range 0x00--7F.
+
+ @param subLen
+ the length of the substring; must be non-negative.
+
+ @return
+ the index (starting at 0) of the first character of the last occurrence
+ of the substring within the string, or -1 if the substring does not occur.
+ If subLen is zero, -1 is returned.
+
+ @since UDK 3.2.7
+*/
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_lastIndexOfAscii_WithLength(
+ sal_Unicode const * str, sal_Int32 len,
+ char const * subStr, sal_Int32 subLen) SAL_THROW_EXTERN_C();
+
+/** Replace all occurrences of a single character within a string.
+
+ If oldChar does not occur within str, then the string is not modified.
+ The string must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param oldChar
+ the old character.
+
+ @param newChar
+ the new character.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_ustr_replaceChar(
+ sal_Unicode * str, sal_Unicode oldChar, sal_Unicode newChar ) SAL_THROW_EXTERN_C();
+
+/** Replace all occurrences of a single character within a string.
+
+ If oldChar does not occur within str, then the string is not modified.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+
+ @param oldChar
+ the old character.
+
+ @param newChar
+ the new character.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_ustr_replaceChar_WithLength(
+ sal_Unicode * str, sal_Int32 len, sal_Unicode oldChar, sal_Unicode newChar ) SAL_THROW_EXTERN_C();
+
+/** Convert all ASCII uppercase letters to lowercase within a string.
+
+ The characters with values between 65 and 90 (ASCII A--Z) are replaced
+ with values between 97 and 122 (ASCII a--z). The string must be
+ null-terminated.
+
+ @param str
+ a null-terminated string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_ustr_toAsciiLowerCase(
+ sal_Unicode * str ) SAL_THROW_EXTERN_C();
+
+/** Convert all ASCII uppercase letters to lowercase within a string.
+
+ The characters with values between 65 and 90 (ASCII A--Z) are replaced
+ with values between 97 and 122 (ASCII a--z).
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_ustr_toAsciiLowerCase_WithLength(
+ sal_Unicode * str, sal_Int32 len ) SAL_THROW_EXTERN_C();
+
+/** Convert all ASCII lowercase letters to uppercase within a string.
+
+ The characters with values between 97 and 122 (ASCII a--z) are replaced
+ with values between 65 and 90 (ASCII A--Z). The string must be
+ null-terminated.
+
+ @param str
+ a null-terminated string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_ustr_toAsciiUpperCase(
+ sal_Unicode * str ) SAL_THROW_EXTERN_C();
+
+/** Convert all ASCII lowercase letters to uppercase within a string.
+
+ The characters with values between 97 and 122 (ASCII a--z) are replaced
+ with values between 65 and 90 (ASCII A--Z).
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the length of the string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_ustr_toAsciiUpperCase_WithLength(
+ sal_Unicode * str, sal_Int32 len ) SAL_THROW_EXTERN_C();
+
+/** Remove white space from both ends of a string.
+
+ All characters with values less than or equal to 32 (the space character)
+ are considered to be white space. This function cannot be used for
+ language-specific operations. The string must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @return
+ the new length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_trim(
+ sal_Unicode * str ) SAL_THROW_EXTERN_C();
+
+/** Remove white space from both ends of the string.
+
+ All characters with values less than or equal to 32 (the space character)
+ are considered to be white space. This function cannot be used for
+ language-specific operations. The string must be null-terminated.
+
+ @param str
+ a string. Need not be null-terminated, but must be at least as long as
+ the specified len.
+
+ @param len
+ the original length of the string.
+
+ @return
+ the new length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_trim_WithLength(
+ sal_Unicode * str, sal_Int32 len ) SAL_THROW_EXTERN_C();
+
+/** Create the string representation of a boolean.
+
+ If b is true, the buffer is filled with the string "true" and 4 is
+ returned. If b is false, the buffer is filled with the string "false" and
+ 5 is returned. This function cannot be used for language-specific
+ operations.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_USTR_MAX_VALUEOFBOOLEAN define to
+ create a buffer that is big enough.
+
+ @param b
+ a boolean value.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_valueOfBoolean(
+ sal_Unicode * str, sal_Bool b ) SAL_THROW_EXTERN_C();
+#define RTL_USTR_MAX_VALUEOFBOOLEAN RTL_STR_MAX_VALUEOFBOOLEAN
+
+/** Create the string representation of a character.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_USTR_MAX_VALUEOFCHAR define to create a
+ buffer that is big enough.
+
+ @param ch
+ a character value.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_valueOfChar(
+ sal_Unicode * str, sal_Unicode ch ) SAL_THROW_EXTERN_C();
+#define RTL_USTR_MAX_VALUEOFCHAR RTL_STR_MAX_VALUEOFCHAR
+
+/** Create the string representation of an integer.
+
+ This function cannot be used for language-specific operations.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_USTR_MAX_VALUEOFINT32 define to create
+ a buffer that is big enough.
+
+ @param i
+ an integer value.
+
+ @param radix
+ the radix. Must be between RTL_USTR_MIN_RADIX (2) and RTL_USTR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_valueOfInt32(
+ sal_Unicode * str, sal_Int32 i, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+#define RTL_USTR_MIN_RADIX RTL_STR_MIN_RADIX
+#define RTL_USTR_MAX_RADIX RTL_STR_MAX_RADIX
+#define RTL_USTR_MAX_VALUEOFINT32 RTL_STR_MAX_VALUEOFINT32
+
+/** Create the string representation of a long integer.
+
+ This function cannot be used for language-specific operations.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_USTR_MAX_VALUEOFINT64 define to create
+ a buffer that is big enough.
+
+ @param l
+ a long integer value.
+
+ @param radix
+ the radix. Must be between RTL_USTR_MIN_RADIX (2) and RTL_USTR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_valueOfInt64(
+ sal_Unicode * str, sal_Int64 l, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+#define RTL_USTR_MAX_VALUEOFINT64 RTL_STR_MAX_VALUEOFINT64
+
+/** Create the string representation of an unsigned long integer.
+
+ This function cannot be used for language-specific operations.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_USTR_MAX_VALUEOFUINT64 define to create
+ a buffer that is big enough.
+
+ @param l
+ a long integer value.
+
+ @param radix
+ the radix. Must be between RTL_USTR_MIN_RADIX (2) and RTL_USTR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_valueOfUInt64(
+ sal_Unicode * str, sal_uInt64 l, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+#define RTL_USTR_MAX_VALUEOFUINT64 RTL_STR_MAX_VALUEOFUINT64
+
+/** Create the string representation of a float.
+
+ This function cannot be used for language-specific conversion.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_USTR_MAX_VALUEOFFLOAT define to create
+ a buffer that is big enough.
+
+ @param f
+ a float value.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_valueOfFloat(
+ sal_Unicode * str, float f ) SAL_THROW_EXTERN_C();
+#define RTL_USTR_MAX_VALUEOFFLOAT RTL_STR_MAX_VALUEOFFLOAT
+
+/** Create the string representation of a double.
+
+ This function cannot be used for language-specific conversion.
+
+ @param str
+ a buffer that is big enough to hold the result and the terminating NUL
+ character. You should use the RTL_USTR_MAX_VALUEOFDOUBLE define to create
+ a buffer that is big enough.
+
+ @param d
+ a double value.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_valueOfDouble(
+ sal_Unicode * str, double d ) SAL_THROW_EXTERN_C();
+#define RTL_USTR_MAX_VALUEOFDOUBLE RTL_STR_MAX_VALUEOFDOUBLE
+
+/** Interpret a string as a boolean.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @return
+ true if the string is "1" or "true" in any ASCII case, false otherwise.
+ */
+SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_ustr_toBoolean(
+ const sal_Unicode * str ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as an integer.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param radix
+ the radix. Must be between RTL_USTR_MIN_RADIX (2) and RTL_USTR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the integer value represented by the string, or 0 if the string does not
+ represent an integer.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_toInt32(
+ const sal_Unicode * str, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as an unsigned integer.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param radix
+ the radix. Must be between RTL_USTR_MIN_RADIX (2) and RTL_USTR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the unsigned integer value represented by the string, or 0 if the string
+ does not represent an unsigned integer.
+
+ @since LibreOffice 4.2
+ */
+SAL_DLLPUBLIC sal_uInt32 SAL_CALL rtl_ustr_toUInt32(
+ const sal_Unicode * str, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as a long integer.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param radix
+ the radix. Must be between RTL_USTR_MIN_RADIX (2) and RTL_USTR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the long integer value represented by the string, or 0 if the string does
+ not represent a long integer.
+ */
+SAL_DLLPUBLIC sal_Int64 SAL_CALL rtl_ustr_toInt64(
+ const sal_Unicode * str, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as a long integer.
+
+ This function cannot be used for language-specific conversion.
+
+ @param str
+ a string.
+
+ @param radix
+ the radix. Must be between RTL_USTR_MIN_RADIX (2) and RTL_USTR_MAX_RADIX
+ (36), inclusive.
+
+ @param nStrLength
+ number of chars to process
+
+ @return
+ the long integer value represented by the string, or 0 if the string does
+ not represent a long integer.
+
+ @internal
+ @since LibreOffice 6.4
+*/
+SAL_DLLPUBLIC sal_Int64 SAL_CALL rtl_ustr_toInt64_WithLength(
+ const sal_Unicode * str, sal_Int16 radix, sal_Int32 nStrLength ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as an unsigned long integer.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param radix
+ the radix. Must be between RTL_USTR_MIN_RADIX (2) and RTL_USTR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the unsigned long integer value represented by the string, or 0 if the
+ string does not represent an unsigned long integer.
+
+ @since LibreOffice 4.1
+ */
+SAL_DLLPUBLIC sal_uInt64 SAL_CALL rtl_ustr_toUInt64(
+ const sal_Unicode * str, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as a float.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @return
+ the float value represented by the string, or 0.0 if the string does not
+ represent a float.
+ */
+SAL_DLLPUBLIC float SAL_CALL rtl_ustr_toFloat(
+ const sal_Unicode * str ) SAL_THROW_EXTERN_C();
+
+/** Interpret a string as a double.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @return
+ the float value represented by the string, or 0.0 if the string does not
+ represent a double.
+ */
+SAL_DLLPUBLIC double SAL_CALL rtl_ustr_toDouble(
+ const sal_Unicode * str ) SAL_THROW_EXTERN_C();
+
+/* ======================================================================= */
+
+/** @cond INTERNAL */
+/** The implementation of a Unicode string.
+*/
+typedef struct SAL_DLLPUBLIC_RTTI _rtl_uString
+{
+ oslInterlockedCount refCount; /* opaque */
+ sal_Int32 length;
+ sal_Unicode buffer[1];
+} rtl_uString;
+/** @endcond */
+
+/* ----------------------------------------------------------------------- */
+
+/** Increment the reference count of a string.
+
+ @param str
+ a string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_acquire(
+ rtl_uString * str ) SAL_THROW_EXTERN_C() SAL_HOT;
+
+/** Decrement the reference count of a string.
+
+ If the count goes to zero than the string data is deleted.
+
+ @param str
+ a string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_release(
+ rtl_uString * str ) SAL_THROW_EXTERN_C() SAL_HOT;
+
+/** Allocate a new string containing no characters.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_new(
+ rtl_uString ** newStr ) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string containing space for a given number of characters.
+
+ The reference count of the new string will be 1. The length of the string
+ will be nLen. This function does not handle out-of-memory conditions.
+
+ For failed allocation this method returns NULL.
+
+ The characters of the capacity are not cleared, and the length is set to
+ nLen, unlike the similar method of rtl_uString_new_WithLength which
+ zeros out the buffer, and sets the length to 0. So should be somewhat
+ more efficient for allocating a new string.
+
+ call rtl_uString_release to release the string
+ alternatively pass ownership to an OUString with
+ rtl::OUString(newStr, SAL_NO_ACQUIRE);
+
+ @param[in] nLen the number of characters. Must be >= 0.
+
+ @return pointer to the new string.
+
+ @since LibreOffice 4.1
+ */
+SAL_DLLPUBLIC rtl_uString * SAL_CALL rtl_uString_alloc(sal_Int32 nLen) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string containing space for a given number of characters.
+
+ If len is greater than zero, the reference count of the new string will be
+ 1. The values of all characters are set to 0 and the length of the string
+ is 0. This function does not handle out-of-memory conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param nLen
+ the number of characters.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_new_WithLength(
+ rtl_uString ** newStr, sal_Int32 nLen ) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string that contains a copy of another string.
+
+ If the length of value is greater than zero, the reference count of the
+ new string will be 1. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param value
+ a valid string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromString(
+ rtl_uString ** newStr, const rtl_uString * value ) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string that contains a copy of a character array.
+
+ If the length of value is greater than zero, the reference count of the
+ new string will be 1. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param value
+ a null-terminated character array.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromStr(
+ rtl_uString ** newStr, const sal_Unicode * value ) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string that contains a copy of a character array.
+
+ If the length of value is greater than zero, the reference count of the
+ new string will be 1. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param value
+ a character array. Need not be null-terminated, but must be at least as
+ long as the specified len.
+
+ @param len
+ the length of the character array.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromStr_WithLength(
+ rtl_uString ** newStr, const sal_Unicode * value, sal_Int32 len ) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string that is a substring of this string.
+
+ The substring begins at the specified beginIndex and contains count
+ characters. Meaningless combinations such as negative beginIndex,
+ or beginIndex + count greater than the length of the string have
+ undefined behaviour.
+
+ @param[out] newStr the specified substring.
+ @param[in] from the String to take the substring from.
+ @param[in] beginIndex the beginning index, inclusive.
+ @param[in] count the number of characters.
+
+ @since LibreOffice 4.0
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromSubString(
+ rtl_uString ** newStr, const rtl_uString * from,
+ sal_Int32 beginIndex, sal_Int32 count ) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string that contains a copy of a character array.
+
+ If the length of value is greater than zero, the reference count of the
+ new string will be 1. This function does not handle out-of-memory
+ conditions.
+
+ Since this function is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range of 0 and 127, inclusive.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param value
+ a null-terminated ASCII character array.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromAscii(
+ rtl_uString ** newStr, const char * value ) SAL_THROW_EXTERN_C();
+
+/**
+ @internal
+ @since LibreOffice 3.6
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromLiteral(
+ rtl_uString ** newStr, const char * value, sal_Int32 len,
+ sal_Int32 allocExtra ) SAL_THROW_EXTERN_C();
+
+/** Allocate a new string from an array of Unicode code points.
+
+ @param newString
+ a non-null pointer to a (possibly null) rtl_uString pointer, which (if
+ non-null) will have been passed to rtl_uString_release before the function
+ returns. Upon return, points to the newly allocated string or to null if
+ there was either an out-of-memory condition or the resulting number of
+ UTF-16 code units would have been larger than SAL_MAX_INT32. The newly
+ allocated string (if any) must ultimately be passed to rtl_uString_release.
+
+ @param codePoints
+ an array of at least codePointCount code points, which each must be in the
+ range from 0 to 0x10FFFF, inclusive. May be null if codePointCount is zero.
+
+ @param codePointCount
+ the non-negative number of code points.
+
+ @since UDK 3.2.7
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromCodePoints(
+ rtl_uString ** newString, sal_uInt32 const * codePoints,
+ sal_Int32 codePointCount) SAL_THROW_EXTERN_C();
+
+/** Assign a new value to a string.
+
+ First releases any value str might currently hold, then acquires
+ rightValue.
+
+ @param str
+ pointer to the string. The pointed-to data must be null or a valid
+ string.
+
+ @param rightValue
+ a valid string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_assign(
+ rtl_uString ** str, rtl_uString * rightValue ) SAL_THROW_EXTERN_C();
+
+/** Return the length of a string.
+
+ The length is equal to the number of characters in the string.
+
+ @param str
+ a valid string.
+
+ @return
+ the length of the string.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_uString_getLength(
+ const rtl_uString * str ) SAL_THROW_EXTERN_C();
+
+/** Return a pointer to the underlying character array of a string.
+
+ @param str
+ a valid string.
+
+ @return
+ a pointer to the null-terminated character array.
+ */
+SAL_DLLPUBLIC sal_Unicode * SAL_CALL rtl_uString_getStr(
+ rtl_uString * str ) SAL_THROW_EXTERN_C();
+
+/** Create a new string that is the concatenation of two other strings.
+
+ The new string does not necessarily have a reference count of 1 (in cases
+ where one of the two other strings is empty), so it must not be modified
+ without checking the reference count. This function does not handle
+ out-of-memory conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param left
+ a valid string.
+
+ @param right
+ a valid string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newConcat(
+ rtl_uString ** newStr, rtl_uString * left, rtl_uString * right ) SAL_THROW_EXTERN_C();
+
+/** Create a new string that is the concatenation of two other strings.
+
+ The new string does not necessarily have a reference count of 1 (in cases
+ where the ASCII string is empty), so it must not be modified without
+ checking the reference count.
+
+ @param newString
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param left
+ a valid string.
+
+ @param right must not be null and must point to memory of at least
+ \p rightLength ASCII bytes
+
+ @param rightLength the length of the \p right string; must be non-negative
+
+ @since LibreOffice 5.1
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newConcatAsciiL(
+ rtl_uString ** newString, rtl_uString * left, char const * right,
+ sal_Int32 rightLength);
+
+/** Create a new string that is the concatenation of two other strings.
+
+ The new string does not necessarily have a reference count of 1 (in cases
+ where the UTF-16 string is empty), so it must not be modified without
+ checking the reference count.
+
+ @param newString pointer to the new string. The pointed-to data must be null
+ or a valid string.
+
+ @param left a valid string.
+
+ @param right must point to memory of at least \p rightLength UTF-16 code units; may be null if
+ \p rigthLength is zero
+
+ @param rightLength the length of the \p right string; must be non-negative
+
+ @since LibreOffice 5.3
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newConcatUtf16L(
+ rtl_uString ** newString, rtl_uString * left, sal_Unicode const * right,
+ sal_Int32 rightLength);
+
+/** Create a new string by replacing a substring of another string.
+
+ The new string results from replacing a number of characters (count),
+ starting at the specified position (index) in the original string (str),
+ with some new substring (subStr). If subStr is null, then only a number
+ of characters is deleted.
+
+ The new string does not necessarily have a reference count of 1, so it
+ must not be modified without checking the reference count. This function
+ does not handle out-of-memory conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param str
+ a valid string.
+
+ @param idx
+ the index into str at which to start replacement. Must be between 0 and
+ the length of str, inclusive.
+
+ @param count
+ the number of characters to remove. Must not be negative, and the sum of
+ index and count must not exceed the length of str.
+
+ @param subStr
+ either null or a valid string to be inserted.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceStrAt(
+ rtl_uString ** newStr, rtl_uString * str, sal_Int32 idx, sal_Int32 count, rtl_uString * subStr ) SAL_THROW_EXTERN_C();
+
+#ifdef LIBO_INTERNAL_ONLY
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceStrAtUtf16L(
+ rtl_uString ** newStr, rtl_uString * str, sal_Int32 idx, sal_Int32 count, sal_Unicode const * subStr, sal_Int32 substrLen ) SAL_THROW_EXTERN_C();
+#endif
+
+/** Create a new string by replacing all occurrences of a single character
+ within another string.
+
+ The new string results from replacing all occurrences of oldChar in str
+ with newChar.
+
+ The new string does not necessarily have a reference count of 1 (in cases
+ where oldChar does not occur in str), so it must not be modified without
+ checking the reference count. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param str
+ a valid string.
+
+ @param oldChar
+ the old character.
+
+ @param newChar
+ the new character.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplace(
+ rtl_uString ** newStr, rtl_uString * str, sal_Unicode oldChar, sal_Unicode newChar ) SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing the first occurrence of a given substring
+ with another substring.
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null
+
+ @param to pointer to the replacing substring; must not be null
+
+ @param[in,out] index pointer to a start index, must not be null; upon entry
+ to the function its value is the index into the original string at which to
+ start searching for the \p from substring, the value must be non-negative
+ and not greater than the original string's length; upon exit from the
+ function its value is the index into the original string at which the
+ replacement took place or -1 if no replacement took place
+
+ @since LibreOffice 3.6
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceFirst(
+ rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
+ rtl_uString const * to, sal_Int32 * index) SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing the first occurrence of a given substring
+ with another substring.
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p fromLength ASCII bytes
+
+ @param fromLength the length of the \p from substring; must be non-negative
+
+ @param to pointer to the replacing substring; must not be null
+
+ @param[in,out] index pointer to a start index, must not be null; upon entry
+ to the function its value is the index into the original string at which to
+ start searching for the \p from substring, the value must be non-negative
+ and not greater than the original string's length; upon exit from the
+ function its value is the index into the original string at which the
+ replacement took place or -1 if no replacement took place
+
+ @since LibreOffice 3.6
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceFirstAsciiL(
+ rtl_uString ** newStr, rtl_uString * str, char const * from,
+ sal_Int32 fromLength, rtl_uString const * to, sal_Int32 * index)
+ SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing the first occurrence of a given substring
+ with another substring.
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null
+
+ @param to pointer to the replacing substring; must not be null and must
+ point to memory of at least \p toLength ASCII bytes
+
+ @param toLength the length of the \p to substring; must be non-negative
+
+ @param[in,out] index pointer to a start index, must not be null; upon entry
+ to the function its value is the index into the original string at which to
+ start searching for the \p from substring, the value must be non-negative
+ and not greater than the original string's length; upon exit from the
+ function its value is the index into the original string at which the
+ replacement took place or -1 if no replacement took place
+
+ @since LibreOffice 5.1
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceFirstToAsciiL(
+ rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
+ char const * to, sal_Int32 toLength, sal_Int32 * index)
+ SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing the first occurrence of a given substring
+ with another substring.
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p fromLength ASCII bytes
+
+ @param fromLength the length of the \p from substring; must be non-negative
+
+ @param to pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p toLength ASCII bytes
+
+ @param toLength the length of the \p to substring; must be non-negative
+
+ @param[in,out] index pointer to a start index, must not be null; upon entry
+ to the function its value is the index into the original string at which to
+ start searching for the \p from substring, the value must be non-negative
+ and not greater than the original string's length; upon exit from the
+ function its value is the index into the original string at which the
+ replacement took place or -1 if no replacement took place
+
+ @since LibreOffice 3.6
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceFirstAsciiLAsciiL(
+ rtl_uString ** newStr, rtl_uString * str, char const * from,
+ sal_Int32 fromLength, char const * to, sal_Int32 toLength,
+ sal_Int32 * index) SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing the first occurrence of a given substring
+ with another substring.
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString; upon return, points to the newly
+ allocated string or to null if there was either an out-of-memory condition
+ or the resulting number of UTF-16 code units would have been larger than
+ SAL_MAX_INT32
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p fromLength ASCII bytes
+
+ @param fromLength the length of the \p from substring; must be non-negative
+
+ @param to pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p toLength UTF-16 code units
+
+ @param toLength the length of the \p to substring; must be non-negative
+
+ @param[in,out] index pointer to a start index, must not be null; upon entry
+ to the function its value is the index into the original string at which to
+ start searching for the \p from substring, the value must be non-negative
+ and not greater than the original string's length; upon exit from the
+ function its value is the index into the original string at which the
+ replacement took place (or would have taken place if \p newStr points to
+ null upon return) or -1 if no replacement took place
+
+ @since LibreOffice 5.3
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceFirstAsciiLUtf16L(
+ rtl_uString ** newStr, rtl_uString * str, char const * from,
+ sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength,
+ sal_Int32 * index) SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing the first occurrence of a given substring
+ with another substring.
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString; upon return, points to the newly
+ allocated string or to null if there was either an out-of-memory condition
+ or the resulting number of UTF-16 code units would have been larger than
+ SAL_MAX_INT32
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p fromLength UTF-16 code units
+
+ @param fromLength the length of the \p from substring; must be non-negative
+
+ @param to pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p toLength ASCII bytes
+
+ @param toLength the length of the \p to substring; must be non-negative
+
+ @param[in,out] index pointer to a start index, must not be null; upon entry
+ to the function its value is the index into the original string at which to
+ start searching for the \p from substring, the value must be non-negative
+ and not greater than the original string's length; upon exit from the
+ function its value is the index into the original string at which the
+ replacement took place (or would have taken place if \p newStr points to
+ null upon return) or -1 if no replacement took place
+
+ @since LibreOffice 5.3
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceFirstUtf16LAsciiL(
+ rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from,
+ sal_Int32 fromLength, char const * to, sal_Int32 toLength,
+ sal_Int32 * index) SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing the first occurrence of a given substring
+ with another substring.
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString; upon return, points to the newly
+ allocated string or to null if there was either an out-of-memory condition
+ or the resulting number of UTF-16 code units would have been larger than
+ SAL_MAX_INT32
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must point to memory of at least
+ \p fromLength UTF-16 code units; may be null if \p toLength is zero
+
+ @param fromLength the length of the \p from substring; must be non-negative
+
+ @param to pointer to the substring to be replaced; must point to memory of at least \p toLength
+ UTF-16 code units; may be null if \p toLength is zero
+
+ @param toLength the length of the \p to substring; must be non-negative
+
+ @param[in,out] index pointer to a start index, must not be null; upon entry
+ to the function its value is the index into the original string at which to
+ start searching for the \p from substring, the value must be non-negative
+ and not greater than the original string's length; upon exit from the
+ function its value is the index into the original string at which the
+ replacement took place (or would have taken place if \p newStr points to
+ null upon return) or -1 if no replacement took place
+
+ @since LibreOffice 5.3
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceFirstUtf16LUtf16L(
+ rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from,
+ sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength,
+ sal_Int32 * index) SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing all occurrences of a given substring with
+ another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null
+
+ @param to pointer to the replacing substring; must not be null
+
+ @since LibreOffice 3.6
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAll(
+ rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
+ rtl_uString const * to) SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing all occurrences of a given substring with
+ another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null
+
+ @param to pointer to the replacing substring; must not be null
+
+ @param fromIndex the position in the string where we will begin searching
+
+ @since LibreOffice 4.0
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllFromIndex(
+ rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
+ rtl_uString const * to, sal_Int32 fromIndex) SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing all occurrences of a given substring with
+ another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p fromLength ASCII bytes
+
+ @param fromLength the length of the \p from substring; must be non-negative
+
+ @param to pointer to the replacing substring; must not be null
+
+ @since LibreOffice 3.6
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllAsciiL(
+ rtl_uString ** newStr, rtl_uString * str, char const * from,
+ sal_Int32 fromLength, rtl_uString const * to) SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing all occurrences of a given substring with
+ another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null
+
+ @param to pointer to the replacing substring; must not be null and must
+ point to memory of at least \p toLength ASCII bytes
+
+ @param toLength the length of the \p to substring; must be non-negative
+
+ @since LibreOffice 5.1
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllToAsciiL(
+ rtl_uString ** newStr, rtl_uString * str, rtl_uString const * from,
+ char const * to, sal_Int32 toLength) SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing all occurrences of a given substring with
+ another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p fromLength ASCII bytes
+
+ @param fromLength the length of the \p from substring; must be non-negative
+
+ @param to pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p toLength ASCII bytes
+
+ @param toLength the length of the \p to substring; must be non-negative
+
+ @since LibreOffice 3.6
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllAsciiLAsciiL(
+ rtl_uString ** newStr, rtl_uString * str, char const * from,
+ sal_Int32 fromLength, char const * to, sal_Int32 toLength)
+ SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing all occurrences of a given substring with
+ another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString; upon return, points to the newly
+ allocated string or to null if there was either an out-of-memory condition
+ or the resulting number of UTF-16 code units would have been larger than
+ SAL_MAX_INT32
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p fromLength ASCII bytes
+
+ @param fromLength the length of the \p from substring; must be non-negative
+
+ @param to pointer to the substring to be replaced; must point to memory of at least \p toLength
+ UTF-16 code units; may be null if \p toLength is zero
+
+ @param toLength the length of the \p to substring; must be non-negative
+
+ @since LibreOffice 3.6
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllAsciiLUtf16L(
+ rtl_uString ** newStr, rtl_uString * str, char const * from,
+ sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength)
+ SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing all occurrences of a given substring with
+ another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString; upon return, points to the newly
+ allocated string or to null if there was either an out-of-memory condition
+ or the resulting number of UTF-16 code units would have been larger than
+ SAL_MAX_INT32
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p fromLength UTF-16 code units
+
+ @param fromLength the length of the \p from substring; must be non-negative
+
+ @param to pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p toLength ASCII bytes
+
+ @param toLength the length of the \p to substring; must be non-negative
+
+ @since LibreOffice 3.6
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllUtf16LAsciiL(
+ rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from,
+ sal_Int32 fromLength, char const * to, sal_Int32 toLength)
+ SAL_THROW_EXTERN_C();
+
+/** Create a new string by replacing all occurrences of a given substring with
+ another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString; upon return, points to the newly
+ allocated string or to null if there was either an out-of-memory condition
+ or the resulting number of UTF-16 code units would have been larger than
+ SAL_MAX_INT32
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p fromLength UTF-16 code units
+
+ @param fromLength the length of the \p from substring; must be non-negative
+
+ @param to pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p toLength UTF-16 code units
+
+ @param toLength the length of the \p to substring; must be non-negative
+
+ @since LibreOffice 3.6
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllUtf16LUtf16L(
+ rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from,
+ sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength)
+ SAL_THROW_EXTERN_C();
+
+#if defined LIBO_INTERNAL_ONLY
+/** Create a new string by replacing all occurrences of a given substring with
+ another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param[in, out] newStr pointer to the new string; must not be null; must
+ point to null or a valid rtl_uString; upon return, points to the newly
+ allocated string or to null if there was either an out-of-memory condition
+ or the resulting number of UTF-16 code units would have been larger than
+ SAL_MAX_INT32
+
+ @param str pointer to the original string; must not be null
+
+ @param from pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p fromLength UTF-16 code units
+
+ @param fromLength the length of the \p from substring; must be non-negative
+
+ @param to pointer to the substring to be replaced; must not be null and
+ must point to memory of at least \p toLength UTF-16 code units
+
+ @param toLength the length of the \p to substring; must be non-negative
+
+ @param fromIndex the position in the string where we will begin searching
+
+ @since LibreOffice 7.1
+*/
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newReplaceAllFromIndexUtf16LUtf16L(
+ rtl_uString ** newStr, rtl_uString * str, sal_Unicode const * from,
+ sal_Int32 fromLength, sal_Unicode const * to, sal_Int32 toLength, sal_Int32 fromIndex)
+ SAL_THROW_EXTERN_C();
+#endif
+
+/** Create a new string by converting all ASCII uppercase letters to lowercase
+ within another string.
+
+ The new string results from replacing all characters with values between
+ 65 and 90 (ASCII A--Z) by values between 97 and 122 (ASCII a--z).
+
+ This function cannot be used for language-specific conversion. The new
+ string does not necessarily have a reference count of 1 (in cases where
+ no characters need to be converted), so it must not be modified without
+ checking the reference count. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param str
+ a valid string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newToAsciiLowerCase(
+ rtl_uString ** newStr, rtl_uString * str ) SAL_THROW_EXTERN_C();
+
+/** Create a new string by converting all ASCII lowercase letters to uppercase
+ within another string.
+
+ The new string results from replacing all characters with values between
+ 97 and 122 (ASCII a--z) by values between 65 and 90 (ASCII A--Z).
+
+ This function cannot be used for language-specific conversion. The new
+ string does not necessarily have a reference count of 1 (in cases where
+ no characters need to be converted), so it must not be modified without
+ checking the reference count. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param str
+ a valid string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newToAsciiUpperCase(
+ rtl_uString ** newStr, rtl_uString * str ) SAL_THROW_EXTERN_C();
+
+/** Create a new string by removing white space from both ends of another
+ string.
+
+ The new string results from removing all characters with values less than
+ or equal to 32 (the space character), and also Unicode General Punctuation
+ area Space and some Control characters, form both ends of str (see
+ implIsWhitespace).
+
+ This function cannot be used for language-specific conversion. The new
+ string does not necessarily have a reference count of 1 (in cases where
+ no characters need to be removed), so it must not be modified without
+ checking the reference count. This function does not handle out-of-memory
+ conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param str
+ a valid string.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newTrim(
+ rtl_uString ** newStr, rtl_uString * str ) SAL_THROW_EXTERN_C();
+
+/** Create a new string by extracting a single token from another string.
+
+ Starting at index, the token's next token is searched for. If there is no
+ such token, the result is an empty string. Otherwise, all characters from
+ the start of that token and up to, but not including the next occurrence
+ of cTok make up the resulting token. The return value is the position of
+ the next token, or -1 if no more tokens follow.
+
+ Example code could look like
+ rtl_uString * pToken = NULL;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ...
+ nIndex = rtl_uString_getToken(&pToken, pStr, 0, ';', nIndex);
+ ...
+ }
+ while (nIndex >= 0);
+
+ The new string does not necessarily have a reference count of 1, so it
+ must not be modified without checking the reference count. This function
+ does not handle out-of-memory conditions.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string. If either token or index is negative, an empty token is stored in
+ newStr (and -1 is returned).
+
+ @param str
+ a valid string.
+
+ @param token
+ the number of the token to return, starting at index.
+
+ @param cTok
+ the character that separates the tokens.
+
+ @param idx
+ the position at which searching for the token starts. Must not be greater
+ than the length of str.
+
+ @return
+ the index of the next token, or -1 if no more tokens follow.
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_uString_getToken(
+ rtl_uString ** newStr , rtl_uString * str, sal_Int32 token, sal_Unicode cTok, sal_Int32 idx ) SAL_THROW_EXTERN_C();
+
+/* ======================================================================= */
+
+/** Supply an ASCII string literal together with its length and text encoding.
+
+ This macro can be used to compute (some of) the arguments in function calls
+ like rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("foo")).
+
+ @param constAsciiStr
+ must be an expression of type "(possibly cv-qualified reference to) array of
+ (possibly cv-qualified) char." Each element of the referenced array must
+ represent an ASCII value in the range 0x00--0x7F. The last element of the
+ referenced array is not considered part of the represented ASCII string, and
+ its value should be 0x00. Depending on where this macro is used, the nature
+ of the supplied expression might be further restricted.
+*/
+// The &foo[0] trick is intentional, it makes sure the type is char* or const char*
+// (plain cast to const char* would not work with non-const char foo[]="a", which seems to be allowed).
+// This is to avoid mistaken use with functions that accept string literals
+// (i.e. const char (&)[N]) where usage of this macro otherwise could match
+// the argument and a following int argument with a default value (e.g. OUString::match()).
+#define RTL_CONSTASCII_USTRINGPARAM( constAsciiStr ) (&(constAsciiStr)[0]), \
+ ((sal_Int32)(SAL_N_ELEMENTS(constAsciiStr)-1)), RTL_TEXTENCODING_ASCII_US
+
+/* ======================================================================= */
+
+/* predefined constants for String-Conversion */
+#define OSTRING_TO_OUSTRING_CVTFLAGS (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MAPTOPRIVATE |\
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |\
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT)
+
+/* ----------------------------------------------------------------------- */
+
+/** Create a new Unicode string by converting a byte string, using a specific
+ text encoding.
+
+ The lengths of the byte string and the Unicode string may differ (e.g.,
+ for double-byte encodings, UTF-7, UTF-8).
+
+ If the length of the byte string is greater than zero, the reference count
+ of the new string will be 1.
+
+ If an out-of-memory condition occurs, newStr will point to a null pointer
+ upon return.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ @param str
+ a byte character array. Need not be null-terminated, but must be at
+ least as long as the specified len.
+
+ @param len
+ the length of the byte character array.
+
+ @param encoding
+ the text encoding to use for conversion.
+
+ @param convertFlags
+ flags which control the conversion. Either use
+ OSTRING_TO_OUSTRING_CVTFLAGS, or see
+ <http://udk.openoffice.org/cpp/man/spec/textconversion.html> for more
+ details.
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_string2UString(
+ rtl_uString ** newStr, const char * str, sal_Int32 len, rtl_TextEncoding encoding, sal_uInt32 convertFlags ) SAL_THROW_EXTERN_C();
+
+/* ======================================================================= */
+/* Interning methods */
+
+/** Return a canonical representation for a string.
+
+ A pool of strings, initially empty is maintained privately
+ by the string class. On invocation, if present in the pool
+ the original string will be returned. Otherwise this string,
+ or a copy thereof will be added to the pool and returned.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ If an out-of-memory condition occurs, newStr will point to a null pointer
+ upon return.
+
+ @param str
+ pointer to the string to be interned.
+
+ @since UDK 3.2.7
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_intern(
+ rtl_uString ** newStr, rtl_uString * str) SAL_THROW_EXTERN_C();
+
+/** Return a canonical representation for a string.
+
+ A pool of strings, initially empty is maintained privately
+ by the string class. On invocation, if present in the pool
+ the original string will be returned. Otherwise this string,
+ or a copy thereof will be added to the pool and returned.
+
+ @param newStr
+ pointer to the new string. The pointed-to data must be null or a valid
+ string.
+
+ If an out-of-memory condition occurs, newStr will point to a null pointer
+ upon return.
+
+ @param str
+ a byte character array. Need not be null-terminated, but must be at
+ least as long as the specified len.
+
+ @param len
+ the length of the byte character array.
+
+ @param encoding
+ the text encoding to use for conversion.
+
+ @param convertFlags
+ flags which control the conversion. Either use
+ OSTRING_TO_OUSTRING_CVTFLAGS, or see
+ <http://udk.openoffice.org/cpp/man/spec/textconversion.html> for more
+ details.
+
+ @param pInfo
+ pointer to return conversion status in, or NULL.
+
+ @since UDK 3.2.7
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_internConvert(
+ rtl_uString ** newStr,
+ const char * str,
+ sal_Int32 len,
+ rtl_TextEncoding encoding,
+ sal_uInt32 convertFlags,
+ sal_uInt32 *pInfo) SAL_THROW_EXTERN_C();
+
+/** Iterate through a string based on code points instead of UTF-16 code units.
+
+ See Chapter 3 of The Unicode Standard 5.0 (Addison--Wesley, 2006) for
+ definitions of the various terms used in this description.
+
+ The given string is interpreted as a sequence of zero or more UTF-16 code
+ units. For each index into this sequence (from zero to one less than the
+ length of the sequence, inclusive), a code point represented starting at the
+ given index is computed as follows:
+
+ - If the UTF-16 code unit addressed by the index constitutes a well-formed
+ UTF-16 code unit sequence, the computed code point is the scalar value
+ encoded by that UTF-16 code unit sequence.
+
+ - Otherwise, if the index is at least two UTF-16 code units away from the
+ end of the sequence, and the sequence of two UTF-16 code units addressed by
+ the index constitutes a well-formed UTF-16 code unit sequence, the computed
+ code point is the scalar value encoded by that UTF-16 code unit sequence.
+
+ - Otherwise, the computed code point is the UTF-16 code unit addressed by
+ the index. (This last case catches unmatched surrogates as well as indices
+ pointing into the middle of surrogate pairs.)
+
+ @param string
+ pointer to a valid string; must not be null.
+
+ @param indexUtf16
+ pointer to a UTF-16 based index into the given string; must not be null. On
+ entry, the index must be in the range from zero to the length of the string
+ (in UTF-16 code units), inclusive. Upon successful return, the index will
+ be updated to address the UTF-16 code unit that is the given
+ incrementCodePoints away from the initial index.
+
+ @param incrementCodePoints
+ the number of code points to move the given *indexUtf16. If non-negative,
+ moving is done after determining the code point at the index. If negative,
+ moving is done before determining the code point at the (then updated)
+ index. The value must be such that the resulting UTF-16 based index is in
+ the range from zero to the length of the string (in UTF-16 code units),
+ inclusive.
+
+ @return
+ the code point (an integer in the range from 0 to 0x10FFFF, inclusive) that
+ is represented within the string starting at the index computed as follows:
+ If incrementCodePoints is non-negative, the index is the initial value of
+ *indexUtf16; if incrementCodePoints is negative, the index is the updated
+ value of *indexUtf16. In either case, the computed index must be in the
+ range from zero to one less than the length of the string (in UTF-16 code
+ units), inclusive.
+
+ @since UDK 3.2.7
+*/
+SAL_DLLPUBLIC sal_uInt32 SAL_CALL rtl_uString_iterateCodePoints(
+ rtl_uString const * string, sal_Int32 * indexUtf16,
+ sal_Int32 incrementCodePoints);
+
+/** Converts a byte string to a Unicode string, signalling failure.
+
+ @param target
+ An out parameter receiving the converted string. Must not be null itself,
+ and must contain either null or a pointer to a valid rtl_uString; the
+ contents are unspecified if conversion fails (rtl_convertStringToUString
+ returns false).
+
+ @param source
+ The byte string. May only be null if length is zero.
+
+ @param length
+ The length of the byte string. Must be non-negative.
+
+ @param encoding
+ The text encoding to convert from. Must be an octet encoding (i.e.,
+ rtl_isOctetTextEncoding(encoding) must return true).
+
+ @param flags
+ A combination of RTL_TEXTTOUNICODE_FLAGS that detail how to do the
+ conversion (see rtl_convertTextToUnicode). RTL_TEXTTOUNICODE_FLAGS_FLUSH
+ need not be included, it is implicitly assumed. Typical uses are either
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR (fail if a byte or multi-byte sequence
+ cannot be converted from the source encoding) or
+ OSTRING_TO_OUSTRING_CVTFLAGS (make a best efforts conversion).
+
+ @return
+ True if the conversion succeeded, false otherwise.
+
+ @since UDK 3.2.9
+*/
+SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_convertStringToUString(
+ rtl_uString ** target, char const * source, sal_Int32 length,
+ rtl_TextEncoding encoding, sal_uInt32 flags) SAL_THROW_EXTERN_C();
+
+/** Ensure a string has enough space for a given number of characters.
+
+ If the given string is large enough and has refcount of 1, it is not altered in any way.
+ Otherwise it is replaced by a copy that has enough space for the given number of characters,
+ data from the source string is copied to the beginning of it, the content of the remaining
+ capacity undefined, the string has refcount of 1, and refcount of the original string is decreased.
+
+ @param str
+ pointer to the string. The pointed-to data must be a valid string.
+
+ @param size
+ the number of characters
+
+ @since LibreOffice 4.1
+ @internal
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_ensureCapacity( rtl_uString ** str, sal_Int32 size ) SAL_THROW_EXTERN_C();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_RTL_USTRING_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/ustring.hxx b/include/rtl/ustring.hxx
new file mode 100644
index 0000000000..c32a083f10
--- /dev/null
+++ b/include/rtl/ustring.hxx
@@ -0,0 +1,3613 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+
+#ifndef INCLUDED_RTL_USTRING_HXX
+#define INCLUDED_RTL_USTRING_HXX
+
+#include "sal/config.h"
+
+#include <cassert>
+#include <cstddef>
+#include <cstdlib>
+#include <limits>
+#include <new>
+#include <ostream>
+#include <utility>
+
+#if defined LIBO_INTERNAL_ONLY
+#include <algorithm>
+#include <string_view>
+#include <type_traits>
+#endif
+
+#include "rtl/math.h"
+#include "rtl/ustring.h"
+#include "rtl/string.hxx"
+#include "rtl/stringutils.hxx"
+#include "rtl/textenc.h"
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+#include "config_global.h"
+#include "o3tl/safeint.hxx"
+#include "rtl/stringconcat.hxx"
+#endif
+
+#ifdef RTL_STRING_UNITTEST
+extern bool rtl_string_unittest_invalid_conversion;
+#endif
+
+// The unittest uses slightly different code to help check that the proper
+// calls are made. The class is put into a different namespace to make
+// sure the compiler generates a different (if generating also non-inline)
+// copy of the function and does not merge them together. The class
+// is "brought" into the proper rtl namespace by a typedef below.
+#ifdef RTL_STRING_UNITTEST
+#define rtl rtlunittest
+#endif
+
+namespace rtl
+{
+
+class OUStringBuffer;
+
+#ifdef RTL_STRING_UNITTEST
+#undef rtl
+#endif
+
+#if defined LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+/// @cond INTERNAL
+
+/**
+A wrapper dressing a string literal as a static-refcount rtl_uString.
+
+This class is not part of public API and is meant to be used only in LibreOffice code.
+@since LibreOffice 4.0
+*/
+template<std::size_t N> class SAL_WARN_UNUSED OUStringLiteral {
+ static_assert(N != 0);
+ static_assert(N - 1 <= std::numeric_limits<sal_Int32>::max(), "literal too long");
+
+public:
+#if HAVE_CPP_CONSTEVAL
+ consteval
+#else
+ constexpr
+#endif
+ OUStringLiteral(char16_t const (&literal)[N]) {
+ assertLayout();
+ assert(literal[N - 1] == '\0');
+ std::copy_n(literal, N, more.buffer);
+ }
+
+ constexpr sal_Int32 getLength() const { return more.length; }
+
+ constexpr sal_Unicode const * getStr() const SAL_RETURNS_NONNULL { return more.buffer; }
+
+ constexpr operator std::u16string_view() const { return {more.buffer, sal_uInt32(more.length)}; }
+
+private:
+ static constexpr void assertLayout() {
+ // These static_asserts verifying the layout compatibility with rtl_uString cannot be class
+ // member declarations, as offsetof requires a complete type, so defer them to here:
+ static_assert(std::is_standard_layout_v<OUStringLiteral>);
+ static_assert(offsetof(OUStringLiteral, str.refCount) == offsetof(OUStringLiteral, more.refCount));
+ static_assert(offsetof(OUStringLiteral, str.length) == offsetof(OUStringLiteral, more.length));
+ static_assert(offsetof(OUStringLiteral, str.buffer) == offsetof(OUStringLiteral, more.buffer));
+ }
+
+ struct Data {
+ Data() = default;
+
+ oslInterlockedCount refCount = 0x40000000; // SAL_STRING_STATIC_FLAG (sal/rtl/strimp.hxx)
+ sal_Int32 length = N - 1;
+ sal_Unicode buffer[N];
+ };
+
+public:
+ // (Data members must be public so that OUStringLiteral is a structural type that can be used as
+ // a non-type template parameter type for operator ""_ustr:)
+ union {
+ rtl_uString str;
+ Data more = {};
+ };
+};
+
+#if defined RTL_STRING_UNITTEST
+namespace libreoffice_internal {
+template<std::size_t N> struct ExceptConstCharArrayDetector<OUStringLiteral<N>> {};
+template<std::size_t N> struct ExceptCharArrayDetector<OUStringLiteral<N>> {};
+}
+#endif
+
+/// @endcond
+#endif
+
+/* ======================================================================= */
+
+/**
+ This String class provides base functionality for C++ like Unicode
+ character array handling. The advantage of this class is that it
+ handles all the memory management for you - and it does it
+ more efficiently. If you assign a string to another string, the
+ data of both strings are shared (without any copy operation or
+ memory allocation) as long as you do not change the string. This class
+ also stores the length of the string, so that many operations are
+ faster than the C-str-functions.
+
+ This class provides only readonly string handling. So you could create
+ a string and you could only query the content from this string.
+ It provides also functionality to change the string, but this results
+ in every case in a new string instance (in the most cases with a
+ memory allocation). You don't have functionality to change the
+ content of the string. If you want to change the string content, then
+ you should use the OStringBuffer class, which provides these
+ functionalities and avoids too much memory allocation.
+
+ The design of this class is similar to the string classes in Java so
+ less people should have understanding problems when they use this class.
+*/
+
+class SAL_WARN_UNUSED SAL_DLLPUBLIC_RTTI OUString
+{
+public:
+ /// @cond INTERNAL
+ rtl_uString * pData;
+ /// @endcond
+
+ /**
+ New string containing no characters.
+ */
+ OUString()
+ {
+ pData = NULL;
+ rtl_uString_new( &pData );
+ }
+
+ /**
+ New string from OUString.
+
+ @param str an OUString.
+ */
+#if defined LIBO_INTERNAL_ONLY && !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ constexpr
+#endif
+ OUString( const OUString & str )
+ {
+ pData = str.pData;
+#if defined LIBO_INTERNAL_ONLY && !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ if (std::is_constant_evaluated()) {
+ //TODO: We would want to
+ //
+ // assert(SAL_STRING_IS_STATIC(pData));
+ //
+ // here, but that wouldn't work because read of member `str` of OUStringLiteral's
+ // anonymous union with active member `more` is not allowed in a constant expression.
+ } else
+#endif
+ rtl_uString_acquire( pData );
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /**
+ Move constructor.
+
+ @param str an OUString.
+ @since LibreOffice 5.2
+ */
+#if !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ constexpr
+#endif
+ OUString( OUString && str ) noexcept
+ {
+ pData = str.pData;
+#if !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ if (std::is_constant_evaluated()) {
+ //TODO: We would want to
+ //
+ // assert(SAL_STRING_IS_STATIC(pData));
+ //
+ // here, but that wouldn't work because read of member `str` of OUStringLiteral's
+ // anonymous union with active member `more` is not allowed in a constant expression.
+ return;
+ }
+#endif
+ str.pData = nullptr;
+ rtl_uString_new( &str.pData );
+ }
+#endif
+
+ /**
+ New string from OUString data.
+
+ @param str an OUString data.
+ */
+ OUString( rtl_uString * str )
+ {
+ pData = str;
+ rtl_uString_acquire( pData );
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /// @cond INTERNAL
+ // Catch inadvertent conversions to the above ctor:
+ OUString(std::nullptr_t) = delete;
+ /// @endcond
+#endif
+
+ /** New OUString from OUString data without acquiring it. Takeover of ownership.
+
+ The SAL_NO_ACQUIRE dummy parameter is only there to distinguish this
+ from other constructors.
+
+ @param str
+ OUString data
+ */
+ OUString( rtl_uString * str, __sal_NoAcquire )
+ { pData = str; }
+
+ /**
+ New string from a single Unicode character.
+
+ @param value a Unicode character.
+ */
+ explicit OUString( sal_Unicode value )
+ : pData (NULL)
+ {
+ rtl_uString_newFromStr_WithLength( &pData, &value, 1 );
+ }
+
+#if defined LIBO_INTERNAL_ONLY && !defined RTL_STRING_UNITTEST_CONCAT
+ /// @cond INTERNAL
+ // Catch inadvertent conversions to the above ctor (but still allow
+ // construction from char literals):
+ OUString(int) = delete;
+ explicit OUString(char c):
+ OUString(sal_Unicode(static_cast<unsigned char>(c)))
+ {}
+ /// @endcond
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+
+ template<typename T> explicit OUString(
+ T const & value,
+ typename libreoffice_internal::CharPtrDetector<T, libreoffice_internal::Dummy>::TypeUtf16
+ = libreoffice_internal::Dummy()):
+ pData(nullptr)
+ { rtl_uString_newFromStr(&pData, value); }
+
+ template<typename T> explicit OUString(
+ T & value,
+ typename
+ libreoffice_internal::NonConstCharArrayDetector<T, libreoffice_internal::Dummy>::TypeUtf16
+ = libreoffice_internal::Dummy()):
+ pData(nullptr)
+ { rtl_uString_newFromStr(&pData, value); }
+
+#else
+
+ /**
+ New string from a Unicode character buffer array.
+
+ @param value a NULL-terminated Unicode character array.
+ */
+ OUString( const sal_Unicode * value )
+ {
+ pData = NULL;
+ rtl_uString_newFromStr( &pData, value );
+ }
+
+#endif
+
+ /**
+ New string from a Unicode character buffer array.
+
+ @param value a Unicode character array.
+ @param length the number of character which should be copied.
+ The character array length must be greater than
+ or equal to this value.
+ */
+ OUString( const sal_Unicode * value, sal_Int32 length )
+ {
+ pData = NULL;
+ rtl_uString_newFromStr_WithLength( &pData, value, length );
+ }
+
+ /**
+ New string from an 8-Bit string literal that is expected to contain only
+ characters in the ASCII set (i.e. first 128 characters). This constructor
+ allows an efficient and convenient way to create OUString
+ instances from ASCII literals. When creating strings from data that
+ is not pure ASCII, it needs to be converted to OUString by explicitly
+ providing the encoding to use for the conversion.
+
+ If there are any embedded \0's in the string literal, the result is undefined.
+ Use the overload that explicitly accepts length.
+
+ @param literal the 8-bit ASCII string literal
+
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ OUString( T& literal, typename libreoffice_internal::ConstCharArrayDetector< T, libreoffice_internal::Dummy >::Type = libreoffice_internal::Dummy() )
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ pData = NULL;
+ if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) {
+ rtl_uString_new(&pData);
+ } else {
+ rtl_uString_newFromLiteral(
+ &pData,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length, 0);
+ }
+#ifdef RTL_STRING_UNITTEST
+ rtl_string_unittest_const_literal = true;
+#endif
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ // Rather use a u""_ustr literal (but don't remove this entirely, to avoid implicit support for
+ // it via std::u16string_view from kicking in):
+ template<typename T> OUString(
+ T &,
+ typename libreoffice_internal::ConstCharArrayDetector<
+ T, libreoffice_internal::Dummy>::TypeUtf16
+ = libreoffice_internal::Dummy()) = delete;
+
+ OUString(OUStringChar c): pData(nullptr) { rtl_uString_newFromStr_WithLength(&pData, &c.c, 1); }
+#endif
+
+#if defined LIBO_INTERNAL_ONLY && defined RTL_STRING_UNITTEST
+ /// @cond INTERNAL
+ /**
+ * Only used by unittests to detect incorrect conversions.
+ * @internal
+ */
+ template< typename T >
+ OUString( T&, typename libreoffice_internal::ExceptConstCharArrayDetector< T >::Type = libreoffice_internal::Dummy() )
+ {
+ pData = NULL;
+ rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage
+ rtl_string_unittest_invalid_conversion = true;
+ }
+ /**
+ * Only used by unittests to detect incorrect conversions.
+ * @internal
+ */
+ template< typename T >
+ OUString( const T&, typename libreoffice_internal::ExceptCharArrayDetector< T >::Type = libreoffice_internal::Dummy() )
+ {
+ pData = NULL;
+ rtl_uString_newFromLiteral( &pData, "!!br0ken!!", 10, 0 ); // set to garbage
+ rtl_string_unittest_invalid_conversion = true;
+ }
+ /// @endcond
+#endif
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ /// @cond INTERNAL
+ /**
+ New string from a string literal.
+
+ @since LibreOffice 5.0
+ */
+ template<std::size_t N> constexpr OUString(OUStringLiteral<N> const & literal):
+ pData(const_cast<rtl_uString *>(&literal.str)) {}
+ template<std::size_t N> OUString(OUStringLiteral<N> &&) = delete;
+ /// @endcond
+#endif
+
+#if defined LIBO_INTERNAL_ONLY && !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ // For operator ""_tstr:
+ template<OStringLiteral L> OUString(detail::OStringHolder<L> const & holder) {
+ pData = nullptr;
+ if (holder.literal.getLength() == 0) {
+ rtl_uString_new(&pData);
+ } else {
+ rtl_uString_newFromLiteral(
+ &pData, holder.literal.getStr(), holder.literal.getLength(), 0);
+ }
+ }
+#endif
+
+ /**
+ New string from an 8-Bit character buffer array.
+
+ @param value An 8-Bit character array.
+ @param length The number of character which should be converted.
+ The 8-Bit character array length must be
+ greater than or equal to this value.
+ @param encoding The text encoding from which the 8-Bit character
+ sequence should be converted.
+ @param convertFlags Flags which control the conversion.
+ see RTL_TEXTTOUNICODE_FLAGS_...
+
+ @exception std::bad_alloc is thrown if an out-of-memory condition occurs
+ */
+ OUString( const char * value, sal_Int32 length,
+ rtl_TextEncoding encoding,
+ sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS )
+ {
+ pData = NULL;
+ rtl_string2UString( &pData, value, length, encoding, convertFlags );
+ if (pData == NULL) {
+ throw std::bad_alloc();
+ }
+ }
+
+ /** Create a new string from an array of Unicode code points.
+
+ @param codePoints
+ an array of at least codePointCount code points, which each must be in
+ the range from 0 to 0x10FFFF, inclusive. May be null if codePointCount
+ is zero.
+
+ @param codePointCount
+ the non-negative number of code points.
+
+ @exception std::bad_alloc
+ is thrown if either an out-of-memory condition occurs or the resulting
+ number of UTF-16 code units would have been larger than SAL_MAX_INT32.
+
+ @since UDK 3.2.7
+ */
+ explicit OUString(
+ sal_uInt32 const * codePoints, sal_Int32 codePointCount):
+ pData(NULL)
+ {
+ rtl_uString_newFromCodePoints(&pData, codePoints, codePointCount);
+ if (pData == NULL) {
+ throw std::bad_alloc();
+ }
+ }
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ /**
+ @overload
+ @internal
+ */
+ template< typename T1, typename T2 >
+ OUString( OUStringConcat< T1, T2 >&& c )
+ {
+ const sal_Int32 l = c.length();
+ pData = rtl_uString_alloc( l );
+ if (l != 0)
+ {
+ sal_Unicode* end = c.addData( pData->buffer );
+ pData->length = l;
+ *end = '\0';
+ }
+ }
+
+ /**
+ @overload
+ @internal
+ */
+ template< std::size_t N >
+ OUString( OUStringNumber< N >&& n )
+ : OUString( n.buf, n.length )
+ {}
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+ explicit OUString(std::u16string_view sv) {
+ if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) {
+ throw std::bad_alloc();
+ }
+ pData = nullptr;
+ rtl_uString_newFromStr_WithLength(&pData, sv.data(), sv.size());
+ }
+#endif
+
+ /**
+ Release the string data.
+ */
+#if defined LIBO_INTERNAL_ONLY && !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ constexpr
+#endif
+ ~OUString()
+ {
+#if defined LIBO_INTERNAL_ONLY && !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+ if (std::is_constant_evaluated()) {
+ //TODO: We would want to
+ //
+ // assert(SAL_STRING_IS_STATIC(pData));
+ //
+ // here, but that wouldn't work because read of member `str` of OUStringLiteral's
+ // anonymous union with active member `more` is not allowed in a constant expression.
+ } else
+#endif
+ rtl_uString_release( pData );
+ }
+
+ /** Provides an OUString const & passing a storage pointer of an
+ rtl_uString * handle.
+ It is more convenient to use C++ OUString member functions when dealing
+ with rtl_uString * handles. Using this function avoids unnecessary
+ acquire()/release() calls for a temporary OUString object.
+
+ @param ppHandle
+ pointer to storage
+ @return
+ OUString const & based on given storage
+ */
+ static OUString const & unacquired( rtl_uString * const * ppHandle )
+ { return * reinterpret_cast< OUString const * >( ppHandle ); }
+
+#if defined LIBO_INTERNAL_ONLY
+ /** Provides an OUString const & passing an OUStringBuffer const reference.
+ It is more convenient to use C++ OUString member functions when checking
+ current buffer content. Use this function instead of toString (that
+ allocates a new OUString from buffer data) when the result is used in
+ comparisons.
+
+ @param str
+ an OUStringBuffer
+ @return
+ OUString const & based on given storage
+ @since LibreOffice 7.4
+ */
+ static OUString const& unacquired(const OUStringBuffer& str);
+#endif
+
+ /**
+ Assign a new string.
+
+ @param str an OUString.
+ */
+ OUString & operator=( const OUString & str )
+ {
+ rtl_uString_assign( &pData, str.pData );
+ return *this;
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /**
+ Move assign a new string.
+
+ @param str an OUString.
+ @since LibreOffice 5.2
+ */
+ OUString & operator=( OUString && str ) noexcept
+ {
+ std::swap(pData, str.pData);
+ return *this;
+ }
+#endif
+
+ /**
+ Assign a new string from an 8-Bit string literal that is expected to contain only
+ characters in the ASCII set (i.e. first 128 characters). This operator
+ allows an efficient and convenient way to assign OUString
+ instances from ASCII literals. When assigning strings from data that
+ is not pure ASCII, it needs to be converted to OUString by explicitly
+ providing the encoding to use for the conversion.
+
+ @param literal the 8-bit ASCII string literal
+
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, OUString& >::Type operator=( T& literal )
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ if (libreoffice_internal::ConstCharArrayDetector<T>::length == 0) {
+ rtl_uString_new(&pData);
+ } else {
+ rtl_uString_newFromLiteral(
+ &pData,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length, 0);
+ }
+ return *this;
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ // Rather assign from a u""_ustr literal (but don't remove this entirely, to avoid implicit
+ // support for it via std::u16string_view from kicking in):
+ template<typename T>
+ typename
+ libreoffice_internal::ConstCharArrayDetector<T, OUString &>::TypeUtf16
+ operator =(T &) = delete;
+
+ OUString & operator =(OUStringChar c) {
+ rtl_uString_newFromStr_WithLength(&pData, &c.c, 1);
+ return *this;
+ }
+
+ /** @overload @since LibreOffice 5.4 */
+ template<std::size_t N> OUString & operator =(OUStringLiteral<N> const & literal) {
+ rtl_uString_release(pData);
+ pData = const_cast<rtl_uString *>(&literal.str);
+ return *this;
+ }
+ template<std::size_t N> OUString & operator =(OUStringLiteral<N> &&) = delete;
+
+ template <std::size_t N>
+ OUString & operator =(OUStringNumber<N> && n) {
+ // n.length should never be zero, so no need to add an optimization for that case
+ rtl_uString_newFromStr_WithLength(&pData, n.buf, n.length);
+ return *this;
+ }
+
+ OUString & operator =(std::u16string_view sv) {
+ if (sv.empty()) {
+ rtl_uString_new(&pData);
+ } else {
+ rtl_uString_newFromStr_WithLength(&pData, sv.data(), sv.size());
+ }
+ return *this;
+ }
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+ /**
+ Append the contents of an OUStringBuffer to this string.
+
+ @param str an OUStringBuffer.
+
+ @exception std::bad_alloc is thrown if an out-of-memory condition occurs
+ @since LibreOffice 6.2
+ */
+ inline OUString & operator+=( const OUStringBuffer & str ) &;
+#endif
+
+ /**
+ Append a string to this string.
+
+ @param str an OUString.
+
+ @exception std::bad_alloc is thrown if an out-of-memory condition occurs
+ */
+ OUString & operator+=( const OUString & str )
+#if defined LIBO_INTERNAL_ONLY
+ &
+#endif
+ {
+ return internalAppend(str.pData);
+ }
+#if defined LIBO_INTERNAL_ONLY
+ void operator+=(OUString const &) && = delete;
+#endif
+
+ /** Append an ASCII string literal to this string.
+
+ @param literal an 8-bit ASCII-only string literal
+
+ @since LibreOffice 5.1
+ */
+ template<typename T>
+ typename libreoffice_internal::ConstCharArrayDetector<T, OUString &>::Type
+ operator +=(T & literal)
+#if defined LIBO_INTERNAL_ONLY
+ &
+#endif
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ rtl_uString_newConcatAsciiL(
+ &pData, pData,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ return *this;
+ }
+#if defined LIBO_INTERNAL_ONLY
+ template<typename T>
+ typename libreoffice_internal::ConstCharArrayDetector<T, OUString &>::Type
+ operator +=(T &) && = delete;
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+ /** @overload @since LibreOffice 5.3 */
+ template<typename T>
+ typename
+ libreoffice_internal::ConstCharArrayDetector<T, OUString &>::TypeUtf16
+ operator +=(T & literal) & {
+ rtl_uString_newConcatUtf16L(
+ &pData, pData,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ return *this;
+ }
+ template<typename T>
+ typename
+ libreoffice_internal::ConstCharArrayDetector<T, OUString &>::TypeUtf16
+ operator +=(T &) && = delete;
+
+ /** @overload @since LibreOffice 5.4 */
+ template<std::size_t N> OUString & operator +=(OUStringLiteral<N> const & literal) & {
+ rtl_uString_newConcatUtf16L(&pData, pData, literal.getStr(), literal.getLength());
+ return *this;
+ }
+ template<std::size_t N> void operator +=(OUStringLiteral<N> const &) && = delete;
+
+ OUString & operator +=(std::u16string_view sv) & {
+ if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) {
+ throw std::bad_alloc();
+ }
+ rtl_uString_newConcatUtf16L(&pData, pData, sv.data(), sv.size());
+ return *this;
+ }
+ void operator +=(std::u16string_view) && = delete;
+#endif
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ /**
+ @overload
+ @internal
+ */
+ template< typename T1, typename T2 >
+ OUString& operator+=( OUStringConcat< T1, T2 >&& c ) & {
+ sal_Int32 l = c.length();
+ if( l == 0 )
+ return *this;
+ l += pData->length;
+ rtl_uString_ensureCapacity( &pData, l );
+ sal_Unicode* end = c.addData( pData->buffer + pData->length );
+ *end = '\0';
+ pData->length = l;
+ return *this;
+ }
+ template<typename T1, typename T2> void operator +=(
+ OUStringConcat<T1, T2> &&) && = delete;
+
+ /**
+ @overload
+ @internal
+ */
+ template< std::size_t N >
+ OUString& operator+=( OUStringNumber< N >&& n ) & {
+ sal_Int32 l = n.length;
+ if( l == 0 )
+ return *this;
+ l += pData->length;
+ rtl_uString_ensureCapacity( &pData, l );
+ sal_Unicode* end = addDataHelper( pData->buffer + pData->length, n.buf, n.length );
+ *end = '\0';
+ pData->length = l;
+ return *this;
+ }
+ template<std::size_t N> void operator +=(
+ OUStringNumber<N> &&) && = delete;
+#endif
+
+ /**
+ Clears the string, i.e, makes a zero-character string
+ @since LibreOffice 4.4
+ */
+ void clear()
+ {
+ rtl_uString_new( &pData );
+ }
+
+ /**
+ Returns the length of this string.
+
+ The length is equal to the number of Unicode characters in this string.
+
+ @return the length of the sequence of characters represented by this
+ object.
+ */
+ sal_Int32 getLength() const { return pData->length; }
+
+ /**
+ Checks if a string is empty.
+
+ @return true if the string is empty;
+ false, otherwise.
+
+ @since LibreOffice 3.4
+ */
+ bool isEmpty() const
+ {
+ return pData->length == 0;
+ }
+
+ /**
+ Returns a pointer to the Unicode character buffer for this string.
+
+ It isn't necessarily NULL terminated.
+
+ @return a pointer to the Unicode characters buffer for this object.
+ */
+ const sal_Unicode * getStr() const SAL_RETURNS_NONNULL { return pData->buffer; }
+
+ /**
+ Access to individual characters.
+
+ @param index must be non-negative and less than length.
+
+ @return the character at the given index.
+
+ @since LibreOffice 3.5
+ */
+ sal_Unicode operator [](sal_Int32 index) const {
+ // silence spurious -Werror=strict-overflow warnings from GCC 4.8.2
+ assert(index >= 0 && static_cast<sal_uInt32>(index) < static_cast<sal_uInt32>(getLength()));
+ return getStr()[index];
+ }
+
+ /**
+ Compares two strings.
+
+ The comparison is based on the numeric value of each character in
+ the strings and return a value indicating their relationship.
+ This function can't be used for language specific sorting.
+
+ @param str the object to be compared.
+ @return 0 - if both strings are equal
+ < 0 - if this string is less than the string argument
+ > 0 - if this string is greater than the string argument
+ */
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 compareTo( std::u16string_view str ) const
+ {
+ return rtl_ustr_compare_WithLength( pData->buffer, pData->length,
+ str.data(), str.length() );
+ }
+#else
+ sal_Int32 compareTo( const OUString & str ) const
+ {
+ return rtl_ustr_compare_WithLength( pData->buffer, pData->length,
+ str.pData->buffer, str.pData->length );
+ }
+#endif
+
+ /**
+ Compares two strings with a maximum count of characters.
+
+ The comparison is based on the numeric value of each character in
+ the strings and return a value indicating their relationship.
+ This function can't be used for language specific sorting.
+
+ @param str the object to be compared.
+ @param maxLength the maximum count of characters to be compared.
+ @return 0 - if both strings are equal
+ < 0 - if this string is less than the string argument
+ > 0 - if this string is greater than the string argument
+
+ @since UDK 3.2.7
+ */
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 compareTo( std::u16string_view str, sal_Int32 maxLength ) const
+ {
+ return rtl_ustr_shortenedCompare_WithLength( pData->buffer, pData->length,
+ str.data(), str.length(), maxLength );
+ }
+#else
+ sal_Int32 compareTo( const OUString & str, sal_Int32 maxLength ) const
+ {
+ return rtl_ustr_shortenedCompare_WithLength( pData->buffer, pData->length,
+ str.pData->buffer, str.pData->length, maxLength );
+ }
+#endif
+
+ /**
+ Compares two strings in reverse order.
+
+ The comparison is based on the numeric value of each character in
+ the strings and return a value indicating their relationship.
+ This function can't be used for language specific sorting.
+
+ @param str the object to be compared.
+ @return 0 - if both strings are equal
+ < 0 - if this string is less than the string argument
+ > 0 - if this string is greater than the string argument
+ */
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 reverseCompareTo(std::u16string_view sv) const {
+ return rtl_ustr_reverseCompare_WithLength(
+ pData->buffer, pData->length, sv.data(), sv.size());
+ }
+#else
+ sal_Int32 reverseCompareTo( const OUString & str ) const
+ {
+ return rtl_ustr_reverseCompare_WithLength( pData->buffer, pData->length,
+ str.pData->buffer, str.pData->length );
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 4.1
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type reverseCompareTo( T& literal ) const
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return rtl_ustr_asciil_reverseCompare_WithLength(
+ pData->buffer, pData->length,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+
+ /**
+ Perform a comparison of two strings.
+
+ The result is true if and only if second string
+ represents the same sequence of characters as the first string.
+ This function can't be used for language specific comparison.
+
+ @param str the object to be compared.
+ @return true if the strings are equal;
+ false, otherwise.
+ */
+ bool equals( const OUString & str ) const
+ {
+ if ( pData->length != str.pData->length )
+ return false;
+ if ( pData == str.pData )
+ return true;
+ return rtl_ustr_reverseCompare_WithLength( pData->buffer, pData->length,
+ str.pData->buffer, str.pData->length ) == 0;
+ }
+
+ /**
+ Perform an ASCII lowercase comparison of two strings.
+
+ The result is true if and only if second string
+ represents the same sequence of characters as the first string,
+ ignoring the case.
+ Character values between 65 and 90 (ASCII A-Z) are interpreted as
+ values between 97 and 122 (ASCII a-z).
+ This function can't be used for language specific comparison.
+
+ @param str the object to be compared.
+ @return true if the strings are equal;
+ false, otherwise.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ bool equalsIgnoreAsciiCase(std::u16string_view sv) const {
+ if ( sal_uInt32(pData->length) != sv.size() )
+ return false;
+ if ( pData->buffer == sv.data() )
+ return true;
+ return
+ rtl_ustr_compareIgnoreAsciiCase_WithLength(
+ pData->buffer, pData->length, sv.data(), sv.size())
+ == 0;
+ }
+#else
+ bool equalsIgnoreAsciiCase( const OUString & str ) const
+ {
+ if ( pData->length != str.pData->length )
+ return false;
+ if ( pData == str.pData )
+ return true;
+ return rtl_ustr_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
+ str.pData->buffer, str.pData->length ) == 0;
+ }
+#endif
+
+ /**
+ Perform an ASCII lowercase comparison of two strings.
+
+ Compare the two strings with uppercase ASCII
+ character values between 65 and 90 (ASCII A-Z) interpreted as
+ values between 97 and 122 (ASCII a-z).
+ This function can't be used for language specific comparison.
+
+ @param str the object to be compared.
+ @return 0 - if both strings are equal
+ < 0 - if this string is less than the string argument
+ > 0 - if this string is greater than the string argument
+
+ @since LibreOffice 4.0
+ */
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 compareToIgnoreAsciiCase(std::u16string_view sv) const {
+ return rtl_ustr_compareIgnoreAsciiCase_WithLength(
+ pData->buffer, pData->length, sv.data(), sv.size());
+ }
+#else
+ sal_Int32 compareToIgnoreAsciiCase( const OUString & str ) const
+ {
+ return rtl_ustr_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length,
+ str.pData->buffer, str.pData->length );
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type equalsIgnoreAsciiCase( T& literal ) const
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return
+ (pData->length
+ == libreoffice_internal::ConstCharArrayDetector<T>::length)
+ && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength(
+ pData->buffer, pData->length,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal))
+ == 0);
+ }
+
+ /**
+ Match against a substring appearing in this string.
+
+ The result is true if and only if the second string appears as a substring
+ of this string, at the given position.
+ This function can't be used for language specific comparison.
+
+ @param str the object (substring) to be compared.
+ @param fromIndex the index to start the comparison from.
+ The index must be greater than or equal to 0
+ and less or equal as the string length.
+ @return true if str match with the characters in the string
+ at the given position;
+ false, otherwise.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ bool match(std::u16string_view sv, sal_Int32 fromIndex = 0) const {
+ return
+ rtl_ustr_shortenedCompare_WithLength(
+ pData->buffer + fromIndex, pData->length - fromIndex, sv.data(), sv.size(),
+ sv.size())
+ == 0;
+ }
+#else
+ bool match( const OUString & str, sal_Int32 fromIndex = 0 ) const
+ {
+ return rtl_ustr_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
+ str.pData->buffer, str.pData->length, str.pData->length ) == 0;
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type match( T& literal, sal_Int32 fromIndex = 0 ) const
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return
+ rtl_ustr_ascii_shortenedCompare_WithLength(
+ pData->buffer+fromIndex, pData->length-fromIndex,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length)
+ == 0;
+ }
+
+ /**
+ Match against a substring appearing in this string, ignoring the case of
+ ASCII letters.
+
+ The result is true if and only if the second string appears as a substring
+ of this string, at the given position.
+ Character values between 65 and 90 (ASCII A-Z) are interpreted as
+ values between 97 and 122 (ASCII a-z).
+ This function can't be used for language specific comparison.
+
+ @param str the object (substring) to be compared.
+ @param fromIndex the index to start the comparison from.
+ The index must be greater than or equal to 0
+ and less than or equal to the string length.
+ @return true if str match with the characters in the string
+ at the given position;
+ false, otherwise.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ bool matchIgnoreAsciiCase(std::u16string_view sv, sal_Int32 fromIndex = 0) const {
+ return
+ rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength(
+ pData->buffer + fromIndex, pData->length - fromIndex, sv.data(), sv.size(),
+ sv.size())
+ == 0;
+ }
+#else
+ bool matchIgnoreAsciiCase( const OUString & str, sal_Int32 fromIndex = 0 ) const
+ {
+ return rtl_ustr_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
+ str.pData->buffer, str.pData->length,
+ str.pData->length ) == 0;
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type matchIgnoreAsciiCase( T& literal, sal_Int32 fromIndex = 0 ) const
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return matchIgnoreAsciiCaseAsciiL(
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length, fromIndex);
+ }
+
+ /**
+ Compares two strings.
+
+ The comparison is based on the numeric value of each character in
+ the strings and return a value indicating their relationship.
+ Since this method is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range between 0 and 127.
+ The ASCII string must be NULL-terminated.
+ This function can't be used for language specific sorting.
+
+ @param asciiStr the 8-Bit ASCII character string to be compared.
+ @return 0 - if both strings are equal
+ < 0 - if this string is less than the string argument
+ > 0 - if this string is greater than the string argument
+ */
+ sal_Int32 compareToAscii( const char* asciiStr ) const
+ {
+ return rtl_ustr_ascii_compare_WithLength( pData->buffer, pData->length, asciiStr );
+ }
+
+ /**
+ Compares two strings with a maximum count of characters.
+
+ The comparison is based on the numeric value of each character in
+ the strings and return a value indicating their relationship.
+ Since this method is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range between 0 and 127.
+ The ASCII string must be NULL-terminated.
+ This function can't be used for language specific sorting.
+
+ @deprecated This is a confusing overload with unexpectedly different
+ semantics from the one-parameter form, so it is marked as deprecated.
+ Practically all uses compare the return value against zero and can thus
+ be replaced with uses of startsWith.
+
+ @param asciiStr the 8-Bit ASCII character string to be compared.
+ @param maxLength the maximum count of characters to be compared.
+ @return 0 - if both strings are equal
+ < 0 - if this string is less than the string argument
+ > 0 - if this string is greater than the string argument
+ */
+ SAL_DEPRECATED(
+ "replace s1.compareToAscii(s2, strlen(s2)) == 0 with s1.startsWith(s2)")
+ sal_Int32 compareToAscii( const char * asciiStr, sal_Int32 maxLength ) const
+ {
+ return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer, pData->length,
+ asciiStr, maxLength );
+ }
+
+ /**
+ Compares two strings in reverse order.
+
+ This could be useful, if normally both strings start with the same
+ content. The comparison is based on the numeric value of each character
+ in the strings and return a value indicating their relationship.
+ Since this method is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range between 0 and 127.
+ The ASCII string must be greater than or equal to asciiStrLength.
+ This function can't be used for language specific sorting.
+
+ @param asciiStr the 8-Bit ASCII character string to be compared.
+ @param asciiStrLength the length of the ascii string
+ @return 0 - if both strings are equal
+ < 0 - if this string is less than the string argument
+ > 0 - if this string is greater than the string argument
+ */
+ sal_Int32 reverseCompareToAsciiL( const char * asciiStr, sal_Int32 asciiStrLength ) const
+ {
+ return rtl_ustr_asciil_reverseCompare_WithLength( pData->buffer, pData->length,
+ asciiStr, asciiStrLength );
+ }
+
+ /**
+ Perform a comparison of two strings.
+
+ The result is true if and only if second string
+ represents the same sequence of characters as the first string.
+ Since this method is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range between 0 and 127.
+ The ASCII string must be NULL-terminated.
+ This function can't be used for language specific comparison.
+
+ @param asciiStr the 8-Bit ASCII character string to be compared.
+ @return true if the strings are equal;
+ false, otherwise.
+ */
+ bool equalsAscii( const char* asciiStr ) const
+ {
+ return rtl_ustr_ascii_compare_WithLength( pData->buffer, pData->length,
+ asciiStr ) == 0;
+ }
+
+ /**
+ Perform a comparison of two strings.
+
+ The result is true if and only if second string
+ represents the same sequence of characters as the first string.
+ Since this method is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range between 0 and 127.
+ The ASCII string must be greater than or equal to asciiStrLength.
+ This function can't be used for language specific comparison.
+
+ @param asciiStr the 8-Bit ASCII character string to be compared.
+ @param asciiStrLength the length of the ascii string
+ @return true if the strings are equal;
+ false, otherwise.
+ */
+ bool equalsAsciiL( const char* asciiStr, sal_Int32 asciiStrLength ) const
+ {
+ if ( pData->length != asciiStrLength )
+ return false;
+
+ return rtl_ustr_asciil_reverseEquals_WithLength(
+ pData->buffer, asciiStr, asciiStrLength );
+ }
+
+ /**
+ Perform an ASCII lowercase comparison of two strings.
+
+ The result is true if and only if second string
+ represents the same sequence of characters as the first string,
+ ignoring the case.
+ Character values between 65 and 90 (ASCII A-Z) are interpreted as
+ values between 97 and 122 (ASCII a-z).
+ Since this method is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range between 0 and 127.
+ The ASCII string must be NULL-terminated.
+ This function can't be used for language specific comparison.
+
+ @param asciiStr the 8-Bit ASCII character string to be compared.
+ @return true if the strings are equal;
+ false, otherwise.
+ */
+ bool equalsIgnoreAsciiCaseAscii( const char * asciiStr ) const
+ {
+ return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ) == 0;
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ bool equalsIgnoreAsciiCaseAscii( std::string_view asciiStr ) const
+ {
+ return o3tl::make_unsigned(pData->length) == asciiStr.length()
+ && rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
+ pData->buffer, pData->length, asciiStr.data(), asciiStr.length()) == 0;
+ }
+#endif
+
+ /**
+ Compares two ASCII strings ignoring case
+
+ The comparison is based on the numeric value of each character in
+ the strings and return a value indicating their relationship.
+ Since this method is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range between 0 and 127.
+ The ASCII string must be NULL-terminated.
+ This function can't be used for language specific sorting.
+
+ @param asciiStr the 8-Bit ASCII character string to be compared.
+ @return 0 - if both strings are equal
+ < 0 - if this string is less than the string argument
+ > 0 - if this string is greater than the string argument
+
+ @since LibreOffice 3.5
+ */
+ sal_Int32 compareToIgnoreAsciiCaseAscii( const char * asciiStr ) const
+ {
+ return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr );
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 compareToIgnoreAsciiCaseAscii( std::string_view asciiStr ) const
+ {
+ sal_Int32 nMax = std::min<size_t>(asciiStr.length(), std::numeric_limits<sal_Int32>::max());
+ sal_Int32 result = rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
+ pData->buffer, pData->length, asciiStr.data(), nMax);
+ if (result == 0 && o3tl::make_unsigned(pData->length) < asciiStr.length())
+ result = -1;
+ return result;
+ }
+#endif
+
+ /**
+ Perform an ASCII lowercase comparison of two strings.
+
+ The result is true if and only if second string
+ represents the same sequence of characters as the first string,
+ ignoring the case.
+ Character values between 65 and 90 (ASCII A-Z) are interpreted as
+ values between 97 and 122 (ASCII a-z).
+ Since this method is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range between 0 and 127.
+ The ASCII string must be greater than or equal to asciiStrLength.
+ This function can't be used for language specific comparison.
+
+ @param asciiStr the 8-Bit ASCII character string to be compared.
+ @param asciiStrLength the length of the ascii string
+ @return true if the strings are equal;
+ false, otherwise.
+ */
+ bool equalsIgnoreAsciiCaseAsciiL( const char * asciiStr, sal_Int32 asciiStrLength ) const
+ {
+ if ( pData->length != asciiStrLength )
+ return false;
+
+ return rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pData->buffer, pData->length, asciiStr ) == 0;
+ }
+
+ /**
+ Match against a substring appearing in this string.
+
+ The result is true if and only if the second string appears as a substring
+ of this string, at the given position.
+ Since this method is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range between 0 and 127.
+ The ASCII string must be greater than or equal to asciiStrLength.
+ This function can't be used for language specific comparison.
+
+ @param asciiStr the object (substring) to be compared.
+ @param asciiStrLength the length of asciiStr.
+ @param fromIndex the index to start the comparison from.
+ The index must be greater than or equal to 0
+ and less than or equal to the string length.
+ @return true if str match with the characters in the string
+ at the given position;
+ false, otherwise.
+ */
+ bool matchAsciiL( const char* asciiStr, sal_Int32 asciiStrLength, sal_Int32 fromIndex = 0 ) const
+ {
+ return rtl_ustr_ascii_shortenedCompare_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
+ asciiStr, asciiStrLength ) == 0;
+ }
+
+ // This overload is left undefined, to detect calls of matchAsciiL that
+ // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of
+ // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit
+ // platforms):
+#if SAL_TYPES_SIZEOFLONG == 8
+ void matchAsciiL(char const *, sal_Int32, rtl_TextEncoding) const;
+#endif
+
+ /**
+ Match against a substring appearing in this string, ignoring the case of
+ ASCII letters.
+
+ The result is true if and only if the second string appears as a substring
+ of this string, at the given position.
+ Character values between 65 and 90 (ASCII A-Z) are interpreted as
+ values between 97 and 122 (ASCII a-z).
+ Since this method is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range between 0 and 127.
+ The ASCII string must be greater than or equal to asciiStrLength.
+ This function can't be used for language specific comparison.
+
+ @param asciiStr the 8-Bit ASCII character string to be compared.
+ @param asciiStrLength the length of the ascii string
+ @param fromIndex the index to start the comparison from.
+ The index must be greater than or equal to 0
+ and less than or equal to the string length.
+ @return true if str match with the characters in the string
+ at the given position;
+ false, otherwise.
+ */
+ bool matchIgnoreAsciiCaseAsciiL( const char* asciiStr, sal_Int32 asciiStrLength, sal_Int32 fromIndex = 0 ) const
+ {
+ return rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
+ asciiStr, asciiStrLength ) == 0;
+ }
+
+ // This overload is left undefined, to detect calls of
+ // matchIgnoreAsciiCaseAsciiL that erroneously use
+ // RTL_CONSTASCII_USTRINGPARAM instead of RTL_CONSTASCII_STRINGPARAM (but
+ // would lead to ambiguities on 32 bit platforms):
+#if SAL_TYPES_SIZEOFLONG == 8
+ void matchIgnoreAsciiCaseAsciiL(char const *, sal_Int32, rtl_TextEncoding)
+ const;
+#endif
+
+ /**
+ Check whether this string starts with a given substring.
+
+ @param str the substring to be compared
+
+ @param rest if non-null, and this function returns true, then assign a
+ copy of the remainder of this string to *rest. Available since
+ LibreOffice 4.2
+
+ @return true if and only if the given str appears as a substring at the
+ start of this string
+
+ @since LibreOffice 4.0
+ */
+#if defined LIBO_INTERNAL_ONLY
+ bool startsWith(std::u16string_view sv, OUString * rest = nullptr) const {
+ auto const b = match(sv);
+ if (b && rest != nullptr) {
+ *rest = copy(sv.size());
+ }
+ return b;
+ }
+#else
+ bool startsWith(OUString const & str, OUString * rest = NULL) const {
+ bool b = match(str);
+ if (b && rest != NULL) {
+ *rest = copy(str.getLength());
+ }
+ return b;
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 4.0
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type startsWith(
+ T & literal, OUString * rest = NULL) const
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ bool b
+ = (libreoffice_internal::ConstCharArrayDetector<T>::length
+ <= sal_uInt32(pData->length))
+ && rtl_ustr_asciil_reverseEquals_WithLength(
+ pData->buffer,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ if (b && rest != NULL) {
+ *rest = copy(
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+ return b;
+ }
+
+ /**
+ Check whether this string starts with a given string, ignoring the case of
+ ASCII letters.
+
+ Character values between 65 and 90 (ASCII A-Z) are interpreted as
+ values between 97 and 122 (ASCII a-z).
+ This function can't be used for language specific comparison.
+
+ @param str the substring to be compared
+
+ @param rest if non-null, and this function returns true, then assign a
+ copy of the remainder of this string to *rest. Available since
+ LibreOffice 4.2
+
+ @return true if and only if the given str appears as a substring at the
+ start of this string, ignoring the case of ASCII letters ("A"--"Z" and
+ "a"--"z")
+
+ @since LibreOffice 4.0
+ */
+#if defined LIBO_INTERNAL_ONLY
+ bool startsWithIgnoreAsciiCase(std::u16string_view sv, OUString * rest = nullptr) const {
+ auto const b = matchIgnoreAsciiCase(sv);
+ if (b && rest != nullptr) {
+ *rest = copy(sv.size());
+ }
+ return b;
+ }
+#else
+ bool startsWithIgnoreAsciiCase(OUString const & str, OUString * rest = NULL)
+ const
+ {
+ bool b = matchIgnoreAsciiCase(str);
+ if (b && rest != NULL) {
+ *rest = copy(str.getLength());
+ }
+ return b;
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 4.0
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type
+ startsWithIgnoreAsciiCase(T & literal, OUString * rest = NULL) const
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ bool b
+ = (libreoffice_internal::ConstCharArrayDetector<T>::length
+ <= sal_uInt32(pData->length))
+ && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
+ pData->buffer,
+ libreoffice_internal::ConstCharArrayDetector<T>::length,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length)
+ == 0);
+ if (b && rest != NULL) {
+ *rest = copy(
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+ return b;
+ }
+
+ /**
+ Check whether this string ends with a given substring.
+
+ @param str the substring to be compared
+
+ @param rest if non-null, and this function returns true, then assign a
+ copy of the remainder of this string to *rest. Available since
+ LibreOffice 4.2
+
+ @return true if and only if the given str appears as a substring at the
+ end of this string
+
+ @since LibreOffice 3.6
+ */
+#if defined LIBO_INTERNAL_ONLY
+ bool endsWith(std::u16string_view sv, OUString * rest = nullptr) const {
+ auto const b = sv.size() <= sal_uInt32(pData->length)
+ && match(sv, pData->length - sv.size());
+ if (b && rest != nullptr) {
+ *rest = copy(0, (pData->length - sv.size()));
+ }
+ return b;
+ }
+#else
+ bool endsWith(OUString const & str, OUString * rest = NULL) const {
+ bool b = str.getLength() <= getLength()
+ && match(str, getLength() - str.getLength());
+ if (b && rest != NULL) {
+ *rest = copy(0, getLength() - str.getLength());
+ }
+ return b;
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type
+ endsWith(T & literal, OUString * rest = NULL) const
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ bool b
+ = (libreoffice_internal::ConstCharArrayDetector<T>::length
+ <= sal_uInt32(pData->length))
+ && rtl_ustr_asciil_reverseEquals_WithLength(
+ (pData->buffer + pData->length
+ - libreoffice_internal::ConstCharArrayDetector<T>::length),
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ if (b && rest != NULL) {
+ *rest = copy(
+ 0,
+ (getLength()
+ - libreoffice_internal::ConstCharArrayDetector<T>::length));
+ }
+ return b;
+ }
+
+ /**
+ Check whether this string ends with a given ASCII string.
+
+ @param asciiStr a sequence of at least asciiStrLength ASCII characters
+ (bytes in the range 0x00--0x7F)
+ @param asciiStrLength the length of asciiStr; must be non-negative
+ @return true if this string ends with asciiStr; otherwise, false is
+ returned
+
+ @since UDK 3.2.7
+ */
+ bool endsWithAsciiL(char const * asciiStr, sal_Int32 asciiStrLength)
+ const
+ {
+ return asciiStrLength <= pData->length
+ && rtl_ustr_asciil_reverseEquals_WithLength(
+ pData->buffer + pData->length - asciiStrLength, asciiStr,
+ asciiStrLength);
+ }
+
+ /**
+ Check whether this string ends with a given string, ignoring the case of
+ ASCII letters.
+
+ Character values between 65 and 90 (ASCII A-Z) are interpreted as
+ values between 97 and 122 (ASCII a-z).
+ This function can't be used for language specific comparison.
+
+ @param str the substring to be compared
+
+ @param rest if non-null, and this function returns true, then assign a
+ copy of the remainder of this string to *rest. Available since
+ LibreOffice 4.2
+
+ @return true if and only if the given str appears as a substring at the
+ end of this string, ignoring the case of ASCII letters ("A"--"Z" and
+ "a"--"z")
+
+ @since LibreOffice 3.6
+ */
+#if defined LIBO_INTERNAL_ONLY
+ bool endsWithIgnoreAsciiCase(std::u16string_view sv, OUString * rest = nullptr) const {
+ auto const b = sv.size() <= sal_uInt32(pData->length)
+ && matchIgnoreAsciiCase(sv, pData->length - sv.size());
+ if (b && rest != nullptr) {
+ *rest = copy(0, pData->length - sv.size());
+ }
+ return b;
+ }
+#else
+ bool endsWithIgnoreAsciiCase(OUString const & str, OUString * rest = NULL) const
+ {
+ bool b = str.getLength() <= getLength()
+ && matchIgnoreAsciiCase(str, getLength() - str.getLength());
+ if (b && rest != NULL) {
+ *rest = copy(0, getLength() - str.getLength());
+ }
+ return b;
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type
+ endsWithIgnoreAsciiCase(T & literal, OUString * rest = NULL) const
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ bool b
+ = (libreoffice_internal::ConstCharArrayDetector<T>::length
+ <= sal_uInt32(pData->length))
+ && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
+ (pData->buffer + pData->length
+ - libreoffice_internal::ConstCharArrayDetector<T>::length),
+ libreoffice_internal::ConstCharArrayDetector<T>::length,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length)
+ == 0);
+ if (b && rest != NULL) {
+ *rest = copy(
+ 0,
+ (getLength()
+ - libreoffice_internal::ConstCharArrayDetector<T>::length));
+ }
+ return b;
+ }
+
+ /**
+ Check whether this string ends with a given ASCII string, ignoring the
+ case of ASCII letters.
+
+ @param asciiStr a sequence of at least asciiStrLength ASCII characters
+ (bytes in the range 0x00--0x7F)
+ @param asciiStrLength the length of asciiStr; must be non-negative
+ @return true if this string ends with asciiStr, ignoring the case of ASCII
+ letters ("A"--"Z" and "a"--"z"); otherwise, false is returned
+ */
+ bool endsWithIgnoreAsciiCaseAsciiL(
+ char const * asciiStr, sal_Int32 asciiStrLength) const
+ {
+ return asciiStrLength <= pData->length
+ && (rtl_ustr_ascii_compareIgnoreAsciiCase_WithLengths(
+ pData->buffer + pData->length - asciiStrLength,
+ asciiStrLength, asciiStr, asciiStrLength)
+ == 0);
+ }
+
+ friend bool operator == ( const OUString& rStr1, const OUString& rStr2 )
+ { return rStr1.equals(rStr2); }
+
+ friend bool operator != ( const OUString& rStr1, const OUString& rStr2 )
+ { return !(operator == ( rStr1, rStr2 )); }
+
+ friend bool operator < ( const OUString& rStr1, const OUString& rStr2 )
+ { return rStr1.compareTo( rStr2 ) < 0; }
+ friend bool operator > ( const OUString& rStr1, const OUString& rStr2 )
+ { return rStr1.compareTo( rStr2 ) > 0; }
+ friend bool operator <= ( const OUString& rStr1, const OUString& rStr2 )
+ { return rStr1.compareTo( rStr2 ) <= 0; }
+ friend bool operator >= ( const OUString& rStr1, const OUString& rStr2 )
+ { return rStr1.compareTo( rStr2 ) >= 0; }
+
+#if defined LIBO_INTERNAL_ONLY
+
+ template<typename T> friend typename libreoffice_internal::CharPtrDetector<T, bool>::TypeUtf16
+ operator ==(OUString const & s1, T const & s2) {
+ return rtl_ustr_compare_WithLength(s1.getStr(), s1.getLength(), s2, rtl_ustr_getLength(s2))
+ == 0;
+ }
+
+ template<typename T>
+ friend typename libreoffice_internal::NonConstCharArrayDetector<T, bool>::TypeUtf16
+ operator ==(OUString const & s1, T & s2) {
+ return rtl_ustr_compare_WithLength(s1.getStr(), s1.getLength(), s2, rtl_ustr_getLength(s2))
+ == 0;
+ }
+
+ template<typename T> friend typename libreoffice_internal::CharPtrDetector<T, bool>::TypeUtf16
+ operator ==(T const & s1, OUString const & s2) {
+ return rtl_ustr_compare_WithLength(s1, rtl_ustr_getLength(s1), s2.getStr(), s2.getLength())
+ == 0;
+ }
+
+ template<typename T>
+ friend typename libreoffice_internal::NonConstCharArrayDetector<T, bool>::TypeUtf16
+ operator ==(T & s1, OUString const & s2) {
+ return rtl_ustr_compare_WithLength(s1, rtl_ustr_getLength(s1), s2.getStr(), s2.getLength())
+ == 0;
+ }
+
+ template<typename T> friend typename libreoffice_internal::CharPtrDetector<T, bool>::TypeUtf16
+ operator !=(OUString const & s1, T const & s2) { return !(s1 == s2); }
+
+ template<typename T>
+ friend typename libreoffice_internal::NonConstCharArrayDetector<T, bool>::TypeUtf16
+ operator !=(OUString const & s1, T & s2) { return !(s1 == s2); }
+
+ template<typename T> friend typename libreoffice_internal::CharPtrDetector<T, bool>::TypeUtf16
+ operator !=(T const & s1, OUString const & s2) { return !(s1 == s2); }
+
+ template<typename T>
+ friend typename libreoffice_internal::NonConstCharArrayDetector<T, bool>::TypeUtf16
+ operator !=(T & s1, OUString const & s2) { return !(s1 == s2); }
+
+#else
+
+ friend bool operator == ( const OUString& rStr1, const sal_Unicode * pStr2 )
+ { return rStr1.compareTo( pStr2 ) == 0; }
+ friend bool operator == ( const sal_Unicode * pStr1, const OUString& rStr2 )
+ { return OUString( pStr1 ).compareTo( rStr2 ) == 0; }
+
+ friend bool operator != ( const OUString& rStr1, const sal_Unicode * pStr2 )
+ { return !(operator == ( rStr1, pStr2 )); }
+ friend bool operator != ( const sal_Unicode * pStr1, const OUString& rStr2 )
+ { return !(operator == ( pStr1, rStr2 )); }
+
+#endif
+
+ /**
+ * Compare string to an ASCII string literal.
+ *
+ * This operator is equal to calling equalsAsciiL().
+ *
+ * @since LibreOffice 3.6
+ */
+ template< typename T >
+ friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator==( const OUString& rString, T& literal )
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return rString.equalsAsciiL(
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+ /**
+ * Compare string to an ASCII string literal.
+ *
+ * This operator is equal to calling equalsAsciiL().
+ *
+ * @since LibreOffice 3.6
+ */
+ template< typename T >
+ friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator==( T& literal, const OUString& rString )
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return rString.equalsAsciiL(
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+ /**
+ * Compare string to an ASCII string literal.
+ *
+ * This operator is equal to calling !equalsAsciiL().
+ *
+ * @since LibreOffice 3.6
+ */
+ template< typename T >
+ friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator!=( const OUString& rString, T& literal )
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return !rString.equalsAsciiL(
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+ /**
+ * Compare string to an ASCII string literal.
+ *
+ * This operator is equal to calling !equalsAsciiL().
+ *
+ * @since LibreOffice 3.6
+ */
+ template< typename T >
+ friend typename libreoffice_internal::ConstCharArrayDetector< T, bool >::Type operator!=( T& literal, const OUString& rString )
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return !rString.equalsAsciiL(
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /** @overload @since LibreOffice 5.3 */
+ template<typename T> friend typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16
+ operator ==(OUString const & string, T & literal) {
+ return
+ rtl_ustr_reverseCompare_WithLength(
+ string.pData->buffer, string.pData->length,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length)
+ == 0;
+ }
+ /** @overload @since LibreOffice 5.3 */
+ template<typename T> friend typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16
+ operator ==(T & literal, OUString const & string) {
+ return
+ rtl_ustr_reverseCompare_WithLength(
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length,
+ string.pData->buffer, string.pData->length)
+ == 0;
+ }
+ /** @overload @since LibreOffice 5.3 */
+ template<typename T> friend typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16
+ operator !=(OUString const & string, T & literal) {
+ return
+ rtl_ustr_reverseCompare_WithLength(
+ string.pData->buffer, string.pData->length,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length)
+ != 0;
+ }
+ /** @overload @since LibreOffice 5.3 */
+ template<typename T> friend typename libreoffice_internal::ConstCharArrayDetector<T, bool>::TypeUtf16
+ operator !=(T & literal, OUString const & string) {
+ return
+ rtl_ustr_reverseCompare_WithLength(
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(
+ literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length,
+ string.pData->buffer, string.pData->length)
+ != 0;
+ }
+#endif
+
+ /**
+ Returns a hashcode for this string.
+
+ @return a hash code value for this object.
+
+ @see rtl::OUStringHash for convenient use of std::unordered_map
+ */
+ sal_Int32 hashCode() const
+ {
+ return rtl_ustr_hashCode_WithLength( pData->buffer, pData->length );
+ }
+
+ /**
+ Returns the index within this string of the first occurrence of the
+ specified character, starting the search at the specified index.
+
+ @param ch character to be located.
+ @param fromIndex the index to start the search from.
+ The index must be greater than or equal to 0
+ and less than or equal to the string length.
+ @return the index of the first occurrence of the character in the
+ character sequence represented by this string that is
+ greater than or equal to fromIndex, or
+ -1 if the character does not occur.
+ */
+ sal_Int32 indexOf( sal_Unicode ch, sal_Int32 fromIndex = 0 ) const
+ {
+ sal_Int32 ret = rtl_ustr_indexOfChar_WithLength( pData->buffer+fromIndex, pData->length-fromIndex, ch );
+ return (ret < 0 ? ret : ret+fromIndex);
+ }
+
+ /**
+ Returns the index within this string of the last occurrence of the
+ specified character, searching backward starting at the end.
+
+ @param ch character to be located.
+ @return the index of the last occurrence of the character in the
+ character sequence represented by this string, or
+ -1 if the character does not occur.
+ */
+ sal_Int32 lastIndexOf( sal_Unicode ch ) const
+ {
+ return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, pData->length, ch );
+ }
+
+ /**
+ Returns the index within this string of the last occurrence of the
+ specified character, searching backward starting before the specified
+ index.
+
+ @param ch character to be located.
+ @param fromIndex the index before which to start the search.
+ @return the index of the last occurrence of the character in the
+ character sequence represented by this string that
+ is less than fromIndex, or -1
+ if the character does not occur before that point.
+ */
+ sal_Int32 lastIndexOf( sal_Unicode ch, sal_Int32 fromIndex ) const
+ {
+ return rtl_ustr_lastIndexOfChar_WithLength( pData->buffer, fromIndex, ch );
+ }
+
+ /**
+ Returns the index within this string of the first occurrence of the
+ specified substring, starting at the specified index.
+
+ If str doesn't include any character, always -1 is
+ returned. This is also the case, if both strings are empty.
+
+ @param str the substring to search for.
+ @param fromIndex the index to start the search from.
+ @return If the string argument occurs one or more times as a substring
+ within this string at the starting index, then the index
+ of the first character of the first such substring is
+ returned. If it does not occur as a substring starting
+ at fromIndex or beyond, -1 is returned.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 indexOf(std::u16string_view sv, sal_Int32 fromIndex = 0) const {
+ auto const n = rtl_ustr_indexOfStr_WithLength(
+ pData->buffer + fromIndex, pData->length - fromIndex, sv.data(), sv.size());
+ return n < 0 ? n : n + fromIndex;
+ }
+#else
+ sal_Int32 indexOf( const OUString & str, sal_Int32 fromIndex = 0 ) const
+ {
+ sal_Int32 ret = rtl_ustr_indexOfStr_WithLength( pData->buffer+fromIndex, pData->length-fromIndex,
+ str.pData->buffer, str.pData->length );
+ return (ret < 0 ? ret : ret+fromIndex);
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type indexOf( T& literal, sal_Int32 fromIndex = 0 ) const
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ sal_Int32 n = rtl_ustr_indexOfAscii_WithLength(
+ pData->buffer + fromIndex, pData->length - fromIndex,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ return n < 0 ? n : n + fromIndex;
+ }
+
+ /**
+ Returns the index within this string of the first occurrence of the
+ specified ASCII substring, starting at the specified index.
+
+ @param str
+ the substring to be searched for. Need not be null-terminated, but must
+ be at least as long as the specified len. Must only contain characters
+ in the ASCII range 0x00--7F.
+
+ @param len
+ the length of the substring; must be non-negative.
+
+ @param fromIndex
+ the index to start the search from. Must be in the range from zero to
+ the length of this string, inclusive.
+
+ @return
+ the index (starting at 0) of the first character of the first occurrence
+ of the substring within this string starting at the given fromIndex, or
+ -1 if the substring does not occur. If len is zero, -1 is returned.
+
+ @since UDK 3.2.7
+ */
+ sal_Int32 indexOfAsciiL(
+ char const * str, sal_Int32 len, sal_Int32 fromIndex = 0) const
+ {
+ sal_Int32 ret = rtl_ustr_indexOfAscii_WithLength(
+ pData->buffer + fromIndex, pData->length - fromIndex, str, len);
+ return ret < 0 ? ret : ret + fromIndex;
+ }
+
+ // This overload is left undefined, to detect calls of indexOfAsciiL that
+ // erroneously use RTL_CONSTASCII_USTRINGPARAM instead of
+ // RTL_CONSTASCII_STRINGPARAM (but would lead to ambiguities on 32 bit
+ // platforms):
+#if SAL_TYPES_SIZEOFLONG == 8
+ void indexOfAsciiL(char const *, sal_Int32 len, rtl_TextEncoding) const;
+#endif
+
+ /**
+ Returns the index within this string of the last occurrence of
+ the specified substring, searching backward starting at the end.
+
+ The returned index indicates the starting index of the substring
+ in this string.
+ If str doesn't include any character, always -1 is
+ returned. This is also the case, if both strings are empty.
+
+ @param str the substring to search for.
+ @return If the string argument occurs one or more times as a substring
+ within this string, then the index of the first character of
+ the last such substring is returned. If it does not occur as
+ a substring, -1 is returned.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 lastIndexOf(std::u16string_view sv) const {
+ return rtl_ustr_lastIndexOfStr_WithLength(
+ pData->buffer, pData->length, sv.data(), sv.size());
+ }
+#else
+ sal_Int32 lastIndexOf( const OUString & str ) const
+ {
+ return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, pData->length,
+ str.pData->buffer, str.pData->length );
+ }
+#endif
+
+ /**
+ Returns the index within this string of the last occurrence of
+ the specified substring, searching backward starting before the specified
+ index.
+
+ The returned index indicates the starting index of the substring
+ in this string.
+ If str doesn't include any character, always -1 is
+ returned. This is also the case, if both strings are empty.
+
+ @param str the substring to search for.
+ @param fromIndex the index before which to start the search.
+ @return If the string argument occurs one or more times as a substring
+ within this string before the starting index, then the index
+ of the first character of the last such substring is
+ returned. Otherwise, -1 is returned.
+ */
+#if defined LIBO_INTERNAL_ONLY
+ sal_Int32 lastIndexOf(std::u16string_view sv, sal_Int32 fromIndex) const {
+ return rtl_ustr_lastIndexOfStr_WithLength(pData->buffer, fromIndex, sv.data(), sv.size());
+ }
+#else
+ sal_Int32 lastIndexOf( const OUString & str, sal_Int32 fromIndex ) const
+ {
+ return rtl_ustr_lastIndexOfStr_WithLength( pData->buffer, fromIndex,
+ str.pData->buffer, str.pData->length );
+ }
+#endif
+
+ /**
+ @overload
+ This function accepts an ASCII string literal as its argument.
+ @since LibreOffice 3.6
+ */
+ template< typename T >
+ typename libreoffice_internal::ConstCharArrayDetector< T, sal_Int32 >::Type lastIndexOf( T& literal ) const
+ {
+ assert(
+ libreoffice_internal::ConstCharArrayDetector<T>::isValid(literal));
+ return rtl_ustr_lastIndexOfAscii_WithLength(
+ pData->buffer, pData->length,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ }
+
+ /**
+ Returns the index within this string of the last occurrence of the
+ specified ASCII substring.
+
+ @param str
+ the substring to be searched for. Need not be null-terminated, but must
+ be at least as long as the specified len. Must only contain characters
+ in the ASCII range 0x00--7F.
+
+ @param len
+ the length of the substring; must be non-negative.
+
+ @return
+ the index (starting at 0) of the first character of the last occurrence
+ of the substring within this string, or -1 if the substring does not
+ occur. If len is zero, -1 is returned.
+
+ @since UDK 3.2.7
+ */
+ sal_Int32 lastIndexOfAsciiL(char const * str, sal_Int32 len) const
+ {
+ return rtl_ustr_lastIndexOfAscii_WithLength(
+ pData->buffer, pData->length, str, len);
+ }
+
+ /**
+ Returns a new string that is a substring of this string.
+
+ The substring begins at the specified beginIndex. If
+ beginIndex is negative or be greater than the length of
+ this string, behaviour is undefined.
+
+ @param beginIndex the beginning index, inclusive.
+ @return the specified substring.
+ */
+ SAL_WARN_UNUSED_RESULT OUString copy( sal_Int32 beginIndex ) const
+ {
+ return copy(beginIndex, getLength() - beginIndex);
+ }
+
+ /**
+ Returns a new string that is a substring of this string.
+
+ The substring begins at the specified beginIndex and contains count
+ characters. If either beginIndex or count are negative,
+ or beginIndex + count are greater than the length of this string
+ then behaviour is undefined.
+
+ @param beginIndex the beginning index, inclusive.
+ @param count the number of characters.
+ @return the specified substring.
+ */
+ SAL_WARN_UNUSED_RESULT OUString copy( sal_Int32 beginIndex, sal_Int32 count ) const
+ {
+ rtl_uString *pNew = NULL;
+ rtl_uString_newFromSubString( &pNew, pData, beginIndex, count );
+ return OUString( pNew, SAL_NO_ACQUIRE );
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ /**
+ Returns a std::u16string_view that is a view of a substring of this string.
+
+ The substring begins at the specified beginIndex. If
+ beginIndex is negative or be greater than the length of
+ this string, behaviour is undefined.
+
+ @param beginIndex the beginning index, inclusive.
+ @return the specified substring.
+ */
+ SAL_WARN_UNUSED_RESULT std::u16string_view subView( sal_Int32 beginIndex ) const
+ {
+ assert(beginIndex >= 0);
+ assert(beginIndex <= getLength());
+ return subView(beginIndex, getLength() - beginIndex);
+ }
+
+ /**
+ Returns a std::u16string_view that is a view of a substring of this string.
+
+ The substring begins at the specified beginIndex and contains count
+ characters. If either beginIndex or count are negative,
+ or beginIndex + count are greater than the length of this string
+ then behaviour is undefined.
+
+ @param beginIndex the beginning index, inclusive.
+ @param count the number of characters.
+ @return the specified substring.
+ */
+ SAL_WARN_UNUSED_RESULT std::u16string_view subView( sal_Int32 beginIndex, sal_Int32 count ) const
+ {
+ assert(beginIndex >= 0);
+ assert(count >= 0);
+ assert(beginIndex <= getLength());
+ assert(count <= getLength() - beginIndex);
+ return std::u16string_view(*this).substr(beginIndex, count);
+ }
+#endif
+
+#ifndef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ /**
+ Concatenates the specified string to the end of this string.
+
+ @param str the string that is concatenated to the end
+ of this string.
+ @return a string that represents the concatenation of this string
+ followed by the string argument.
+ */
+ SAL_WARN_UNUSED_RESULT OUString concat( const OUString & str ) const
+ {
+ rtl_uString* pNew = NULL;
+ rtl_uString_newConcat( &pNew, pData, str.pData );
+ return OUString( pNew, SAL_NO_ACQUIRE );
+ }
+#endif
+
+#ifndef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ friend OUString operator+( const OUString& rStr1, const OUString& rStr2 )
+ {
+ return rStr1.concat( rStr2 );
+ }
+#endif
+
+// hide this from internal code to avoid ambiguous lookup error
+#ifndef LIBO_INTERNAL_ONLY
+ /**
+ Returns a new string resulting from replacing n = count characters
+ from position index in this string with newStr.
+
+ @param index the replacing index in str.
+ The index must be greater than or equal to 0 and
+ less than or equal to the length of the string.
+ @param count the count of characters that will be replaced
+ The count must be greater than or equal to 0 and
+ less than or equal to the length of the string minus index.
+ @param newStr the new substring.
+ @return the new string.
+ */
+ SAL_WARN_UNUSED_RESULT OUString replaceAt( sal_Int32 index, sal_Int32 count, const OUString& newStr ) const
+ {
+ rtl_uString* pNew = NULL;
+ rtl_uString_newReplaceStrAt( &pNew, pData, index, count, newStr.pData );
+ return OUString( pNew, SAL_NO_ACQUIRE );
+ }
+#endif
+
+#ifdef LIBO_INTERNAL_ONLY
+ SAL_WARN_UNUSED_RESULT OUString replaceAt( sal_Int32 index, sal_Int32 count, std::u16string_view newStr ) const
+ {
+ rtl_uString* pNew = NULL;
+ rtl_uString_newReplaceStrAtUtf16L( &pNew, pData, index, count, newStr.data(), newStr.size() );
+ return OUString( pNew, SAL_NO_ACQUIRE );
+ }
+#endif
+
+ /**
+ Returns a new string resulting from replacing all occurrences of
+ oldChar in this string with newChar.
+
+ If the character oldChar does not occur in the character sequence
+ represented by this object, then the string is assigned with
+ str.
+
+ @param oldChar the old character.
+ @param newChar the new character.
+ @return a string derived from this string by replacing every
+ occurrence of oldChar with newChar.
+ */
+ SAL_WARN_UNUSED_RESULT OUString replace( sal_Unicode oldChar, sal_Unicode newChar ) const
+ {
+ rtl_uString* pNew = NULL;
+ rtl_uString_newReplace( &pNew, pData, oldChar, newChar );
+ return OUString( pNew, SAL_NO_ACQUIRE );
+ }
+
+ /**
+ Returns a new string resulting from replacing the first occurrence of a
+ given substring with another substring.
+
+ @param from the substring to be replaced
+
+ @param to the replacing substring
+
+ @param[in,out] index pointer to a start index; if the pointer is
+ non-null: upon entry to the function, its value is the index into this
+ string at which to start searching for the \p from substring, the value
+ must be non-negative and not greater than this string's length; upon exiting
+ the function its value is the index into this string at which the
+ replacement took place or -1 if no replacement took place; if the pointer
+ is null, searching always starts at index 0
+
+ @since LibreOffice 3.6
+ */
+#if defined LIBO_INTERNAL_ONLY
+ [[nodiscard]] OUString replaceFirst(
+ std::u16string_view from, std::u16string_view to, sal_Int32 * index = nullptr) const
+ {
+ rtl_uString * s = nullptr;
+ sal_Int32 i = 0;
+ rtl_uString_newReplaceFirstUtf16LUtf16L(
+ &s, pData, from.data(), from.size(), to.data(), to.size(),
+ index == nullptr ? &i : index);
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+#else
+ SAL_WARN_UNUSED_RESULT OUString replaceFirst(
+ OUString const & from, OUString const & to, sal_Int32 * index = NULL) const
+ {
+ rtl_uString * s = NULL;
+ sal_Int32 i = 0;
+ rtl_uString_newReplaceFirst(
+ &s, pData, from.pData, to.pData, index == NULL ? &i : index);
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+#endif
+
+ /**
+ Returns a new string resulting from replacing the first occurrence of a
+ given substring with another substring.
+
+ @param from ASCII string literal, the substring to be replaced
+
+ @param to the replacing substring
+
+ @param[in,out] index pointer to a start index; if the pointer is
+ non-null: upon entry to the function, its value is the index into the this
+ string at which to start searching for the \p from substring, the value
+ must be non-negative and not greater than this string's length; upon exiting
+ the function its value is the index into this string at which the
+ replacement took place or -1 if no replacement took place; if the pointer
+ is null, searching always starts at index 0
+
+ @since LibreOffice 3.6
+ */
+#if defined LIBO_INTERNAL_ONLY
+ template<typename T> [[nodiscard]]
+ typename libreoffice_internal::ConstCharArrayDetector<T, OUString >::Type replaceFirst(
+ T & from, std::u16string_view to, sal_Int32 * index = nullptr) const
+ {
+ assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(from));
+ rtl_uString * s = nullptr;
+ sal_Int32 i = 0;
+ rtl_uString_newReplaceFirstAsciiLUtf16L(
+ &s, pData, libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from),
+ libreoffice_internal::ConstCharArrayDetector<T>::length, to.data(), to.size(),
+ index == nullptr ? &i : index);
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+#else
+ template< typename T >
+ SAL_WARN_UNUSED_RESULT typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceFirst( T& from, OUString const & to,
+ sal_Int32 * index = NULL) const
+ {
+ assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(from));
+ rtl_uString * s = NULL;
+ sal_Int32 i = 0;
+ rtl_uString_newReplaceFirstAsciiL(
+ &s, pData,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from),
+ libreoffice_internal::ConstCharArrayDetector<T>::length, to.pData,
+ index == NULL ? &i : index);
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+#endif
+
+ /**
+ Returns a new string resulting from replacing the first occurrence of a
+ given substring with another substring.
+
+ @param from the substring to be replaced
+
+ @param to ASCII string literal, the replacing substring
+
+ @param[in,out] index pointer to a start index; if the pointer is
+ non-null: upon entry to the function, its value is the index into the this
+ string at which to start searching for the \p from substring, the value
+ must be non-negative and not greater than this string's length; upon exiting
+ the function its value is the index into this string at which the
+ replacement took place or -1 if no replacement took place; if the pointer
+ is null, searching always starts at index 0
+
+ @since LibreOffice 5.1
+ */
+#if defined LIBO_INTERNAL_ONLY
+ template<typename T> [[nodiscard]]
+ typename libreoffice_internal::ConstCharArrayDetector<T, OUString >::Type replaceFirst(
+ std::u16string_view from, T & to, sal_Int32 * index = nullptr) const
+ {
+ assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(to));
+ rtl_uString * s = nullptr;
+ sal_Int32 i = 0;
+ rtl_uString_newReplaceFirstUtf16LAsciiL(
+ &s, pData, from.data(), from.size(),
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to),
+ libreoffice_internal::ConstCharArrayDetector<T>::length, index == nullptr ? &i : index);
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+#else
+ template< typename T >
+ SAL_WARN_UNUSED_RESULT typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceFirst( OUString const & from, T& to,
+ sal_Int32 * index = NULL) const
+ {
+ assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(to));
+ rtl_uString * s = NULL;
+ sal_Int32 i = 0;
+ rtl_uString_newReplaceFirstToAsciiL(
+ &s, pData, from.pData,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to),
+ libreoffice_internal::ConstCharArrayDetector<T>::length,
+ index == NULL ? &i : index);
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+#endif
+
+ /**
+ Returns a new string resulting from replacing the first occurrence of a
+ given substring with another substring.
+
+ @param from ASCII string literal, the substring to be replaced
+
+ @param to ASCII string literal, the substring to be replaced
+
+ @param[in,out] index pointer to a start index; if the pointer is
+ non-null: upon entry to the function, its value is the index into the this
+ string at which to start searching for the \p from substring, the value
+ must be non-negative and not greater than this string's length; upon exiting
+ the function its value is the index into this string at which the
+ replacement took place or -1 if no replacement took place; if the pointer
+ is null, searching always starts at index 0
+
+ @since LibreOffice 3.6
+ */
+ template< typename T1, typename T2 >
+ SAL_WARN_UNUSED_RESULT typename libreoffice_internal::ConstCharArrayDetector< T1, typename libreoffice_internal::ConstCharArrayDetector< T2, OUString >::Type >::Type
+ replaceFirst( T1& from, T2& to, sal_Int32 * index = NULL) const
+ {
+ assert(libreoffice_internal::ConstCharArrayDetector<T1>::isValid(from));
+ assert(libreoffice_internal::ConstCharArrayDetector<T2>::isValid(to));
+ rtl_uString * s = NULL;
+ sal_Int32 i = 0;
+ rtl_uString_newReplaceFirstAsciiLAsciiL(
+ &s, pData,
+ libreoffice_internal::ConstCharArrayDetector<T1>::toPointer(from),
+ libreoffice_internal::ConstCharArrayDetector<T1>::length,
+ libreoffice_internal::ConstCharArrayDetector<T2>::toPointer(to),
+ libreoffice_internal::ConstCharArrayDetector<T2>::length,
+ index == NULL ? &i : index);
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+
+ /**
+ Returns a new string resulting from replacing all occurrences of a given
+ substring with another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param from the substring to be replaced
+
+ @param to the replacing substring
+
+ @param fromIndex the position in the string where we will begin searching
+
+ @since LibreOffice 4.0
+ */
+#if defined LIBO_INTERNAL_ONLY
+ [[nodiscard]] OUString replaceAll(
+ std::u16string_view from, std::u16string_view to, sal_Int32 fromIndex = 0) const
+ {
+ rtl_uString * s = nullptr;
+ rtl_uString_newReplaceAllFromIndexUtf16LUtf16L(
+ &s, pData, from.data(), from.size(), to.data(), to.size(), fromIndex);
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+#else
+ SAL_WARN_UNUSED_RESULT OUString replaceAll(
+ OUString const & from, OUString const & to, sal_Int32 fromIndex = 0) const
+ {
+ rtl_uString * s = NULL;
+ rtl_uString_newReplaceAllFromIndex(&s, pData, from.pData, to.pData, fromIndex);
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+#endif
+
+ /**
+ Returns a new string resulting from replacing all occurrences of a given
+ substring with another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param from ASCII string literal, the substring to be replaced
+
+ @param to the replacing substring
+
+ @since LibreOffice 3.6
+ */
+#if defined LIBO_INTERNAL_ONLY
+ template<typename T> [[nodiscard]]
+ typename libreoffice_internal::ConstCharArrayDetector<T, OUString >::Type replaceAll(
+ T & from, std::u16string_view to) const
+ {
+ assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(from));
+ rtl_uString * s = nullptr;
+ rtl_uString_newReplaceAllAsciiLUtf16L(
+ &s, pData, libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from),
+ libreoffice_internal::ConstCharArrayDetector<T>::length, to.data(), to.size());
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+#else
+ template< typename T >
+ SAL_WARN_UNUSED_RESULT typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( T& from, OUString const & to) const
+ {
+ assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(from));
+ rtl_uString * s = NULL;
+ rtl_uString_newReplaceAllAsciiL(
+ &s, pData,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(from),
+ libreoffice_internal::ConstCharArrayDetector<T>::length, to.pData);
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+#endif
+
+ /**
+ Returns a new string resulting from replacing all occurrences of a given
+ substring with another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param from the substring to be replaced
+
+ @param to ASCII string literal, the replacing substring
+
+ @since LibreOffice 5.1
+ */
+#if defined LIBO_INTERNAL_ONLY
+ template<typename T> [[nodiscard]]
+ typename libreoffice_internal::ConstCharArrayDetector<T, OUString >::Type replaceAll(
+ std::u16string_view from, T & to) const
+ {
+ assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(to));
+ rtl_uString * s = nullptr;
+ rtl_uString_newReplaceAllUtf16LAsciiL(
+ &s, pData, from.data(), from.size(),
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+#else
+ template< typename T >
+ SAL_WARN_UNUSED_RESULT typename libreoffice_internal::ConstCharArrayDetector< T, OUString >::Type replaceAll( OUString const & from, T& to) const
+ {
+ assert(libreoffice_internal::ConstCharArrayDetector<T>::isValid(to));
+ rtl_uString * s = NULL;
+ rtl_uString_newReplaceAllToAsciiL(
+ &s, pData, from.pData,
+ libreoffice_internal::ConstCharArrayDetector<T>::toPointer(to),
+ libreoffice_internal::ConstCharArrayDetector<T>::length);
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+#endif
+
+ /**
+ Returns a new string resulting from replacing all occurrences of a given
+ substring with another substring.
+
+ Replacing subsequent occurrences picks up only after a given replacement.
+ That is, replacing from "xa" to "xx" in "xaa" results in "xxa", not "xxx".
+
+ @param from ASCII string literal, the substring to be replaced
+
+ @param to ASCII string literal, the substring to be replaced
+
+ @since LibreOffice 3.6
+ */
+ template< typename T1, typename T2 >
+ SAL_WARN_UNUSED_RESULT typename libreoffice_internal::ConstCharArrayDetector< T1, typename libreoffice_internal::ConstCharArrayDetector< T2, OUString >::Type >::Type
+ replaceAll( T1& from, T2& to ) const
+ {
+ assert(libreoffice_internal::ConstCharArrayDetector<T1>::isValid(from));
+ assert(libreoffice_internal::ConstCharArrayDetector<T2>::isValid(to));
+ rtl_uString * s = NULL;
+ rtl_uString_newReplaceAllAsciiLAsciiL(
+ &s, pData,
+ libreoffice_internal::ConstCharArrayDetector<T1>::toPointer(from),
+ libreoffice_internal::ConstCharArrayDetector<T1>::length,
+ libreoffice_internal::ConstCharArrayDetector<T2>::toPointer(to),
+ libreoffice_internal::ConstCharArrayDetector<T2>::length);
+ return OUString(s, SAL_NO_ACQUIRE);
+ }
+
+ /**
+ Converts from this string all ASCII uppercase characters (65-90)
+ to ASCII lowercase characters (97-122).
+
+ This function can't be used for language specific conversion.
+ If the string doesn't contain characters which must be converted,
+ then the new string is assigned with str.
+
+ @return the string, converted to ASCII lowercase.
+ */
+ SAL_WARN_UNUSED_RESULT OUString toAsciiLowerCase() const
+ {
+ rtl_uString* pNew = NULL;
+ rtl_uString_newToAsciiLowerCase( &pNew, pData );
+ return OUString( pNew, SAL_NO_ACQUIRE );
+ }
+
+ /**
+ Converts from this string all ASCII lowercase characters (97-122)
+ to ASCII uppercase characters (65-90).
+
+ This function can't be used for language specific conversion.
+ If the string doesn't contain characters which must be converted,
+ then the new string is assigned with str.
+
+ @return the string, converted to ASCII uppercase.
+ */
+ SAL_WARN_UNUSED_RESULT OUString toAsciiUpperCase() const
+ {
+ rtl_uString* pNew = NULL;
+ rtl_uString_newToAsciiUpperCase( &pNew, pData );
+ return OUString( pNew, SAL_NO_ACQUIRE );
+ }
+
+ /**
+ Returns a new string resulting from removing white space from both ends
+ of the string.
+
+ All characters that have codes less than or equal to
+ 32 (the space character), and Unicode General Punctuation area Space
+ and some Control characters are considered to be white space (see
+ implIsWhitespace).
+ If the string doesn't contain white spaces at both ends,
+ then the new string is assigned with str.
+
+ @return the string, with white space removed from the front and end.
+ */
+ SAL_WARN_UNUSED_RESULT OUString trim() const
+ {
+ rtl_uString* pNew = NULL;
+ rtl_uString_newTrim( &pNew, pData );
+ return OUString( pNew, SAL_NO_ACQUIRE );
+ }
+
+ /**
+ Returns a token in the string.
+
+ Example:
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ...
+ OUString aToken = aStr.getToken( 0, ';', nIndex );
+ ...
+ }
+ while ( nIndex >= 0 );
+
+ @param token the number of the token to return
+ @param cTok the character which separate the tokens.
+ @param index the position at which the token is searched in the
+ string.
+ The index must not be greater than the length of the
+ string.
+ This param is set to the position of the
+ next token or to -1, if it is the last token.
+ @return the token; if either token or index is negative, an empty token
+ is returned (and index is set to -1)
+ */
+ OUString getToken( sal_Int32 token, sal_Unicode cTok, sal_Int32& index ) const
+ {
+ rtl_uString * pNew = NULL;
+ index = rtl_uString_getToken( &pNew, pData, token, cTok, index );
+ return OUString( pNew, SAL_NO_ACQUIRE );
+ }
+
+ /**
+ Returns a token from the string.
+
+ The same as getToken(sal_Int32, sal_Unicode, sal_Int32 &), but always
+ passing in 0 as the start index in the third argument.
+
+ @param count the number of the token to return, starting with 0
+ @param separator the character which separates the tokens
+
+ @return the given token, or an empty string
+
+ @since LibreOffice 3.6
+ */
+ OUString getToken(sal_Int32 count, sal_Unicode separator) const {
+ sal_Int32 n = 0;
+ return getToken(count, separator, n);
+ }
+
+ /**
+ Returns the Boolean value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @return true, if the string is 1 or "True" in any ASCII case.
+ false in any other case.
+ */
+ bool toBoolean() const
+ {
+ return rtl_ustr_toBoolean( pData->buffer );
+ }
+
+ /**
+ Returns the first character from this string.
+
+ @return the first character from this string or 0, if this string
+ is empty.
+ */
+ sal_Unicode toChar() const
+ {
+ return pData->buffer[0];
+ }
+
+ /**
+ Returns the int32 value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @param radix the radix (between 2 and 36)
+ @return the int32 represented from this string.
+ 0 if this string represents no number or one of too large
+ magnitude.
+ */
+ sal_Int32 toInt32( sal_Int16 radix = 10 ) const
+ {
+ return rtl_ustr_toInt32( pData->buffer, radix );
+ }
+
+ /**
+ Returns the uint32 value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @param radix the radix (between 2 and 36)
+ @return the uint32 represented from this string.
+ 0 if this string represents no number or one of too large
+ magnitude.
+
+ @since LibreOffice 4.2
+ */
+ sal_uInt32 toUInt32( sal_Int16 radix = 10 ) const
+ {
+ return rtl_ustr_toUInt32( pData->buffer, radix );
+ }
+
+ /**
+ Returns the int64 value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @param radix the radix (between 2 and 36)
+ @return the int64 represented from this string.
+ 0 if this string represents no number or one of too large
+ magnitude.
+ */
+ sal_Int64 toInt64( sal_Int16 radix = 10 ) const
+ {
+ return rtl_ustr_toInt64( pData->buffer, radix );
+ }
+
+ /**
+ Returns the uint64 value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @param radix the radix (between 2 and 36)
+ @return the uint64 represented from this string.
+ 0 if this string represents no number or one of too large
+ magnitude.
+
+ @since LibreOffice 4.1
+ */
+ sal_uInt64 toUInt64( sal_Int16 radix = 10 ) const
+ {
+ return rtl_ustr_toUInt64( pData->buffer, radix );
+ }
+
+ /**
+ Returns the float value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @return the float represented from this string.
+ 0.0 if this string represents no number.
+ */
+ float toFloat() const
+ {
+ return rtl_ustr_toFloat( pData->buffer );
+ }
+
+ /**
+ Returns the double value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @return the double represented from this string.
+ 0.0 if this string represents no number.
+ */
+ double toDouble() const
+ {
+ return rtl_ustr_toDouble( pData->buffer );
+ }
+
+
+ /**
+ Return a canonical representation for a string.
+
+ A pool of strings, initially empty is maintained privately
+ by the string class. On invocation, if present in the pool
+ the original string will be returned. Otherwise this string,
+ or a copy thereof will be added to the pool and returned.
+
+ @return
+ a version of the string from the pool.
+
+ @exception std::bad_alloc is thrown if an out-of-memory condition occurs
+
+ @since UDK 3.2.7
+ */
+ OUString intern() const
+ {
+ rtl_uString * pNew = NULL;
+ rtl_uString_intern( &pNew, pData );
+ if (pNew == NULL) {
+ throw std::bad_alloc();
+ }
+ return OUString( pNew, SAL_NO_ACQUIRE );
+ }
+
+ /**
+ Return a canonical representation for a converted string.
+
+ A pool of strings, initially empty is maintained privately
+ by the string class. On invocation, if present in the pool
+ the original string will be returned. Otherwise this string,
+ or a copy thereof will be added to the pool and returned.
+
+ @param value a 8-Bit character array.
+ @param length the number of character which should be converted.
+ The 8-Bit character array length must be
+ greater than or equal to this value.
+ @param encoding the text encoding from which the 8-Bit character
+ sequence should be converted.
+ @param convertFlags flags which controls the conversion.
+ see RTL_TEXTTOUNICODE_FLAGS_...
+ @param pInfo pointer to return conversion status or NULL.
+
+ @return
+ a version of the converted string from the pool.
+
+ @exception std::bad_alloc is thrown if an out-of-memory condition occurs
+
+ @since UDK 3.2.7
+ */
+ static OUString intern( const char * value, sal_Int32 length,
+ rtl_TextEncoding encoding,
+ sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS,
+ sal_uInt32 *pInfo = NULL )
+ {
+ rtl_uString * pNew = NULL;
+ rtl_uString_internConvert( &pNew, value, length, encoding,
+ convertFlags, pInfo );
+ if (pNew == NULL) {
+ throw std::bad_alloc();
+ }
+ return OUString( pNew, SAL_NO_ACQUIRE );
+ }
+
+ /**
+ Converts to an OString, signalling failure.
+
+ @param pTarget
+ An out parameter receiving the converted OString. Must not be null; the
+ contents are not modified if conversion fails (convertToOString returns
+ false).
+
+ @param nEncoding
+ The text encoding to convert into. Must be an octet encoding (i.e.,
+ rtl_isOctetTextEncoding(nEncoding) must return true).
+
+ @param nFlags
+ A combination of RTL_UNICODETOTEXT_FLAGS that detail how to do the
+ conversion (see rtl_convertUnicodeToText). RTL_UNICODETOTEXT_FLAGS_FLUSH
+ need not be included, it is implicitly assumed. Typical uses are either
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR (fail if a Unicode character cannot
+ be converted to the target nEncoding) or OUSTRING_TO_OSTRING_CVTFLAGS
+ (make a best efforts conversion).
+
+ @return
+ True if the conversion succeeded, false otherwise.
+ */
+ bool convertToString(OString * pTarget, rtl_TextEncoding nEncoding,
+ sal_uInt32 nFlags) const
+ {
+ return rtl_convertUStringToString(&pTarget->pData, pData->buffer,
+ pData->length, nEncoding, nFlags);
+ }
+
+ /** Iterate through this string based on code points instead of UTF-16 code
+ units.
+
+ See Chapter 3 of The Unicode Standard 5.0 (Addison--Wesley, 2006) for
+ definitions of the various terms used in this description.
+
+ This string is interpreted as a sequence of zero or more UTF-16 code
+ units. For each index into this sequence (from zero to one less than
+ the length of the sequence, inclusive), a code point represented
+ starting at the given index is computed as follows:
+
+ - If the UTF-16 code unit addressed by the index constitutes a
+ well-formed UTF-16 code unit sequence, the computed code point is the
+ scalar value encoded by that UTF-16 code unit sequence.
+
+ - Otherwise, if the index is at least two UTF-16 code units away from
+ the end of the sequence, and the sequence of two UTF-16 code units
+ addressed by the index constitutes a well-formed UTF-16 code unit
+ sequence, the computed code point is the scalar value encoded by that
+ UTF-16 code unit sequence.
+
+ - Otherwise, the computed code point is the UTF-16 code unit addressed
+ by the index. (This last case catches unmatched surrogates as well as
+ indices pointing into the middle of surrogate pairs.)
+
+ @param indexUtf16
+ pointer to a UTF-16 based index into this string; must not be null. On
+ entry, the index must be in the range from zero to the length of this
+ string (in UTF-16 code units), inclusive. Upon successful return, the
+ index will be updated to address the UTF-16 code unit that is the given
+ incrementCodePoints away from the initial index.
+
+ @param incrementCodePoints
+ the number of code points to move the given *indexUtf16. If
+ non-negative, moving is done after determining the code point at the
+ index. If negative, moving is done before determining the code point
+ at the (then updated) index. The value must be such that the resulting
+ UTF-16 based index is in the range from zero to the length of this
+ string (in UTF-16 code units), inclusive.
+
+ @return
+ the code point (an integer in the range from 0 to 0x10FFFF, inclusive)
+ that is represented within this string starting at the index computed as
+ follows: If incrementCodePoints is non-negative, the index is the
+ initial value of *indexUtf16; if incrementCodePoints is negative, the
+ index is the updated value of *indexUtf16. In either case, the computed
+ index must be in the range from zero to one less than the length of this
+ string (in UTF-16 code units), inclusive.
+
+ @since UDK 3.2.7
+ */
+ sal_uInt32 iterateCodePoints(
+ sal_Int32 * indexUtf16, sal_Int32 incrementCodePoints = 1) const
+ {
+ return rtl_uString_iterateCodePoints(
+ pData, indexUtf16, incrementCodePoints);
+ }
+
+ /**
+ * Convert an OString to an OUString, assuming that the OString is
+ * UTF-8-encoded.
+ *
+ * @param rSource
+ * an OString to convert
+ *
+ * @since LibreOffice 4.4
+ */
+#if defined LIBO_INTERNAL_ONLY
+ static OUString fromUtf8(std::string_view rSource)
+ {
+ OUString aTarget;
+ bool bSuccess = rtl_convertStringToUString(&aTarget.pData,
+ rSource.data(),
+ rSource.length(),
+ RTL_TEXTENCODING_UTF8,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR);
+ (void) bSuccess;
+ assert(bSuccess);
+ return aTarget;
+ }
+#else
+ static OUString fromUtf8(const OString& rSource)
+ {
+ OUString aTarget;
+ bool bSuccess = rtl_convertStringToUString(&aTarget.pData,
+ rSource.getStr(),
+ rSource.getLength(),
+ RTL_TEXTENCODING_UTF8,
+ RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR|RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR|RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR);
+ (void) bSuccess;
+ assert(bSuccess);
+ return aTarget;
+ }
+#endif
+
+ /**
+ * Convert this string to an OString, assuming that the string can be
+ * UTF-8-encoded successfully.
+ *
+ * In other words, you must not use this method on a random sequence of
+ * UTF-16 code units, but only at places where it is assumed that the
+ * content is a proper string.
+ *
+ * @since LibreOffice 4.4
+ */
+ OString toUtf8() const
+ {
+ OString aTarget;
+ bool bSuccess = rtl_convertUStringToString(&aTarget.pData,
+ getStr(),
+ getLength(),
+ RTL_TEXTENCODING_UTF8,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR|RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR);
+ (void) bSuccess;
+ assert(bSuccess);
+ return aTarget;
+ }
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+
+ static auto number( int i, sal_Int16 radix = 10 )
+ {
+ return OUStringNumber<RTL_USTR_MAX_VALUEOFINT32>(rtl_ustr_valueOfInt32, i, radix);
+ }
+ static auto number( long long ll, sal_Int16 radix = 10 )
+ {
+ return OUStringNumber<RTL_USTR_MAX_VALUEOFINT64>(rtl_ustr_valueOfInt64, ll, radix);
+ }
+ static auto number( unsigned long long ll, sal_Int16 radix = 10 )
+ {
+ return OUStringNumber<RTL_USTR_MAX_VALUEOFUINT64>(rtl_ustr_valueOfUInt64, ll, radix);
+ }
+ static auto number( unsigned int i, sal_Int16 radix = 10 )
+ {
+ return number( static_cast< unsigned long long >( i ), radix );
+ }
+ static auto number( long i, sal_Int16 radix = 10)
+ {
+ return number( static_cast< long long >( i ), radix );
+ }
+ static auto number( unsigned long i, sal_Int16 radix = 10 )
+ {
+ return number( static_cast< unsigned long long >( i ), radix );
+ }
+#else
+ /**
+ Returns the string representation of the integer argument.
+
+ This function can't be used for language specific conversion.
+
+ @param i an integer value
+ @param radix the radix (between 2 and 36)
+ @return a string with the string representation of the argument.
+ @since LibreOffice 4.1
+ */
+ static OUString number( int i, sal_Int16 radix = 10 )
+ {
+ sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFINT32];
+ return OUString(aBuf, rtl_ustr_valueOfInt32(aBuf, i, radix));
+ }
+ /// @overload
+ /// @since LibreOffice 4.1
+ static OUString number( unsigned int i, sal_Int16 radix = 10 )
+ {
+ return number( static_cast< unsigned long long >( i ), radix );
+ }
+ /// @overload
+ /// @since LibreOffice 4.1
+ static OUString number( long i, sal_Int16 radix = 10)
+ {
+ return number( static_cast< long long >( i ), radix );
+ }
+ /// @overload
+ /// @since LibreOffice 4.1
+ static OUString number( unsigned long i, sal_Int16 radix = 10 )
+ {
+ return number( static_cast< unsigned long long >( i ), radix );
+ }
+ /// @overload
+ /// @since LibreOffice 4.1
+ static OUString number( long long ll, sal_Int16 radix = 10 )
+ {
+ sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFINT64];
+ return OUString(aBuf, rtl_ustr_valueOfInt64(aBuf, ll, radix));
+ }
+ /// @overload
+ /// @since LibreOffice 4.1
+ static OUString number( unsigned long long ll, sal_Int16 radix = 10 )
+ {
+ sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFUINT64];
+ return OUString(aBuf, rtl_ustr_valueOfUInt64(aBuf, ll, radix));
+ }
+#endif
+
+ /**
+ Returns the string representation of the float argument.
+
+ This function can't be used for language specific conversion.
+
+ @param f a float.
+ @return a string with the decimal representation of the argument.
+ @since LibreOffice 4.1
+ */
+ static OUString number( float f )
+ {
+ rtl_uString* pNew = NULL;
+ // Same as rtl::str::valueOfFP, used for rtl_ustr_valueOfFloat
+ rtl_math_doubleToUString(&pNew, NULL, 0, f, rtl_math_StringFormat_G,
+ RTL_USTR_MAX_VALUEOFFLOAT - SAL_N_ELEMENTS("-x.E-xxx") + 1, '.',
+ NULL, 0, true);
+ if (pNew == NULL)
+ throw std::bad_alloc();
+
+ return OUString(pNew, SAL_NO_ACQUIRE);
+ }
+
+ /**
+ Returns the string representation of the double argument.
+
+ This function can't be used for language specific conversion.
+
+ @param d a double.
+ @return a string with the decimal representation of the argument.
+ @since LibreOffice 4.1
+ */
+ static OUString number( double d )
+ {
+ rtl_uString* pNew = NULL;
+ // Same as rtl::str::valueOfFP, used for rtl_ustr_valueOfDouble
+ rtl_math_doubleToUString(&pNew, NULL, 0, d, rtl_math_StringFormat_G,
+ RTL_USTR_MAX_VALUEOFDOUBLE - SAL_N_ELEMENTS("-x.E-xxx") + 1, '.',
+ NULL, 0, true);
+ if (pNew == NULL)
+ throw std::bad_alloc();
+
+ return OUString(pNew, SAL_NO_ACQUIRE);
+ }
+
+#ifdef LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+ static auto boolean(bool b)
+ {
+ return OUStringNumber<RTL_USTR_MAX_VALUEOFBOOLEAN>(rtl_ustr_valueOfBoolean, b);
+ }
+#else
+ /**
+ Returns the string representation of the sal_Bool argument.
+
+ If the sal_Bool is true, the string "true" is returned.
+ If the sal_Bool is false, the string "false" is returned.
+ This function can't be used for language specific conversion.
+
+ @param b a sal_Bool.
+ @return a string with the string representation of the argument.
+ @deprecated use boolean()
+ */
+ SAL_DEPRECATED("use boolean()") static OUString valueOf( sal_Bool b )
+ {
+ return boolean(b);
+ }
+
+ /**
+ Returns the string representation of the boolean argument.
+
+ If the argument is true, the string "true" is returned.
+ If the argument is false, the string "false" is returned.
+ This function can't be used for language specific conversion.
+
+ @param b a bool.
+ @return a string with the string representation of the argument.
+ @since LibreOffice 4.1
+ */
+ static OUString boolean( bool b )
+ {
+ sal_Unicode aBuf[RTL_USTR_MAX_VALUEOFBOOLEAN];
+ return OUString(aBuf, rtl_ustr_valueOfBoolean(aBuf, b));
+ }
+#endif
+
+ /**
+ Returns the string representation of the char argument.
+
+ @param c a character.
+ @return a string with the string representation of the argument.
+ @deprecated use operator, function or constructor taking char or sal_Unicode argument
+ */
+ SAL_DEPRECATED("convert to OUString or use directly") static OUString valueOf( sal_Unicode c )
+ {
+ return OUString( &c, 1 );
+ }
+
+ /**
+ Returns the string representation of the int argument.
+
+ This function can't be used for language specific conversion.
+
+ @param i a int32.
+ @param radix the radix (between 2 and 36)
+ @return a string with the string representation of the argument.
+ @deprecated use number()
+ */
+ SAL_DEPRECATED("use number()") static OUString valueOf( sal_Int32 i, sal_Int16 radix = 10 )
+ {
+ return number( i, radix );
+ }
+
+ /**
+ Returns the string representation of the long argument.
+
+ This function can't be used for language specific conversion.
+
+ @param ll a int64.
+ @param radix the radix (between 2 and 36)
+ @return a string with the string representation of the argument.
+ @deprecated use number()
+ */
+ SAL_DEPRECATED("use number()") static OUString valueOf( sal_Int64 ll, sal_Int16 radix = 10 )
+ {
+ return number( ll, radix );
+ }
+
+ /**
+ Returns the string representation of the float argument.
+
+ This function can't be used for language specific conversion.
+
+ @param f a float.
+ @return a string with the string representation of the argument.
+ @deprecated use number()
+ */
+ SAL_DEPRECATED("use number()") static OUString valueOf( float f )
+ {
+ return number(f);
+ }
+
+ /**
+ Returns the string representation of the double argument.
+
+ This function can't be used for language specific conversion.
+
+ @param d a double.
+ @return a string with the string representation of the argument.
+ @deprecated use number()
+ */
+ SAL_DEPRECATED("use number()") static OUString valueOf( double d )
+ {
+ return number(d);
+ }
+
+ /**
+ Returns an OUString copied without conversion from an ASCII
+ character string.
+
+ Since this method is optimized for performance, the ASCII character
+ values are not converted in any way. The caller has to make sure that
+ all ASCII characters are in the allowed range between 0 and 127.
+ The ASCII string must be NULL-terminated.
+
+ Note that for string literals it is simpler and more efficient
+ to directly use the OUString constructor.
+
+ @param value the 8-Bit ASCII character string
+ @return a string with the string representation of the argument.
+ */
+ static OUString createFromAscii( const char * value )
+ {
+ rtl_uString* pNew = NULL;
+ rtl_uString_newFromAscii( &pNew, value );
+ return OUString( pNew, SAL_NO_ACQUIRE );
+ }
+
+#if defined LIBO_INTERNAL_ONLY
+ static OUString createFromAscii(std::string_view value) {
+ rtl_uString * p = nullptr;
+ rtl_uString_newFromLiteral(&p, value.data(), value.size(), 0); //TODO: check for overflow
+ return OUString(p, SAL_NO_ACQUIRE);
+ }
+ #endif
+
+#if defined LIBO_INTERNAL_ONLY
+ operator std::u16string_view() const { return {getStr(), sal_uInt32(getLength())}; }
+#endif
+
+#if defined LIBO_INTERNAL_ONLY
+ // A wrapper for the first expression in an
+ //
+ // OUString::Concat(e1) + e2 + ...
+ //
+ // concatenation chain, when neither of the first two e1, e2 is one of our rtl string-related
+ // classes (so something like
+ //
+ // OUString s = "a" + (b ? std::u16string_view(u"c") : std::u16string_view(u"dd"));
+ //
+ // would not compile):
+ template<typename T> [[nodiscard]] static
+ OUStringConcat<OUStringConcatMarker, T>
+ Concat(T const & value) { return OUStringConcat<OUStringConcatMarker, T>(value); }
+
+ // This overload is needed so that an argument of type 'char const[N]' ends up as
+ // 'OUStringConcat<rtl::OUStringConcatMarker, char const[N]>' rather than as
+ // 'OUStringConcat<rtl::OUStringConcatMarker, char[N]>':
+ template<typename T, std::size_t N> [[nodiscard]] static
+ OUStringConcat<OUStringConcatMarker, T[N]>
+ Concat(T (& value)[N]) { return OUStringConcat<OUStringConcatMarker, T[N]>(value); }
+#endif
+
+private:
+ OUString & internalAppend( rtl_uString* pOtherData )
+ {
+ rtl_uString* pNewData = NULL;
+ rtl_uString_newConcat( &pNewData, pData, pOtherData );
+ if (pNewData == NULL) {
+ throw std::bad_alloc();
+ }
+ rtl_uString_assign(&pData, pNewData);
+ rtl_uString_release(pNewData);
+ return *this;
+ }
+
+};
+
+#if defined LIBO_INTERNAL_ONLY
+// Prevent the operator ==/!= overloads with 'sal_Unicode const *' parameter from
+// being selected for nonsensical code like
+//
+// if (ouIdAttr == nullptr)
+//
+void operator ==(OUString const &, std::nullptr_t) = delete;
+void operator ==(std::nullptr_t, OUString const &) = delete;
+void operator !=(OUString const &, std::nullptr_t) = delete;
+void operator !=(std::nullptr_t, OUString const &) = delete;
+#endif
+
+#if defined LIBO_INTERNAL_ONLY && !defined RTL_STRING_UNITTEST
+inline bool operator ==(OUString const & lhs, StringConcatenation<char16_t> const & rhs)
+{ return lhs == std::u16string_view(rhs); }
+inline bool operator !=(OUString const & lhs, StringConcatenation<char16_t> const & rhs)
+{ return lhs != std::u16string_view(rhs); }
+inline bool operator ==(StringConcatenation<char16_t> const & lhs, OUString const & rhs)
+{ return std::u16string_view(lhs) == rhs; }
+inline bool operator !=(StringConcatenation<char16_t> const & lhs, OUString const & rhs)
+{ return std::u16string_view(lhs) != rhs; }
+#endif
+
+#if defined LIBO_INTERNAL_ONLY // "RTL_FAST_STRING"
+/// @cond INTERNAL
+
+/**
+ @internal
+*/
+template<>
+struct ToStringHelper< OUString >
+{
+ static std::size_t length( const OUString& s ) { return s.getLength(); }
+ sal_Unicode* operator() ( sal_Unicode* buffer, const OUString& s ) const { return addDataHelper( buffer, s.getStr(), s.getLength()); }
+};
+
+/**
+ @internal
+*/
+template<std::size_t N>
+struct ToStringHelper< OUStringLiteral<N> >
+{
+ static std::size_t length( const OUStringLiteral<N>& str ) { return str.getLength(); }
+ sal_Unicode* operator()( sal_Unicode* buffer, const OUStringLiteral<N>& str ) const { return addDataHelper( buffer, str.getStr(), str.getLength() ); }
+};
+
+/**
+ @internal
+*/
+template< typename charT, typename traits, typename T1, typename T2 >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, OUStringConcat< T1, T2 >&& concat)
+{
+ return stream << OUString( std::move(concat) );
+}
+
+/// @endcond
+#endif
+
+/** A helper to use OUStrings with hash maps.
+
+ Instances of this class are unary function objects that can be used as
+ hash function arguments to std::unordered_map and similar constructs.
+ */
+struct OUStringHash
+{
+ /** Compute a hash code for a string.
+
+ @param rString
+ a string.
+
+ @return
+ a hash code for the string. This hash code should not be stored
+ persistently, as its computation may change in later revisions.
+ */
+ size_t operator()(const OUString& rString) const
+ { return static_cast<size_t>(rString.hashCode()); }
+};
+
+/* ======================================================================= */
+
+/** Convert an OString to an OUString, using a specific text encoding.
+
+ The lengths of the two strings may differ (e.g., for double-byte
+ encodings, UTF-7, UTF-8).
+
+ @param rStr
+ an OString to convert.
+
+ @param encoding
+ the text encoding to use for conversion.
+
+ @param convertFlags
+ flags which control the conversion. Either use
+ OSTRING_TO_OUSTRING_CVTFLAGS, or see
+ <http://udk.openoffice.org/cpp/man/spec/textconversion.html> for more
+ details.
+ */
+#if defined LIBO_INTERNAL_ONLY
+inline OUString OStringToOUString( std::string_view rStr,
+ rtl_TextEncoding encoding,
+ sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS )
+{
+ return OUString( rStr.data(), rStr.length(), encoding, convertFlags );
+}
+#else
+inline OUString OStringToOUString( const OString & rStr,
+ rtl_TextEncoding encoding,
+ sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS )
+{
+ return OUString( rStr.getStr(), rStr.getLength(), encoding, convertFlags );
+}
+#endif
+
+/** Convert an OUString to an OString, using a specific text encoding.
+
+ The lengths of the two strings may differ (e.g., for double-byte
+ encodings, UTF-7, UTF-8).
+
+ @param rUnicode
+ an OUString to convert.
+
+ @param encoding
+ the text encoding to use for conversion.
+
+ @param convertFlags
+ flags which control the conversion. Either use
+ OUSTRING_TO_OSTRING_CVTFLAGS, or see
+ <http://udk.openoffice.org/cpp/man/spec/textconversion.html> for more
+ details.
+ */
+#if defined LIBO_INTERNAL_ONLY
+inline OString OUStringToOString( std::u16string_view rUnicode,
+ rtl_TextEncoding encoding,
+ sal_uInt32 convertFlags = OUSTRING_TO_OSTRING_CVTFLAGS )
+{
+ return OString( rUnicode.data(), rUnicode.length(), encoding, convertFlags );
+}
+#else
+inline OString OUStringToOString( const OUString & rUnicode,
+ rtl_TextEncoding encoding,
+ sal_uInt32 convertFlags = OUSTRING_TO_OSTRING_CVTFLAGS )
+{
+ return OString( rUnicode.getStr(), rUnicode.getLength(), encoding, convertFlags );
+}
+#endif
+
+/* ======================================================================= */
+
+/**
+ Support for rtl::OUString in std::ostream (and thus in
+ CPPUNIT_ASSERT or SAL_INFO macros, for example).
+
+ The rtl::OUString is converted to UTF-8.
+
+ @since LibreOffice 3.5.
+*/
+template< typename charT, typename traits >
+inline std::basic_ostream<charT, traits> & operator <<(
+ std::basic_ostream<charT, traits> & stream, OUString const & rString)
+{
+ return stream <<
+ OUStringToOString(rString, RTL_TEXTENCODING_UTF8);
+ // best effort; potentially loses data due to conversion failures
+ // (stray surrogate halves) and embedded null characters
+}
+
+} // namespace
+
+#ifdef RTL_STRING_UNITTEST
+namespace rtl
+{
+typedef rtlunittest::OUString OUString;
+}
+#endif
+
+// In internal code, allow to use classes like OUString without having to
+// explicitly refer to the rtl namespace, which is kind of superfluous given
+// that OUString itself is namespaced by its OU prefix:
+#if defined LIBO_INTERNAL_ONLY && !defined RTL_STRING_UNITTEST
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+using ::rtl::OStringToOUString;
+using ::rtl::OUStringToOString;
+using ::rtl::OUStringLiteral;
+using ::rtl::OUStringChar;
+using ::rtl::Concat2View;
+#endif
+
+#if defined LIBO_INTERNAL_ONLY && !(defined _MSC_VER && _MSC_VER <= 1929 && defined _MANAGED)
+
+template<
+#if defined RTL_STRING_UNITTEST
+ rtlunittest::
+#endif
+ OUStringLiteral L>
+constexpr
+#if defined RTL_STRING_UNITTEST
+ rtlunittest::
+#endif
+ OUString
+operator ""_ustr() { return L; }
+
+#endif
+
+/// @cond INTERNAL
+/**
+ Make OUString hashable by default for use in STL containers.
+
+ @since LibreOffice 6.0
+*/
+#if defined LIBO_INTERNAL_ONLY
+namespace std {
+
+template<>
+struct hash<::rtl::OUString>
+{
+ std::size_t operator()(::rtl::OUString const & s) const
+ {
+ if constexpr (sizeof(std::size_t) == 8)
+ {
+ // return a hash that uses the full 64-bit range instead of a 32-bit value
+ size_t n = s.getLength();
+ for (sal_Int32 i = 0, len = s.getLength(); i < len; ++i)
+ n = 37 * n + s[i];
+ return n;
+ }
+ else
+ return std::size_t(s.hashCode());
+ }
+};
+
+}
+
+#endif
+/// @endcond
+
+#endif /* _RTL_USTRING_HXX */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/rtl/uuid.h b/include/rtl/uuid.h
new file mode 100644
index 0000000000..e65c5e12b4
--- /dev/null
+++ b/include/rtl/uuid.h
@@ -0,0 +1,186 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * 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 .
+ */
+
+/*
+ * This file is part of LibreOffice published API.
+ */
+#ifndef INCLUDED_RTL_UUID_H
+#define INCLUDED_RTL_UUID_H
+
+#include "sal/config.h"
+
+#include "rtl/string.h"
+#include "sal/saldllapi.h"
+#include "sal/types.h"
+
+/**
+ @file
+ Specification (from draft-leach-uuids-guids-01.txt )
+
+ <p>
+ A UUID is an identifier that is unique across both space and time,
+ with respect to the space of all UUIDs. To be precise, the UUID
+ consists of a finite bit space. Thus, collision cannot be avoided in
+ principle. A UUID can be used for multiple purposes, from tagging objects
+ with an extremely short lifetime, to reliably identifying very persistent
+ objects across a network.
+
+ <p>
+ The generation of UUIDs does not require that a registration
+ authority be contacted for each identifier. Instead, Version 4 UUIDs are
+ generated from (pseudo unique) sequences of (pseudo) random bits.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Generates a new Version 4 (random number based) UUID (Universally Unique
+ IDentifier).
+
+ @param pTargetUUID pointer to at least 16 bytes of memory. After the call it contains
+ the newly generated uuid in network byte order.
+ @param pPredecessorUUID ignored (was used when this function returned
+ Version 1 instead of Version 4 UUIDs).
+ @param bUseEthernetAddress ignored (was used when this function returned
+ Version 1 instead of Version 4 UUIDs).
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_createUuid(
+ sal_uInt8 *pTargetUUID,
+ const sal_uInt8 *pPredecessorUUID,
+ sal_Bool bUseEthernetAddress );
+
+/** Compare two UUID's lexically
+
+ <p>
+ Note: lexical ordering is not temporal ordering!
+ <p>
+ Note: For equalnesschecking, a memcmp(pUUID1,pUUID2,16) is more efficient
+
+ @return
+ <ul>
+ <li>-1 u1 is lexically before u2
+ <li>0 u1 is equal to u2
+ <li>1 u1 is lexically after u2
+ </ul>
+
+ */
+SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_compareUuid(
+ const sal_uInt8 *pUUID1 , const sal_uInt8 *pUUID2 );
+
+/** Creates named UUIDs.
+
+ <p>
+ The version 3 UUID is meant for generating UUIDs from <em>names</em> that
+ are drawn from, and unique within, some <em>name space</em>. Some examples
+ of names (and, implicitly, name spaces) might be DNS names, URLs, ISO
+ Object IDs (OIDs), reserved words in a programming language, or X.500
+ Distinguished Names (DNs); thus, the concept of name and name space
+ should be broadly construed, and not limited to textual names.
+
+ <p>
+ The requirements for such UUIDs are as follows:
+
+ <ul>
+ <li> The UUIDs generated at different times from the same name in the
+ same namespace MUST be equal
+
+ <li> The UUIDs generated from two different names in the same namespace
+ should be different (with very high probability)
+
+ <li> The UUIDs generated from the same name in two different namespaces
+ should be different with (very high probability)
+
+ <li> If two UUIDs that were generated from names are equal, then they
+ were generated from the same name in the same namespace (with very
+ high probability).
+ </ul>
+
+ @param pTargetUUID pointer to at least 16 bytes of memory. After the call
+ it contains the newly generated uuid in network byte order.
+ @param pNameSpaceUUID The namespace uuid. Below are some predefined ones,
+ but any arbitrary uuid can be used as namespace.
+
+ @param pName the name
+ */
+SAL_DLLPUBLIC void SAL_CALL rtl_createNamedUuid(
+ sal_uInt8 *pTargetUUID,
+ const sal_uInt8 *pNameSpaceUUID,
+ const rtl_String *pName
+ );
+
+
+
+/*
+ Predefined Namespaces
+ (Use them the following way : sal_uInt8 aNsDNS[16]) = RTL_UUID_NAMESPACE_DNS;
+ */
+/** namespace DNS
+
+ <p>
+ (Use them the following way : sal_uInt8 aNsDNS[16]) = RTL_UUID_NAMESPACE_DNS;
+ <p>
+ 6ba7b810-9dad-11d1-80b4-00c04fd430c8 */
+#define RTL_UUID_NAMESPACE_DNS {\
+ 0x6b,0xa7,0xb8,0x10,\
+ 0x9d,0xad,\
+ 0x11,0xd1,\
+ 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8\
+ }
+
+/** namespace URL
+
+ <p>
+ 6ba7b811-9dad-11d1-80b4-00c04fd430c8 */
+#define RTL_UUID_NAMESPACE_URL { \
+ 0x6b, 0xa7, 0xb8, 0x11,\
+ 0x9d, 0xad,\
+ 0x11, 0xd1,\
+ 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8\
+ }
+
+/** namespace oid
+
+ <p>
+ 6ba7b812-9dad-11d1-80b4-00c04fd430c8 */
+#define RTL_UUID_NAMESPACE_OID {\
+ 0x6b, 0xa7, 0xb8, 0x12,\
+ 0x9d, 0xad,\
+ 0x11, 0xd1,\
+ 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8\
+ }
+
+/** namespace X500
+
+ <p>
+ 6ba7b814-9dad-11d1-80b4-00c04fd430c8 */
+#define RTL_UUID_NAMESPACE_X500 {\
+ 0x6b, 0xa7, 0xb8, 0x14,\
+ 0x9d, 0xad,\
+ 0x11, 0xd1,\
+ 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8\
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */