示例#1
0
        private void LoadDvbS(ChannelList list, string path, string mappingName)
        {
            if (!File.Exists(path))
            {
                return;
            }

            var data = File.ReadAllBytes(path);

            if (data.Length < 12)
            {
                return;
            }

            var version = chanLstBin.VersionMajor;

            if (version <= 11)
            {
                var checksum = BitConverter.ToUInt32(data, data.Length - 4);

                var crcObj = new Crc32(false, Crc32.NormalPoly);
                var crc    = ~crcObj.CalcCrc32(data, 0, data.Length - 4);
                if (checksum != crc)
                {
                    throw new FileLoadException("Invalid CRC32 in " + path);
                }
            }


            int recordSize  = BitConverter.ToInt32(data, 4);
            int recordCount = BitConverter.ToInt32(data, 8);

            if (recordSize == 0 && version != 1)
            {
                recordSize = recordCount == 0 ? 0 : (data.Length - 12) / recordCount;
            }

            if (chanLstBin.VersionMajor <= 11)
            {
                // 12 bytes header, then a "next/prev" table, then the service records, then a CRC32
                // the "next/prev" table is a ring-list, every entry consists of 2 ushorts with the next and previous channel, wrapping around on the ends
                if (data.Length != 12 + recordCount * 4 + recordCount * recordSize + 4)
                {
                    throw new FileLoadException("Unsupported file content: " + path);
                }
            }

            this.dataFilePaths.Add(path);

            var dvbStringDecoder = new DvbStringDecoder(this.DefaultEncoding);

            var mapping = new DataMapping(this.ini.GetSection(mappingName));

            mapping.SetDataPtr(data, 12 + (chanLstBin.VersionMajor <= 11 ? recordCount * 4 : 0));
            for (int i = 0; i < recordCount; i++, mapping.BaseOffset += recordSize)
            {
                var ch = LoadDvbsChannel(list, mapping, i, dvbStringDecoder);
                this.DataRoot.AddChannel(list, ch);
            }
        }
示例#2
0
        public override void Load()
        {
            var decoder = new DvbStringDecoder(this.DefaultEncoding);

            var pos = 0;

            content = File.ReadAllBytes(this.FileName);
            int prevPos = 0, nextPos;

            while (prevPos < content.Length && content[prevPos] != 0 && (nextPos = Array.FindIndex(content, prevPos, ch => ch == (byte)'\n')) >= 0)
            {
                if (nextPos - prevPos == 0)
                {
                    continue;
                }
                string      line    = Encoding.ASCII.GetString(content, prevPos, nextPos - prevPos);
                ChannelInfo channel = new Channel(pos, line, content, prevPos, nextPos - prevPos, decoder);
                this.DataRoot.AddChannel(this.allChannels, channel);
                pos++;
                prevPos = nextPos + 1;
            }

            // SATCODX105 files contain a \0 character to mark the end, followed by an arbitrary number or spaces (or whatever data). We'll preserve it as-is.
            this.trailingDataPos = prevPos;
        }
示例#3
0
 private bool GetRecommendedEncoding(ref Encoding encoding, out int startOffset, out int bytesPerChar)
 {
     startOffset  = 0;
     bytesPerChar = 1;
     if (RawName[0] < 0x10) // single byte character sets
     {
         encoding    = DvbStringDecoder.GetEncoding(RawName[0]);
         startOffset = 1;
     }
     else if (RawName[0] == 0x10) // prefix for 16 bit code page ID with single byte character sets
     {
         if (RawName.Length < 3)
         {
             return(false);
         }
         encoding    = DvbStringDecoder.GetEncoding(0x100000 + RawName[1] * 256 + RawName[2]);
         startOffset = 3;
     }
     else if (RawName[0] == 0x15) // UTF-8
     {
         encoding    = Encoding.UTF8;
         startOffset = 1;
     }
     else if (RawName[0] < 0x20) // various 2-byte character sets
     {
         encoding     = DvbStringDecoder.GetEncoding(RawName[0]);
         startOffset  = 1;
         bytesPerChar = 2;
     }
     return(true);
 }
