public static bool TryProcess(HeaderFileContent content, string keyName, string keyValue, [NotNullWhen(false)] out string?exceptionMessage)
        {
            List <Coordinates>?channelCoordinates = content.GetChannelCoordinates() !;

            if (!FileLoaderCommon.TryParseChannelNumber(keyName, out int channelNumber))
            {
                exceptionMessage = $"{Resources.UnrecognizedKey} {keyName}";
                return(false);
            }

            if (channelNumber != channelCoordinates.Count + 1)
            {
                exceptionMessage = $"{Resources.NonConsecutiveChannelNumber} {keyName}";
                return(false);
            }

            if (channelNumber <= 0)
            {
                exceptionMessage = $"{Resources.UnrecognizedKey} {keyName}";
                return(false);
            }

            bool success = TryParseCoordinates(keyValue, out Coordinates coordinates, out string?errorText);

            if (!success)
            {
                exceptionMessage = $"{errorText} {Resources.Channel} {keyName}";
                return(false);
            }

            channelCoordinates.Add(coordinates);

            exceptionMessage = null;
            return(true);
        }
        public static bool TryProcess(HeaderFileContent content, string keyName, string keyValue, [NotNullWhen(false)] out string?exceptionMessage)
        {
            if (!Enum.TryParse(keyName, true, out Definitions.BinaryInfosKeys key))
            {
                exceptionMessage = $"{Resources.UnrecognizedKey} {keyName}";
                return(false);
            }

            switch (key)
            {
            case Definitions.BinaryInfosKeys.BinaryFormat:
            {
                if (!Enum.TryParse(keyValue, true, out BinaryFormat value))
                {
                    exceptionMessage = $"{Resources.UnrecognizedKeyValue} {keyValue}";
                    return(false);
                }

                content.BinaryFormat = value;
            }
            break;

            default:
                throw new NotImplementedException();     // should never happen
            }

            exceptionMessage = null;
            return(true);
        }
Beispiel #3
0
        public static void ProcessSectionComment(HeaderFileContent content, Definitions.Section section, string comment)
        {
            switch (section)
            {
            case Definitions.Section.NoSection:
                content.InlinedComments.BelowHeaderSection = FileLoaderCommon.ConcatenateWithNewLine(content.InlinedComments.BelowHeaderSection, comment);
                break;

            case Definitions.Section.CommonInfos:
                content.InlinedComments.BelowCommonInfosSection = FileLoaderCommon.ConcatenateWithNewLine(content.InlinedComments.BelowCommonInfosSection, comment);
                break;

            case Definitions.Section.BinaryInfos:
                content.InlinedComments.BelowBinaryInfosSection = FileLoaderCommon.ConcatenateWithNewLine(content.InlinedComments.BelowBinaryInfosSection, comment);
                break;

            case Definitions.Section.ChannelInfos:
                content.InlinedComments.BelowChannelInfosSection = FileLoaderCommon.ConcatenateWithNewLine(content.InlinedComments.BelowChannelInfosSection, comment);
                break;

            case Definitions.Section.Coordinates:
                content.InlinedComments.BelowCoordinatesInfosSection = FileLoaderCommon.ConcatenateWithNewLine(content.InlinedComments.BelowCoordinatesInfosSection, comment);
                break;

            case Definitions.Section.Comment:
                content.InlinedComments.BelowCommentSection = FileLoaderCommon.ConcatenateWithNewLine(content.InlinedComments.BelowCommentSection, comment);
                break;

            default:
                throw new NotImplementedException();     // should never happen
            }
        }
Beispiel #4
0
        public static void ProcessKeyComment(HeaderFileContent content, Definitions.Section section, string keyName, string comment)
        {
            switch (section)
            {
            case Definitions.Section.CommonInfos:
                if (keyName == Definitions.CommonInfosKeys.DataOrientation.ToString())
                {
                    content.InlinedComments.AboveDataOrientation = FileLoaderCommon.ConcatenateWithNewLine(content.InlinedComments.AboveDataOrientation, comment);
                }
                else if (keyName == Definitions.CommonInfosKeys.SamplingInterval.ToString())
                {
                    content.InlinedComments.AboveSamplingInterval = FileLoaderCommon.ConcatenateWithNewLine(content.InlinedComments.AboveSamplingInterval, comment);
                }
                else
                {
                    Debug.Fail("Unhandled comment");
                }
                break;

            case Definitions.Section.NoSection:
            case Definitions.Section.BinaryInfos:
            case Definitions.Section.ChannelInfos:
            case Definitions.Section.Coordinates:
            case Definitions.Section.Comment:
                Debug.Fail("Unhandled comment");
                break;

            default:
                throw new NotImplementedException();     // should never happen
            }
        }
