ApplicationInformationSection::ApplicationInformationSection(const uint8_t * const buffer) : LongCrcSection(buffer)
{
	commonDescriptorsLength = sectionLength > 10 ? DVB_LENGTH(&buffer[8]) : 0;

	uint16_t pos = 10;
	uint16_t bytesLeft = sectionLength > 11 ? sectionLength - 11 : 0;
	uint16_t loopLength = 0;
	uint16_t bytesLeft2 = commonDescriptorsLength;

	while (bytesLeft >= bytesLeft && bytesLeft2 > 1 && bytesLeft2 >= (loopLength = 2 + buffer[pos+1])) {
		descriptor(&buffer[pos], SCOPE_MHP);
		pos += loopLength;
		bytesLeft -= loopLength;
		bytesLeft2 -= loopLength;
	}

	if (!bytesLeft2 && bytesLeft > 1) {
		bytesLeft2 = applicationLoopLength = DVB_LENGTH(&buffer[pos]);
		pos+=2;
		bytesLeft-=2;
		while (bytesLeft >= bytesLeft2 && bytesLeft2 > 8 && bytesLeft2 >= (loopLength = 8 + DVB_LENGTH(&buffer[pos+7]))) {
			applicationInformation.push_back(new ApplicationInformation(&buffer[pos]));
			pos += loopLength;
			bytesLeft -= loopLength;
			bytesLeft2 -= loopLength;
		}
	}
	else
		applicationLoopLength = 0;
}
NetworkInformationSection::NetworkInformationSection(const uint8_t * const buffer) : LongCrcSection(buffer)
{
	networkId = UINT16(&buffer[3]);
	networkDescriptorsLength = sectionLength > 9 ? DVB_LENGTH(&buffer[8]) : 0;
	
	uint16_t pos = 10;
	uint16_t bytesLeft = sectionLength > 11 ? sectionLength - 11 : 0;
	uint16_t loopLength = 0;
	uint16_t bytesLeft2 = networkDescriptorsLength;

	while ( bytesLeft >= bytesLeft2 && bytesLeft2 > 1 && bytesLeft2 >= (loopLength = 2 + buffer[pos+1])) {
		descriptor(&buffer[pos], SCOPE_SI);
		pos += loopLength;
		bytesLeft -= loopLength;
		bytesLeft2 -= loopLength;
	}

	if (!bytesLeft2 && bytesLeft > 1) {
		bytesLeft2 = transportStreamLoopLength = DVB_LENGTH(&buffer[pos]);
		bytesLeft -= 2;
		pos += 2;
		while (bytesLeft >= bytesLeft2 && bytesLeft2 > 4 && bytesLeft2 >= (loopLength = 6 + DVB_LENGTH(&buffer[pos+4]))) {
			tsInfo.push_back(new TransportStreamInfo(&buffer[pos]));
			bytesLeft -= loopLength;
			bytesLeft2 -= loopLength;
			pos += loopLength;
		}
	}
}
ApplicationInformation::ApplicationInformation(const uint8_t * const buffer)
{
	applicationIdentifier = new ApplicationIdentifier(&buffer[0]);
	applicationControlCode = buffer[6];
	applicationDescriptorsLoopLength = DVB_LENGTH(&buffer[7]);

	for (size_t i = 0; i < applicationDescriptorsLoopLength; i += buffer[i + 10] + 2)
		descriptor(&buffer[i + 9], SCOPE_MHP);
}
TransportStreamInfo::TransportStreamInfo(const uint8_t * const buffer)
{
	transportStreamId = UINT16(&buffer[0]);
	originalNetworkId = UINT16(&buffer[2]);
	transportDescriptorsLength = DVB_LENGTH(&buffer[4]);

	for (size_t i = 6; i < transportDescriptorsLength + 6; i += buffer[i + 1] + 2)
		descriptor(&buffer[i], SCOPE_SI);
}
ApplicationInformationSection::ApplicationInformationSection(const uint8_t * const buffer) : LongCrcSection(buffer),
	commonDescriptorsLength(0),
	applicationLoopLength(0)
{
	unsigned int pos, length;

	if (sectionLength < 13)
		return;

	commonDescriptorsLength = DVB_LENGTH(&buffer[8]);
	if (sectionLength < 13 + commonDescriptorsLength)
		return;

	for (pos = 10; pos < 10 + commonDescriptorsLength; pos += length) {
		if (pos + 2 > 10 + commonDescriptorsLength)
			break;
		length = buffer[pos + 1] + 2;
		if (pos + length > 10 + commonDescriptorsLength)
			break;
		descriptor(&buffer[pos], SCOPE_MHP);
	}

	if (pos != 10 + commonDescriptorsLength)
		return;

	applicationLoopLength = DVB_LENGTH(&buffer[pos]);
	if (sectionLength < 13 + commonDescriptorsLength + applicationLoopLength)
		return;

	for (pos += 2; pos < 12 + commonDescriptorsLength + applicationLoopLength; pos += length) {
		if (pos + 9 > 12 + commonDescriptorsLength + applicationLoopLength)
			break;
		length = DVB_LENGTH(&buffer[pos + 7]) + 9;
		if (pos + length > 12 + commonDescriptorsLength + applicationLoopLength)
			break;
		applicationInformation.push_back(new ApplicationInformation(&buffer[pos]));
	}
}
ApplicationInformation::ApplicationInformation(const uint8_t * const buffer)
{
	unsigned int length;

	applicationIdentifier = new ApplicationIdentifier(&buffer[0]);
	applicationControlCode = buffer[6];
	applicationDescriptorsLoopLength = DVB_LENGTH(&buffer[7]);

	for (size_t i = 0; i < applicationDescriptorsLoopLength; i += length) {
		if (i + 2 > applicationDescriptorsLoopLength)
			break;
		length = buffer[i + 10] + 2;
		if (i + length > applicationDescriptorsLoopLength)
			break;
		descriptor(&buffer[i + 9], SCOPE_MHP);
	}
}