def _parse_volume_descriptors(self):
        # type: () -> None
        '''
        An internal method to parse the volume descriptors on an ISO.

        Parameters:
         None.
        Returns:
         Nothing.
        '''
        # Ecma-119 says that the Volume Descriptor set is a sequence of volume
        # descriptors recorded in consecutively numbered Logical Sectors
        # starting with Logical Sector Number 16.  Since sectors are 2048 bytes
        # in length, we start at sector 16 * 2048

        # Ecma-119, 6.2.1 says that the Volume Space is divided into a System
        # Area and a Data Area, where the System Area is in logical sectors 0
        # to 15, and whose contents is not specified by the standard.
        self._cdfp.seek(16 * 2048)
        while True:
            # All volume descriptors are exactly 2048 bytes long
            curr_extent = self._cdfp.tell() // 2048
            vd = self._cdfp.read(2048)
            if len(vd) != 2048:
                raise pycdlibexception.PyCdlibInvalidISO('Failed to read entire volume descriptor')
            (desc_type, ident) = struct.unpack_from('=B5s', vd, 0)
            if desc_type not in (headervd.VOLUME_DESCRIPTOR_TYPE_PRIMARY,
                                 headervd.VOLUME_DESCRIPTOR_TYPE_SET_TERMINATOR,
                                 headervd.VOLUME_DESCRIPTOR_TYPE_BOOT_RECORD,
                                 headervd.VOLUME_DESCRIPTOR_TYPE_SUPPLEMENTARY) or ident not in (b'CD001', b'BEA01', b'NSR02', b'TEA01'):
                # We read the next extent, and it wasn't a descriptor.  Abort
                # the loop, remembering to back up the input file descriptor.
                self._cdfp.seek(-2048, os.SEEK_CUR)
                break
            if desc_type == headervd.VOLUME_DESCRIPTOR_TYPE_PRIMARY:
                pvd = headervd.PrimaryOrSupplementaryVD(headervd.VOLUME_DESCRIPTOR_TYPE_PRIMARY)
                pvd.parse(vd, curr_extent)
                self.pvds.append(pvd)
            elif desc_type == headervd.VOLUME_DESCRIPTOR_TYPE_SET_TERMINATOR:
                vdst = headervd.VolumeDescriptorSetTerminator()
                vdst.parse(vd, curr_extent)
                self.vdsts.append(vdst)
            elif desc_type == headervd.VOLUME_DESCRIPTOR_TYPE_BOOT_RECORD:
                # Both an Ecma-119 Boot Record and a Ecma-TR 071 UDF-Bridge
                # Beginning Extended Area Descriptor have the first byte as 0,
                # so we can't tell which it is until we look at the next 5
                # bytes (Boot Record will have 'CD001', BEAD will have 'BEA01').
                if ident == b'CD001':
                    br = headervd.BootRecord()
                    br.parse(vd, curr_extent)
                    self.brs.append(br)
                elif ident == b'BEA01':
                    self._has_udf = True
                    self.udf_bea.parse(vd, curr_extent)
                elif ident == b'NSR02':
                    self.udf_nsr.parse(vd, curr_extent)
                elif ident == b'TEA01':
                    self.udf_tea.parse(vd, curr_extent)
                else:
                    # This isn't really possible, since we would have aborted
                    # the loop above.
                    raise pycdlibexception.PyCdlibInvalidISO('Invalid volume identification type')
            elif desc_type == headervd.VOLUME_DESCRIPTOR_TYPE_SUPPLEMENTARY:
                svd = headervd.PrimaryOrSupplementaryVD(headervd.VOLUME_DESCRIPTOR_TYPE_SUPPLEMENTARY)
                svd.parse(vd, curr_extent)
                self.svds.append(svd)
            # Since we checked for the valid descriptors above, it is impossible
            # to see an invalid desc_type here, so no check necessary.

        # The language in Ecma-119, p.8, Section 6.7.1 says:
        #
        # The sequence shall contain one Primary Volume Descriptor (see 8.4) recorded at least once.
        #
        # The important bit there is "at least one", which means that we have
        # to accept ISOs with more than one PVD.
        if not self.pvds:
            raise pycdlibexception.PyCdlibInvalidISO('Valid ISO9660 filesystems must have at least one PVD')

        self.pvd = self.pvds[0]

        # Make sure any other PVDs agree with the first one.
        for pvd in self.pvds[1:]:
            if pvd != self.pvd:
                raise pycdlibexception.PyCdlibInvalidISO('Multiple occurrences of PVD did not agree!')

            pvd.root_dir_record = self.pvd.root_dir_record

        if not self.vdsts:
            raise pycdlibexception.PyCdlibInvalidISO('Valid ISO9660 filesystems must have at least one Volume Descriptor Set Terminator')
An internal method to parse the volume descriptors on an ISO.

        Parameters:
         None.
        Returns:
         Nothing.