    ﻿using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Text.RegularExpressions;

    namespace Nikse.SubtitleEdit.Core.SubtitleFormats
    {
        public class Csv2 : SubtitleFormat
        {
            private const string Separator = ",";

            //1,01:00:10:03,01:00:15:25,I thought I should let my sister-in-law know.
            private static readonly Regex CsvLine = new Regex(@"^\d+" + Separator + @"\d\d:\d\d:\d\d:\d\d" + Separator + @"\d\d:\d\d:\d\d:\d\d" + Separator, RegexOptions.Compiled);

            public override string Extension => ".csv";

            public override string Name => "Csv2";

            public override bool IsMine(List<string> lines, string fileName)
            {
                int fine = 0;
                int failed = 0;
                bool continuation = false;
                foreach (string line in lines)
                {
                    Match m = CsvLine.Match(line);
                    if (m.Success)
                    {
                        fine++;
                        string s = line.Remove(0, m.Length);
                        continuation = s.StartsWith('"');
                    }
                    else if (!string.IsNullOrWhiteSpace(line))
                    {
                        if (continuation)
                            continuation = false;
                        else
                            failed++;
                    }
                }
                return fine > failed;
            }

            public override string ToText(Subtitle subtitle, string title)
            {
                const string format = "{1}{0}{2}{0}{3}{0}\"{4}\"";
                var sb = new StringBuilder();
                sb.AppendLine(string.Format(format, Separator, "Number", "Start time (hh:mm:ss:ff)", "End time (hh:mm:ss:ff)", "Text"));
                foreach (Paragraph p in subtitle.Paragraphs)
                {
                    sb.AppendLine(string.Format(format, Separator, p.Number, EncodeTimeCode(p.StartTime), EncodeTimeCode(p.EndTime), p.Text.Replace(Environment.NewLine, "\n")));
                }
                return sb.ToString().Trim();
            }

            private static string EncodeTimeCode(TimeCode time)
            {
                return $"{time.Hours:00}:{time.Minutes:00}:{time.Seconds:00}:{MillisecondsToFramesMaxFrameRate(time.Milliseconds):00}";
            }

            public override void LoadSubtitle(Subtitle subtitle, List<string> lines, string fileName)
            {
                _errorCount = 0;
                bool continuation = false;
                Paragraph p = null;
                foreach (string line in lines)
                {
                    Match m = CsvLine.Match(line);
                    if (m.Success)
                    {
                        string[] parts = line.Substring(0, m.Length).Split(Separator.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                        if (parts.Length == 3)
                            try
                            {
                                var start = DecodeTimeCode(parts[1]);
                                var end = DecodeTimeCode(parts[2]);
                                string text = line.Remove(0, m.Length);
                                continuation = text.StartsWith('"') && !text.EndsWith('"');
                                text = text.Trim('"');
                                p = new Paragraph(start, end, text);
                                subtitle.Paragraphs.Add(p);
                            }
                            catch
                            {
                                _errorCount++;
                            }
                    }
                    else if (!string.IsNullOrWhiteSpace(line))
                    {
                        if (continuation)
                        {
                            if (p != null && p.Text.Length < 300)
                                p.Text = (p.Text + Environment.NewLine + line.TrimEnd('"')).Trim();
                            continuation = !line.TrimEnd().EndsWith('"');
                        }
                        else
                        {
                            _errorCount++;
                        }
                    }
                }
                subtitle.Renumber();
            }

            private static TimeCode DecodeTimeCode(string part)
            {
                string[] parts = part.Split(new[] { '.', ':' }, StringSplitOptions.RemoveEmptyEntries);

                //00:00:07:12
                string hour = parts[0];
                string minutes = parts[1];
                string seconds = parts[2];
                string frames = parts[3];

                return new TimeCode(int.Parse(hour), int.Parse(minutes), int.Parse(seconds), FramesToMillisecondsMax999(int.Parse(frames)));
            }

        }
    }

↑ V3095 The 'line' object was used before it was verified against null. Check lines: 77, 88.

↑ V3095 The 'line' object was used before it was verified against null. Check lines: 30, 33.