示例#4
0
        private void ParseNames()
        {
            mapping.SetDataPtr(this.rawData, this.baseOffset);
            DvbStringDecoder dec = new DvbStringDecoder(mapping.DefaultEncoding);
            string           longName, shortName;

            dec.GetChannelNames(this.rawData, this.baseOffset + mapping.GetOffsets(_Name)[0], mapping.GetByte(_NameLength),
                                out longName, out shortName);
            this.Name      = longName;
            this.ShortName = shortName;
        }
示例#5
0
        public override void Load()
        {
            var decoder = new DvbStringDecoder(this.DefaultEncoding);

            var pos = 0;

            content = File.ReadAllBytes(this.FileName);
            int prevPos = 0, nextPos;

            while (prevPos < content.Length && (nextPos = Array.FindIndex(content, prevPos, ch => ch == (byte)'\n')) >= 0)
            {
                if (nextPos - prevPos == 0)
                {
                    continue;
                }
                string      line    = Encoding.ASCII.GetString(content, prevPos, nextPos - prevPos);
                ChannelInfo channel = new Channels(pos, line, content, prevPos, nextPos - prevPos, decoder);
                this.DataRoot.AddChannel(this.allChannels, channel);
                pos++;
                prevPos = nextPos + 1;
            }
        }
示例#6
0
        private void InsertChannelData(DbCommand cmd, int listId)
        {
            PrepareChannelInsert(cmd);

            DvbStringDecoder decoder     = new DvbStringDecoder(this.DefaultEncoding);
            DataMapping      dvbsMapping = this.dvbsMappings.GetMapping(this.dvbsBlockSize);

            dvbsMapping.SetDataPtr(this.fileContent, this.dvbsBlockOffset + this.satConfig.ChannelListOffset);
            for (int slot = 0; slot < this.dvbsChannelCount; slot++)
            {
                cmd.Parameters["@listid"].Value   = listId;
                cmd.Parameters["@slot"].Value     = slot;
                cmd.Parameters["@seq"].Value      = DBNull.Value;
                cmd.Parameters["@isdel"].Value    = dvbsMapping.GetFlag("InUse") ? 0 : 1;
                cmd.Parameters["@progmask"].Value = dvbsMapping.GetWord("offProgramNr");
                cmd.Parameters["@prognr"].Value   = dvbsMapping.GetWord("offProgramNr") & 0x3FFF;
                cmd.Parameters["@progfix"].Value  = dvbsMapping.GetWord("offProgramNrPreset");
                int    absNameOffset = dvbsMapping.BaseOffset + dvbsMapping.GetOffsets("offName")[0];
                string longName, shortName;
                decoder.GetChannelNames(fileContent, absNameOffset, dvbsMapping.GetByte("offNameLength"), out longName, out shortName);
                cmd.Parameters["@name"].Value = longName;
                cmd.Parameters["@tpnr"].Value = dvbsMapping.GetWord("offTransponderIndex");
                var transp = this.DataRoot.Transponder.TryGet(dvbsMapping.GetWord("offTransponderIndex"));
                cmd.Parameters["@satnr"].Value = transp == null ? (object)DBNull.Value : transp.Satellite.Id;
                cmd.Parameters["@onid"].Value  = transp == null ? (object)DBNull.Value : transp.OriginalNetworkId;
                cmd.Parameters["@tsid"].Value  = transp == null ? (object)DBNull.Value : transp.TransportStreamId;
                cmd.Parameters["@ssid"].Value  = (int)dvbsMapping.GetWord("offServiceId");
                cmd.Parameters["@uid"].Value   = transp == null
                                         ? (object)DBNull.Value
                                         : transp.TransportStreamId + "-" + transp.OriginalNetworkId + "-" +
                                                 dvbsMapping.GetWord("offServiceId");
                cmd.Parameters["@favcrypt"].Value     = (int)dvbsMapping.GetByte("offFavorites");
                cmd.Parameters["@lockskiphide"].Value = (int)dvbsMapping.GetByte("offLock");
                cmd.ExecuteNonQuery();
                dvbsMapping.BaseOffset += this.satConfig.dvbsChannelLength;
            }
        }
