// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/zucchini/disassembler_ztf.h"

#include <algorithm>
#include <cmath>
#include <iterator>
#include <numeric>

#include "base/logging.h"
#include "base/macros.h"
#include "base/numerics/checked_math.h"
#include "components/zucchini/algorithm.h"
#include "components/zucchini/buffer_source.h"
#include "components/zucchini/buffer_view.h"
#include "components/zucchini/io_utils.h"

namespace zucchini {

namespace {

constexpr uint8_t kDelimiter = ',';

constexpr int kHeaderMagicSize = 4;
constexpr int kFooterMagicSize = 5;
constexpr int kTotalMagicSize = kHeaderMagicSize + kFooterMagicSize;

// Number of characters that aren't digits in each type of reference.
constexpr int kNumConstCharInAbs = 3;
constexpr int kNumConstCharInRel = 5;

/******** ZtfConfig ********/

// For passing around metadata about the type of reference to match.
// - |digits_per_dim| is the length of the offset in lines/cols of a
//   reference.
// - |open_char| is an ASCII character representing the opening char.
// - |close_char| is an ASCII character representing the closing char.
struct ZtfConfig {
  uint8_t digits_per_dim;
  uint8_t open_char;
  uint8_t close_char;

  constexpr uint8_t abs_width() const {
    return digits_per_dim * 2 + kNumConstCharInAbs;
  }

  constexpr uint8_t rel_width() const {
    return digits_per_dim * 2 + kNumConstCharInRel;
  }

  uint8_t Width(ztf::LineCol /* lc */) const { return abs_width(); }

  uint8_t Width(ztf::DeltaLineCol /* dlc */) const { return rel_width(); }
};

// Creates a ZtfConfig for parsing or writing based on the desired |digits| and
// |pool|.
template <DisassemblerZtf::ReferencePool pool>
constexpr ZtfConfig MakeZtfConfig(uint8_t digits) {
  switch (pool) {
    case DisassemblerZtf::kAngles:
      return ZtfConfig{digits, '<', '>'};
    case DisassemblerZtf::kBraces:
      return ZtfConfig{digits, '{', '}'};
    case DisassemblerZtf::kBrackets:
      return ZtfConfig{digits, '[', ']'};
    case DisassemblerZtf::kParentheses:
      break;  // Handled below.
  }
  return ZtfConfig{digits, '(', ')'};
}

/******** ZtfParser ********/

// ZtfParser is used to extract (absolute) LineCol and (relative) DeltaLineCol
// from a ZTF file, and contains various helpers for character, digits, and sign
// matching.
class ZtfParser {
 public:
  ZtfParser(offset_t hi, ConstBufferView image, ZtfConfig config)
      : image_(image), hi_(hi), config_(config) {
    DCHECK_LE(static_cast<size_t>(std::pow(10U, config_.digits_per_dim)),
              ztf::kMaxDimValue);
  }

  // Attempts to match an absolute reference at |offset|. If successful then
  // assigns the result to |abs_lc| and returns true. Otherwise returns false.
  // An absolute reference takes the form:
  // <open><digits><delimiter><digits><close>
  bool MatchAtOffset(offset_t offset, ztf::LineCol* abs_lc) {
    if (hi_ < config_.abs_width() || offset > hi_ - config_.abs_width())
      return false;
    offset_ = offset;
    return MatchChar(config_.open_char) && MatchDigits(+1, &abs_lc->line) &&
           MatchChar(kDelimiter) && MatchDigits(+1, &abs_lc->col) &&
           MatchChar(config_.close_char);
  }

