filespecutils.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:12k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: filespecutils.cpp,v 1.2.32.3 2004/07/09 01:44:17 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "filespecutils.h"
  50. #include "hxtick.h"
  51. #include "hxrand.h"
  52. #include "dbcs.h"
  53. #define NFS_SUPER_MAGIC 0x6969
  54. #define SMB_SUPER_MAGIC 0x517B
  55. //////////////////////////////////////////////////////////
  56. //
  57. // Utility base class -- CHXFileSpecUtils
  58. //
  59. //////////////////////////////////////////////////////////
  60. //******************************************************************************
  61. //#if defined(_FREEBSD) || defined (_OSF1)
  62. //#include <sys/mount.h>
  63. //#else
  64. //#include <sys/vfs.h>
  65. //#endif
  66. #include "op_fs.h"
  67. #include <sys/stat.h>
  68. //#include <dirent.h>
  69. #include <sys/types.h>
  70. #define ONEGIG (1<<30)
  71. #define STATFS_PATH_TYPE const char*
  72. #define HXStatfsStruct        struct OpFsStatStruct
  73. #define HXStatfs(path,sf)     OpFsStat((STATFS_PATH_TYPE)(path),(sf))
  74. HX_RESULT CHXFileSpecUtils::GetFreeSpaceOnDisk(const CHXDirSpecifier& volSpec, INT64& freeSpace)
  75. {
  76.     HX_RESULT result = HXR_NOTIMPL;
  77.     const char *szPath = volSpec.GetPathName();
  78.     
  79.     HXStatfsStruct sf;
  80.     if (kOpFsErrAny != HXStatfs(szPath, &sf))
  81.     {
  82.     freeSpace = (UINT64)sf.size;
  83.         result = HXR_OK;
  84.     }
  85.     else
  86.     {
  87. perror("statfs");
  88. freeSpace = ONEGIG; 
  89.     }
  90.     return result;
  91. }
  92. //******************************************************************************
  93. HX_RESULT CHXFileSpecUtils::GetTotalSpaceOnDisk(const CHXDirSpecifier& volSpec, 
  94. INT64& totalSpace)
  95.     HX_RESULT result = HXR_NOTIMPL;
  96.     const char *szPath = volSpec.GetPathName();
  97.     
  98.     HXStatfsStruct sf;
  99.     if (kOpFsErrAny != HXStatfs(szPath, &sf))
  100.     {
  101.         totalSpace = (UINT64)sf.size;
  102.         result = HXR_OK;
  103.     }
  104.     else
  105.     {
  106. perror("statfs");
  107. totalSpace = ONEGIG; 
  108.     }
  109.     return result;
  110. }
  111. //******************************************************************************
  112. BOOL CHXFileSpecUtils::IsDiskEjectable(const CHXDirSpecifier& volSpec)
  113. {
  114.     return FALSE;
  115. }
  116. // IsLocal returns TRUE if the file or directory is on a local volume
  117. // (not on a server)
  118. //******************************************************************************
  119. /* Include correct headers to get more fs types below... */
  120. BOOL CHXFileSpecUtils::IsDiskLocal(const CHXDirSpecifier& volSpec)
  121. {
  122.     return TRUE;
  123. }
  124. // file/dir utilities
  125. //******************************************************************** **********
  126. HX_RESULT CHXFileSpecUtils::RemoveDir(const CHXDirSpecifier& dirSpec)
  127. {
  128.     return HXR_NOTIMPL;
  129. };
  130. //******************************************************************** **********
  131. HX_RESULT CHXFileSpecUtils::RemoveFile(const CHXFileSpecifier& fileSpec)
  132. {
  133.     if (kOpFsErrAny != OpFsRemove(fileSpec.GetPathName()))
  134.     {
  135.         return HXR_OK;
  136.     }
  137.     return HXR_FAILED;
  138. };
  139. //******************************************************************************
  140. HX_RESULT CHXFileSpecUtils::GetFileSize(const CHXFileSpecifier& fileSpec, INT64& fSize)
  141. {
  142.     HX_RESULT result = HXR_FAIL;
  143.  
  144.     HXStatfsStruct sf;
  145.     if (kOpFsErrAny != HXStatfs(fileSpec.GetPathName(), &sf))
  146.     {
  147.         fSize = sf.size;
  148.         result = HXR_OK;
  149.     }
  150.     return result;
  151. }
  152. //******************************************************************************
  153. HX_RESULT CHXFileSpecUtils::GetDirectorySize(const CHXDirSpecifier& dirSpec, BOOL shouldDescend, INT64& fSize)
  154. {
  155. return HXR_NOTIMPL;
  156. }
  157. //******************************************************************************
  158. CHXFileSpecifier CHXFileSpecUtils::GetCurrentApplication(void)
  159. {
  160.     /* AFAIK there is no way to implement this.  Prove me wrong */
  161.     CHXFileSpecifier spec;
  162.     return spec;
  163. }
  164. //******************************************************************************
  165. CHXDirSpecifier CHXFileSpecUtils::GetCurrentApplicationDir(void)
  166. {
  167.     /* AFAIK there is no way to implement this.  Prove me wrong */
  168.     CHXDirSpecifier  dirSpec;
  169.     return dirSpec;
  170. }
  171. //******************************************************************************
  172. BOOL CHXFileSpecUtils::FileExists(const CHXFileSpecifier& fileSpec)
  173. {
  174.     BOOL result = FALSE;
  175.  
  176. HXStatfsStruct sf;
  177.     if (kOpFsErrAny != HXStatfs(fileSpec.GetPathName(), &sf))
  178. {
  179.        result = TRUE;
  180.     }
  181.     return result;
  182. }
  183. //******************************************************************************
  184. BOOL CHXFileSpecUtils::DirectoryExists(const CHXDirSpecifier& dirSpec)
  185. {
  186.     BOOL result = FALSE;
  187.  
  188. HXStatfsStruct sf;
  189.     if (kOpFsErrAny != HXStatfs(dirSpec.GetPathName(), &sf))
  190. {
  191.        result = TRUE;
  192.     }
  193.     return result;
  194. }
  195. //******************************************************************************
  196. HX_RESULT CHXFileSpecUtils::CreateDir(const CHXDirSpecifier& dirSpec)
  197. {        
  198. return HXR_NOTIMPL;;
  199. }
  200. //******************************************************************************
  201. static CHXFileSpecifier GetUniqueFileSpecInternal(const CHXDirSpecifier& locationSpec, 
  202. const char *pszNameFirst, const char *pszTemplate, 
  203. const char *pszWildcard, UINT32 nStartNum);
  204. const UINT32 kNumWrapValue = 9999+1; // limit insertions to 4-digit numbers
  205. CHXFileSpecifier CHXFileSpecUtils::GetUniqueFileSpec(const CHXDirSpecifier& locationSpec, 
  206. const char *pszNameFirst, const char *pszTemplate, 
  207. const char *pszWildcard)
  208. {
  209. return GetUniqueFileSpecInternal(locationSpec, pszNameFirst, pszTemplate, pszWildcard, 0);
  210. }
  211. CHXFileSpecifier CHXFileSpecUtils::GetUniqueTempFileSpec(const CHXDirSpecifier& locationSpec, 
  212. const char *pszTemplate, const char *pszWildcard)
  213. {
  214. CMultiplePrimeRandom  rand(HX_GET_TICKCOUNT());
  215. UINT32 num;
  216. num = rand.GetRandomNumber();
  217. num %= kNumWrapValue;
  218. if (num == 0 || num == 1) num = 2;
  219. return GetUniqueFileSpecInternal(locationSpec, NULL, pszTemplate, pszWildcard, num);
  220. }
  221. static CHXFileSpecifier GetUniqueFileSpecInternal(const CHXDirSpecifier& locationSpec, 
  222.                                                   const char *pszNameFirst, const char *pszTemplate, 
  223.                                                   const char *pszWildcard, UINT32 nStartNum)
  224. {
  225.     CHXFileSpecifier  resultFileSpec;
  226.     require_return(locationSpec.IsSet(), resultFileSpec);
  227.     require_return(pszTemplate != NULL && pszWildcard != NULL, resultFileSpec);
  228.     require_return(pszNameFirst != NULL || nStartNum != 0, resultFileSpec);
  229.     CHXFileSpecifier  testFileSpec;
  230.     CHXDirSpecifier  testDirSpec;
  231.     CHXString strNumber;
  232.     CHXString strName;
  233.     UINT32 nCurrentNum;
  234.     nCurrentNum = nStartNum;
  235.     while (1) 
  236.     {
  237.         // if the number is non-zero, make a string from the template;
  238.         // if the number is zero, user the initial name string
  239.         if (nCurrentNum == 0)
  240.         {
  241.             // replace the wildcard in the template with the number string
  242.             strName = pszNameFirst;
  243.         }
  244.         else
  245.         {
  246.             // replace the wildcard in the template with the number string
  247.             strNumber.Empty();
  248.             strNumber.AppendULONG(nCurrentNum);
  249.             strName = pszTemplate;
  250.             strName.FindAndReplace(pszWildcard, strNumber); // replace first wildcard with number string
  251.         }
  252.         // test if a file or directory exists with that name
  253.         testFileSpec = locationSpec.SpecifyChildFile(strName);
  254.         testDirSpec = locationSpec.SpecifyChildDirectory(strName);
  255.         if (CHXFileSpecUtils::FileExists(testFileSpec)
  256.             || CHXFileSpecUtils::DirectoryExists(testDirSpec))
  257.         {
  258.             // an item already has that name, so increment & wrap the number
  259.             nCurrentNum++;
  260.             nCurrentNum %= kNumWrapValue;
  261.             // don't use 0 again, and skip 1 since "MyFile2.txt" logically follows "MyFile.txt"
  262.             if (nCurrentNum == 0 || nCurrentNum == 1) 
  263.             {
  264.                 nCurrentNum = 2; 
  265.             }
  266.             // a quick sanity check
  267.             if (nCurrentNum == nStartNum)
  268.             {
  269.                 check(!"GetUniqueFileSpecInternal number wrapped");
  270.                 break;
  271.             }
  272.         }
  273.         else
  274.         {
  275.             // the name is unique
  276.             resultFileSpec = testFileSpec;
  277.             break;
  278.         }
  279.     } // while
  280.     return resultFileSpec;
  281. }
  282. //******************************************************************************
  283. CHXDirSpecifier CHXFileSpecUtils::GetSystemTempDirectory()
  284. {
  285.     return CHXDirSpecifier(getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp");
  286. }
  287. BOOL CHXFileSpecUtils::MakeNameLegal(char *pszName)
  288. {
  289.     const char *badChars = "\/:*?"<>| ][()'";
  290.     const char replacementChar = '_';
  291.     const long maxNameLength = 255;
  292.     char *pCurrChar = pszName;
  293.     
  294.     BOOL bChanged;
  295.     
  296.     require_nonnull_return(pszName, FALSE);
  297.     
  298.     bChanged = FALSE;
  299.     
  300.     // replace any illegal characters
  301.     while (*pCurrChar)
  302.     {
  303.         if (strchr(badChars, *pCurrChar))
  304.         {
  305.             *pCurrChar = replacementChar;
  306.             bChanged = TRUE;
  307.         }
  308.         pCurrChar = HXGetNextChar(pCurrChar);
  309.         
  310.         // be sure the name isn't too long
  311.         if (pCurrChar - pszName >= maxNameLength)
  312.         {
  313.             if (pCurrChar - pszName >= maxNameLength + 1)
  314.                 pCurrChar = HXGetPrevChar(pszName, pCurrChar);
  315.             *pCurrChar = 0;
  316.             bChanged = TRUE;
  317.         }
  318.     }
  319.     
  320.     return bChanged;
  321. }
  322. //******************************************************************************
  323. CHXDirSpecifier 
  324. CHXFileSpecUtils::GetAppDataDir(const char* szAppName)
  325. {
  326.     return CHXDirSpecifier("/huh");
  327. }