示例#7
0
        /// <summary>
        /// SATCODX103 files can contain channel names with unspecified implicit encoding, so we support reparsing based on a user selected default code page
        /// </summary>
        /// <param name="decoder"></param>
        public void ParseName(DvbStringDecoder decoder)
        {
            var length = this.Length;
            var start  = this.FileOffset;

            // 43-50 + 115-126 in version 103 or 115-131 in version 105: channel name
            byte[] nameBytes = new byte[8 + 17];
            var    nameLen2  = Math.Min(length - 115, 17); // version 103 has 12 extra bytes for channel name, version 105 has 17

            Array.Copy(data, start + 43, nameBytes, 0, 8);
            Array.Copy(data, start + 115, nameBytes, 8, nameLen2);

            // I have seen format 103 files using only implicit CP1252 encoding for Umlauts, as well as format 105 with implicit UTF-8/explicit DVB-encoding
            var oldDefaultEncoding = decoder.DefaultEncoding;

            if (nameLen2 > 12)
            {
                decoder.DefaultEncoding = Encoding.UTF8;
            }
            decoder.GetChannelNames(nameBytes, 0, nameBytes.Length, out var longName, out var shortName);
            decoder.DefaultEncoding = oldDefaultEncoding;
            this.Name      = longName.TrimEnd();
            this.ShortName = shortName.TrimEnd();
        }
示例#8
0
        private void LoadChannels()
        {
            if (this.doc["channelList"] == null)
            {
                throw new FileLoadException("JSON does not contain a channelList node");
            }

            var dec = new DvbStringDecoder(this.DefaultEncoding);
            int i   = 0;

            foreach (var node in this.doc["channelList"])
            {
                var ch = new GcChannel <JToken>(0, i, node);
                ch.PcrPid     = (int)node["pcrPid"];
                ch.IsDisabled = (bool)node["disabled"];
                ch.FreqInMhz  = (int)node["frequency"];
                if (ch.FreqInMhz >= 100000 && ch.FreqInMhz < 1000000) // DVBS is given in MHz, DVBC/T in kHz
                {
                    ch.FreqInMhz /= 1000;
                }
                ch.AudioPid = (int)node["audioPid"];

                ch.Source = (string)node["sourceIndex"];
                if (ch.Source == "SATELLITE DIGITAL")
                {
                    ch.SignalSource |= SignalSource.DvbS;
                }
                else if (ch.Source == "CABLE DIGITAL")
                {
                    ch.SignalSource |= SignalSource.DvbC;
                }
                else if (ch.Source.Contains("DIGITAL")) // not seen yet. maybe DIGITAL ANTENNA?
                {
                    ch.SignalSource |= SignalSource.DvbT;
                }

                ch.Skip      = (bool)node["skipped"];
                ch.Hidden    = (bool)node["Invisible"];
                ch.IsDeleted = (bool)node["deleted"];
                //if (int.TryParse((string) node["satelliteId"], out var satId))
                ch.Satellite = (string)node["satelliteId"]; //this.DataRoot.Satellites.TryGet(satId);
                ch.Encrypted = (bool)node["scrambled"];
                var nameBytes = Convert.FromBase64String((string)node["chNameBase64"]);
                dec.GetChannelNames(nameBytes, 0, nameBytes.Length, out var name, out var shortName);
                ch.Name      = name;
                ch.ShortName = shortName;
                ch.VideoPid  = (int)node["videoPid"];
                var transSystem = (string)node["transSystem"];
                var tpId        = (string)node["tpId"];
                if (tpId != null && tpId.Length == 10)
                {
                    ch.Transponder = this.DataRoot.Transponder.TryGet((int.Parse(tpId.Substring(0, 4)) << 16) + int.Parse(tpId.Substring(4))); // satId + freq, e.g. 0192126041
                }
                ch.TransportStreamId = (int)node["TSID"];
                ch.OldProgramNr      = ch.IsDeleted ? -1 : (int)node["majorNumber"];
                ch.ServiceType       = (int)node["serviceType"];
                ch.Lock = (bool)node["locked"];
                if (string.IsNullOrWhiteSpace(ch.Name))
                {
                    ch.Name = (string)node["channelName"];
                }
                ch.ServiceId = (int)node["SVCID"];
                if (ch.ServiceId == 0)
                {
                    ch.ServiceId = (int)node["programNum"];
                }
                ch.OriginalNetworkId = (int)node["ONID"];
                ch.SignalSource     |= LookupData.Instance.IsRadioTvOrData(ch.ServiceType);

                if ((ch.OldProgramNr & 0x4000) != 0)
                {
                    ch.OldProgramNr &= 0x3FFF;
                    ch.SignalSource |= SignalSource.Radio;
                }

                var list = this.DataRoot.GetChannelList(ch.SignalSource);
                this.DataRoot.AddChannel(list, ch);
            }
        }
