/* ///////////////////////////////////////////////////////////////////////// * File: stlsoft/string/cstring_maker.hpp * * Purpose: Simple utility class for creating (constant) C-strings. * * Created: 14th May 2004 * Updated: 17th April 2012 * * Home: http://stlsoft.org/ * * Copyright (c) 2004-2012, Matthew Wilson and Synesis Software * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of * any contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * ////////////////////////////////////////////////////////////////////// */ /** \file stlsoft/string/cstring_maker.hpp * * \brief [C++ only] Definition of the stlsoft::string_maker class template * (\ref group__library__string "String" Library). */ #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_CSTRING_MAKER #define STLSOFT_INCL_STLSOFT_STRING_HPP_CSTRING_MAKER #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION # define STLSOFT_VER_STLSOFT_STRING_HPP_CSTRING_MAKER_MAJOR 4 # define STLSOFT_VER_STLSOFT_STRING_HPP_CSTRING_MAKER_MINOR 0 # define STLSOFT_VER_STLSOFT_STRING_HPP_CSTRING_MAKER_REVISION 2 # define STLSOFT_VER_STLSOFT_STRING_HPP_CSTRING_MAKER_EDIT 46 #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */ /* ///////////////////////////////////////////////////////////////////////// * Includes */ #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT # include #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */ #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_CHAR_TRAITS # include #endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_CHAR_TRAITS */ #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_BASE # include // for STLSOFT_LF_ALLOCATOR_REBIND_SUPPORT #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_BASE */ #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR # include #endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR */ /* ///////////////////////////////////////////////////////////////////////// * Namespace */ #ifndef _STLSOFT_NO_NAMESPACE namespace stlsoft { #endif /* _STLSOFT_NO_NAMESPACE */ /* ///////////////////////////////////////////////////////////////////////// * Classes */ #if !defined(_STLSOFT_NO_NAMESPACE) && \ ( !defined(STLSOFT_COMPILER_IS_MSVC) || \ _MSC_VER > 1200) namespace { #endif /* _STLSOFT_NO_NAMESPACE */ #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION template struct char_to_byte__traits_ { static ss_size_t byte_size_(ss_size_t cch) { return cch * sizeof(C); } }; STLSOFT_TEMPLATE_SPECIALISATION struct char_to_byte__traits_ { static ss_size_t byte_size_(ss_size_t cch) { return cch; } }; #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */ #if !defined(_STLSOFT_NO_NAMESPACE) && \ ( !defined(STLSOFT_COMPILER_IS_MSVC) || \ _MSC_VER > 1200) } // anonymous namespace #endif /* _STLSOFT_NO_NAMESPACE */ /** \brief Utility class that creates/destroys fixed-size C-strings for * other classes. * * \ingroup group__library__string */ #if defined(STLSOFT_DOCUMENTATION_SKIP_SECTION) || \ ( ( !defined(STLSOFT_COMPILER_IS_GCC) || \ __GNUC__ >= 3) && \ ( !defined(STLSOFT_COMPILER_IS_MSVC) || \ _MSC_VER != 1100)) template< ss_typename_param_k C , ss_typename_param_k A = ss_typename_type_def_k allocator_selector::allocator_type , ss_typename_param_k T = stlsoft_char_traits > struct cstring_maker { typedef C char_type; typedef A allocator_type; typedef T traits_type; typedef ss_size_t size_type; typedef cstring_maker class_type; private: struct block { size_type n; char_type data[1]; }; public: /// Allocates uninitialised storage for writing into a string /// /// \note Includes space for a nul-terminator character /// /// \param cch The number of characters to allocate static char_type* alloc(size_type cch) { #if defined(WIN32) || \ defined(_WIN32) cch = char_to_byte__traits_::byte_size_(cch); #endif /* WIN32 || _WIN32 */ size_type cb = offsetof(block, data) + sizeof(char_type) * (1 + cch); #ifdef STLSOFT_LF_ALLOCATOR_REBIND_SUPPORT ss_typename_type_k allocator_type::ss_template_qual_k rebind::other byte_ator; #else /* ? STLSOFT_LF_ALLOCATOR_REBIND_SUPPORT */ allocator_selector::allocator_type byte_ator; #endif /* STLSOFT_LF_ALLOCATOR_REBIND_SUPPORT */ cb = (cb + 31) & ~31; block *pblock = static_cast(static_cast(byte_ator.allocate(cb, NULL))); if(NULL == pblock) { return NULL; } else { pblock->n = cch; pblock->data[cch] = '\0'; return &pblock->data[0]; } } /// Allocates a new copy of the given string /// /// \note Includes nul-terminator character /// /// \param s The string to copy. Cannot be null pointer static char_type* dup(char_type const* s) { STLSOFT_ASSERT(NULL != s); size_type len = traits_type::length(s); char_type *s_ = alloc(len); if(NULL != s_) { traits_type::copy(s_, s, 1 + len); } return s_; } /// Allocates a new copy of the given string, or returns NULL if given null string /// /// \note Includes nul-terminator character /// /// \param s The string to copy. Can be null pointer, in which case NULL is returned static char_type* dup_null(char_type const* s) { return (NULL == s) ? NULL : dup(s); } /// Releases the storage associated with the string /// /// \param s The string to free static void free(char_type* s) { #ifdef STLSOFT_LF_ALLOCATOR_REBIND_SUPPORT ss_typename_type_k allocator_type::ss_template_qual_k rebind::other byte_ator; #else /* ? STLSOFT_LF_ALLOCATOR_REBIND_SUPPORT */ allocator_selector::allocator_type byte_ator; #endif /* STLSOFT_LF_ALLOCATOR_REBIND_SUPPORT */ if(NULL != s) { union { ss_byte_t *py; block *pblock; } u; u.py = static_cast(static_cast(s)) - offsetof(block, data); STLSOFT_ASSERT(u.pblock->data[u.pblock->n] == '\0'); byte_ator.deallocate(u.py, u.pblock->n); } } }; #else /* ? _MSC_VER */ template< ss_typename_param_k C > struct cstring_maker; STLSOFT_TEMPLATE_SPECIALISATION struct cstring_maker { public: typedef char char_type; typedef allocator_selector::allocator_type allocator_type; typedef char_traits traits_type; typedef ss_size_t size_type; typedef cstring_maker class_type; public: static char_type* alloc(size_type cch) { return static_cast(malloc((1 + cch) * sizeof(char_type))); } static char_type* dup(char_type const* s) { return strdup(s); } static char_type* dup_null(char_type const* s) { return (NULL == s) ? NULL : dup(s); } static void free(char_type* s) { ::free(s); } }; # if !defined(STLSOFT_COMPILER_IS_GCC) STLSOFT_TEMPLATE_SPECIALISATION struct cstring_maker { public: typedef wchar_t char_type; typedef allocator_selector::allocator_type allocator_type; typedef char_traits traits_type; typedef ss_size_t size_type; typedef cstring_maker class_type; public: static char_type* alloc(size_type cch) { return static_cast(malloc((1 + cch) * sizeof(char_type))); } static char_type* dup(char_type const* s) { return _wcsdup(s); } static char_type* dup_null(char_type const* s) { return (NULL == s) ? NULL : dup(s); } static void free(char_type* s) { ::free(s); } }; # endif /* compiler */ #endif /* _MSC_VER != 1100 */ //////////////////////////////////////////////////////////////////////////// // Unit-testing #ifdef STLSOFT_UNITTEST # include "./unittest/cstring_maker_unittest_.h" #endif /* STLSOFT_UNITTEST */ /* ////////////////////////////////////////////////////////////////////// */ #ifndef _STLSOFT_NO_NAMESPACE } // namespace stlsoft #endif /* _STLSOFT_NO_NAMESPACE */ /* ////////////////////////////////////////////////////////////////////// */ #endif /* !STLSOFT_INCL_STLSOFT_STRING_HPP_CSTRING_MAKER */ /* ///////////////////////////// end of file //////////////////////////// */