BoxHeader Parser::parseBoxHeader()

in cpp/spectrum/codecs/isobmff/IsoBmffParser.cpp [44:89]


BoxHeader Parser::parseBoxHeader() {
  BoxHeader result;

  std::uint32_t size;
  SPECTRUM_ERROR_IF_NOT(
      _source.read(reinterpret_cast<char*>(&size), 4) == 4,
      error::IsoBmffEarlyStreamEnd);
  size = core::utils::convertValueToNativeByteOrder(size, false);
  SPECTRUM_ERROR_IF(size > _maxBoxSize, error::IsoBmffBoxTooLarge);

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

  // handle special size cases: unlimited or 64-bit size
  if (size == 1) {
    std::uint64_t largeSize;
    SPECTRUM_ERROR_IF_NOT(
        _source.read(reinterpret_cast<char*>(&largeSize), 8) == 8,
        error::IsoBmffEarlyStreamEnd);
    result.size = core::utils::convertValueToNativeByteOrder(largeSize, false);
    SPECTRUM_ERROR_IF(largeSize > _maxBoxSize, error::IsoBmffBoxTooLarge);
  } else if (size == 0) {
    SPECTRUM_ERROR_IF(
        _maxBoxSize != std::numeric_limits<std::uint64_t>::max(),
        error::IsoBmffBoxTooLarge);
    result.size = folly::none;
  } else {
    result.size = size;
  }

  // read custom user ID if ftyp is `uuid`
  if (isUuidType(result.boxType)) {
    SPECTRUM_ERROR_IF_NOT(
        _source.read(
            reinterpret_cast<char*>(result.userType.data()),
            result.userType.size()) == result.userType.size(),
        error::IsoBmffEarlyStreamEnd);
  } else {
    std::memset(result.userType.data(), 0, result.userType.size());
  }

  return result;
}