示例#9
0
        private ChannelInfo LoadDvbsChannel(ChannelList list, DataMapping mapping, int recordIndex, DvbStringDecoder dvbStringDecoder)
        {
            var transponderId = mapping.GetWord("offTransponderIndex");
            var progNr        = mapping.GetWord("offProgNr");
            var ch            = new ChannelInfo(list.SignalSource, recordIndex, progNr, null);

            // deleted channels must be kept in the list because their records must also be physically reordered when saving the list
            if (progNr == 0xFFFF || transponderId == 0xFFFF)
            {
                ch.IsDeleted    = true;
                ch.OldProgramNr = -1;
                return(ch);
            }

            // onid, tsid, pcrpid and vpid can be 0 in some lists
            ch.PcrPid            = mapping.GetWord("offPcrPid") & mapping.GetMask("maskPcrPid");
            ch.Lock              = mapping.GetFlag("Locked");
            ch.OriginalNetworkId = mapping.GetWord("OffOnid");
            ch.TransportStreamId = mapping.GetWord("offTsid");
            ch.ServiceId         = mapping.GetWord("offSid");
            ch.VideoPid          = mapping.GetWord("offVpid") & mapping.GetMask("maskVpid");
            ch.Favorites         = mapping.GetFlag("IsFav") ? Favorites.A : 0;
            ch.OldProgramNr      = progNr;

            // the 0x1F as the first byte of the channel name is likely the DVB encoding indicator for UTF-8. So we use the DvbStringDecoder here
            dvbStringDecoder.GetChannelNames(mapping.Data, mapping.BaseOffset + mapping.GetConst("offName", 0), mapping.GetConst("lenName", 0), out var longName, out var shortName);
            ch.Name      = longName.TrimEnd('\0');
            ch.ShortName = shortName.TrimEnd('\0');

            dvbStringDecoder.GetChannelNames(mapping.Data, mapping.BaseOffset + mapping.GetConst("offProvider", 0), mapping.GetConst("lenProvider", 0), out var provider, out _);
            ch.Provider = provider.TrimEnd('\0');

            // copy values from the satellite/transponder tables to the channel
            if (this.DataRoot.Transponder.TryGetValue(transponderId, out var t))
            {
                ch.Transponder = t;
                ch.FreqInMhz   = t.FrequencyInMhz;
                ch.SymbolRate  = t.SymbolRate;
                ch.SatPosition = t.Satellite?.OrbitalPosition;
                ch.Satellite   = t.Satellite?.Name;
                if (t.OriginalNetworkId != 0)
                {
                    ch.OriginalNetworkId = t.OriginalNetworkId;
                }
                if (t.TransportStreamId != 0)
                {
                    ch.TransportStreamId = t.TransportStreamId;
                }
            }

            return(ch);
        }
