OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This file contains the code to apply a Courgette patch. | 5 // This file contains the code to apply a Courgette patch. |
6 | 6 |
7 #include "courgette/ensemble.h" | 7 #include "courgette/ensemble.h" |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 ensemble_correction, output); | 357 ensemble_correction, output); |
358 if (status != C_OK) | 358 if (status != C_OK) |
359 return status; | 359 return status; |
360 | 360 |
361 return C_OK; | 361 return C_OK; |
362 } | 362 } |
363 | 363 |
364 Status ApplyEnsemblePatch(const FilePath::CharType* old_file_name, | 364 Status ApplyEnsemblePatch(const FilePath::CharType* old_file_name, |
365 const FilePath::CharType* patch_file_name, | 365 const FilePath::CharType* patch_file_name, |
366 const FilePath::CharType* new_file_name) { | 366 const FilePath::CharType* new_file_name) { |
367 Status status; | |
368 | |
369 // First read enough of the patch file to validate the header is well-formed. | 367 // First read enough of the patch file to validate the header is well-formed. |
370 // A few varint32 numbers should fit in 100. | 368 // A few varint32 numbers should fit in 100. |
371 FilePath patch_file_path(patch_file_name); | 369 FilePath patch_file_path(patch_file_name); |
372 const int BIG_ENOUGH_FOR_HEADER = 100; | 370 file_util::MemoryMappedFile patch_file; |
373 char buffer[BIG_ENOUGH_FOR_HEADER]; | 371 if (!patch_file.Initialize(patch_file_path)) |
374 int read_count = | |
375 file_util::ReadFile(patch_file_path, buffer, sizeof(buffer)); | |
376 if (read_count < 0) | |
377 return C_READ_OPEN_ERROR; | 372 return C_READ_OPEN_ERROR; |
378 | 373 |
379 // 'Dry-run' the first step of the patch process to validate format of header. | 374 // 'Dry-run' the first step of the patch process to validate format of header. |
380 SourceStream patch_header_stream; | 375 SourceStream patch_header_stream; |
381 patch_header_stream.Init(buffer, read_count); | 376 patch_header_stream.Init(patch_file.data(), patch_file.length()); |
382 EnsemblePatchApplication patch_process; | 377 EnsemblePatchApplication patch_process; |
383 status = patch_process.ReadHeader(&patch_header_stream); | 378 Status status = patch_process.ReadHeader(&patch_header_stream); |
384 if (status != C_OK) | 379 if (status != C_OK) |
385 return status; | 380 return status; |
386 | 381 |
387 // Header smells good so read the whole patch file for real. | |
388 int64 patch_file_size = 0; | |
389 if (!file_util::GetFileSize(patch_file_path, &patch_file_size)) | |
390 return C_READ_ERROR; | |
391 std::string patch_file_buffer; | |
392 patch_file_buffer.reserve(static_cast<size_t>(patch_file_size)); | |
393 if (!file_util::ReadFileToString(patch_file_path, &patch_file_buffer)) | |
394 return C_READ_ERROR; | |
395 | |
396 // Read the old_file. | 382 // Read the old_file. |
397 FilePath old_file_path(old_file_name); | 383 FilePath old_file_path(old_file_name); |
398 int64 old_file_size = 0; | 384 file_util::MemoryMappedFile old_file; |
399 if (!file_util::GetFileSize(old_file_path, &old_file_size)) | 385 if (!old_file.Initialize(old_file_path)) |
400 return C_READ_ERROR; | |
401 std::string old_file_buffer; | |
402 old_file_buffer.reserve(static_cast<size_t>(old_file_size)); | |
403 if (!file_util::ReadFileToString(old_file_path, &old_file_buffer)) | |
404 return C_READ_ERROR; | 386 return C_READ_ERROR; |
405 | 387 |
406 // Apply patch on streams. | 388 // Apply patch on streams. |
407 SourceStream old_source_stream; | 389 SourceStream old_source_stream; |
408 SourceStream patch_source_stream; | 390 SourceStream patch_source_stream; |
409 old_source_stream.Init(old_file_buffer); | 391 old_source_stream.Init(old_file.data(), old_file.length()); |
410 patch_source_stream.Init(patch_file_buffer); | 392 patch_source_stream.Init(patch_file.data(), patch_file.length()); |
411 SinkStream new_sink_stream; | 393 SinkStream new_sink_stream; |
412 status = ApplyEnsemblePatch(&old_source_stream, &patch_source_stream, | 394 status = ApplyEnsemblePatch(&old_source_stream, &patch_source_stream, |
413 &new_sink_stream); | 395 &new_sink_stream); |
414 | 396 |
415 // Write the patched data to |new_file_name|. | 397 // Write the patched data to |new_file_name|. |
416 FilePath new_file_path(new_file_name); | 398 FilePath new_file_path(new_file_name); |
417 int written = | 399 int written = |
418 file_util::WriteFile( | 400 file_util::WriteFile( |
419 new_file_path, | 401 new_file_path, |
420 reinterpret_cast<const char*>(new_sink_stream.Buffer()), | 402 reinterpret_cast<const char*>(new_sink_stream.Buffer()), |
421 static_cast<int>(new_sink_stream.Length())); | 403 static_cast<int>(new_sink_stream.Length())); |
422 if (written == -1) | 404 if (written == -1) |
423 return C_WRITE_OPEN_ERROR; | 405 return C_WRITE_OPEN_ERROR; |
424 if (static_cast<size_t>(written) != new_sink_stream.Length()) | 406 if (static_cast<size_t>(written) != new_sink_stream.Length()) |
425 return C_WRITE_ERROR; | 407 return C_WRITE_ERROR; |
426 | 408 |
427 return C_OK; | 409 return C_OK; |
428 } | 410 } |
429 | 411 |
430 } // namespace | 412 } // namespace |
OLD | NEW |