// // SpliceInfoSection.swift // // // Created by Robert Galluccio on 06/02/2021. // import Foundation /** ``` { table_id 8 uimsbf section_syntax_indicator 1 bslbf private_indicator 1 bslbf sap_type 2 bslbf section_length 12 uimsbf protocol_version 8 uimsbf encrypted_packet 1 bslbf encryption_algorithm 6 uimsbf pts_adjustment 33 uimsbf cw_index 8 uimsbf tier 12 bslbf splice_command_length 12 uimsbf splice_command_type 8 uimsbf E if(splice_command_type == 0x00) splice_null() E if(splice_command_type == 0x04) splice_schedule() E if(splice_command_type == 0x05) splice_insert() E if(splice_command_type == 0x06) time_signal() E if(splice_command_type == 0x07) bandwidth_reservation() E if(splice_command_type == 0xff) private_command() E descriptor_loop_length 16 uimsbf E for(i=0; i= 4, value <= 31 { return nil } else if value >= 32, value <= 63 { self = .userPrivate(value) } else { return nil } } } } // MARK: - Parsing public extension SpliceInfoSection { /// Creates a `SpliceInfoSection` from the provided `Data`. /// - Parameter data: `Data` representing SCTE-35 information. /// - Throws: `SCTE35ParserError` init(data: Data) throws { let bitReader = DataReader(data: data) do { try bitReader.validate( expectedMinimumBitsLeft: 24, parseDescription: "SpliceInfoSection; need at least 24 bits to get to end of section_length field" ) self.tableID = bitReader.byte() guard bitReader.bit() == 0 else { throw ParserError.invalidSectionSyntaxIndicator } guard bitReader.bit() == 0 else { throw ParserError.invalidPrivateIndicator } self.sapType = SAPType(rawValue: bitReader.byte(fromBits: 2)) ?? .unspecified let sectionLengthInBytes = bitReader.int(fromBits: 12) try bitReader.validate( expectedMinimumBitsLeft: sectionLengthInBytes * 8, parseDescription: "SpliceInfoSection; section_length defined as \(sectionLengthInBytes)" ) self.protocolVersion = bitReader.byte() let isEncrypted = bitReader.bit() == 1 if isEncrypted { throw ParserError.encryptedMessageNotSupported } let _ /* encryptionAlgorithm */ = EncryptedPacket.EncryptionAlgorithm(bitReader.byte(fromBits: 6)) self.ptsAdjustment = bitReader.uint64(fromBits: 33) let _ /* cwIndex */ = bitReader.byte() self.tier = bitReader.uint16(fromBits: 12) let spliceCommandLength = bitReader.int(fromBits: 12) self.spliceCommand = try SpliceCommand(bitReader: bitReader, spliceCommandLength: spliceCommandLength) let descriptorLoopLength = bitReader.int(fromBits: 16) self.spliceDescriptors = try [SpliceDescriptor].init(bitReader: bitReader, descriptorLoopLength: descriptorLoopLength) if isEncrypted { throw ParserError.encryptedMessageNotSupported } else { self.encryptedPacket = nil while bitReader.bitsLeft >= 40 { _ = bitReader.byte() } } self.CRC_32 = bitReader.uint32(fromBits: 32) self.nonFatalErrors = bitReader.nonFatalErrors } catch { guard let parserError = error as? ParserError else { throw error } throw SCTE35ParserError(error: parserError, underlyingError: bitReader.nonFatalErrors.first) } } }