blob: d72f3e5100777ad9363f45d237aa33500362fc2a [file] [edit]
// 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_