00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef RTL_STRINGCONCAT_HXX
00011 #define RTL_STRINGCONCAT_HXX
00012
00013 #include <rtl/stringutils.hxx>
00014
00015 #include <string.h>
00016
00017 #ifdef RTL_FAST_STRING
00018
00019 #ifdef RTL_STRING_UNITTEST
00020 #define rtl rtlunittest
00021 #endif
00022 namespace rtl
00023 {
00024 #ifdef RTL_STRING_UNITTEST
00025 #undef rtl
00026 #endif
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00047 template< typename T >
00048 struct ToStringHelper
00049 {
00051 static int length( const T& );
00053 static char* addData( char* buffer, const T& );
00055 static sal_Unicode* addData( sal_Unicode* buffer, const T& );
00057 static const bool allowOStringConcat = false;
00059 static const bool allowOUStringConcat = false;
00060 };
00061
00062 inline
00063 char* addDataHelper( char* buffer, const char* data, int length )
00064 {
00065 memcpy( buffer, data, length );
00066 return buffer + length;
00067 }
00068
00069 inline
00070 sal_Unicode* addDataHelper( sal_Unicode* buffer, const sal_Unicode* data, int length )
00071 {
00072 memcpy( buffer, data, length * sizeof( sal_Unicode ));
00073 return buffer + length;
00074 }
00075
00076 inline
00077 sal_Unicode* addDataLiteral( sal_Unicode* buffer, const char* data, int length )
00078 {
00079 while( length-- > 0 )
00080 *buffer++ = *data++;
00081 return buffer;
00082 }
00083
00084 inline
00085 char* addDataCString( char* buffer, const char* str )
00086 {
00087 while( *str != '\0' )
00088 *buffer++ = *str++;
00089 return buffer;
00090 }
00091
00092 inline
00093 sal_Unicode* addDataUString( sal_Unicode* buffer, const sal_Unicode* str )
00094 {
00095 while( *str != '\0' )
00096 *buffer++ = *str++;
00097 return buffer;
00098 }
00099
00100 template<>
00101 struct ToStringHelper< const char* >
00102 {
00103 static int length( const char* str ) {
00104 return sal::static_int_cast<int>(strlen( str ));
00105 }
00106 static char* addData( char* buffer, const char* str ) { return addDataCString( buffer, str ); }
00107 static const bool allowOStringConcat = true;
00108 static const bool allowOUStringConcat = false;
00109 };
00110
00111 template<>
00112 struct ToStringHelper< char* >
00113 {
00114 static int length( const char* str ) {
00115 return sal::static_int_cast<int>(strlen( str ));
00116 }
00117 static char* addData( char* buffer, const char* str ) { return addDataCString( buffer, str ); }
00118 static const bool allowOStringConcat = true;
00119 static const bool allowOUStringConcat = false;
00120 };
00121
00122 template< int N >
00123 struct ToStringHelper< char[ N ] >
00124 {
00125 static int length( const char str[ N ] ) {
00126 return sal::static_int_cast<int>(strlen( str ));
00127 }
00128 static char* addData( char* buffer, const char str[ N ] ) { return addDataCString( buffer, str ); }
00129 static sal_Unicode* addData( sal_Unicode* buffer, const char str[ N ] ) { return addDataLiteral( buffer, str, N - 1 ); }
00130 static const bool allowOStringConcat = true;
00131 static const bool allowOUStringConcat = false;
00132 };
00133
00134 template< int N >
00135 struct ToStringHelper< const char[ N ] >
00136 {
00137 static int length( const char str[ N ] ) { (void)str; assert( strlen( str ) == N - 1 ); return N - 1; }
00138 static char* addData( char* buffer, const char str[ N ] ) { return addDataHelper( buffer, str, N - 1 ); }
00139 static sal_Unicode* addData( sal_Unicode* buffer, const char str[ N ] ) { return addDataLiteral( buffer, str, N - 1 ); }
00140 static const bool allowOStringConcat = true;
00141 static const bool allowOUStringConcat = true;
00142 };
00143
00150 template< typename T1, typename T2 >
00151 struct OStringConcat
00152 {
00153 public:
00154 OStringConcat( const T1& left_, const T2& right_ ) : left( left_ ), right( right_ ) {}
00155 int length() const { return ToStringHelper< T1 >::length( left ) + ToStringHelper< T2 >::length( right ); }
00156 char* addData( char* buffer ) const { return ToStringHelper< T2 >::addData( ToStringHelper< T1 >::addData( buffer, left ), right ); }
00157
00158
00159
00160 private:
00161 const T1& left;
00162 const T2& right;
00163 };
00164
00171 template< typename T1, typename T2 >
00172 struct OUStringConcat
00173 {
00174 public:
00175 OUStringConcat( const T1& left_, const T2& right_ ) : left( left_ ), right( right_ ) {}
00176 int length() const { return ToStringHelper< T1 >::length( left ) + ToStringHelper< T2 >::length( right ); }
00177 sal_Unicode* addData( sal_Unicode* buffer ) const { return ToStringHelper< T2 >::addData( ToStringHelper< T1 >::addData( buffer, left ), right ); }
00178 private:
00179 const T1& left;
00180 const T2& right;
00181 };
00182
00183 template< typename T1, typename T2 >
00184 struct ToStringHelper< OStringConcat< T1, T2 > >
00185 {
00186 static int length( const OStringConcat< T1, T2 >& c ) { return c.length(); }
00187 static char* addData( char* buffer, const OStringConcat< T1, T2 >& c ) { return c.addData( buffer ); }
00188 static const bool allowOStringConcat = ToStringHelper< T1 >::allowOStringConcat && ToStringHelper< T2 >::allowOStringConcat;
00189 static const bool allowOUStringConcat = false;
00190 };
00191
00192 template< typename T1, typename T2 >
00193 struct ToStringHelper< OUStringConcat< T1, T2 > >
00194 {
00195 static int length( const OUStringConcat< T1, T2 >& c ) { return c.length(); }
00196 static sal_Unicode* addData( sal_Unicode* buffer, const OUStringConcat< T1, T2 >& c ) { return c.addData( buffer ); }
00197 static const bool allowOStringConcat = false;
00198 static const bool allowOUStringConcat = ToStringHelper< T1 >::allowOUStringConcat && ToStringHelper< T2 >::allowOUStringConcat;
00199 };
00200
00201 template< typename T1, typename T2 >
00202 inline
00203 SAL_WARN_UNUSED_RESULT
00204 typename internal::Enable< OStringConcat< T1, T2 >, ToStringHelper< T1 >::allowOStringConcat && ToStringHelper< T2 >::allowOStringConcat >::Type operator+( const T1& left, const T2& right )
00205 {
00206 return OStringConcat< T1, T2 >( left, right );
00207 }
00208
00209
00210 template< typename T, int N >
00211 inline
00212 SAL_WARN_UNUSED_RESULT
00213 typename internal::Enable< OStringConcat< T, const char[ N ] >, ToStringHelper< T >::allowOStringConcat >::Type operator+( const T& left, const char (&right)[ N ] )
00214 {
00215 return OStringConcat< T, const char[ N ] >( left, right );
00216 }
00217
00218 template< typename T, int N >
00219 inline
00220 SAL_WARN_UNUSED_RESULT
00221 typename internal::Enable< OStringConcat< const char[ N ], T >, ToStringHelper< T >::allowOStringConcat >::Type operator+( const char (&left)[ N ], const T& right )
00222 {
00223 return OStringConcat< const char[ N ], T >( left, right );
00224 }
00225
00226 template< typename T, int N >
00227 inline
00228 SAL_WARN_UNUSED_RESULT
00229 typename internal::Enable< OStringConcat< T, char[ N ] >, ToStringHelper< T >::allowOStringConcat >::Type operator+( const T& left, char (&right)[ N ] )
00230 {
00231 return OStringConcat< T, char[ N ] >( left, right );
00232 }
00233
00234 template< typename T, int N >
00235 inline
00236 SAL_WARN_UNUSED_RESULT
00237 typename internal::Enable< OStringConcat< char[ N ], T >, ToStringHelper< T >::allowOStringConcat >::Type operator+( char (&left)[ N ], const T& right )
00238 {
00239 return OStringConcat< char[ N ], T >( left, right );
00240 }
00241
00242 template< typename T1, typename T2 >
00243 inline
00244 typename internal::Enable< OUStringConcat< T1, T2 >, ToStringHelper< T1 >::allowOUStringConcat && ToStringHelper< T2 >::allowOUStringConcat >::Type operator+( const T1& left, const T2& right )
00245 {
00246 return OUStringConcat< T1, T2 >( left, right );
00247 }
00248
00249 template< typename T1, typename T2 >
00250 inline
00251 typename internal::Enable< OUStringConcat< T1, T2 >, ToStringHelper< T1 >::allowOUStringConcat && ToStringHelper< T2 >::allowOUStringConcat && internal::ConstCharArrayDetector< T1, void >::ok >::Type operator+( T1& left, const T2& right )
00252 {
00253 return OUStringConcat< T1, T2 >( left, right );
00254 }
00255
00256 template< typename T1, typename T2 >
00257 inline
00258 typename internal::Enable< OUStringConcat< T1, T2 >, ToStringHelper< T1 >::allowOUStringConcat && ToStringHelper< T2 >::allowOUStringConcat && internal::ConstCharArrayDetector< T2, void >::ok >::Type operator+( const T1& left, T2& right )
00259 {
00260 return OUStringConcat< T1, T2 >( left, right );
00261 }
00262
00263 }
00264
00265 #endif
00266
00267 #endif