Beispiel #5
0
 private static bool TryProcessKey(HeaderFileContent content, Definitions.Section section, string keyName, string keyValue, [NotNullWhen(false)] out string?exceptionMessage)
 {
     return(section switch
     {
         Definitions.Section.NoSection => GlobalSectionLoader.TryProcess(keyName, out exceptionMessage), // (content, keyName, keyValue)
         Definitions.Section.CommonInfos => CommonInfosSectionLoader.TryProcess(content, keyName, keyValue, out exceptionMessage),
         Definitions.Section.BinaryInfos => BinaryInfosSectionLoader.TryProcess(content, keyName, keyValue, out exceptionMessage),
         Definitions.Section.ChannelInfos => ChannelInfosSectionLoader.TryProcess(content, keyName, keyValue, out exceptionMessage),
         Definitions.Section.Coordinates => CoordinatesInfosSectionLoader.TryProcess(content, keyName, keyValue, out exceptionMessage),
         Definitions.Section.Comment => throw new NotImplementedException(), // should never happen
         Definitions.Section.Unknown => throw new NotImplementedException(), // should never happen
         _ => throw new NotImplementedException(),                           // should never happen
     });
Beispiel #6
0
        private static void InitializeSectionContent(HeaderFileContent content, Definitions.Section section)
        {
            switch (section)
            {
            case Definitions.Section.ChannelInfos:
                content.SetChannelInfos(new List <ChannelInfo>());
                break;

            case Definitions.Section.Coordinates:
                content.SetChannelCoordinates(new List <Coordinates>());
                break;
            }
        }
Beispiel #7
0
 public IHeaderFileContentVer1 LoadVer1()
 {
     if (_newFileBeingCreated)
     {
         HeaderFileContent content = new HeaderFileContent(Definitions.IdentificationText, new Version(1, 0));
         return(content);
     }
     else
     {
         FileLoader fileLoader = new FileLoader(_file);
         return(fileLoader.LoadVer1());
     }
 }
        public static bool TryProcess(HeaderFileContent content, string keyName, string keyValue, [NotNullWhen(false)] out string?exceptionMessage)
        {
            if (!Enum.TryParse(keyName, true, out Definitions.CommonInfosKeys key))
            {
                exceptionMessage = $"{Resources.UnrecognizedKey} {keyName}";
                return(false);
            }

            switch (key)
            {
            case Definitions.CommonInfosKeys.Codepage:
            {
                // resolving Utf-8 string as Utf8 enum
                if (0 == string.Compare(keyValue, Definitions.Utf8Enum, true, CultureInfo.InvariantCulture))
                {
                    content.CodePage = Codepage.Utf8;
                }
                else
                {
                    if (!Enum.TryParse(keyValue, true, out Codepage value))
                    {
                        exceptionMessage = $"{Resources.UnrecognizedKeyValue} {keyValue}";
                        return(false);
                    }

                    // Utf8 is not valid, only Utf-8 is valid
                    if (value == Codepage.Utf8)
                    {
                        exceptionMessage = $"{Resources.UnrecognizedKeyValue} {keyValue}";
                        return(false);
                    }

                    content.CodePage = value;
                }
            }
            break;

            case Definitions.CommonInfosKeys.DataFile:
                if (string.IsNullOrWhiteSpace(keyValue))
                {
                    exceptionMessage = $"{Resources.FileNameCannotBeEmpty} {keyName}";
                    return(false);
                }

                string eegFileExtension        = Path.GetExtension(keyValue);
                bool   isEegFileExtensionValid = s_validEegFileExtensions.Select(p => $".{p}").Contains(eegFileExtension);
                if (!isEegFileExtensionValid)
                {
                    exceptionMessage = $"{Resources.UnrecognizedFileExtension} {ToCommaSeparatedText(s_validEegFileExtensions)}: {keyName}";
                    return(false);
                }
                content.DataFile = keyValue;
                break;

            case Definitions.CommonInfosKeys.MarkerFile:
                if (string.IsNullOrWhiteSpace(keyValue))
                {
                    exceptionMessage = $"{Resources.FileNameCannotBeEmpty} {keyName}";
                    return(false);
                }

                string markerFileExtension        = Path.GetExtension(keyValue);
                bool   isMarkerFileExtensionValid = s_validMarkerFileExtensions.Select(p => $".{p}").Contains(markerFileExtension);
                if (!isMarkerFileExtensionValid)
                {
                    exceptionMessage = $"{Resources.UnrecognizedFileExtension} {ToCommaSeparatedText(s_validMarkerFileExtensions)}: {keyName}";
                    return(false);
                }
                content.MarkerFile = keyValue;
                break;

            case Definitions.CommonInfosKeys.DataFormat:
            {
                if (!Enum.TryParse(keyValue, true, out DataFormat value))
                {
                    exceptionMessage = $"{Resources.UnrecognizedKeyValue} {keyValue}";
                    return(false);
                }

                content.DataFormat = value;
            }
            break;

            case Definitions.CommonInfosKeys.DataType:
            {
                if (!Enum.TryParse(keyValue, true, out DataType value))
                {
                    exceptionMessage = $"{Resources.UnrecognizedKeyValue} {keyValue}";
                    return(false);
                }

                content.DataType = value;
            }
            break;

            case Definitions.CommonInfosKeys.DataOrientation:
            {
                if (!Enum.TryParse(keyValue, true, out DataOrientation value))
                {
                    exceptionMessage = $"{Resources.UnrecognizedKeyValue} {keyValue}";
                    return(false);
                }

                content.DataOrientation = value;
            }
            break;

            case Definitions.CommonInfosKeys.SamplingInterval:
            {
                if (!double.TryParse(keyValue, NumberStyles.Float, CultureInfo.InvariantCulture, out double value))
                {
                    exceptionMessage = $"{Resources.UnrecognizedKeyValue} {keyValue}";
                    return(false);
                }

                if (value <= 0.0)
                {
                    exceptionMessage = $"{Resources.ValueCannotBeNegativeOrZero} {keyName}";
                    return(false);
                }

                content.SamplingInterval = value;
            }
            break;

            case Definitions.CommonInfosKeys.NumberOfChannels:
            {
                if (!int.TryParse(keyValue, NumberStyles.Integer, CultureInfo.InvariantCulture, out int value))
                {
                    exceptionMessage = $"{Resources.UnrecognizedKeyValue} {keyValue}";
                    return(false);
                }

                if (value <= 0)
                {
                    exceptionMessage = $"{Resources.ValueCannotBeNegativeOrZero} {keyName}";
                    return(false);
                }

                content.NumberOfChannels = value;
            }
            break;

            case Definitions.CommonInfosKeys.Averaged:
            {
                if (!Enum.TryParse(keyValue, true, out YesNo value))
                {
                    exceptionMessage = $"{Resources.UnrecognizedKeyValue} {keyValue}";
                    return(false);
                }

                content.Averaged = value == YesNo.YES;
            }
            break;

            case Definitions.CommonInfosKeys.AveragedSegments:
            {
                if (!int.TryParse(keyValue, NumberStyles.Integer, CultureInfo.InvariantCulture, out int value))
                {
                    exceptionMessage = $"{Resources.UnrecognizedKeyValue} {keyValue}";
                    return(false);
                }

                if (value < 0)
                {
                    exceptionMessage = $"{Resources.ValueCannotBeNegative} {keyName}";
                    return(false);
                }

                content.AveragedSegments = value;
            }
            break;

            case Definitions.CommonInfosKeys.SegmentDataPoints:
            {
                if (!int.TryParse(keyValue, NumberStyles.Integer, CultureInfo.InvariantCulture, out int value))
                {
                    exceptionMessage = $"{Resources.UnrecognizedKeyValue} {keyValue}";
                    return(false);
                }

                if (value < 0)
                {
                    exceptionMessage = $"{Resources.ValueCannotBeNegative} {keyName}";
                    return(false);
                }

                content.SegmentDataPoints = value;
            }
            break;

            case Definitions.CommonInfosKeys.SegmentationType:
            {
                if (!Enum.TryParse(keyValue, true, out SegmentationType value))
                {
                    exceptionMessage = $"{Resources.UnrecognizedKeyValue} {keyValue}";
                    return(false);
                }

                content.SegmentationType = value;
            }
            break;

            default:
                throw new NotImplementedException();     // should never happen
            }

            exceptionMessage = null;
            return(true);
        }
Beispiel #9
0
        public IHeaderFileContentVer1 LoadVer1()
        {
            _reader.BaseStream.Seek(0, SeekOrigin.Begin);

            Definitions.Section currentSection = Definitions.Section.NoSection;
            int currentLineNumber = -1;

            string?identificationText = _reader.ReadLine();

            ++currentLineNumber;

            if (!TryParseVersionFromIdentificationText(identificationText, out Version version))
            {
                throw new InvalidHeaderFileFormatException(0, $"{Resources.UnrecognizedIdentificationText} {Definitions.IdentificationText}"); // should never happen
            }
            if (version.Major != 1)
            {
                throw new InvalidHeaderFileFormatException(0, $"{Resources.UnsupportedVersion} {version}");
            }

            HeaderFileContent content = new HeaderFileContent(identificationText, version);

            // storing sections and keys for duplication checks
            List <string> alreadyCreatedSections             = new List <string>();
            List <string> alreadyCreatedKeysInCurrentSection = new List <string>();

            string?keyInlinedComments       = null;
            bool   isInSectionInlineComment = true; // section in-line comment is any comment between [section] and first key in section

            string line;

            while ((line = _reader.ReadLine()) != null)
            {
                ++currentLineNumber;

                if (IniFormat.IsCommentLine(line))
                {
                    string commentLineText = line.Substring(1); // removing ';' from text
                    if (isInSectionInlineComment)
                    {
                        InlinedCommentsLoader.ProcessSectionComment(content, currentSection, commentLineText);
                    }
                    else
                    {
                        keyInlinedComments = FileLoaderCommon.ConcatenateWithNewLine(keyInlinedComments, commentLineText);
                    }
                }
                else if (currentSection == Definitions.Section.Comment)
                {
                    CommentInfosSectionLoader.TryProcess(content, line);
                }
                else if (IniFormat.IsValidKeyLine(line, out string?keyName, out string?keyValue))
                {
                    if (keyInlinedComments != null)
                    {
                        InlinedCommentsLoader.ProcessKeyComment(content, currentSection, keyName, keyInlinedComments);
                        keyInlinedComments = null;
                    }

                    if (alreadyCreatedKeysInCurrentSection.Any(p => 0 == string.Compare(p, keyName, true, CultureInfo.InvariantCulture)))
                    {
                        throw new InvalidHeaderFileFormatException(currentLineNumber, $"{Resources.DuplicatedKey} {keyName}");
                    }

                    if (!TryProcessKey(content, currentSection, keyName, keyValue, out string?exceptionMessage))
                    {
                        throw new InvalidHeaderFileFormatException(currentLineNumber, exceptionMessage);
                    }

                    alreadyCreatedKeysInCurrentSection.Add(keyName);
                    isInSectionInlineComment = false;
                }
                else if (IniFormat.IsSectionLine(line, out string?sectionName))
                {
                    Definitions.Section section = Definitions.ParseSectionName(sectionName);

                    bool isValidSection = section != Definitions.Section.Unknown && section != Definitions.Section.NoSection;
                    if (!isValidSection)
                    {
                        throw new InvalidHeaderFileFormatException(currentLineNumber, $"{Resources.UnrecognizedSection} {sectionName}");
                    }

                    if (alreadyCreatedSections.Any(p => 0 == string.Compare(p, sectionName, true, CultureInfo.InvariantCulture)))
                    {
                        throw new InvalidHeaderFileFormatException(currentLineNumber, $"{Resources.DuplicatedSection} {sectionName}");
                    }

                    InitializeSectionContent(content, section);

                    currentSection           = section;
                    isInSectionInlineComment = true;

                    alreadyCreatedSections.Add(sectionName);
                    alreadyCreatedKeysInCurrentSection.Clear();
                }
                else if (string.IsNullOrWhiteSpace(line))
                {
                    // do nothing
                }
                else
                {
                    throw new InvalidHeaderFileFormatException(currentLineNumber, $"{Resources.InvalidLine} {line}");
                }
            }

            ThrowExceptionIfMandatoryFieldMissing(content);
            ThrowExceptionIfMandatoryFieldHasInvalidKeyValue(content);
            ThrowExceptionIfNumberOfChannelsDoesNotMatchChannels(content);
            ThrowExceptionIfCoordinatesDoNotMatchChannels(content);
            return(content);
        }