예제 #1
0
파일: pdc1.c 프로젝트: mwgoldsmith/zvbi
/* Attention! This function returns a static string. */
static const char *
pil_str				(vbi_pil		pil)
{
    static char buffer[32];

    switch (pil) {
    case VBI_PIL_TIMER_CONTROL:
        return "TC";
    case VBI_PIL_INHIBIT_TERMINATE:
        return "RI/T";
    case VBI_PIL_INTERRUPTION:
        return "INT";
    case VBI_PIL_CONTINUE:
        return "CONT";
    case VBI_PIL_NSPV:
        return "NSPV/END";

    default:
        snprintf (buffer, sizeof (buffer),
                  "%02u%02uT%02u%02u",
                  VBI_PIL_MONTH (pil),
                  VBI_PIL_DAY (pil),
                  VBI_PIL_HOUR (pil),
                  VBI_PIL_MINUTE (pil));
        return buffer;
    }
}
예제 #2
0
파일: pdc.c 프로젝트: OpenDMM/zvbi
/**
 * @param pil Program Identification Label.
 *
 * Determines if @a pil represents a valid date and time.
 *
 * Since PILs have no year field February 29th is considered valid.
 * You can find out if this date is valid in a given year with the
 * vbi_pil_to_time() function.
 *
 * 24:00 is not valid (an unreal hour) as defined in EN 300 231
 * Annex F and EIA 608-B Section 9.5.1.1.
 *
 * @returns
 * @c TRUE if @a pil represents a valid date and time, @c FALSE
 * if @a pil contains an unreal date or time (e.g. Jan 0 27:61),
 * a service code or unallocated code.
 *
 * @since 0.2.34
 */
vbi_bool
vbi_pil_is_valid_date		(vbi_pil		pil)
{
	unsigned int month;
	unsigned int day;

	month = VBI_PIL_MONTH (pil);
	day = VBI_PIL_DAY (pil);

	/* Note this also checks for zero month and day. */
	return (month - 1 < 12
		&& day - 1 < month_days[month - 1]
		&& VBI_PIL_HOUR (pil) < 24
		&& VBI_PIL_MINUTE (pil) < 60);
}
예제 #3
0
파일: pdc.c 프로젝트: OpenDMM/zvbi
/**
 * @internal
 * @param pil vbi_pil to print.
 * @param fp Destination stream.
 *
 * Prints a vbi_pil as service code or date and time string without
 * trailing newline. This is intended for debugging.
 */
