![]() |
![]() |
|
|
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: 8th April 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 14 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 /* ////////////////////////////////////////////////////////////////////// */
|
|
FastFormat Library documentation © Matthew Wilson, 2006-2009 |
|