示例#10
0
        internal Channels(int pos, string line, byte[] data, int start, int length, DvbStringDecoder decoder)
        {
            this.FileOffset  = start;
            this.Length      = length;
            this.RecordIndex = pos;
            this.RecordOrder = this.OldProgramNr = pos + 1;

            if (!line.StartsWith("SATCODX"))
            {
                throw new FileLoadException("Only SAT channels are supported");
            }
            if (line.Length < 106)
            {
                throw new FileLoadException("Unrecognized channel format");
            }

            this.Satellite = line.Substring(10, 18);

            var type = line[28];

            this.SignalSource = SignalSource.Digital | SignalSource.Sat | (type == 'T' ? SignalSource.Tv : type == 'R' ? SignalSource.Radio : 0);
            this.ServiceType  = type == 'T' ? 1 : type == 'R' ? 2 : 0; // 1=SD-TV, 2=Radio

            if (int.TryParse(line.Substring(34, 5), out var mhz))
            {
                this.FreqInMhz = mhz;
            }

            this.Polarity = line[39] == '1' ? 'H' : 'V';

            byte[] nameBytes = new byte[8 + 17];
            var    nameLen2  = Math.Min(length - 115, 17); // version 103 has 12 extra bytes for channel name, version 105 has 17

            Array.Copy(data, start + 43, nameBytes, 0, 8);
            Array.Copy(data, start + 115, nameBytes, 8, nameLen2);
            decoder.GetChannelNames(nameBytes, 0, nameBytes.Length, out var longName, out var shortName);
            this.Name      = longName.TrimEnd();
            this.ShortName = shortName.TrimEnd();

            var spos = line.Substring(51, 4).TrimStart('0');

            this.SatPosition = spos.Substring(0, spos.Length - 1) + CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator + spos.Substring(spos.Length - 1);

            if (int.TryParse(line.Substring(69, 5), out var symrate))
            {
                this.SymbolRate = symrate;
            }

            if (int.TryParse(line.Substring(87, 5), out var sid))
            {
                this.ServiceId = sid;
            }

            if (int.TryParse(line.Substring(92, 5), out var onid))
            {
                this.OriginalNetworkId = onid;
            }

            if (int.TryParse(line.Substring(97, 5), out var tsid))
            {
                this.TransportStreamId = tsid;
            }
        }
示例#11
0
        internal Channel(int pos, string line, byte[] data, int start, int length, DvbStringDecoder decoder)
        {
            this.data        = data;
            this.FileOffset  = start;
            this.Length      = length;
            this.RecordIndex = pos;
            this.RecordOrder = this.OldProgramNr = pos + 1;

            if (!line.StartsWith("SATCODX"))
            {
                throw new FileLoadException("Only SAT channels are supported");
            }
            if (line.Length < 106)
            {
                throw new FileLoadException("Unrecognized channel format");
            }

            // 10-27: satellite name
            this.Satellite = line.Substring(10, 18);

            // 28: channel type
            var type = line[28];

            this.SignalSource    = SignalSource.Digital | SignalSource.Sat | (type == 'T' ? SignalSource.Tv : type == 'R' ? SignalSource.Radio : 0);
            this.ServiceTypeName = type == 'T' ? "TV" : type == 'R' ? "Radio" : type == 'D' ? "Data" : "Other";

            // 29-32: broadcast system

            // 33-41: frequency in kHz
            if (int.TryParse(line.Substring(33, 9), out var khz))
            {
                this.FreqInMhz = (decimal)khz / 1000;
            }

            // 42: polarity
            this.Polarity = line[42] == '1' ? 'H' : 'V';

            // 43-50 + 115-126 in version 103 or 115-131 in version 105: channel name
            this.ParseName(decoder);

            // 51-54: sat position
            var spos = line.Substring(51, 4).TrimStart('0');

            this.SatPosition = spos.Substring(0, spos.Length - 1) + CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator + spos.Substring(spos.Length - 1);

            // 69-73: symbol rate
            if (int.TryParse(line.Substring(69, 5), out var symrate))
            {
                this.SymbolRate = symrate;
            }

            // 74: FEC 0=-, 1=1/2, 2=2/3, 3=3/4, 5=5/6, 7=7/8

            // 75-78: vpid or ____
            // 79-82: apid or ____
            // 83-86: pcrpid or ____

            // 87-91: sid
            if (int.TryParse(line.Substring(87, 5), out var sid))
            {
                this.ServiceId = sid;
            }

            // 92-96: nid / onid
            if (int.TryParse(line.Substring(92, 5), out var onid))
            {
                this.OriginalNetworkId = onid;
            }

            // 97-101: tsid
            if (int.TryParse(line.Substring(97, 5), out var tsid))
            {
                this.TransportStreamId = tsid;
            }

            // 102-104: language
            // 106-107: country code
            // 108-110: language code
            // 111-114: crypto code
        }