patch_utils.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef COMPONENTS_ZUCCHINI_PATCH_UTILS_H_
  5. #define COMPONENTS_ZUCCHINI_PATCH_UTILS_H_
  6. #include <stdint.h>
  7. #include <iterator>
  8. #include <type_traits>
  9. #include "components/zucchini/image_utils.h"
  10. #include "components/zucchini/version_info.h"
  11. namespace zucchini {
  12. // A Zucchini 'ensemble' patch is the concatenation of a patch header with a
  13. // list of patch 'elements', each containing data for patching individual
  14. // elements.
  15. // Supported by MSVC, g++, and clang++. Ensures no gaps in packing.
  16. #pragma pack(push, 1)
  17. // Header for a Zucchini patch, found at the beginning of an ensemble patch.
  18. struct PatchHeader {
  19. // Magic signature at the beginning of a Zucchini patch file.
  20. enum : uint32_t { kMagic = 'Z' | ('u' << 8) | ('c' << 16) | ('c' << 24) };
  21. uint32_t magic = 0;
  22. uint16_t major_version = kInvalidVersion;
  23. uint16_t minor_version = kInvalidVersion;
  24. uint32_t old_size = 0;
  25. uint32_t old_crc = 0;
  26. uint32_t new_size = 0;
  27. uint32_t new_crc = 0;
  28. };
  29. // Sanity check.
  30. static_assert(sizeof(PatchHeader) == 24, "PatchHeader must be 24 bytes");
  31. // Header for a patch element, found at the beginning of every patch element.
  32. struct PatchElementHeader {
  33. uint32_t old_offset;
  34. uint32_t old_length;
  35. uint32_t new_offset;
  36. uint32_t new_length;
  37. uint32_t exe_type; // ExecutableType.
  38. uint16_t version = kInvalidVersion;
  39. };
  40. // Sanity check.
  41. static_assert(sizeof(PatchElementHeader) == 22,
  42. "PatchElementHeader must be 22 bytes");
  43. #pragma pack(pop)
  44. // Descibes a raw FIX operation.
  45. struct RawDeltaUnit {
  46. offset_t copy_offset; // Offset in copy regions.
  47. int8_t diff; // Bytewise difference.
  48. };
  49. // A Zucchini patch contains data streams encoded using varint format to reduce
  50. // uncompressed size.
  51. // Writes |value| as a varint in |dst| and returns an iterator pointing beyond
  52. // the written region. |dst| is assumed to hold enough space. Typically, this
  53. // will write to a vector using back insertion, e.g.:
  54. // EncodeVarUInt(value, std::back_inserter(vector));
  55. template <class T, class It>
  56. It EncodeVarUInt(T value, It dst) {
  57. static_assert(std::is_unsigned<T>::value, "Value type must be unsigned");
  58. while (value >= 0x80) {
  59. *dst++ = static_cast<uint8_t>(value) | 0x80;
  60. value >>= 7;
  61. }
  62. *dst++ = static_cast<uint8_t>(value);
  63. return dst;
  64. }
  65. // Same as EncodeVarUInt(), but for signed values.
  66. template <class T, class It>
  67. It EncodeVarInt(T value, It dst) {
  68. static_assert(std::is_signed<T>::value, "Value type must be signed");
  69. using unsigned_value_type = typename std::make_unsigned<T>::type;
  70. if (value < 0)
  71. return EncodeVarUInt((unsigned_value_type(~value) << 1) | 1, dst);
  72. else
  73. return EncodeVarUInt(unsigned_value_type(value) << 1, dst);
  74. }
  75. // Tries to read a varint unsigned integer from |[first, last)|. If
  76. // succesful, writes result into |value| and returns the number of bytes
  77. // read from |[first, last)|. Otherwise returns 0.
  78. template <class T, class It>
  79. typename std::iterator_traits<It>::difference_type DecodeVarUInt(It first,
  80. It last,
  81. T* value) {
  82. static_assert(std::is_unsigned<T>::value, "Value type must be unsigned");
  83. uint8_t sh = 0;
  84. T val = 0;
  85. for (auto it = first; it != last;) {
  86. val |= T(*it & 0x7F) << sh;
  87. if (*(it++) < 0x80) {
  88. *value = val;
  89. return it - first;
  90. }
  91. sh += 7;
  92. if (sh >= sizeof(T) * 8) // Overflow!
  93. return 0;
  94. }
  95. return 0;
  96. }
  97. // Same as DecodeVarUInt(), but for signed values.
  98. template <class T, class It>
  99. typename std::iterator_traits<It>::difference_type DecodeVarInt(It first,
  100. It last,
  101. T* value) {
  102. static_assert(std::is_signed<T>::value, "Value type must be signed");
  103. typename std::make_unsigned<T>::type tmp = 0;
  104. auto res = DecodeVarUInt(first, last, &tmp);
  105. if (res) {
  106. if (tmp & 1)
  107. *value = ~static_cast<T>(tmp >> 1);
  108. else
  109. *value = static_cast<T>(tmp >> 1);
  110. }
  111. return res;
  112. }
  113. } // namespace zucchini
  114. #endif // COMPONENTS_ZUCCHINI_PATCH_UTILS_H_