  // Attempts to match an absolute reference at |offset|. If successful then
  // assigns the result to |rel_lc| and returns true. Otherwise returns false. A
  // relative reference takes the form:
  // <open><sign><digits><delimiter><sign><digits><close>
  bool MatchAtOffset(offset_t offset, ztf::DeltaLineCol* rel_dlc) {
    if (hi_ < config_.rel_width() || offset > hi_ - config_.rel_width())
      return false;
    offset_ = offset;
    ztf::dim_t line_sign;
    ztf::dim_t col_sign;
    return MatchChar(config_.open_char) && MatchSign(&line_sign) &&
           MatchDigits(line_sign, &rel_dlc->line) && MatchChar(kDelimiter) &&
           MatchSign(&col_sign) && MatchDigits(col_sign, &rel_dlc->col) &&
           MatchChar(config_.close_char);
  }

 private:
  // The Match*() functions below can advance |offset_|, and return a bool to
  // indicate success to allow chaining using &&.

  // Returns true if |character| is at location |offset_| in |image_| and
  // increments |offset_|.
  bool MatchChar(uint8_t character) {
    return character == image_.read<uint8_t>(offset_++);
  }

  // Looks for '+' or '-' at |offset_|. If found, stores +1 or -1 in |sign| and
  // returns true. Otherwise returns false.
  bool MatchSign(ztf::dim_t* sign) {
    uint8_t val = image_.read<uint8_t>(offset_++);
    if (val == static_cast<uint8_t>(ztf::SignChar::kMinus)) {
      *sign = -1;
      return true;
    }
    if (val == static_cast<uint8_t>(ztf::SignChar::kPlus)) {
      *sign = 1;
      return true;
    }
    return false;
  }

  // Attempts to extract a number with the number of base 10 digits equal to
  // |config_.digits_per_dim| from |image_| starting from |offset_|. Returns
  // true and assigns the integer value to |value| if successful.
  bool MatchDigits(ztf::dim_t sign, ztf::dim_t* value) {
    ztf::dim_t output = 0;
    for (int i = 0; i < config_.digits_per_dim; ++i) {
      auto digit = image_.read<uint8_t>(offset_++);
      if (digit >= '0' && digit < '0' + 10)
        output = output * 10 + digit - '0';
      else
        return false;
    }
    if (!output && sign < 0)  // Disallow "-0", "-00", etc.
      return false;
    *value = sign * output;
    return true;
  }

  ConstBufferView image_;
  const offset_t hi_;
  const ZtfConfig config_;
  offset_t offset_ = 0;

  DISALLOW_COPY_AND_ASSIGN(ZtfParser);
};

/******** ZtfWriter ********/

// ZtfWriter is used to write references to an image. This includes writing
// the enclosing characters around the reference.
class ZtfWriter {
 public:
  ZtfWriter(MutableBufferView image, ZtfConfig config)
      : image_(image),
        config_(config),
        val_bound_(
            static_cast<ztf::dim_t>(std::pow(10, config_.digits_per_dim))) {}

  // Write an absolute reference |abs_ref| at |offset|. Note that references
  // that would overwrite a newline are skipped as this would invalidate all
  // the other reference line numbers.
  void Write(offset_t offset, ztf::LineCol abs_ref) {
    offset_ = offset;
    if (!SafeToWriteNumber(abs_ref.line) || !SafeToWriteNumber(abs_ref.col) ||
        !SafeToWriteData(offset_, offset_ + config_.abs_width())) {
      return;
    }
    WriteChar(config_.open_char);
    WriteNumber(abs_ref.line);
    WriteChar(kDelimiter);
    WriteNumber(abs_ref.col);
    WriteChar(config_.close_char);
  }

  // Write a relative reference |rel_ref| at |offset|. Note that references
  // that would overwrite a newline are skipped as this would invalidate all
  // the other reference line numbers.
  void Write(offset_t offset, ztf::DeltaLineCol rel_ref) {
    offset_ = offset;
    if (!SafeToWriteNumber(rel_ref.line) || !SafeToWriteNumber(rel_ref.col) ||
        !SafeToWriteData(offset_, offset_ + config_.rel_width())) {
      return;
    }
    WriteChar(config_.open_char);
    WriteSign(rel_ref.line);
    WriteNumber(rel_ref.line);
    WriteChar(kDelimiter);
    WriteSign(rel_ref.col);
    WriteNumber(rel_ref.col);
    WriteChar(config_.close_char);
  }

