copyfile.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:7k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include <string.h>
  36. #include "hxtypes.h"
  37. #include "copyfile.h"
  38. OSErr DoCopyFile(FSSpec &srcSpec, FSSpec &dstSpec, Boolean moveflag)
  39. {
  40. FInfo dstinfo,srcinfo;
  41. OSErr err = noErr;
  42. short srcRefNum, dstRefNum;
  43. Ptr filePtr = nil;
  44. UINT32 dataleft,fsize,vleft;
  45. long numBytes, blockSize;
  46. if (EqualFSSpec(dstSpec, srcSpec)) return noErr;
  47. err = FSpDelete(&dstSpec);
  48. if (err && err != fnfErr) return err;
  49. if ((dstSpec.vRefNum == srcSpec.vRefNum) && moveflag) { // if on same volume, do it the easy way.
  50. FSSpec dstFolder;
  51. err = FSpRename(&srcSpec,dstSpec.name);
  52. if (err) return err;
  53. memcpy(&dstSpec.name[1],&srcSpec.name[1],srcSpec.name[0]); /* Flawfinder: ignore */
  54. dstSpec.name[0] = srcSpec.name[0];
  55. err = FSMakeFSSpec(dstSpec.vRefNum, dstSpec.parID,NULL, &dstFolder);
  56. if(err) return err;
  57. // if (err = FSSpecFromDirID(dstSpec.vRefNum, dstSpec.parID, dstFolder)) return err;
  58. err = FSpCatMove(&srcSpec,&dstFolder);
  59. if (err) return err;
  60. return noErr;
  61. }
  62. err = GetFileSize(srcSpec,&fsize);
  63. if (err) return err;
  64. vleft = GetVolumeFreeSpace(dstSpec.vRefNum);
  65. if (fsize > vleft) return dskFulErr;
  66. // Get all Finder information for the existing file
  67. err = FSpGetFInfo(&srcSpec,&srcinfo);
  68. if (err) goto here;
  69. // Create the data fork of the new file
  70. FSpCreateResFile(&dstSpec, srcinfo.fdCreator, srcinfo.fdType,smCurrentScript);
  71. err = ResError();
  72. if (err) goto here;
  73. err = FSpGetFInfo(&dstSpec, &dstinfo);
  74. if (err) goto here;
  75. vleft = 0;
  76. // Open up the data fork of the existing file. Copy the entire data fork of the
  77. // source file into the destination file.
  78. blockSize = 0;
  79. err = FSpOpenDF(&srcSpec, fsRdPerm, &srcRefNum);
  80. if (!err) GetEOF(srcRefNum,&blockSize);
  81. dataleft = blockSize;
  82. if (blockSize && !err) {
  83. do {
  84. filePtr = NewPtr(blockSize);
  85. if (!filePtr) blockSize = blockSize * 3L / 4L;
  86. } while (!filePtr);
  87. err = FSpOpenDF(&dstSpec, fsWrPerm, &dstRefNum);
  88. if (!err) {
  89. err = SetFPos(srcRefNum, fsFromStart, 0L);
  90. err = SetFPos(dstRefNum, fsFromStart, 0L);
  91. do {
  92. numBytes = min(blockSize,dataleft);
  93. err = FSRead(srcRefNum, &numBytes, filePtr);
  94. err = FSWrite(dstRefNum, &numBytes, filePtr);
  95. vleft += numBytes;
  96. dataleft -= numBytes;
  97. } while (dataleft);
  98. err = FSClose(dstRefNum);
  99. }
  100. DisposePtr(filePtr);
  101. }
  102. err = FSClose(srcRefNum);
  103. // Open up the resource fork of the existing file. Only if there is a resource fork on the
  104. // existing file do we create a resource fork for the new file. Copy the entire resource fork
  105. // of the source file into the destination file.
  106. blockSize = 0;
  107. err = FSpOpenRF(&srcSpec, fsRdPerm, &srcRefNum);
  108. if (!err) GetEOF(srcRefNum,&blockSize);
  109. dataleft = blockSize;
  110. if (blockSize && !err) {
  111. do {
  112. filePtr = NewPtr(blockSize);
  113. if (!filePtr) blockSize = blockSize * 3L / 4L;
  114. } while (!filePtr);
  115. err = FSpOpenRF(&dstSpec, fsWrPerm, &dstRefNum);
  116. if (!err) {
  117. err = SetEOF(dstRefNum, 0L); // set to zip
  118. err = SetFPos(srcRefNum, fsFromStart, 0L);
  119. err = SetFPos(dstRefNum, fsFromStart, 0L);
  120. do {
  121. numBytes = min(blockSize,dataleft);
  122. err = FSRead(srcRefNum, &numBytes, filePtr);
  123. err = FSWrite(dstRefNum, &numBytes, filePtr);
  124. vleft += numBytes;
  125. dataleft -= numBytes;
  126. } while (dataleft);
  127. err = FSClose(dstRefNum);
  128. }
  129. DisposePtr(filePtr);
  130. }
  131. err = FSClose(srcRefNum);
  132. // Restore the (almost) exact finder information as the original source file
  133. srcinfo.fdLocation.h =
  134. srcinfo.fdLocation.v = -1;
  135. err = FSpSetFInfo(&dstSpec, &srcinfo); 
  136. here:
  137. if (moveflag) return FSpDelete(&srcSpec);
  138. return noErr;
  139. }
  140. long GetVolumeFreeSpace(short vRefNum)
  141. {
  142. #ifdef _CARBON
  143. // xxxbobclark PBXGetVolInfoSync exists in OS 8.5 and later, but still
  144. // I'll leave the old code there for all non-Carbon. By only using it
  145. // in Carbon code we'll never even risk calling it accidentally.
  146. XVolumeParam xpb;
  147. xpb.ioCompletion = NULL;
  148. xpb.ioNamePtr = NULL;
  149. xpb.ioVRefNum = vRefNum;
  150. OSErr err = PBXGetVolInfoSync(&xpb);
  151. if (err) return 0;
  152. if (xpb.ioVFreeBytes > 0x000000007fffffff)
  153. {
  154. return 0x7fffffff;
  155. }
  156. return (long)xpb.ioVFreeBytes;
  157. #else
  158. HVolumeParam block;
  159. OSErr err;
  160. long freeSpace = 0L;
  161. Str255 volname = {0};
  162. memset(&block,0,sizeof(HVolumeParam));
  163. block.ioVRefNum = vRefNum;
  164. err = PBHGetVInfoSync((HParmBlkPtr)&block);
  165. if (!err) {
  166. err = GetVInfo(block.ioVDrvInfo,volname,&vRefNum,&freeSpace);
  167. }
  168. return freeSpace;
  169. #endif
  170. }
  171. Boolean EqualFSSpec(FSSpec &srcSpec, FSSpec &dstSpec)
  172. {
  173. Boolean bEqual = srcSpec.vRefNum == dstSpec.vRefNum;
  174. if(bEqual)
  175. {
  176. bEqual = srcSpec.parID == dstSpec.parID;
  177. }
  178. if(bEqual)
  179. {
  180. bEqual = srcSpec.name[0] == dstSpec.name[0];
  181. }
  182. if(bEqual)
  183. {
  184. bEqual = memcmp(&srcSpec.name[1],&dstSpec.name[1],srcSpec.name[0]) == 0;
  185. }
  186. return bEqual;
  187. }
  188. OSErr GetFileSize(FSSpec &srcSpec,UINT32 *fsize)
  189. {
  190. short srcRefNum;
  191. OSErr err = FSpOpenDF(&srcSpec, fsRdPerm, &srcRefNum);
  192. if (!err) 
  193. {
  194. err = GetEOF(srcRefNum,(long*)fsize);
  195. FSClose(srcRefNum);
  196. }
  197. if(err)
  198. {
  199. *fsize = 0;
  200. }
  201. return err;
  202. }