| // Copyright 2026 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| |
| #ifndef THIRD_PARTY_CREDENTIO_UTILS_BYTE_INSTRUCTION_H_ |
| #define THIRD_PARTY_CREDENTIO_UTILS_BYTE_INSTRUCTION_H_ |
| |
| #include <cstdint> |
| #include <string> |
| |
| #include "absl/base/nullability.h" |
| #include "absl/status/status.h" |
| #include "absl/types/span.h" |
| #include "riegeli/bytes/reader.h" |
| #include "riegeli/bytes/writer.h" |
| |
| namespace credentio { |
| |
| // A ByteInstruction is a single instruction for modifying a target asset. |
| // The instructions are applied in order and are based on the original asset. |
| struct ByteInstruction { |
| enum class Operation { |
| kInsert, // Add the bytes in this instruction to the destination. |
| kReplace, // Overwrite the bytes in the destination with the bytes in this |
| // instruction. |
| }; |
| |
| Operation operation; |
| // The offset of the destination in the target asset, based on the start of |
| // the asset before any adjustments are made. |
| uint64_t offset; |
| std::string bytes; |
| |
| bool operator==(const ByteInstruction& other) const { |
| return operation == other.operation && offset == other.offset && |
| bytes == other.bytes; |
| } |
| }; |
| |
| // Applies a series of byte instructions to a source reader, writing the |
| // modified content to a destination writer. |
| // |
| // Bytes are copied from `source` to `destination` based on instructions: |
| // - If `instruction.operation` is `kInsert`, `instruction.bytes` are inserted |
| // at `instruction.offset`. |
| // - If `instruction.operation` is `kReplace`, `instruction.bytes` replace |
| // `instruction.bytes.size()` bytes in `source` starting at |
| // `instruction.offset`. |
| // |
| // After all instructions are applied, any remaining bytes in `source` are |
| // copied to `destination`. |
| // |
| // Returns an error if `source` or `destination` fail or if the wrong number of |
| // bytes are copied or if the instructions are not in ascending order. |
| absl::Status ApplyByteInstructions( |
| riegeli::Reader* absl_nonnull source, |
| absl::Span<const ByteInstruction> instructions, |
| riegeli::Writer* absl_nonnull destination); |
| // Does the same as above, but applies the instructions in place to the given |
| // writer. |
| absl::Status ApplyByteInstructions( |
| absl::Span<const credentio::ByteInstruction> instructions, |
| riegeli::Writer* absl_nonnull writer); |
| |
| } // namespace credentio |
| |
| #endif // THIRD_PARTY_CREDENTIO_UTILS_BYTE_INSTRUCTION_H_ |