 private:
  // Returns whether it is safe to modify bytes in |[lo, hi)| in |image_| for
  // Reference correction. Failure cases are:
  // - Out-of-bound writes.
  // - Overwriting '\n'. This is a ZTF special case since '\n' dictates file
  //   structure, and Reference correction should never mess with this.
  bool SafeToWriteData(offset_t lo, offset_t hi) const {
    DCHECK_LE(lo, hi);
    // Out of bounds.
    if (hi > image_.size())
      return false;
    for (offset_t i = lo; i < hi; ++i) {
      if (image_.read<uint8_t>(i) == '\n')
        return false;
    }
    return true;
  }

  // Checks whether it is safe to write a |val| based on
  // |config_.digits_per_dim|.
  bool SafeToWriteNumber(ztf::dim_t val) const {
    return std::abs(val) < val_bound_;
  }

  // The Write*() functions each advance |offset_| by a fixed distance. The
  // caller should ensure there's enough space to write data.

  // Write |character| at |offset_| and increment |offset_|.
  void WriteChar(uint8_t character) { image_.write(offset_++, character); }

  // Write the sign of |value| at |offset_| and increment |offset_|.
  void WriteSign(ztf::dim_t value) {
    image_.write(offset_++,
                 value >= 0 ? ztf::SignChar::kPlus : ztf::SignChar::kMinus);
  }

  // Writes the absolute value of the number represented by |value| at |offset_|
  // using zero padding to fill |config_.digits_per_dim|.
  void WriteNumber(ztf::dim_t value) {
    size_t size = config_.digits_per_dim + 1;
    DCHECK_LE(size, kMaxDigitCount + 1);
    char digits[kMaxDigitCount + 1];  // + 1 for terminator.
    int len =
        snprintf(digits, size, "%0*u", config_.digits_per_dim, std::abs(value));
    DCHECK_EQ(len, config_.digits_per_dim);
    for (int i = 0; i < len; ++i)
      image_.write(offset_++, digits[i]);
  }

  MutableBufferView image_;
  const ZtfConfig config_;
  // Bound on numeric values, as limited by |config_.digits_per_dim|.
  const ztf::dim_t val_bound_;
  offset_t offset_ = 0;
  DISALLOW_COPY_AND_ASSIGN(ZtfWriter);
};

// Specialization of ReferenceReader for reading text references.
template <typename T>
class ZtfReferenceReader : public ReferenceReader {
 public:
  ZtfReferenceReader(offset_t lo,
                     offset_t hi,
                     ConstBufferView image,
                     const ZtfTranslator& translator,
                     ZtfConfig config)
      : offset_(lo),
        hi_(hi),
        translator_(translator),
        config_(config),
        parser_(hi_, image, config_) {
    DCHECK_LE(hi_, image.size());
  }

  // Walks |offset_| from |lo| to |hi_| running |parser_|. If any matches are
  // found they are returned.
  base::Optional<Reference> GetNext() override {
    T line_col;
    for (; offset_ < hi_; ++offset_) {
      if (!parser_.MatchAtOffset(offset_, &line_col))
        continue;

      auto target = ConvertToTargetOffset(offset_, line_col);
      // Ignore targets that point outside the file.
      if (target == kInvalidOffset)
        continue;
      offset_t location = offset_;
      offset_ += config_.Width(line_col);
      return Reference{location, target};
    }
    return base::nullopt;
  }

 private:
  // Converts |lc| (an absolute reference) to an offset using |translator_|.
  offset_t ConvertToTargetOffset(offset_t /* location */,
                                 ztf::LineCol lc) const {
    return translator_.LineColToOffset(lc);
  }

