- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages
- Examples

# 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 |