VirtualBox

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

Last change on this file since 77829 was 77825, checked in by vboxsync, 6 years ago

IPRT: Split RTFileCopyEx and RTFileCopyByHandlesEx out of r3/fileio.cpp so we can do platform specific implementations of these. bugref:9172

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.1 KB
Line 
1/* $Id: RTFileCopyByHandlesEx-generic.cpp 77825 2019-03-21 12:33:42Z vboxsync $ */
2/** @file
3 * IPRT - RTFileCopyByHandlesEx, generic implementation.
4 */
5
6/*
7 * Copyright (C) 2006-2019 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 FileSrc, RTFILE FileDst, PFNRTPROGRESS pfnProgress, void *pvUser)
41{
42 /*
43 * Validate input.
44 */
45 AssertMsgReturn(RTFileIsValid(FileSrc), ("FileSrc=%RTfile\n", FileSrc), VERR_INVALID_PARAMETER);
46 AssertMsgReturn(RTFileIsValid(FileDst), ("FileDst=%RTfile\n", FileDst), VERR_INVALID_PARAMETER);
47 AssertMsgReturn(!pfnProgress || VALID_PTR(pfnProgress), ("pfnProgress=%p\n", pfnProgress), VERR_INVALID_PARAMETER);
48
49 /*
50 * Save file offset.
51 */
52 RTFOFF offSrcSaved;
53 int rc = RTFileSeek(FileSrc, 0, RTFILE_SEEK_CURRENT, (uint64_t *)&offSrcSaved);
54 if (RT_FAILURE(rc))
55 return rc;
56
57 /*
58 * Get the file size.
59 */
60 RTFOFF cbSrc;
61 rc = RTFileSeek(FileSrc, 0, RTFILE_SEEK_END, (uint64_t *)&cbSrc);
62 if (RT_FAILURE(rc))
63 return rc;
64
65 /*
66 * Allocate buffer.
67 */
68 size_t cbBuf;
69 uint8_t *pbBufFree = NULL;
70 uint8_t *pbBuf;
71 if (cbSrc < _512K)
72 {
73 cbBuf = 8*_1K;
74 pbBuf = (uint8_t *)alloca(cbBuf);
75 }
76 else
77 {
78 cbBuf = _128K;
79 pbBuf = pbBufFree = (uint8_t *)RTMemTmpAlloc(cbBuf);
80 }
81 if (pbBuf)
82 {
83 /*
84 * Seek to the start of each file
85 * and set the size of the destination file.
86 */
87 rc = RTFileSeek(FileSrc, 0, RTFILE_SEEK_BEGIN, NULL);
88 if (RT_SUCCESS(rc))
89 {
90 rc = RTFileSeek(FileDst, 0, RTFILE_SEEK_BEGIN, NULL);
91 if (RT_SUCCESS(rc))
92 rc = RTFileSetSize(FileDst, cbSrc);
93 if (RT_SUCCESS(rc) && pfnProgress)
94 rc = pfnProgress(0, pvUser);
95 if (RT_SUCCESS(rc))
96 {
97 /*
98 * Copy loop.
99 */
100 unsigned uPercentage = 0;
101 RTFOFF off = 0;
102 RTFOFF cbPercent = cbSrc / 100;
103 RTFOFF offNextPercent = cbPercent;
104 while (off < cbSrc)
105 {
106 /* copy block */
107 RTFOFF cbLeft = cbSrc - off;
108 size_t cbBlock = cbLeft >= (RTFOFF)cbBuf ? cbBuf : (size_t)cbLeft;
109 rc = RTFileRead(FileSrc, pbBuf, cbBlock, NULL);
110 if (RT_FAILURE(rc))
111 break;
112 rc = RTFileWrite(FileDst, pbBuf, cbBlock, NULL);
113 if (RT_FAILURE(rc))
114 break;
115
116 /* advance */
117 off += cbBlock;
118 if (pfnProgress && offNextPercent < off && uPercentage < 100)
119 {
120 do
121 {
122 uPercentage++;
123 offNextPercent += cbPercent;
124 } while (offNextPercent < off && uPercentage < 100);
125 rc = pfnProgress(uPercentage, pvUser);
126 if (RT_FAILURE(rc))
127 break;
128 }
129 }
130
131#if 0
132 /*
133 * Copy OS specific data (EAs and stuff).
134 */
135 rtFileCopyOSStuff(FileSrc, FileDst);
136#endif
137
138 /* 100% */
139 if (pfnProgress && uPercentage < 100 && RT_SUCCESS(rc))
140 rc = pfnProgress(100, pvUser);
141 }
142 }
143 RTMemTmpFree(pbBufFree);
144 }
145 else
146 rc = VERR_NO_MEMORY;
147
148 /*
149 * Restore source position.
150 */
151 RTFileSeek(FileSrc, offSrcSaved, RTFILE_SEEK_BEGIN, NULL);
152
153 return rc;
154}
155
Note: See TracBrowser for help on using the repository browser.

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