////////////////////////////////////////////////////////////////////////////////// // // // 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 DomainObjects; namespace DVBServices { /// /// The class that describes MediaHighway2 title data. /// public class MediaHighway2TitleData { /// /// Get the channel identification. /// public int ChannelID { get { return (channelID); } } /// /// Get the event identification. /// public int EventID { get { return (eventID); } } /// /// Get the start time of the event. /// public DateTime StartTime { get { return (baseDate + new TimeSpan(hours, minutes, 0)); }} /// /// Get the duration of the event. /// public TimeSpan Duration { get { return (duration); } } /// /// Get the theme identification of the event. /// public int CategoryID { get { return ((mainCategory << 6) + subCategory); } } /// /// Get the theme group of the event. /// public int MainCategory { get { return (mainCategory); } } /// /// Get the theme subgroup of the event. /// public int SubCategory { get { return (subCategory); } } /// /// Get the name of the event. /// public string EventName { get { return (eventName); } } /// /// Get the unknown data. /// public byte[] Unknown { get { byte[] outputBytes = new byte[unknown0.Length + unknown1.Length + unknown2.Length]; unknown0.CopyTo(outputBytes, 0); unknown1.CopyTo(outputBytes, unknown0.Length); unknown2.CopyTo(outputBytes, unknown0.Length + unknown1.Length); return (outputBytes); } } /// /// Get the index of the next byte in the MPEG2 section following the title data. /// /// /// The title data has not been processed. /// public int Index { get { if (lastIndex == -1) throw (new InvalidOperationException("MediaHighway2TitleData: Index requested before block processed")); return (lastIndex); } } private byte[] unknown0; private int channelID; private byte[] unknown1; private int mainCategory; private DateTime baseDate; private int hours; private int minutes; private byte[] unknown2; private TimeSpan duration; private string eventName; private int subCategory; private int eventID; private int lastIndex = -1; /// /// Initialize a new instance of the MediaHighway2TitleData class. /// public MediaHighway2TitleData() { } /// /// Parse the title data. /// /// The MPEG2 section containing the title data. /// Index of the first byte of the title data in the MPEG2 section. internal void Process(byte[] byteData, int index) { lastIndex = index; try { unknown0 = Utils.GetBytes(byteData, 3, 15); channelID = (int)byteData[lastIndex]; lastIndex++; unknown1 = Utils.GetBytes(byteData, lastIndex, 10); lastIndex += unknown1.Length; mainCategory = byteData[7] & 0x0f; baseDate = getDate(Utils.Convert2BytesToInt(byteData, lastIndex)); lastIndex += 2; hours = ((byteData[lastIndex] >> 4) * 10) + (byteData[lastIndex] & 0x0f); lastIndex++; minutes = ((byteData[lastIndex] >> 4) * 10) + (byteData[lastIndex] & 0x0f); lastIndex++; unknown2 = Utils.GetBytes(byteData, lastIndex, 1); lastIndex += unknown2.Length; int durationMinutes = (byteData[lastIndex] << 4) + (byteData[lastIndex + 1] >> 4); duration = new TimeSpan(durationMinutes / 60, durationMinutes % 60, 0); lastIndex += 2; int eventNameLength = byteData[lastIndex] & 0x3f; lastIndex++; eventName = Utils.GetString(byteData, lastIndex, eventNameLength, ReplaceMode.TransferUnchanged); lastIndex += eventNameLength; subCategory = byteData[lastIndex] & 0x3f; lastIndex++; eventID = Utils.Convert2BytesToInt(byteData, lastIndex); lastIndex += 2; 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 data fields. /// /// /// A title data field is not valid. /// public void Validate() { } /// /// Log the title data fields. /// public void LogMessage() { if (Logger.ProtocolLogger == null) return; Logger.ProtocolLogger.Write(Logger.ProtocolIndent + "MHW2 TITLE DATA: Channel ID: " + channelID + " Unknown0: " + Utils.ConvertToHex(unknown0) + " Unknown1: " + Utils.ConvertToHex(unknown1) + " Main cat: " + mainCategory + " Base date: " + baseDate + " Hours: " + hours + " Minutes: " + minutes + " Unknown2: " + Utils.ConvertToHex(unknown2) + " Duration: " + duration + " Event name: " + eventName + " Sub cat: " + mainCategory + " Event ID: " + eventID); } } }