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
00041
00049 #ifndef INETSTL_INCL_INETSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
00050 #define INETSTL_INCL_INETSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS
00051
00052 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00053 # define INETSTL_VER_INETSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_MAJOR 4
00054 # define INETSTL_VER_INETSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_MINOR 2
00055 # define INETSTL_VER_INETSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_REVISION 2
00056 # define INETSTL_VER_INETSTL_FILESYSTEM_HPP_FILESYSTEM_TRAITS_EDIT 75
00057 #endif
00058
00059
00060
00061
00062
00063 #ifndef INETSTL_INCL_INETSTL_H_INETSTL
00064 # include <inetstl/inetstl.h>
00065 #endif
00066 #ifndef INETSTL_OS_IS_WINDOWS
00067 # error This file is currently compatible only with the Win32/Win64 API
00068 #endif
00069 #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_SAP_CAST
00070 # include <stlsoft/conversion/sap_cast.hpp>
00071 #endif
00072 #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_ANY_CAST
00073 # include <stlsoft/conversion/any_cast.hpp>
00074 #endif
00075 #ifndef STLSOFT_INCL_STLSOFT_INTERNAL_H_SAFESTR
00076 # include <stlsoft/internal/safestr.h>
00077 #endif
00078
00079 #ifndef STLSOFT_INCL_H_STRING
00080 # define STLSOFT_INCL_H_STRING
00081 # include <string.h>
00082 #endif
00083 #ifndef STLSOFT_INCL_H_WCHAR
00084 # define STLSOFT_INCL_H_WCHAR
00085 # include <wchar.h>
00086 #endif
00087
00088
00089
00090
00091
00092 #ifndef _INETSTL_NO_NAMESPACE
00093 # if defined(_STLSOFT_NO_NAMESPACE) || \
00094 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00095
00096 namespace inetstl
00097 {
00098 # else
00099
00100
00101 namespace stlsoft
00102 {
00103
00104 namespace inetstl_project
00105 {
00106
00107 # endif
00108 #endif
00109
00110
00111
00112
00113
00114 #ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
00115
00124 template <ss_typename_param_k C>
00125 struct filesystem_traits
00126 {
00129 public:
00131 typedef C char_type;
00133 typedef is_size_t size_type;
00135 typedef is_ptrdiff_t difference_type;
00137 typedef WIN32_FIND_DATA find_data_type;
00139 typedef WIN32_FIND_DATA stat_data_type;
00141 typedef filesystem_traits<C> class_type;
00143 typedef is_int_t int_type;
00145 typedef is_bool_t bool_type;
00147 typedef DWORD error_type;
00149
00152 public:
00154 static char_type* char_copy(char_type* dest, char_type const* src, size_type n);
00155 #if !defined(STLSOFT_USING_SAFE_STR_FUNCTIONS) || \
00156 defined(_CRT_SECURE_NO_DEPRECATE)
00158 static char_type* str_copy(char_type* dest, char_type const* src);
00160 static char_type* str_n_copy(char_type* dest, char_type const* src, is_size_t cch);
00162 static char_type* str_cat(char_type* dest, char_type const* src);
00163 #endif
00165 static int_type str_compare(char_type const* s1, char_type const* s2);
00167 static int_type str_compare_no_case(char_type const* s1, char_type const* s2);
00169 static int_type str_n_compare(char_type const* s1, char_type const* s2, size_type cch);
00171 static size_type str_len(char_type const* src);
00173 static char_type* str_chr(char_type const* s, char_type ch);
00175 static char_type* str_rchr(char_type const* s, char_type ch);
00177 static char_type* str_str(char_type const* s, char_type const* sub);
00179
00182 public:
00186 static char_type* ensure_dir_end(char_type* dir);
00190 static char_type* remove_dir_end(char_type* dir);
00194 static bool_type has_dir_end(char_type const* dir);
00195
00197 static bool_type is_dots(char_type const* dir);
00199 static bool_type is_path_rooted(char_type const* path);
00201 static bool_type is_path_absolute(char_type const* path);
00202
00206 static bool_type is_path_name_separator(char_type ch);
00207
00211 static char_type path_separator();
00215 static char_type path_name_separator();
00219 static char_type const* pattern_all();
00221 static size_type get_full_path_name(HINTERNET hconn, char_type const* fileName, size_type cchBuffer, char_type* buffer, char_type** ppFile);
00223 static size_type get_full_path_name(HINTERNET hconn, char_type const* fileName, size_type cchBuffer, char_type* buffer);
00225
00228 public:
00230 static HINTERNET internet_open(char_type const* agent, is_dword_t accessType, char_type const* proxy, char_type const* proxyBypass, is_dword_t flags);
00232 static HINTERNET internet_connect(HINTERNET hsess, char_type const* server, INTERNET_PORT port, char_type const* userName, char_type const* password, is_dword_t service, is_dword_t flags, is_dword_t context);
00234 static void close_connection(HINTERNET hconn);
00236
00239 public:
00241 static HINTERNET find_first_file(HINTERNET hconn, char_type const* spec, find_data_type *findData, is_dword_t flags = 0, is_dword_t context = 0);
00243 static bool_type find_next_file(HANDLE h, find_data_type *findData);
00245 static void find_close(HINTERNET hfind);
00247
00250 public:
00252 static bool_type set_current_directory(HINTERNET hconn, char_type const* dir);
00254 static bool_type get_current_directory(HINTERNET hconn, is_size_t &cchBuffer, char_type* buffer);
00255
00257 static bool_type file_exists(HINTERNET hconn, char_type const* fileName);
00259 static bool_type is_file(HINTERNET hconn, char_type const* path);
00261 static bool_type is_directory(HINTERNET hconn, char_type const* path);
00263 static bool_type stat(HINTERNET hconn, char_type const* path, stat_data_type *stat_data);
00264
00266 static bool_type is_file(stat_data_type const* stat_data);
00268 static bool_type is_directory(stat_data_type const* stat_data);
00270 static bool_type is_link(stat_data_type const* stat_data);
00272 static bool_type is_readonly(stat_data_type const* stat_data);
00274
00277 public:
00279 static bool_type create_directory(HINTERNET hconn, char_type const* dir);
00281 static bool_type remove_directory(HINTERNET hconn, char_type const* dir);
00282
00284 static bool_type delete_file(HINTERNET hconn, char_type const* file);
00286 static bool_type rename_file(HINTERNET hconn, char_type const* currentName, char_type const* newName);
00288 };
00289
00290 #else
00291
00292 template <ss_typename_param_k C>
00293 struct filesystem_traits;
00294
00295 STLSOFT_TEMPLATE_SPECIALISATION
00296 struct filesystem_traits<is_char_a_t>
00297 {
00298 public:
00299 typedef is_char_a_t char_type;
00300 typedef is_size_t size_type;
00301 typedef is_ptrdiff_t difference_type;
00302 typedef WIN32_FIND_DATAA find_data_type;
00303 typedef WIN32_FIND_DATAA stat_data_type;
00304 typedef filesystem_traits<is_char_a_t> class_type;
00305 typedef is_int_t int_type;
00306 typedef is_bool_t bool_type;
00307 typedef DWORD error_type;
00308
00309 public:
00310 static char_type* char_copy(char_type* dest, char_type const* src, size_type n)
00311 {
00312 INETSTL_ASSERT(NULL != dest);
00313 INETSTL_ASSERT(0 == n || NULL != src);
00314
00315 return static_cast<char_type*>(::memcpy(dest, src, sizeof(char_type) * n));
00316 }
00317
00318
00319 #if !defined(STLSOFT_USING_SAFE_STR_FUNCTIONS) || \
00320 defined(_CRT_SECURE_NO_DEPRECATE)
00321 static char_type* str_copy(char_type* dest, char_type const* src)
00322 {
00323 INETSTL_ASSERT(NULL != dest);
00324 INETSTL_ASSERT(NULL != src);
00325
00326 # ifdef STLSOFT_MIN_CRT
00327 return ::lstrcpyA(dest, src);
00328 # else
00329 return ::strcpy(dest, src);
00330 # endif
00331 }
00332
00333 static char_type* str_n_copy(char_type* dest, char_type const* src, is_size_t cch)
00334 {
00335 INETSTL_ASSERT(NULL != dest);
00336 INETSTL_ASSERT(0 == cch || NULL != src);
00337
00338 return ::strncpy(dest, src, cch);
00339 }
00340
00341 static char_type* str_cat(char_type* dest, char_type const* src)
00342 {
00343 INETSTL_ASSERT(NULL != dest);
00344 INETSTL_ASSERT(NULL != src);
00345
00346 # ifdef STLSOFT_MIN_CRT
00347 return ::lstrcatA(dest, src);
00348 # else
00349 return ::strcat(dest, src);
00350 # endif
00351 }
00352 #endif
00353
00354 static int_type str_compare(char_type const* s1, char_type const* s2)
00355 {
00356 INETSTL_ASSERT(NULL != s1);
00357 INETSTL_ASSERT(NULL != s2);
00358
00359 #ifdef STLSOFT_MIN_CRT
00360 return ::lstrcmpA(s1, s2);
00361 #else
00362 return ::strcmp(s1, s2);
00363 #endif
00364 }
00365
00366 static int_type str_compare_no_case(char_type const* s1, char_type const* s2)
00367 {
00368 INETSTL_ASSERT(NULL != s1);
00369 INETSTL_ASSERT(NULL != s2);
00370
00371 return ::lstrcmpiA(s1, s2);
00372 }
00373
00374 static int_type str_n_compare(char_type const* s1, char_type const* s2, size_type cch)
00375 {
00376 INETSTL_ASSERT(NULL != s1);
00377 INETSTL_ASSERT(NULL != s2);
00378
00379 return ::strncmp(s1, s2, cch);
00380 }
00381
00382 static size_type str_len(char_type const* src)
00383 {
00384 #ifdef STLSOFT_MIN_CRT
00385 return static_cast<size_type>(::lstrlenA(src));
00386 #else
00387 return ::strlen(src);
00388 #endif
00389 }
00390
00391 static char_type* str_chr(char_type const* s, char_type ch)
00392 {
00393 return const_cast<char_type*>(::strchr(s, ch));
00394 }
00395
00396 static char_type* str_rchr(char_type const* s, char_type ch)
00397 {
00398 return const_cast<char_type*>(::strrchr(s, ch));
00399 }
00400
00401 static char_type* str_str(char_type const* s, char_type const* sub)
00402 {
00403 return const_cast<char_type*>(::strstr(s, sub));
00404 }
00405
00406
00407 static char_type* ensure_dir_end(char_type* dir)
00408 {
00409 char_type *end;
00410 char_type const separator = (NULL == str_chr(dir, '/') && NULL != str_chr(dir, '\\')) ? '\\' : '/';
00411
00412 for(end = dir; *end != '\0'; ++end)
00413 {}
00414
00415 if( dir < end &&
00416 *(end - 1) != separator)
00417 {
00418 *end = separator;
00419 *(end + 1) = '\0';
00420 }
00421
00422 return dir;
00423 }
00424
00425 static char_type* remove_dir_end(char_type* dir)
00426 {
00427 char_type *end;
00428
00429 for(end = dir; *end != '\0'; ++end)
00430 {}
00431
00432 if( dir < end &&
00433 *(end - 1) == path_name_separator())
00434 {
00435 *(end - 1) = '\0';
00436 }
00437
00438 return dir;
00439 }
00440
00441 static bool_type has_dir_end(char_type const* dir)
00442 {
00443 is_size_t len = str_len(dir);
00444
00445 return (0 < len) && path_name_separator() == dir[len - 1];
00446 }
00447
00448 static bool_type is_dots(char_type const* dir)
00449 {
00450 return dir != 0 &&
00451 dir[0] == '.' &&
00452 ( dir[1] == '\0' ||
00453 ( dir[1] == '.' &&
00454 dir[2] == '\0'));
00455 }
00456
00457 static bool_type is_path_rooted(char_type const* path)
00458 {
00459 INETSTL_ASSERT(NULL != path);
00460
00461 return '/' == *path;
00462 }
00463
00464 static bool_type is_path_absolute(char_type const* path)
00465 {
00466 return is_path_rooted(path);
00467 }
00468
00469 static bool_type is_path_name_separator(char_type ch)
00470 {
00471 return '/' == ch;
00472 }
00473
00474 static char_type path_separator()
00475 {
00476 return ';';
00477 }
00478
00479 static char_type path_name_separator()
00480 {
00481 return '/';
00482 }
00483
00484 static char_type const* pattern_all()
00485 {
00486 return "*";
00487 }
00488
00489 static size_type get_full_path_name(HINTERNET hconn, char_type const* fileName, size_type cchBuffer, char_type* buffer, char_type** ppFile)
00490 {
00491 INETSTL_ASSERT(0 == cchBuffer || NULL != buffer);
00492 INETSTL_ASSERT(NULL == buffer || 0 != cchBuffer);
00493 INETSTL_ASSERT(NULL != fileName);
00494
00495
00496 char_type const separator = (NULL == str_chr(fileName, '/') && NULL != str_chr(fileName, '\\')) ? '\\' : '/';
00497 char_type fullPath[1 + _MAX_PATH];
00498 size_type len = str_len(fileName);
00499
00500
00501 if(separator != *fileName)
00502 {
00503 is_size_t cchBuffer = STLSOFT_NUM_ELEMENTS(fullPath);
00504 const int isDot = '.' == 0[fileName] && '\0' == 0[fileName];
00505
00506 #ifdef __SYNSOFT_DBS_COMPILER_SUPPORTS_PRAGMA_MESSAGE
00507 # pragma message(_sscomp_fileline_message("This looks a bit dodgy. Better to use an auto_buffer, and cycle the size, testing the return value from get_current_directory"))
00508 #endif
00509
00510 if(!get_current_directory(hconn, cchBuffer, fullPath))
00511 {
00512 fullPath[0] = '\0';
00513 }
00514 size_type cchFullPath = str_len(fullPath);
00515
00516 if(!isDot)
00517 {
00518 if(!has_dir_end(fullPath))
00519 {
00520 ensure_dir_end(fullPath);
00521 ++cchFullPath;
00522 }
00523 char_copy(&fullPath[0] + cchFullPath, fileName, 1 + len);
00524 }
00525
00526 fileName = fullPath;
00527 len += cchFullPath;
00528 }
00529
00530 if(NULL != buffer)
00531 {
00532 if(cchBuffer < len)
00533 {
00534 len = cchBuffer;
00535 }
00536
00537 char_copy(buffer, fileName, cchBuffer);
00538
00539 if(NULL != ppFile)
00540 {
00541 char_type const* pRSlash = str_rchr(buffer, '/');
00542 char_type const* pRBackSlash = str_rchr(buffer, '\\');
00543
00544 if(pRSlash < pRBackSlash)
00545 {
00546 pRSlash = pRBackSlash;
00547 }
00548
00549 if(NULL == pRSlash)
00550 {
00551 *ppFile = NULL;
00552 }
00553 else
00554 {
00555 *ppFile = const_cast<char_type*>(pRSlash) + 1;
00556 }
00557 }
00558 }
00559
00560 return len;
00561 }
00562
00563 static size_type get_full_path_name(HINTERNET hconn, char_type const* fileName, size_type cchBuffer, char_type* buffer)
00564 {
00565 char_type* pFile;
00566
00567 return get_full_path_name(hconn, fileName, cchBuffer, buffer, &pFile);
00568 }
00569
00570
00571 static HINTERNET internet_open(char_type const* agent, is_dword_t accessType, char_type const* proxy, char_type const* proxyBypass, is_dword_t flags)
00572 {
00573 return ::InternetOpenA(agent, accessType, proxy, proxyBypass, flags);
00574 }
00575
00576 static HINTERNET internet_connect(HINTERNET hsess, char_type const* server, INTERNET_PORT port, char_type const* userName, char_type const* password, is_dword_t service, is_dword_t flags, is_dword_t context)
00577 {
00578 return ::InternetConnectA(hsess, server, port, userName, password, service, flags, context);
00579 }
00580
00581 static void close_connection(HINTERNET hconn)
00582 {
00583 INETSTL_ASSERT(NULL != hconn);
00584
00585 ::InternetCloseHandle(hconn);
00586 }
00587
00588
00589 static HINTERNET find_first_file(HINTERNET hconn, char_type const* spec, find_data_type *findData, is_dword_t flags = 0, is_dword_t context = 0)
00590 {
00591 HINTERNET hfind = ::FtpFindFirstFileA(hconn, spec, stlsoft_ns_qual(any_caster)<find_data_type*, LPWIN32_FIND_DATAA, LPWIN32_FIND_DATAW>(findData), flags, context);
00592
00593 #if 0
00594 if(NULL == hfind)
00595 {
00596 findData->cFileName[0] = '\0';
00597 }
00598
00599 printf("find_first_file(0x%08x, %s => %s)\n", hfind, spec, findData->cFileName);
00600 #endif
00601
00602 return hfind;
00603 }
00604
00605 static bool_type find_next_file(HANDLE h, find_data_type *findData)
00606 {
00607 return FALSE != ::InternetFindNextFileA(h, findData);
00608 }
00609
00610 static void find_close(HINTERNET hfind)
00611 {
00612 INETSTL_ASSERT(NULL != hfind);
00613
00614 ::InternetCloseHandle(hfind);
00615 }
00616
00617
00618 static bool_type set_current_directory(HINTERNET hconn, char_type const* dir)
00619 {
00620 return ::FtpSetCurrentDirectoryA(hconn, dir) != FALSE;
00621 }
00622
00623 static bool_type get_current_directory(HINTERNET hconn, is_size_t &cchBuffer, char_type* buffer)
00624 {
00625 return FALSE != ::FtpGetCurrentDirectoryA(hconn, buffer, sap_cast<unsigned long*>(&cchBuffer));
00626 }
00627
00628 static bool_type file_exists(HINTERNET hconn, char_type const* fileName)
00629 {
00630 find_data_type data;
00631 HINTERNET hfind = find_first_file(hconn, fileName, &data);
00632
00633 return (NULL == hfind) ? false : (find_close(hfind), true);
00634 }
00635
00636 #if 0
00637 static bool_type is_file(HINTERNET hconn, char_type const* path);
00638 static bool_type is_directory(HINTERNET hconn, char_type const* path);
00639 static bool_type stat(HINTERNET hconn, char_type const* path, stat_data_type *stat_data);
00640 #endif
00641
00642 static bool_type is_file(stat_data_type const* stat_data)
00643 {
00644 return FILE_ATTRIBUTE_DIRECTORY != (stat_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
00645 }
00646 static bool_type is_directory(stat_data_type const* stat_data)
00647 {
00648 return FILE_ATTRIBUTE_DIRECTORY == (stat_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
00649 }
00650 static bool_type is_link(stat_data_type const* stat_data);
00651 static bool_type is_readonly(stat_data_type const* stat_data)
00652 {
00653 return FILE_ATTRIBUTE_READONLY == (stat_data->dwFileAttributes & FILE_ATTRIBUTE_READONLY);
00654 }
00655
00656
00657 static bool_type create_directory(HINTERNET hconn, char_type const* dir)
00658 {
00659 return FALSE != ::FtpCreateDirectoryA(hconn, dir);
00660 }
00661
00662 static bool_type remove_directory(HINTERNET hconn, char_type const* dir)
00663 {
00664 return FALSE != ::FtpRemoveDirectoryA(hconn, dir);
00665 }
00666
00667 static bool_type delete_file(HINTERNET hconn, char_type const* file)
00668 {
00669 return FALSE != ::FtpDeleteFileA(hconn, file);
00670 }
00671
00672 static bool_type rename_file(HINTERNET hconn, char_type const* currentName, char_type const* newName)
00673 {
00674 return FALSE != ::FtpRenameFileA(hconn, currentName, newName);
00675 }
00676 };
00677
00678 STLSOFT_TEMPLATE_SPECIALISATION
00679 struct filesystem_traits<is_char_w_t>
00680 {
00681 public:
00682 typedef is_char_w_t char_type;
00683 typedef is_size_t size_type;
00684 typedef is_ptrdiff_t difference_type;
00685 typedef WIN32_FIND_DATAW find_data_type;
00686 typedef WIN32_FIND_DATAW stat_data_type;
00687 typedef filesystem_traits<is_char_w_t> class_type;
00688 typedef is_int_t int_type;
00689 typedef is_bool_t bool_type;
00690 typedef DWORD error_type;
00691
00692 public:
00693 static char_type* char_copy(char_type* dest, char_type const* src, size_type n)
00694 {
00695 INETSTL_ASSERT(NULL != dest);
00696 INETSTL_ASSERT(0 == n || NULL != src);
00697
00698 return static_cast<char_type*>(::memcpy(dest, src, sizeof(char_type) * n));
00699 }
00700
00701
00702 #if !defined(STLSOFT_USING_SAFE_STR_FUNCTIONS) || \
00703 defined(_CRT_SECURE_NO_DEPRECATE)
00704 static char_type* str_copy(char_type* dest, char_type const* src)
00705 {
00706 INETSTL_ASSERT(NULL != dest);
00707 INETSTL_ASSERT(NULL != src);
00708
00709 # ifdef STLSOFT_MIN_CRT
00710 return ::lstrcpyW(dest, src);
00711 # else
00712 return ::wcscpy(dest, src);
00713 # endif
00714 }
00715
00716 static char_type* str_n_copy(char_type* dest, char_type const* src, is_size_t cch)
00717 {
00718 INETSTL_ASSERT(NULL != dest);
00719 INETSTL_ASSERT(0 == cch || NULL != src);
00720
00721 return ::wcsncpy(dest, src, cch);
00722 }
00723
00724 static char_type* str_cat(char_type* dest, char_type const* src)
00725 {
00726 INETSTL_ASSERT(NULL != dest);
00727 INETSTL_ASSERT(NULL != src);
00728
00729 # ifdef STLSOFT_MIN_CRT
00730 return ::lstrcatW(dest, src);
00731 # else
00732 return ::wcscat(dest, src);
00733 # endif
00734 }
00735 #endif
00736
00737 static int_type str_compare(char_type const* s1, char_type const* s2)
00738 {
00739 INETSTL_ASSERT(NULL != s1);
00740 INETSTL_ASSERT(NULL != s2);
00741
00742 #ifdef STLSOFT_MIN_CRT
00743 return ::lstrcmpW(s1, s2);
00744 #else
00745 return ::wcscmp(s1, s2);
00746 #endif
00747 }
00748
00749 static int_type str_compare_no_case(char_type const* s1, char_type const* s2)
00750 {
00751 INETSTL_ASSERT(NULL != s1);
00752 INETSTL_ASSERT(NULL != s2);
00753
00754 return ::lstrcmpiW(s1, s2);
00755 }
00756
00757 static int_type str_n_compare(char_type const* s1, char_type const* s2, size_type cch)
00758 {
00759 INETSTL_ASSERT(NULL != s1);
00760 INETSTL_ASSERT(NULL != s2);
00761
00762 return ::wcsncmp(s1, s2, cch);
00763 }
00764
00765 static size_type str_len(char_type const* src)
00766 {
00767 #ifdef STLSOFT_MIN_CRT
00768 return static_cast<size_type>(::lstrlenW(src));
00769 #else
00770 return ::wcslen(src);
00771 #endif
00772 }
00773
00774 static char_type* str_chr(char_type const* s, char_type ch)
00775 {
00776 return const_cast<char_type*>(::wcschr(s, ch));
00777 }
00778
00779 static char_type* str_rchr(char_type const* s, char_type ch)
00780 {
00781 return const_cast<char_type*>(::wcsrchr(s, ch));
00782 }
00783
00784 static char_type* str_str(char_type const* s, char_type const* sub)
00785 {
00786 return const_cast<char_type*>(::wcsstr(s, sub));
00787 }
00788
00789
00790 static char_type* ensure_dir_end(char_type* dir)
00791 {
00792 char_type *end;
00793 char_type const separator = (NULL == str_chr(dir, L'/') && NULL != str_chr(dir, L'\\')) ? L'\\' : L'/';
00794
00795 for(end = dir; *end != L'\0'; ++end)
00796 {}
00797
00798 if( dir < end &&
00799 *(end - 1) != separator)
00800 {
00801 *end = separator;
00802 *(end + 1) = L'\0';
00803 }
00804
00805 return dir;
00806 }
00807
00808 static char_type* remove_dir_end(char_type* dir)
00809 {
00810 char_type *end;
00811
00812 for(end = dir; *end != '\0'; ++end)
00813 {}
00814
00815 if( dir < end &&
00816 *(end - 1) == path_name_separator())
00817 {
00818 *(end - 1) = '\0';
00819 }
00820
00821 return dir;
00822 }
00823
00824 static bool_type has_dir_end(char_type const* dir)
00825 {
00826 is_size_t len = str_len(dir);
00827
00828 return (0 < len) && path_name_separator() == dir[len - 1];
00829 }
00830
00831 static bool_type is_dots(char_type const* dir)
00832 {
00833 return dir != 0 &&
00834 dir[0] == '.' &&
00835 ( dir[1] == L'\0' ||
00836 ( dir[1] == L'.' &&
00837 dir[2] == L'\0'));
00838 }
00839
00840 static bool_type is_path_rooted(char_type const* path)
00841 {
00842 INETSTL_ASSERT(NULL != path);
00843
00844 return L'/' == *path;
00845 }
00846
00847 static bool_type is_path_absolute(char_type const* path)
00848 {
00849 return is_path_rooted(path);
00850 }
00851
00852 static bool_type is_path_name_separator(char_type ch)
00853 {
00854 return L'/' == ch;
00855 }
00856
00857 static char_type path_separator()
00858 {
00859 return L';';
00860 }
00861
00862 static char_type path_name_separator()
00863 {
00864 return L'/';
00865 }
00866
00867 static char_type const* pattern_all()
00868 {
00869 return L"*";
00870 }
00871
00872 static size_type get_full_path_name(HINTERNET hconn, char_type const* fileName, size_type cchBuffer, char_type* buffer, char_type** ppFile)
00873 {
00874 INETSTL_ASSERT(0 == cchBuffer || NULL != buffer);
00875 INETSTL_ASSERT(NULL == buffer || 0 != cchBuffer);
00876 INETSTL_ASSERT(NULL != fileName);
00877
00878
00879 char_type const separator = (NULL == str_chr(fileName, L'/') && NULL != str_chr(fileName, L'\\')) ? L'\\' : L'/';
00880 char_type fullPath[1 + _MAX_PATH];
00881 size_type len = str_len(fileName);
00882
00883
00884 if(separator != *fileName)
00885 {
00886 is_size_t cchBuffer = STLSOFT_NUM_ELEMENTS(fullPath);
00887 const int isDot = L'.' == 0[fileName] && L'\0' == 0[fileName];
00888
00889 #ifdef __SYNSOFT_DBS_COMPILER_SUPPORTS_PRAGMA_MESSAGE
00890 # pragma message(_sscomp_fileline_message("This looks a bit dodgy. Better to use an auto_buffer, and cycle the size, testing the return value from get_current_directory"))
00891 #endif
00892
00893 if(!get_current_directory(hconn, cchBuffer, fullPath))
00894 {
00895 fullPath[0] = L'\0';
00896 }
00897 size_type cchFullPath = str_len(fullPath);
00898
00899 if(!isDot)
00900 {
00901 if(!has_dir_end(fullPath))
00902 {
00903 ensure_dir_end(fullPath);
00904 ++cchFullPath;
00905 }
00906 char_copy(&fullPath[0] + cchFullPath, fileName, 1 + len);
00907 }
00908
00909 fileName = fullPath;
00910 len += cchFullPath;
00911 }
00912
00913 if(NULL != buffer)
00914 {
00915 if(cchBuffer < len)
00916 {
00917 len = cchBuffer;
00918 }
00919
00920 char_copy(buffer, fileName, cchBuffer);
00921
00922 if(NULL != ppFile)
00923 {
00924 char_type const* pRSlash = str_rchr(buffer, L'/');
00925 char_type const* pRBackSlash = str_rchr(buffer, L'\\');
00926
00927 if(pRSlash < pRBackSlash)
00928 {
00929 pRSlash = pRBackSlash;
00930 }
00931
00932 if(NULL == pRSlash)
00933 {
00934 *ppFile = NULL;
00935 }
00936 else
00937 {
00938 *ppFile = const_cast<char_type*>(pRSlash) + 1;
00939 }
00940 }
00941 }
00942
00943 return len;
00944 }
00945
00946 static size_type get_full_path_name(HINTERNET hconn, char_type const* fileName, size_type cchBuffer, char_type* buffer)
00947 {
00948 char_type* pFile;
00949
00950 return get_full_path_name(hconn, fileName, cchBuffer, buffer, &pFile);
00951 }
00952
00953
00954 static HINTERNET internet_open(char_type const* agent, is_dword_t accessType, char_type const* proxy, char_type const* proxyBypass, is_dword_t flags)
00955 {
00956 return ::InternetOpenW(agent, accessType, proxy, proxyBypass, flags);
00957 }
00958
00959 static HINTERNET internet_connect(HINTERNET hsess, char_type const* server, INTERNET_PORT port, char_type const* userName, char_type const* password, is_dword_t service, is_dword_t flags, is_dword_t context)
00960 {
00961 return ::InternetConnectW(hsess, server, port, userName, password, service, flags, context);
00962 }
00963
00964 static void close_connection(HINTERNET hconn)
00965 {
00966 INETSTL_ASSERT(NULL != hconn);
00967
00968 ::InternetCloseHandle(hconn);
00969 }
00970
00971
00972 static HINTERNET find_first_file(HINTERNET hconn, char_type const* spec, find_data_type *findData, is_dword_t flags = 0, is_dword_t context = 0)
00973 {
00974 return ::FtpFindFirstFileW(hconn, spec, stlsoft_ns_qual(any_caster)<find_data_type*, LPWIN32_FIND_DATAA, LPWIN32_FIND_DATAW>(findData), flags, context);
00975 }
00976
00977 static bool_type find_next_file(HANDLE h, find_data_type *findData)
00978 {
00979 return FALSE != ::InternetFindNextFileW(h, findData);
00980 }
00981
00982 static void find_close(HINTERNET hfind)
00983 {
00984 INETSTL_ASSERT(NULL != hfind);
00985
00986 ::InternetCloseHandle(hfind);
00987 }
00988
00989
00990 static bool_type set_current_directory(HINTERNET hconn, char_type const* dir)
00991 {
00992 return ::FtpSetCurrentDirectoryW(hconn, dir) != FALSE;
00993 }
00994
00995 static bool_type get_current_directory(HINTERNET hconn, is_size_t &cchBuffer, char_type* buffer)
00996 {
00997 return FALSE != ::FtpGetCurrentDirectoryW(hconn, buffer, sap_cast<unsigned long*>(&cchBuffer));
00998 }
00999
01001 static bool_type file_exists(HINTERNET hconn, char_type const* fileName)
01002 {
01003 find_data_type data;
01004 HINTERNET hfind = find_first_file(hconn, fileName, &data);
01005
01006 return (NULL == hfind) ? false : (find_close(hfind), true);
01007 }
01008
01009 #if 0
01010 static bool_type is_file(HINTERNET hconn, char_type const* path);
01011 static bool_type is_directory(HINTERNET hconn, char_type const* path);
01012 static bool_type stat(HINTERNET hconn, char_type const* path, stat_data_type *stat_data);
01013 #endif
01014
01015 static bool_type is_file(stat_data_type const* stat_data)
01016 {
01017 return FILE_ATTRIBUTE_DIRECTORY != (stat_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
01018 }
01019 static bool_type is_directory(stat_data_type const* stat_data)
01020 {
01021 return FILE_ATTRIBUTE_DIRECTORY == (stat_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
01022 }
01023 static bool_type is_link(stat_data_type const* stat_data);
01024 static bool_type is_readonly(stat_data_type const* stat_data)
01025 {
01026 return FILE_ATTRIBUTE_READONLY == (stat_data->dwFileAttributes & FILE_ATTRIBUTE_READONLY);
01027 }
01028
01029
01030 static bool_type create_directory(HINTERNET hconn, char_type const* dir)
01031 {
01032 return FALSE != ::FtpCreateDirectoryW(hconn, dir);
01033 }
01034
01035 static bool_type remove_directory(HINTERNET hconn, char_type const* dir)
01036 {
01037 return FALSE != ::FtpRemoveDirectoryW(hconn, dir);
01038 }
01039
01040 static bool_type delete_file(HINTERNET hconn, char_type const* file)
01041 {
01042 return FALSE != ::FtpDeleteFileW(hconn, file);
01043 }
01044
01045 static bool_type rename_file(HINTERNET hconn, char_type const* currentName, char_type const* newName)
01046 {
01047 return FALSE != ::FtpRenameFileW(hconn, currentName, newName);
01048 }
01049 };
01050
01051 #endif
01052
01053
01054
01055 #ifndef _INETSTL_NO_NAMESPACE
01056 # if defined(_STLSOFT_NO_NAMESPACE) || \
01057 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
01058 }
01059 # else
01060 }
01061 }
01062 # endif
01063 #endif
01064
01065
01066
01067 #endif
01068
01069