  // Converts |dlc| (a relative reference) to an offset using |translator_|.
  // This requires converting the |dlc| to a ztf::LineCol to find the offset.
  offset_t ConvertToTargetOffset(offset_t location,
                                 ztf::DeltaLineCol dlc) const {
    auto lc = translator_.OffsetToLineCol(location);
    if (!lc.has_value())
      return kInvalidOffset;
    return translator_.LineColToOffset(lc.value() + dlc);
  }

  offset_t offset_;
  const offset_t hi_;
  const ZtfTranslator& translator_;
  const ZtfConfig config_;
  ZtfParser parser_;
};

// Specialization of ReferenceWriter for writing text references.
template <typename T>
class ZtfReferenceWriter : public ReferenceWriter {
 public:
  ZtfReferenceWriter(MutableBufferView image,
                     const ZtfTranslator& translator,
                     ZtfConfig config)
      : translator_(translator), writer_(image, config) {}

  void PutNext(Reference reference) override {
    T line_col;
    if (!ConvertToTargetLineCol(reference, &line_col))
      return;

    writer_.Write(reference.location, line_col);
  }

 private:
  // Converts |reference| to an absolute reference to be stored in |out_lc|.
  // Returns true on success.
  bool ConvertToTargetLineCol(Reference reference, ztf::LineCol* out_lc) {
    auto temp_lc = translator_.OffsetToLineCol(reference.target);
    if (!temp_lc.has_value() || !translator_.IsValid(temp_lc.value()))
      return false;

    *out_lc = temp_lc.value();
    return true;
  }

  // Converts |reference| to a relative reference to be stored in |out_dlc|.
  // Will return true on success.
  bool ConvertToTargetLineCol(Reference reference, ztf::DeltaLineCol* out_dlc) {
    auto location_lc = translator_.OffsetToLineCol(reference.location);
    if (!location_lc.has_value())
      return false;

    auto target_lc = translator_.OffsetToLineCol(reference.target);
    if (!target_lc.has_value())
      return false;

    *out_dlc = target_lc.value() - location_lc.value();
    return translator_.IsValid(reference.location, *out_dlc);
  }

