VirtualBox

source: vbox/trunk/src/VBox/Runtime/generic/RTFileCopyByHandlesEx-generic.cpp@ 91586

Last change on this file since 91586 was 90789, checked in by vboxsync, 3 years ago

IPRT: More VALID_PTR -> RT_VALID_PTR/AssertPtr.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.3 KB
Line 
1/* $Id: RTFileCopyByHandlesEx-generic.cpp 90789 2021-08-23 10:27:29Z vboxsync $ */
2/** @file
3 * IPRT - RTFileCopyByHandlesEx, generic implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include "internal/iprt.h"
32#include <iprt/file.h>
33
34#include <iprt/alloca.h>
35#include <iprt/assert.h>
36#include <iprt/mem.h>
37#include <iprt/errcore.h>
38
39
40RTDECL(int) RTFileCopyByHandlesEx(RTFILE hFileSrc, RTFILE hFileDst, PFNRTPROGRESS pfnProgress, void *pvUser)
41{
42 /*
43 * Validate input.
44 */
45 AssertMsgReturn(RTFileIsValid(hFileSrc), ("hFileSrc=%RTfile\n", hFileSrc), VERR_INVALID_PARAMETER);
46 AssertMsgReturn(RTFileIsValid(hFileDst), ("hFileDst=%RTfile\n", hFileDst), VERR_INVALID_PARAMETER);
47 AssertPtrNullReturn(pfnProgress, VERR_INVALID_POINTER);
48
49 /*
50 * Save file offset.
51 */
52 uint64_t offSrcSaved;
53 int rc = RTFileSeek(hFileSrc, 0, RTFILE_SEEK_CURRENT, &offSrcSaved);
54 if (RT_FAILURE(rc))
55 return rc;
56
57 /*
58 * Get the file size and figure out how much we'll copy at a time.
59 */
60 uint64_t cbSrc;
61 rc = RTFileQuerySize(hFileSrc, &cbSrc);
62 if (RT_FAILURE(rc))
63 return rc;
64
65 uint64_t cbChunk = cbSrc;
66 if (pfnProgress && cbSrc > _1M)
67 {
68 cbChunk /= 100;
69 if (cbChunk > _64M)
70 cbChunk = RT_ALIGN_64(cbChunk, _2M);
71 else
72 cbChunk = RT_ALIGN_64(cbChunk, _128K);
73 }
74
75 /*
76 * Prepare buffers.
77 */
78 RTFILECOPYPARTBUFSTATE BufState;
79 rc = RTFileCopyPartPrep(&BufState, cbChunk);
80 if (RT_SUCCESS(rc))
81 {
82 /*
83 * Prepare the destination file.
84 */
85 uint64_t cbDst;
86 rc = RTFileQuerySize(hFileDst, &cbDst);
87 if (RT_SUCCESS(rc) && cbDst > cbSrc)
88 rc = RTFileSetSize(hFileDst, cbSrc);
89 if (RT_SUCCESS(rc) && cbDst < cbSrc)
90 {
91 rc = RTFileSetAllocationSize(hFileDst, cbSrc, RTFILE_ALLOC_SIZE_F_DEFAULT);
92 if (rc == VERR_NOT_SUPPORTED)
93 rc = RTFileSetSize(hFileDst, cbSrc);
94 }
95 if (RT_SUCCESS(rc))
96 {
97 /*
98 * Copy loop that works till we reach EOF.
99 */
100 RTFOFF off = 0;
101 RTFOFF cbPercent = cbSrc / 100;
102 RTFOFF offNextPercent = pfnProgress ? cbPercent : RTFOFF_MAX;
103 unsigned uPercentage = pfnProgress ? 0 : 100;
104 for (;;)
105 {
106 /*
107 * Copy a block.
108 */
109 uint64_t cbCopied = 0;
110 rc = RTFileCopyPartEx(hFileSrc, off, hFileDst, off, cbChunk, 0 /*fFlags*/, &BufState, &cbCopied);
111 if (RT_FAILURE(rc))
112 break;
113 if (cbCopied == 0)
114 {
115 /*
116 * We reached the EOF. Complete the copy operation.
117 */
118 rc = RTFileSetSize(hFileDst, off);
119 if (RT_SUCCESS(rc))
120 rc = RTFileCopyAttributes(hFileSrc, hFileDst, 0);
121 break;
122 }
123
124 /*
125 * Advance and work the progress callback.
126 */
127 off += cbCopied;
128 if ( off >= offNextPercent
129 && pfnProgress
130 && uPercentage < 99)
131 {
132 do
133 {
134 uPercentage++;
135 offNextPercent += cbPercent;
136 } while ( offNextPercent <= off
137 && uPercentage < 99);
138 rc = pfnProgress(uPercentage, pvUser);
139 if (RT_FAILURE(rc))
140 break;
141 }
142 }
143 }
144
145 RTFileCopyPartCleanup(&BufState);
146
147 /*
148 * 100%.
149 */
150 if ( pfnProgress
151 && RT_SUCCESS(rc))
152 rc = pfnProgress(100, pvUser);
153 }
154
155 /*
156 * Restore source position.
157 */
158 RTFileSeek(hFileSrc, offSrcSaved, RTFILE_SEEK_BEGIN, NULL);
159 return rc;
160}
161
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette