Synesis Software STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ...

fastformat/sinks/auto_buffer.hpp

Go to the documentation of this file.
00001 /* /////////////////////////////////////////////////////////////////////////
00002  * File:        fastformat/sinks/auto_buffer.hpp
00003  *
00004  * Purpose:     A FastFormat sink for STLSoft's auto_buffer class template.
00005  *
00006  * Created:     21st April 2008
00007  * Updated:     11th August 2009
00008  *
00009  * Home:        http://www.fastformat.org/
00010  *
00011  * Copyright (c) 2008-2009, Matthew Wilson and Synesis Software
00012  * All rights reserved.
00013  *
00014  * Redistribution and use in source and binary forms, with or without
00015  * modification, are permitted provided that the following conditions are
00016  * met:
00017  *
00018  * - Redistributions of source code must retain the above copyright notice,
00019  *   this list of conditions and the following disclaimer.
00020  * - Redistributions in binary form must reproduce the above copyright
00021  *   notice, this list of conditions and the following disclaimer in the
00022  *   documentation and/or other materials provided with the distribution.
00023  * - Neither the names of Matthew Wilson and Synesis Software nor the names
00024  *   of any contributors may be used to endorse or promote products derived
00025  *   from this software without specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00028  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
00029  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00030  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
00031  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00032  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00033  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00034  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00035  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00036  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00037  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00038  *
00039  * ////////////////////////////////////////////////////////////////////// */
00040 
00041 
00047 #ifndef FASTFORMAT_INCL_FASTFORMAT_SINK_HPP_AUTO_BUFFER
00048 #define FASTFORMAT_INCL_FASTFORMAT_SINK_HPP_AUTO_BUFFER
00049 
00050 /* /////////////////////////////////////////////////////////////////////////
00051  * Version information
00052  */
00053 
00054 #ifndef FASTFORMAT_DOCUMENTATION_SKIP_SECTION
00055 # define FASTFORMAT_VER_FASTFORMAT_SINK_HPP_AUTO_BUFFER_SINK_MAJOR      1
00056 # define FASTFORMAT_VER_FASTFORMAT_SINK_HPP_AUTO_BUFFER_SINK_MINOR      1
00057 # define FASTFORMAT_VER_FASTFORMAT_SINK_HPP_AUTO_BUFFER_SINK_REVISION   2
00058 # define FASTFORMAT_VER_FASTFORMAT_SINK_HPP_AUTO_BUFFER_SINK_EDIT       15
00059 #endif /* !FASTFORMAT_DOCUMENTATION_SKIP_SECTION */
00060 
00061 /* /////////////////////////////////////////////////////////////////////////
00062  * Language
00063  */
00064 
00065 #ifndef __cplusplus
00066 # error This file can only be included in C++ compilation units
00067 #endif /* !__cplusplus */
00068 
00069 /* /////////////////////////////////////////////////////////////////////////
00070  * Includes
00071  */
00072 
00073 #include <fastformat/fastformat.h>
00074 #include <fastformat/quality/contract.h>
00075 #include <fastformat/util/sinks/helpers.hpp>
00076 #include <fastformat/format/standard_flags.hpp>
00077 
00078 #include <fastformat/util/memory/auto_buffer_selector.hpp>
00079 
00080 /* /////////////////////////////////////////////////////////////////////////
00081  * Compatibility
00082  */
00083 
00084 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00085     _MSC_VER < 1310
00086 # ifndef FASTFORMAT_NO_IMPLICIT_ACTION_SHIMS
00087 #  define FASTFORMAT_AUTO_BUFFER_SINK_ONLY_SIMPLE_FORM_SUPPORT
00088 # endif /* !FASTFORMAT_NO_IMPLICIT_ACTION_SHIMS */
00089 #endif /* compiler */
00090 
00091 /* /////////////////////////////////////////////////////////////////////////
00092  * Namespace
00093  */
00094 
00095 #if !defined(FASTFORMAT_NO_NAMESPACE)
00096 namespace fastformat
00097 {
00098 namespace sinks
00099 {
00100 #endif /* !FASTFORMAT_NO_NAMESPACE */
00101 
00102 /* /////////////////////////////////////////////////////////////////////////
00103  * Classes
00104  */
00105 
00106 /* /////////////////////////////////////////////////////////////////////////
00107  * Action Shims
00108  */
00109 
00110 #ifndef STLSOFT_AUTO_BUFFER_NEW_FORM
00111 # error This is only compatible with stlsoft::auto_buffer in new mode
00112 #endif /* !STLSOFT_AUTO_BUFFER_NEW_FORM */
00113 
00130 #ifndef FASTFORMAT_AUTO_BUFFER_SINK_ONLY_SIMPLE_FORM_SUPPORT
00131 template <typename C, size_t N, typename A>
00132 inline stlsoft::auto_buffer<C, N, A>& fmt_slices(
00133     stlsoft::auto_buffer<C, N, A>&      sink
00134 #else /* ? !FASTFORMAT_AUTO_BUFFER_SINK_ONLY_SIMPLE_FORM_SUPPORT */
00135 inline stlsoft::auto_buffer<ff_char_t>& fmt_slices(
00136     stlsoft::auto_buffer<ff_char_t>&    sink
00137 #endif /* !FASTFORMAT_AUTO_BUFFER_SINK_ONLY_SIMPLE_FORM_SUPPORT */
00138 ,   int                                 flags
00139 ,   size_t                              cchTotal
00140 ,   size_t                              numResults
00141 ,   ff_string_slice_t const*            results
00142 )
00143 {
00144 #ifndef FASTFORMAT_AUTO_BUFFER_SINK_ONLY_SIMPLE_FORM_SUPPORT
00145     typedef C           char_t;
00146 #else /* ? !FASTFORMAT_AUTO_BUFFER_SINK_ONLY_SIMPLE_FORM_SUPPORT */
00147     typedef ff_char_t   char_t;
00148 #endif /* !FASTFORMAT_AUTO_BUFFER_SINK_ONLY_SIMPLE_FORM_SUPPORT */
00149 
00150     STLSOFT_STATIC_ASSERT(sizeof(char_t) == sizeof(ff_char_t));
00151 
00152     // There're some complications with the size here:
00153     //
00154     //  - auto_buffer is guaranteed not to discard allocated memory as long
00155     //    as resize(0) is not called
00156     //  - we want strong exception semantics
00157     //
00158     // Consequently we ask for the maximum possible size, which is
00159     //  <current-size> + cchTotal + 1 (for '\0') + 2 (for CR / LF). We will
00160     // subsequently discard some of this if not needed, without risking
00161     // needing to ask again for more memory later
00162 
00163     const size_t            initialSize = sink.size();
00164 
00165     // do the resize
00166     if(sink.resize(initialSize + cchTotal + 1 + 2)) // Check for alloc failure, even though will never return false when exception-handling support is on
00167     {
00168         size_t currentSize = initialSize;
00169 
00170         // first we check for a current trailing nul character
00171 
00172         if( 0 != currentSize && 
00173             '\0' == sink[currentSize - 1])
00174         {
00175             --currentSize;
00176         }
00177 
00178         // next we concatenate all the slices
00179 
00180         ff_char_t* p = sink.data() + currentSize;
00181 
00182         { for(size_t i = 0; i < numResults; ++i)
00183         {
00184             ff_string_slice_t const& slice = results[i];
00185 
00186             ::memcpy(p, slice.ptr, slice.len * sizeof(char_t));
00187             p += slice.len;
00188         }}
00189 
00190         // then append the new line, if required
00191 
00192         if(flags::ff_newLine & flags)
00193         {
00194             const ff_string_slice_t crlf = fastformat_getNewlineForPlatform();
00195 
00196             ::memcpy(p, crlf.ptr, crlf.len * sizeof(char_t));
00197             p += crlf.len;
00198         }
00199 
00200         // finally we append the terminating nul character
00201 
00202         *p++ = '\0';
00203 
00204         FASTFORMAT_CONTRACT_ENFORCE_POSTCONDITION_STATE_APPL_LAYER(p <= sink.end(), "auto_buffer sink writing logic failed: write pointer exceeds available space");
00205         FASTFORMAT_CONTRACT_ENFORCE_POSTCONDITION_STATE_APPL_LAYER(static_cast<size_t>(p - sink.data()) <= sink.size(), "auto_buffer sink writing logic failed: write pointer exceeds available space");
00206         //FASTFORMAT_CONTRACT_ENFORCE_POSTCONDITION_STATE_APPL_LAYER(static_cast<size_t>(p - sink.data()) == currentSize, "auto_buffer sink writing logic failed: write pointer exceeds available space");
00207         FASTFORMAT_CONTRACT_ENFORCE_POSTCONDITION_STATE_APPL_LAYER(((sink.data() + currentSize) - p) < static_cast<ptrdiff_t>(fastformat_getNewlineForPlatform().len), "auto_buffer sink writing logic failed: write pointer exceeds available space");
00208 
00209         sink.resize(static_cast<size_t>(p - sink.data()));
00210     }
00211 
00212     return sink;
00213 }
00214 
00215 /* /////////////////////////////////////////////////////////////////////////
00216  * Namespace
00217  */
00218 
00219 #if !defined(FASTFORMAT_NO_NAMESPACE)
00220 } /* namespace sinks */
00221 } /* namespace fastformat */
00222 #endif /* !FASTFORMAT_NO_NAMESPACE */
00223 
00224 /* ////////////////////////////////////////////////////////////////////// */
00225 
00226 #endif /* FASTFORMAT_INCL_FASTFORMAT_SINK_HPP_AUTO_BUFFER */
00227 
00228 /* ///////////////////////////// end of file //////////////////////////// */

FastFormat Library documentation © Matthew Wilson, 2006-2009 SourceForge.net Logo