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" |
| 11 #include "base/logging.h" |
11 | 12 |
12 #include "courgette/crc.h" | 13 #include "courgette/crc.h" |
13 #include "courgette/image_info.h" | 14 #include "courgette/image_info.h" |
14 #include "courgette/region.h" | 15 #include "courgette/region.h" |
15 #include "courgette/streams.h" | 16 #include "courgette/streams.h" |
16 #include "courgette/simple_delta.h" | 17 #include "courgette/simple_delta.h" |
17 #include "courgette/win32_x86_patcher.h" | 18 #include "courgette/win32_x86_patcher.h" |
18 | 19 |
19 namespace courgette { | 20 namespace courgette { |
20 | 21 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 private: | 57 private: |
57 Status SubpatchStreamSets(SinkStreamSet* predicted_items, | 58 Status SubpatchStreamSets(SinkStreamSet* predicted_items, |
58 SourceStream* correction, | 59 SourceStream* correction, |
59 SourceStreamSet* corrected_items, | 60 SourceStreamSet* corrected_items, |
60 SinkStream* corrected_items_storage); | 61 SinkStream* corrected_items_storage); |
61 | 62 |
62 Region base_region_; // Location of in-memory copy of 'old' version. | 63 Region base_region_; // Location of in-memory copy of 'old' version. |
63 | 64 |
64 uint32 source_checksum_; | 65 uint32 source_checksum_; |
65 uint32 target_checksum_; | 66 uint32 target_checksum_; |
| 67 uint32 final_patch_input_size_prediction_; |
66 | 68 |
67 std::vector<TransformationPatcher*> patchers_; | 69 std::vector<TransformationPatcher*> patchers_; |
68 | 70 |
69 SinkStream corrected_parameters_storage_; | 71 SinkStream corrected_parameters_storage_; |
70 SinkStream corrected_elements_storage_; | 72 SinkStream corrected_elements_storage_; |
71 | 73 |
72 DISALLOW_COPY_AND_ASSIGN(EnsemblePatchApplication); | 74 DISALLOW_COPY_AND_ASSIGN(EnsemblePatchApplication); |
73 }; | 75 }; |
74 | 76 |
75 EnsemblePatchApplication::EnsemblePatchApplication() | 77 EnsemblePatchApplication::EnsemblePatchApplication() |
76 : source_checksum_(0), target_checksum_(0) { | 78 : source_checksum_(0), target_checksum_(0), |
| 79 final_patch_input_size_prediction_(0) { |
77 } | 80 } |
78 | 81 |
79 EnsemblePatchApplication::~EnsemblePatchApplication() { | 82 EnsemblePatchApplication::~EnsemblePatchApplication() { |
80 for (size_t i = 0; i < patchers_.size(); ++i) { | 83 for (size_t i = 0; i < patchers_.size(); ++i) { |
81 delete patchers_[i]; | 84 delete patchers_[i]; |
82 } | 85 } |
83 } | 86 } |
84 | 87 |
85 Status EnsemblePatchApplication::ReadHeader(SourceStream* header_stream) { | 88 Status EnsemblePatchApplication::ReadHeader(SourceStream* header_stream) { |
86 uint32 magic; | 89 uint32 magic; |
87 if (!header_stream->ReadVarint32(&magic)) | 90 if (!header_stream->ReadVarint32(&magic)) |
88 return C_BAD_ENSEMBLE_MAGIC; | 91 return C_BAD_ENSEMBLE_MAGIC; |
89 | 92 |
90 if (magic != CourgettePatchFile::kMagic) | 93 if (magic != CourgettePatchFile::kMagic) |
91 return C_BAD_ENSEMBLE_MAGIC; | 94 return C_BAD_ENSEMBLE_MAGIC; |
92 | 95 |
93 uint32 version; | 96 uint32 version; |
94 if (!header_stream->ReadVarint32(&version)) | 97 if (!header_stream->ReadVarint32(&version)) |
95 return C_BAD_ENSEMBLE_VERSION; | 98 return C_BAD_ENSEMBLE_VERSION; |
96 | 99 |
97 if (version != CourgettePatchFile::kVersion) | 100 if (version != CourgettePatchFile::kVersion) |
98 return C_BAD_ENSEMBLE_VERSION; | 101 return C_BAD_ENSEMBLE_VERSION; |
99 | 102 |
100 if (!header_stream->ReadVarint32(&source_checksum_)) | 103 if (!header_stream->ReadVarint32(&source_checksum_)) |
101 return C_BAD_ENSEMBLE_HEADER; | 104 return C_BAD_ENSEMBLE_HEADER; |
102 | 105 |
103 if (!header_stream->ReadVarint32(&target_checksum_)) | 106 if (!header_stream->ReadVarint32(&target_checksum_)) |
104 return C_BAD_ENSEMBLE_HEADER; | 107 return C_BAD_ENSEMBLE_HEADER; |
105 | 108 |
| 109 if (!header_stream->ReadVarint32(&final_patch_input_size_prediction_)) |
| 110 return C_BAD_ENSEMBLE_HEADER; |
| 111 |
106 return C_OK; | 112 return C_OK; |
107 } | 113 } |
108 | 114 |
109 Status EnsemblePatchApplication::InitBase(const Region& region) { | 115 Status EnsemblePatchApplication::InitBase(const Region& region) { |
110 base_region_.assign(region); | 116 base_region_.assign(region); |
111 return C_OK; | 117 return C_OK; |
112 } | 118 } |
113 | 119 |
114 Status EnsemblePatchApplication::ValidateBase() { | 120 Status EnsemblePatchApplication::ValidateBase() { |
115 uint32 checksum = CalculateCrc(base_region_.start(), base_region_.length()); | 121 uint32 checksum = CalculateCrc(base_region_.start(), base_region_.length()); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 correction, | 213 correction, |
208 corrected_elements, | 214 corrected_elements, |
209 &corrected_elements_storage_); | 215 &corrected_elements_storage_); |
210 } | 216 } |
211 | 217 |
212 Status EnsemblePatchApplication::TransformDown( | 218 Status EnsemblePatchApplication::TransformDown( |
213 SourceStreamSet* transformed_elements, | 219 SourceStreamSet* transformed_elements, |
214 SinkStream* basic_elements) { | 220 SinkStream* basic_elements) { |
215 // Construct blob of original input followed by reformed elements. | 221 // Construct blob of original input followed by reformed elements. |
216 | 222 |
| 223 basic_elements->Reserve(final_patch_input_size_prediction_); |
| 224 |
217 // The original input: | 225 // The original input: |
218 basic_elements->Write(base_region_.start(), base_region_.length()); | 226 basic_elements->Write(base_region_.start(), base_region_.length()); |
219 | 227 |
220 for (size_t i = 0; i < patchers_.size(); ++i) { | 228 for (size_t i = 0; i < patchers_.size(); ++i) { |
221 SourceStreamSet single_corrected_element; | 229 SourceStreamSet single_corrected_element; |
222 if (!transformed_elements->ReadSet(&single_corrected_element)) | 230 if (!transformed_elements->ReadSet(&single_corrected_element)) |
223 return C_STREAM_ERROR; | 231 return C_STREAM_ERROR; |
224 Status status = patchers_[i]->Reform(&single_corrected_element, | 232 Status status = patchers_[i]->Reform(&single_corrected_element, |
225 basic_elements); | 233 basic_elements); |
226 if (status != C_OK) | 234 if (status != C_OK) |
227 return status; | 235 return status; |
228 if (!single_corrected_element.Empty()) | 236 if (!single_corrected_element.Empty()) |
229 return C_STREAM_NOT_CONSUMED; | 237 return C_STREAM_NOT_CONSUMED; |
230 } | 238 } |
231 | 239 |
232 if (!transformed_elements->Empty()) | 240 if (!transformed_elements->Empty()) |
233 return C_STREAM_NOT_CONSUMED; | 241 return C_STREAM_NOT_CONSUMED; |
| 242 corrected_elements_storage_.Retire(); |
234 | 243 |
235 return C_OK; | 244 return C_OK; |
236 } | 245 } |
237 | 246 |
238 Status EnsemblePatchApplication::SubpatchFinalOutput( | 247 Status EnsemblePatchApplication::SubpatchFinalOutput( |
239 SourceStream* original, | 248 SourceStream* original, |
240 SourceStream* correction, | 249 SourceStream* correction, |
241 SinkStream* corrected_ensemble) { | 250 SinkStream* corrected_ensemble) { |
242 Status delta_status = ApplySimpleDelta(original, correction, | 251 Status delta_status = ApplySimpleDelta(original, correction, |
243 corrected_ensemble); | 252 corrected_ensemble); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 | 376 |
368 // 'Dry-run' the first step of the patch process to validate format of header. | 377 // 'Dry-run' the first step of the patch process to validate format of header. |
369 SourceStream patch_header_stream; | 378 SourceStream patch_header_stream; |
370 patch_header_stream.Init(buffer, read_count); | 379 patch_header_stream.Init(buffer, read_count); |
371 EnsemblePatchApplication patch_process; | 380 EnsemblePatchApplication patch_process; |
372 status = patch_process.ReadHeader(&patch_header_stream); | 381 status = patch_process.ReadHeader(&patch_header_stream); |
373 if (status != C_OK) | 382 if (status != C_OK) |
374 return status; | 383 return status; |
375 | 384 |
376 // Header smells good so read the whole patch file for real. | 385 // Header smells good so read the whole patch file for real. |
| 386 int64 patch_file_size = 0; |
| 387 if (!file_util::GetFileSize(patch_file_path, &patch_file_size)) |
| 388 return C_READ_ERROR; |
377 std::string patch_file_buffer; | 389 std::string patch_file_buffer; |
| 390 patch_file_buffer.reserve(static_cast<size_t>(patch_file_size)); |
378 if (!file_util::ReadFileToString(patch_file_path, &patch_file_buffer)) | 391 if (!file_util::ReadFileToString(patch_file_path, &patch_file_buffer)) |
379 return C_READ_ERROR; | 392 return C_READ_ERROR; |
380 | 393 |
381 // Read the old_file. | 394 // Read the old_file. |
382 FilePath old_file_path(old_file_name); | 395 FilePath old_file_path(old_file_name); |
| 396 int64 old_file_size = 0; |
| 397 if (!file_util::GetFileSize(old_file_path, &old_file_size)) |
| 398 return C_READ_ERROR; |
383 std::string old_file_buffer; | 399 std::string old_file_buffer; |
| 400 old_file_buffer.reserve(static_cast<size_t>(old_file_size)); |
384 if (!file_util::ReadFileToString(old_file_path, &old_file_buffer)) | 401 if (!file_util::ReadFileToString(old_file_path, &old_file_buffer)) |
385 return C_READ_ERROR; | 402 return C_READ_ERROR; |
386 | 403 |
387 // Apply patch on streams. | 404 // Apply patch on streams. |
388 SourceStream old_source_stream; | 405 SourceStream old_source_stream; |
389 SourceStream patch_source_stream; | 406 SourceStream patch_source_stream; |
390 old_source_stream.Init(old_file_buffer); | 407 old_source_stream.Init(old_file_buffer); |
391 patch_source_stream.Init(patch_file_buffer); | 408 patch_source_stream.Init(patch_file_buffer); |
392 SinkStream new_sink_stream; | 409 SinkStream new_sink_stream; |
393 status = ApplyEnsemblePatch(&old_source_stream, &patch_source_stream, | 410 status = ApplyEnsemblePatch(&old_source_stream, &patch_source_stream, |
394 &new_sink_stream); | 411 &new_sink_stream); |
395 | 412 |
396 // Write the patched data to |new_file_name|. | 413 // Write the patched data to |new_file_name|. |
397 FilePath new_file_path(new_file_name); | 414 FilePath new_file_path(new_file_name); |
398 int written = | 415 int written = |
399 file_util::WriteFile( | 416 file_util::WriteFile( |
400 new_file_path, | 417 new_file_path, |
401 reinterpret_cast<const char*>(new_sink_stream.Buffer()), | 418 reinterpret_cast<const char*>(new_sink_stream.Buffer()), |
402 static_cast<int>(new_sink_stream.Length())); | 419 static_cast<int>(new_sink_stream.Length())); |
403 if (written == -1) | 420 if (written == -1) |
404 return C_WRITE_OPEN_ERROR; | 421 return C_WRITE_OPEN_ERROR; |
405 if (static_cast<size_t>(written) != new_sink_stream.Length()) | 422 if (static_cast<size_t>(written) != new_sink_stream.Length()) |
406 return C_WRITE_ERROR; | 423 return C_WRITE_ERROR; |
407 | 424 |
408 return C_OK; | 425 return C_OK; |
409 } | 426 } |
410 | 427 |
411 } // namespace | 428 } // namespace |
OLD | NEW |