//////////////////////////////////////////////////////////////////////////////////
// //
// Copyright © 2005-2020 nzsjb //
// //
// This Program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation; either version 2, or (at your option) //
// any later version. //
// //
// This Program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with GNU Make; see the file COPYING. If not, write to //
// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. //
// http://www.gnu.org/copyleft/gpl.html //
// //
//////////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections.ObjectModel;
using DomainObjects;
namespace DVBServices
{
///
/// The class that describes an Open TV title header.
///
public class OpenTVTitleHeader
{
///
/// Get the channel identification.
///
public int ChannelID { get { return (channelID); } }
///
/// Get the title date base.
///
public DateTime BaseDate { get { return (baseDate); } }
///
/// Get the data collection related to this title.
///
public Collection TitleData { get { return (titleData); } }
///
/// Get the index of the next byte in the MPEG2 section following the title header.
///
///
/// The title header has not been processed.
///
public int Index
{
get
{
if (lastIndex == -1)
throw (new InvalidOperationException("OpenTVTitleHeader: Index requested before block processed"));
return (lastIndex);
}
}
private int channelID;
private DateTime baseDate;
private Collection titleData;
private int lastIndex = -1;
///
/// Initialize a new instance of the OpenTVTitleHeader class.
///
public OpenTVTitleHeader() { }
///
/// Parse the title header.
///
/// The MPEG2 section containing the title header.
/// Index of the first byte of the title header in the MPEG2 section.
/// The MPEG2 header of the section.
/// The PID of the section.
/// The table ID of the section.
internal void Process(byte[] byteData, int index, Mpeg2ExtendedHeader mpeg2Header, int pid, int tid)
{
lastIndex = index;
channelID = mpeg2Header.TableIDExtension;
try
{
baseDate = getDate(Utils.Convert2BytesToInt(byteData, lastIndex));
lastIndex += 2;
while (lastIndex < byteData.Length - 4)
{
OpenTVTitleData data = new OpenTVTitleData();
data.Process(byteData, lastIndex, baseDate, channelID, pid, tid);
if (!data.IsEmpty)
{
if (titleData == null)
titleData = new Collection();
titleData.Add(data);
}
lastIndex = data.Index;
}
Validate();
}
catch (IndexOutOfRangeException)
{
throw (new ArgumentOutOfRangeException("lastIndex = " + lastIndex));
}
}
private DateTime getDate(int mjd)
{
int j = mjd + 2400001 + 68569;
int c = 4 * j / 146097;
j = j - (146097 * c + 3) / 4;
int y = 4000 * (j + 1) / 1461001;
j = j - 1461 * y / 4 + 31;
int m = 80 * j / 2447;
int day = j - 2447 * m / 80;
j = m / 11;
int month = m + 2 - (12 * j);
int year = 100 * (c - 49) + y + j;
return (new DateTime(year, month, day));
}
///
/// Validate the title header fields.
///
///
/// A title header field is not valid.
///
public void Validate() { }
///
/// Log the title header fields.
///
public void LogMessage()
{
if (Logger.ProtocolLogger == null)
return;
Logger.ProtocolLogger.Write(Logger.ProtocolIndent + "OPENTV TITLE HEADER: Channel ID: " + channelID +
" Base date : " + baseDate);
if (titleData != null)
{
Logger.IncrementProtocolIndent();
foreach (OpenTVTitleData data in titleData)
data.LogMessage();
Logger.DecrementProtocolIndent();
}
}
}
}