FtypBox Parser::parseFtypBox()

in cpp/spectrum/codecs/isobmff/IsoBmffParser.cpp [91:135]


FtypBox Parser::parseFtypBox() {
  FtypBox result;

  result.boxHeader = parseBoxHeader();

  // Do not allow ftyp boxes with unlimited length
  SPECTRUM_ENFORCE_IF_NOT(result.boxHeader.size.hasValue());
  SPECTRUM_ERROR_IF_NOT(
      *result.boxHeader.size >= 8, error::IsoBmffFtypBoxTooSmall);

  SPECTRUM_ERROR_IF(
      std::strncmp(
          reinterpret_cast<const char*>(result.boxHeader.boxType.data()),
          boxtype::ftyp.begin(),
          boxtype::ftyp.size()) != 0,
      error::IsoBmffFtypBoxExpectedButNotFound);

  SPECTRUM_ERROR_IF_NOT(
      _source.read(
          reinterpret_cast<char*>(result.majorBrand.data()),
          result.majorBrand.size()) == result.majorBrand.size(),
      error::IsoBmffEarlyStreamEnd);

  SPECTRUM_ERROR_IF_NOT(
      _source.read(
          reinterpret_cast<char*>(result.minorVersion.data()),
          result.minorVersion.size()) == result.minorVersion.size(),
      error::IsoBmffEarlyStreamEnd);

  uint64_t remainingSize = *result.boxHeader.size - 8;
  Brand brand;
  SPECTRUM_ENFORCE_IF_NOT(remainingSize % brand.size() == 0);
  while (remainingSize >= brand.size()) {
    SPECTRUM_ERROR_IF_NOT(
        _source.read(reinterpret_cast<char*>(brand.data()), brand.size()) ==
            brand.size(),
        error::IsoBmffEarlyStreamEnd);

    result.compatibleBrands.push_back(brand);
    remainingSize -= brand.size();
  }
  result.compatibleBrands.shrink_to_fit();

  return result;
}