void
_vbi_pil_dump			(vbi_pil		pil,
				 FILE *			fp)
{
	switch (pil) {
	case VBI_PIL_TIMER_CONTROL:
		fputs ("TC", fp);
		break;

	case VBI_PIL_INHIBIT_TERMINATE:
		fputs ("RI/T", fp);
		break;

	case VBI_PIL_INTERRUPTION:
		fputs ("INT", fp);
		break;

	case VBI_PIL_CONTINUE:
		fputs ("CONT", fp);
		break;

	case VBI_PIL_NSPV:
		/* VBI_PIL_NSPV (PDC) == VBI_PIL_END (XDS) */
		fputs ("NSPV/END", fp);
		break;

	default:
		fprintf (fp, "%05x (%02u-%02u %02u:%02u)",
			 pil,
			 VBI_PIL_MONTH (pil),
			 VBI_PIL_DAY (pil),
			 VBI_PIL_HOUR (pil),
			 VBI_PIL_MINUTE (pil));
		break;
	}
}
예제 #4
0
파일: pdc.c 프로젝트: OpenDMM/zvbi
static vbi_bool
tm_mon_mday_from_pil		(struct tm *		tm,
				 vbi_pil		pil)
{
	unsigned int month0;

	month0 = VBI_PIL_MONTH (pil) - 1;

	if (month0 >= (unsigned int) tm->tm_mon + 6) {
		/* POSIX defines tm_year as int. */
		if (unlikely (tm->tm_year <= INT_MIN))
			return FALSE;
		--tm->tm_year;
	} else if (month0 + 6 < (unsigned int) tm->tm_mon) {
		if (unlikely (tm->tm_year >= INT_MAX))
			return FALSE;
		++tm->tm_year;
	}

	tm->tm_mon = month0;
	tm->tm_mday = VBI_PIL_DAY (pil);

	return TRUE;
}
예제 #5
0
파일: pdc.c 프로젝트: OpenDMM/zvbi
/**
 * @param begin The start of the validity of the PIL will be stored
 *   here.
 * @param end The end of the validity of the PIL will be stored here.
 * @param pil Program Identification Label (PIL).
 * @param start The most recently announced start time of the program.
 *   If zero the current system time will be used.
 * @param tz A time zone name in the same format as the TZ environment
 *   variable. If @c NULL the current value of TZ will be used.
 *
 * This function calculates the validity time window of a PIL
 * according to EN 300 231. That is the time window where a network
 * can be expected to broadcast this PIL, usually from 00:00 on the
 * same day until 04:00 on the next day.
 *
 * Since PILs do not contain a year field, the year is determined from
 * the @a start parameter, that is the most recently announced start
 * time of the program or "AT-1" in EN 300 231 parlance. If @a pil
 * contains a month more than five months after @a start, @a pil is
 * assumed to refer to an earlier date than @a start.
 *
 * @a pil is assumed to be a time in the time zone specified by @a
 * seconds_east. @a start will be converted to a local time in the
 * same time zone to determine the correct year.
 *
 * Teletext packet 8/30 format 2, VPS and DVB PDC descriptors give a
 * PIL relative to the time zone of the intended audience of the
 * program. Ideally the time zone would be specified as a geographic
 * area like "Europe/London", such that the function can determine the
 * correct offset from UTC and if daylight-saving time is in effect at
 * any time within the validity window. See the documentation of the
 * localtime() function and the TZ environment variable for details.
 *
 * If @a pil is @c VBI_PIL_NSPV this function returns the same values
 * as vbi_pty_validity_window().
 *
 * @returns
 * On error the function returns @c FALSE:
 * - @a pil is not @c VBI_PIL_NSPV and does not contain a
 *   valid date or time. February 29th is a valid date only if the
 *   estimated year is a leap year.
 * - @a tz is empty or contains an equal sign '='.
 * - @a start is zero and the current system time could not be
 *   determined.
 * - The time specified by @a pil, @a start and @a tz cannot be
 *   represented as a time_t value.
 * - Insufficient memory was available.
 *
 * @since 0.2.34
 *
 * @bug
 * This function is not thread safe unless @a tz is @c NULL.
 * That is a limitation of the C library which permits the conversion
 * of a broken-down time in an arbitrary time zone only by setting
 * the TZ environment variable. The function may also fail to restore
 * the value of TZ if insufficient memory is available.
 */
vbi_bool
vbi_pil_validity_window		(time_t *		begin,
				 time_t *		end,
				 vbi_pil		pil,
				 time_t			start,
				 const char *		tz)
{
	unsigned int month;

	assert (NULL != begin);
	assert (NULL != end);

	month = VBI_PIL_MONTH (pil);
	if (0 == month) {
		/* EN 300 231 Annex F: "Unallocated". */
#if 3 == VBI_VERSION_MINOR
		errno = VBI_ERR_INVALID_PIL;
#else
		errno = 0;
#endif
		return FALSE;
	} else if (month <= 12) {
		unsigned int day;
		vbi_bool success;

		day = VBI_PIL_DAY (pil);
		if (day - 1 >= month_days[month - 1]) {
			/* Annex F: "Invalid days
			   - indefinite time window". */
			*begin = TIME_MIN;
			*end = TIME_MAX;
			return TRUE;
		}

		success = valid_pil_validity_window
			(begin, end, pil, start, tz);
#if 2 == VBI_VERSION_MINOR
		errno = 0;
#endif
		return success;
	} else if (month <= 14) {
		/* Annex F: "Indefinite time window". */
		*begin = TIME_MIN;
		*end = TIME_MAX;
		return TRUE;
	} else {
		vbi_bool success;

		/* Annex F: "Unallocated except for the following
		 * service codes (for which there is no restriction to
		 * the time window of validity)". */
		switch (pil) {
		case VBI_PIL_TIMER_CONTROL:
		case VBI_PIL_INHIBIT_TERMINATE:
		case VBI_PIL_INTERRUPTION:
		case VBI_PIL_CONTINUE:
			*begin = TIME_MIN;
			*end = TIME_MAX;
			return TRUE;

		/* EN 300 231 Section 9.3, Annex E.3. */
		case VBI_PIL_NSPV:
			success = vbi_pty_validity_window
				(begin, end, start, tz);
#if 2 == VBI_VERSION_MINOR
			errno = 0;
#endif
			return success;

		default:
#if 3 == VBI_VERSION_MINOR
			errno = VBI_ERR_INVALID_PIL;
#else
			errno = 0;
#endif
			return FALSE;
		}
	}
}