00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00047 #ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_PATH_FUNCTIONS
00048 #define UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_PATH_FUNCTIONS
00049
00050 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00051 # define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_PATH_FUNCTIONS_MAJOR 1
00052 # define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_PATH_FUNCTIONS_MINOR 1
00053 # define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_PATH_FUNCTIONS_REVISION 5
00054 # define UNIXSTL_VER_UNIXSTL_FILESYSTEM_HPP_PATH_FUNCTIONS_EDIT 12
00055 #endif
00056
00057
00058
00059
00060
00061 #ifndef UNIXSTL_INCL_UNIXSTL_H_UNIXSTL
00062 # include <unixstl/unixstl.h>
00063 #endif
00064
00065 #ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
00066 # include <unixstl/filesystem/filesystem_traits.hpp>
00067 #endif
00068 #ifndef UNIXSTL_INCL_UNIXSTL_FILESYSTEM_HPP_PATH
00069 # include <unixstl/filesystem/path.hpp>
00070 #endif
00071 #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
00072 # include <stlsoft/shims/access/string.hpp>
00073 #endif
00074 #if defined(_WIN32) || \
00075 defined(_WIN64)
00076 # include <ctype.h>
00077 #endif
00078
00079 #ifdef STLSOFT_UNITTEST
00080 #endif // STLSOFT_UNITTEST
00081
00082
00083
00084
00085
00086 #ifndef _UNIXSTL_NO_NAMESPACE
00087 # if defined(_STLSOFT_NO_NAMESPACE) || \
00088 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00089
00090 namespace unixstl
00091 {
00092 # else
00093
00094
00095 namespace stlsoft
00096 {
00097
00098 namespace unixstl_project
00099 {
00100
00101 # endif
00102 #endif
00103
00104
00105
00106
00107
00108 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00109
00110 template <ss_typename_param_k C>
00111 us_size_t path_squeeze_impl(
00112 C const* path
00113 , us_size_t pathLen
00114 , C* buffer
00115 , us_size_t cchBuffer
00116 )
00117 {
00118 typedef C char_t;
00119 typedef filesystem_traits<C> traits_t;
00120 typedef us_size_t size_t;
00121
00122 if(NULL == buffer)
00123 {
00124 cchBuffer = pathLen + 1u;
00125 }
00126 else if(0 != cchBuffer)
00127 {
00128 basic_path<char_t> p(path, pathLen);
00129 char_t const* file_ptr = p.get_file();
00130 char_t const* path_ptr = p.c_str();
00131 const size_t fileLen = p.size() - (file_ptr - path_ptr);
00132
00133 if(cchBuffer > pathLen)
00134 {
00135
00136
00137 traits_t::char_copy(buffer, path_ptr, pathLen);
00138 buffer[pathLen] = '\0';
00139
00140 cchBuffer = pathLen + 1u;
00141 }
00142 else
00143 {
00144 size_t rootLen;
00145
00146
00147
00148
00149
00150
00151
00152
00153 if(p.is_rooted())
00154 {
00155 if(p.is_absolute())
00156 {
00157 if(traits_t::is_path_UNC(path_ptr))
00158 {
00159
00160
00161 char_t const* p1 = traits_t::str_chr(path_ptr + 2, '\\');
00162
00163 rootLen = 1 + static_cast<size_t>(p1 - path_ptr);
00164 }
00165 #if defined(_WIN32) || \
00166 defined(_WIN64)
00167 else if(isalpha(path_ptr[0]) &&
00168 ':' == path_ptr[1])
00169 {
00170
00171 rootLen = 3;
00172 }
00173 #endif
00174 else
00175 {
00176
00177 rootLen = 1;
00178 }
00179 }
00180 else
00181 {
00182
00183 rootLen = 1;
00184 }
00185 }
00186 else
00187 {
00188
00189 rootLen = 0;
00190 }
00191
00192 if(cchBuffer < 5 + 1)
00193 {
00194 traits_t::char_copy(buffer, file_ptr, cchBuffer - 1);
00195 buffer[cchBuffer - 1] = '\0';
00196
00197 if(cchBuffer > fileLen)
00198 {
00199 cchBuffer = fileLen + 1;
00200 }
00201 }
00202 else if(cchBuffer < fileLen + 1)
00203 {
00204
00205 size_t leftLen = (cchBuffer - 3 - 1) / 2;
00206 size_t rightLen = (cchBuffer - 3 - 1) - leftLen;
00207
00208 traits_t::char_copy(buffer, file_ptr, leftLen);
00209 buffer[leftLen + 0] = '.';
00210 buffer[leftLen + 1] = '.';
00211 buffer[leftLen + 2] = '.';
00212 traits_t::char_copy(buffer + leftLen + 3, file_ptr + (fileLen - rightLen), rightLen);
00213 buffer[leftLen + 3 + rightLen] = '\0';
00214 }
00215 else if(cchBuffer < rootLen + 3 + 1 + fileLen + 1)
00216 {
00217
00218
00219 traits_t::char_copy(buffer, file_ptr, fileLen);
00220 buffer[fileLen] = '\0';
00221
00222 if(cchBuffer > fileLen)
00223 {
00224 cchBuffer = fileLen + 1;
00225 }
00226 }
00227 else
00228 {
00229 UNIXSTL_ASSERT(cchBuffer < pathLen + 1);
00230
00231
00232 size_t rightLen = 1 + fileLen;
00233 size_t leftLen = (cchBuffer - 3 - 1) - rightLen;
00234
00235 traits_t::char_copy(buffer, path_ptr, leftLen);
00236 buffer[leftLen + 0] = '.';
00237 buffer[leftLen + 1] = '.';
00238 buffer[leftLen + 2] = '.';
00239 traits_t::char_copy(buffer + leftLen + 3, file_ptr - 1, rightLen);
00240 buffer[leftLen + 3 + rightLen] = '\0';
00241 }
00242 }
00243 }
00244
00245 return cchBuffer;
00246 }
00247
00248
00249 template<ss_typename_param_k S>
00250 us_size_t path_squeeze_impl2(S const& path, us_char_a_t* buffer, us_size_t cchBuffer)
00251 {
00252 return path_squeeze_impl(stlsoft_ns_qual(c_str_ptr_a)(path), stlsoft_ns_qual(c_str_len)(path), buffer, cchBuffer);
00253 }
00254
00255 template<ss_typename_param_k S>
00256 us_size_t path_squeeze_impl2(S const& path, us_char_w_t* buffer, us_size_t cchBuffer)
00257 {
00258 return path_squeeze_impl(stlsoft_ns_qual(c_str_ptr_w)(path), stlsoft_ns_qual(c_str_len)(path), buffer, cchBuffer);
00259 }
00260
00261 #endif
00262
00263 #if 0
00264 template <ss_typename_param_k C>
00265 us_size_t path_squeeze(C const* path, C* buffer, us_size_t cchBuffer)
00266 {
00267 typedef filesystem_traits<C> traits_t;
00268
00269 return path_squeeze_impl(path, traits_t::str_len(path), buffer, cchBuffer);
00270 }
00271 #endif
00272
00273 template< ss_typename_param_k S
00274 , ss_typename_param_k C
00275 >
00276 us_size_t path_squeeze(S const& path, C* buffer, us_size_t cchBuffer)
00277 {
00278 return path_squeeze_impl2(path, buffer, cchBuffer);
00279 }
00280
00281
00282
00283
00284
00285 #ifdef STLSOFT_UNITTEST
00286 # include "./unittest/path_functions_unittest_.h"
00287 #endif
00288
00289
00290
00291 #ifndef _UNIXSTL_NO_NAMESPACE
00292 # if defined(_STLSOFT_NO_NAMESPACE) || \
00293 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00294 }
00295 # else
00296 }
00297 }
00298 # endif
00299
00300 #endif
00301
00302
00303
00304 #endif
00305
00306