  const ZtfTranslator& translator_;
  ZtfWriter writer_;
};

// Reads a text header to check for the magic string "ZTxt" at the start
// indicating the file should be treated as a Zucchini text file.
bool ReadZtfHeader(ConstBufferView image) {
  BufferSource source(image);
  // Reject empty images and "ZTxtxTZ\n" (missing 't').
  if (source.size() < kTotalMagicSize)
    return false;
  return source.CheckNextBytes({'Z', 'T', 'x', 't'});
}

}  // namespace

/******** ZtfTranslator ********/

ZtfTranslator::ZtfTranslator() {}

ZtfTranslator::~ZtfTranslator() = default;

bool ZtfTranslator::Init(ConstBufferView image) {
  line_starts_.clear();
  // Record the starting offset of every line in |image_| into |line_start_|.
  line_starts_.push_back(0);
  for (size_t i = 0; i < image.size(); ++i) {
    if (image.read<uint8_t>(i) == '\n') {
      // Maximum number of entries is |ztf::kMaxDimValue|, including the end
      // sentinel.
      if (line_starts_.size() >= ztf::kMaxDimValue)
        return false;
      line_starts_.push_back(i + 1);
      // Check that the line length is reachable from an absolute reference.
      if (line_starts_.back() - *std::next(line_starts_.rbegin()) >=
          ztf::kMaxDimValue) {
        return false;
      }
    }
  }
  // Since the last character of ZTF file is always '\n', |line_starts_| will
  // always contain the file length as the last element, which serves as a
  // sentinel.
  CHECK_EQ(image.size(), static_cast<size_t>(line_starts_.back()));
  return true;
}

bool ZtfTranslator::IsValid(ztf::LineCol lc) const {
  DCHECK(!line_starts_.empty());
  return lc.line >= 1 && lc.col >= 1 &&
         static_cast<offset_t>(lc.line) <= NumLines() &&
         static_cast<offset_t>(lc.col) <= LineLength(lc.line);
}

bool ZtfTranslator::IsValid(offset_t offset, ztf::DeltaLineCol dlc) const {
  DCHECK(!line_starts_.empty());
  auto abs_lc = OffsetToLineCol(offset);
  if (!abs_lc.has_value())
    return false;

  if (!base::CheckAdd(abs_lc->line, dlc.line).IsValid() ||
      !base::CheckAdd(abs_lc->col, dlc.col).IsValid()) {
    return false;
  }
  return IsValid(abs_lc.value() + dlc);
}

offset_t ZtfTranslator::LineColToOffset(ztf::LineCol lc) const {
  // Guard against out of bounds access to |line_starts_| and ensure the
  // |lc| falls within the file.
  DCHECK(!line_starts_.empty());
  if (!IsValid(lc))
    return kInvalidOffset;

  offset_t target = line_starts_[lc.line - 1] + lc.col - 1;
  DCHECK_LT(target, line_starts_.back());
  return target;
}

base::Optional<ztf::LineCol> ZtfTranslator::OffsetToLineCol(
    offset_t offset) const {
  DCHECK(!line_starts_.empty());
  // Don't place a target outside the image.
  if (offset >= line_starts_.back())
    return base::nullopt;
  auto it = SearchForRange(offset);
  ztf::LineCol lc;
  lc.line = std::distance(line_starts_.cbegin(), it) + 1;
  lc.col = offset - line_starts_[lc.line - 1] + 1;
  DCHECK_LE(static_cast<offset_t>(lc.col), LineLength(lc.line));
  return lc;
}

std::vector<offset_t>::const_iterator ZtfTranslator::SearchForRange(
    offset_t offset) const {
  DCHECK(!line_starts_.empty());
  auto it =
      std::upper_bound(line_starts_.cbegin(), line_starts_.cend(), offset);
  DCHECK(it != line_starts_.cbegin());
  return --it;
}

offset_t ZtfTranslator::LineLength(uint16_t line) const {
  DCHECK_GE(line, 1);
  DCHECK_LE(line, NumLines());
  return line_starts_[line] - line_starts_[line - 1];
}

/******** DisassemblerZtf ********/

// Use 2 even though reference "chaining" isn't present in ZTF as it is the
// usual case for other Disassemblers and this is meant to mimic that as closely
// as possible.
DisassemblerZtf::DisassemblerZtf() : Disassembler(2) {}

DisassemblerZtf::~DisassemblerZtf() = default;

// static.
bool DisassemblerZtf::QuickDetect(ConstBufferView image) {
  return ReadZtfHeader(image);
}

ExecutableType DisassemblerZtf::GetExeType() const {
  return kExeTypeZtf;
}

std::string DisassemblerZtf::GetExeTypeString() const {
  return "Zucchini Text Format";
}

std::vector<ReferenceGroup> DisassemblerZtf::MakeReferenceGroups() const {
  return {
      {{5, TypeTag(kAnglesAbs1), PoolTag(kAngles)},
       &DisassemblerZtf::MakeReadAbs<1, kAngles>,
       &DisassemblerZtf::MakeWriteAbs<1, kAngles>},
      {{7, TypeTag(kAnglesAbs2), PoolTag(kAngles)},
       &DisassemblerZtf::MakeReadAbs<2, kAngles>,
       &DisassemblerZtf::MakeWriteAbs<2, kAngles>},
      {{9, TypeTag(kAnglesAbs3), PoolTag(kAngles)},
       &DisassemblerZtf::MakeReadAbs<3, kAngles>,
       &DisassemblerZtf::MakeWriteAbs<3, kAngles>},
      {{7, TypeTag(kAnglesRel1), PoolTag(kAngles)},
       &DisassemblerZtf::MakeReadRel<1, kAngles>,
       &DisassemblerZtf::MakeWriteRel<1, kAngles>},
      {{9, TypeTag(kAnglesRel2), PoolTag(kAngles)},
       &DisassemblerZtf::MakeReadRel<2, kAngles>,
       &DisassemblerZtf::MakeWriteRel<2, kAngles>},
      {{11, TypeTag(kAnglesRel3), PoolTag(kAngles)},
       &DisassemblerZtf::MakeReadRel<3, kAngles>,
       &DisassemblerZtf::MakeWriteRel<3, kAngles>},
      {{5, TypeTag(kBracesAbs1), PoolTag(kBraces)},
       &DisassemblerZtf::MakeReadAbs<1, kBraces>,
       &DisassemblerZtf::MakeWriteAbs<1, kBraces>},
      {{7, TypeTag(kBracesAbs2), PoolTag(kBraces)},
       &DisassemblerZtf::MakeReadAbs<2, kBraces>,
       &DisassemblerZtf::MakeWriteAbs<2, kBraces>},
      {{9, TypeTag(kBracesAbs3), PoolTag(kBraces)},
       &DisassemblerZtf::MakeReadAbs<3, kBraces>,
       &DisassemblerZtf::MakeWriteAbs<3, kBraces>},
      {{7, TypeTag(kBracesRel1), PoolTag(kBraces)},
       &DisassemblerZtf::MakeReadRel<1, kBraces>,
       &DisassemblerZtf::MakeWriteRel<1, kBraces>},
      {{9, TypeTag(kBracesRel2), PoolTag(kBraces)},
       &DisassemblerZtf::MakeReadRel<2, kBraces>,
       &DisassemblerZtf::MakeWriteRel<2, kBraces>},
      {{11, TypeTag(kBracesRel3), PoolTag(kBraces)},
       &DisassemblerZtf::MakeReadRel<3, kBraces>,
       &DisassemblerZtf::MakeWriteRel<3, kBraces>},
      {{5, TypeTag(kBracketsAbs1), PoolTag(kBrackets)},
       &DisassemblerZtf::MakeReadAbs<1, kBrackets>,
       &DisassemblerZtf::MakeWriteAbs<1, kBrackets>},
      {{7, TypeTag(kBracketsAbs2), PoolTag(kBrackets)},
       &DisassemblerZtf::MakeReadAbs<2, kBrackets>,
       &DisassemblerZtf::MakeWriteAbs<2, kBrackets>},
      {{9, TypeTag(kBracketsAbs3), PoolTag(kBrackets)},
       &DisassemblerZtf::MakeReadAbs<3, kBrackets>,
       &DisassemblerZtf::MakeWriteAbs<3, kBrackets>},
      {{7, TypeTag(kBracketsRel1), PoolTag(kBrackets)},
       &DisassemblerZtf::MakeReadRel<1, kBrackets>,
       &DisassemblerZtf::MakeWriteRel<1, kBrackets>},
      {{9, TypeTag(kBracketsRel2), PoolTag(kBrackets)},
       &DisassemblerZtf::MakeReadRel<2, kBrackets>,
       &DisassemblerZtf::MakeWriteRel<2, kBrackets>},
      {{11, TypeTag(kBracketsRel3), PoolTag(kBrackets)},
       &DisassemblerZtf::MakeReadRel<3, kBrackets>,
       &DisassemblerZtf::MakeWriteRel<3, kBrackets>},
      {{5, TypeTag(kParenthesesAbs1), PoolTag(kParentheses)},
       &DisassemblerZtf::MakeReadAbs<1, kParentheses>,
       &DisassemblerZtf::MakeWriteAbs<1, kParentheses>},
      {{7, TypeTag(kParenthesesAbs2), PoolTag(kParentheses)},
       &DisassemblerZtf::MakeReadAbs<2, kParentheses>,
       &DisassemblerZtf::MakeWriteAbs<2, kParentheses>},
      {{9, TypeTag(kParenthesesAbs3), PoolTag(kParentheses)},
       &DisassemblerZtf::MakeReadAbs<3, kParentheses>,
       &DisassemblerZtf::MakeWriteAbs<3, kParentheses>},
      {{7, TypeTag(kParenthesesRel1), PoolTag(kParentheses)},
       &DisassemblerZtf::MakeReadRel<1, kParentheses>,
       &DisassemblerZtf::MakeWriteRel<1, kParentheses>},
      {{9, TypeTag(kParenthesesRel2), PoolTag(kParentheses)},
       &DisassemblerZtf::MakeReadRel<2, kParentheses>,
       &DisassemblerZtf::MakeWriteRel<2, kParentheses>},
      {{11, TypeTag(kParenthesesRel3), PoolTag(kParentheses)},
       &DisassemblerZtf::MakeReadRel<3, kParentheses>,
       &DisassemblerZtf::MakeWriteRel<3, kParentheses>},
  };
}

template <uint8_t digits, DisassemblerZtf::ReferencePool pool>
std::unique_ptr<ReferenceReader> DisassemblerZtf::MakeReadAbs(offset_t lo,
                                                              offset_t hi) {
  static_assert(digits >= 1 && digits <= kMaxDigitCount,
                "|digits| must be in range [1, 3]");
  return std::make_unique<ZtfReferenceReader<ztf::LineCol>>(
      lo, hi, image_, translator_, MakeZtfConfig<pool>(digits));
}

template <uint8_t digits, DisassemblerZtf::ReferencePool pool>
std::unique_ptr<ReferenceReader> DisassemblerZtf::MakeReadRel(offset_t lo,
                                                              offset_t hi) {
  static_assert(digits >= 1 && digits <= kMaxDigitCount,
                "|digits| must be in range [1, 3]");
  return std::make_unique<ZtfReferenceReader<ztf::DeltaLineCol>>(
      lo, hi, image_, translator_, MakeZtfConfig<pool>(digits));
}

template <uint8_t digits, DisassemblerZtf::ReferencePool pool>
std::unique_ptr<ReferenceWriter> DisassemblerZtf::MakeWriteAbs(
    MutableBufferView image) {
  static_assert(digits >= 1 && digits <= kMaxDigitCount,
                "|digits| must be in range [1, 3]");
  return std::make_unique<ZtfReferenceWriter<ztf::LineCol>>(
      image, translator_, MakeZtfConfig<pool>(digits));
}

template <uint8_t digits, DisassemblerZtf::ReferencePool pool>
std::unique_ptr<ReferenceWriter> DisassemblerZtf::MakeWriteRel(
    MutableBufferView image) {
  static_assert(digits >= 1 && digits <= kMaxDigitCount,
                "|digits| must be in range [1, 3]");
  return std::make_unique<ZtfReferenceWriter<ztf::DeltaLineCol>>(
      image, translator_, MakeZtfConfig<pool>(digits));
}

bool DisassemblerZtf::Parse(ConstBufferView image) {
  image_ = image;
  if (!ReadZtfHeader(image_))
    return false;

  CHECK_GE(image_.size(),
           static_cast<size_t>(kTotalMagicSize));  // Needs header and footer.

  // Find the terminating footer "txTZ\n" that indicates the end of the image.
  offset_t offset = 0;
  for (; offset <= image_.size() - kFooterMagicSize; offset++) {
    if (image_.read<uint8_t>(offset) == 't' &&
        image_.read<uint8_t>(offset + 1) == 'x' &&
        image_.read<uint8_t>(offset + 2) == 'T' &&
        image_.read<uint8_t>(offset + 3) == 'Z' &&
        image_.read<uint8_t>(offset + 4) == '\n') {
      break;
    }
  }

  // If no footer is found before the end of the image then the parsing failed.
  if (offset > image_.size() - kFooterMagicSize)
    return false;
  image_.shrink(offset + kFooterMagicSize);

  return translator_.Init(image_);
}

}  // namespace zucchini
