MCPcopy Create free account
hub / github.com/BernardoGiordano/Checkpoint / copyFile

Method copyFile

3ds/source/io.cpp:112–185  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

110}
111
112Result io::copyFile(
113 FS_Archive srcArch, FS_Archive dstArch, const std::u16string& srcPath, const std::u16string& dstPath, ProgressSink& sink, u8* buffer)
114{
115 u32 size = 0;
116 FSStream input(srcArch, srcPath, FS_OPEN_READ);
117 if (input.good()) {
118 size = input.size() > BUFFER_SIZE ? BUFFER_SIZE : input.size();
119 }
120 else {
121 Logging::error("Failed to open source file {} during copy with result {}.", StringUtils::UTF16toUTF8(srcPath), input.result());
122 return input.result();
123 }
124
125 FSStream output(dstArch, dstPath, FS_OPEN_WRITE, input.size());
126 if (!output.good()) {
127 Logging::error("Failed to open destination file {} during copy with result {}.", StringUtils::UTF16toUTF8(dstPath), output.result());
128 input.close();
129 return output.result();
130 }
131
132 size_t slashpos = srcPath.rfind(StringUtils::UTF8toUTF16("/"));
133 sink.startFile(srcPath.substr(slashpos + 1, srcPath.length() - slashpos - 1), input.size());
134
135 Result res = 0;
136 u32 offset = 0;
137 u32 chunk = size; // shrinks toward the readable-data boundary on RES_FS_PAST_DATA
138 do {
139 if (sink.cancelled()) {
140 break;
141 }
142 u32 rd = input.read(buffer, chunk);
143 if (R_FAILED(input.result())) {
144 // Sparse extdata: this offset+chunk runs past the file's real data. Halve
145 // the request to recover any readable prefix at this offset; once even a
146 // single byte can't be read here, we've hit the true end of data — stop
147 // this file cleanly and keep the backup going.
148 if ((u32)input.result() == RES_FS_PAST_DATA) {
149 if (chunk > 1) {
150 chunk /= 2;
151 continue;
152 }
153 Logging::info("Reached end of readable data for {} at offset {} (sparse extdata); backing up {} bytes.",
154 StringUtils::UTF16toUTF8(srcPath), offset, offset);
155 break;
156 }
157 res = input.result();
158 Logging::error("Read failure during copy of {} with result 0x{:08X}.", StringUtils::UTF16toUTF8(srcPath), (u32)res);
159 break;
160 }
161 if (rd == 0) {
162 break;
163 }
164 u32 wt = output.write(buffer, rd);
165 if (R_FAILED(output.result())) {
166 res = output.result();
167 Logging::error("Write failure during copy of {} with result 0x{:08X}.", StringUtils::UTF16toUTF8(dstPath), (u32)res);
168 break;
169 }

Callers

nothing calls this directly

Calls 13

errorFunction · 0.85
infoFunction · 0.85
resultMethod · 0.80
goodMethod · 0.45
sizeMethod · 0.45
closeMethod · 0.45
startFileMethod · 0.45
cancelledMethod · 0.45
readMethod · 0.45
writeMethod · 0.45
advanceBytesMethod · 0.45
eofMethod · 0.45

Tested by

no test coverage detected