private static void Analyze(FileInfo sFileName) { try { Assembly asm = Assembly.LoadFile(sFileName.FullName); if (asm != null) { List <Type> lTypes = GetTypeList <ILineProvider>(asm); m_logger.InfoFormat("Analyzing assembly {0} ({1})", asm.FullName, sFileName); foreach (Type t in lTypes) { try { ILineProvider provider = Activator.CreateInstance(t) as ILineProvider; ExcpHelper.ThrowIf(string.IsNullOrEmpty(provider.UniqueName), "Cannot create provider instance of type {0} from dll '{1}'. Unique Name is empty", t, sFileName); m_diProviders.Add(provider.UniqueName, provider); } catch (Exception excp) { m_logger.Excp(excp, "Cannot create provider instance of type {0} from dll '{1}'", t, sFileName); } } } } catch (Exception excp) { m_logger.Excp(excp, "Cannot get provider(s) from dll '{0}'", sFileName); } }
public void WillCheckPreviousPage() { var scheduler = new TestScheduler(); using (var file = new TestFile()) { file.Append(Enumerable.Range(1, 20).Select(i => i.ToString()).ToArray()); ILineProvider lineProvider = null; using (file.Info.Index(scheduler).Exclude(str => str.Contains("9")).Subscribe(x => lineProvider = x)) { scheduler.AdvanceByMilliSeconds(250); lineProvider.Count.Should().Be(20); var lines = lineProvider.ReadLines(new ScrollRequest(10)).AsArray(); lines.Count().Should().Be(9); var expected = Enumerable.Range(1, 20) .Select(i => i.ToString()) .Where(str => !str.Contains("9")) .Reverse() .Take(10); //slines.Select(line => line.Text).Should().BeEquivalentTo(expected); } } }
public static ParseResult <Image> Parse(GedcomLine first, ILineProvider lineProvider) { var image = new Image(); image.ID = ParserHelper.ParseID(first.GetFirstItem()).ToString(); var initialLevel = first.Level; GedcomLine line = default; ReadOnlySpan <char> currentRawLine; while ((currentRawLine = lineProvider.ReadLine()) != null) { line = ParserHelper.ParseLine(currentRawLine); if (line.Level == first.Level) { break; } var splitLine = line.GetFirstItem(); if (ParserHelper.Equals(splitLine, "TITL")) { var title = line.GetLineContent(4); image.Title = title.ToString(); } else if (ParserHelper.Equals(splitLine, "FILE")) { var filePath = line.GetLineContent(4); image.FilePath = filePath.ToString(); } } return(ParseResult.Create(image, line)); }
public ExludedLinesProvider([NotNull] ILineProvider lines, Func<string, bool> itemsToExclude) { if (lines == null) throw new ArgumentNullException(nameof(lines)); _lines = lines; _itemsToExclude = itemsToExclude; Count = lines.Count; }
public ReportEngineProvider() { _clientTypeManager = GetContainer().Resolve <ICustomerTypeProvider>(); _smsProvider = GetContainer().Resolve <ISmsProvider>(); _callProvider = GetContainer().Resolve <ICallProvider>(); _customerProvider = GetContainer().Resolve <ICustomerProvider>(); _packageProvider = GetContainer().Resolve <IPackageProvider>(); _lineProvider = GetContainer().Resolve <ILineProvider>(); }
public ExludedLinesProvider([NotNull] ILineProvider lines, Func <string, bool> itemsToExclude) { if (lines == null) { throw new ArgumentNullException(nameof(lines)); } _lines = lines; _itemsToExclude = itemsToExclude; Count = lines.Count; }
public CRMProvider() { _obj = new Object(); _customerProvider = ModulesRegistrations.RegisterCRMModule().Resolve <ICustomerProvider>(); _packageProvider = ModulesRegistrations.RegisterCRMModule().Resolve <IPackageProvider>(); _customerTypeProvider = ModulesRegistrations.RegisterCRMModule().Resolve <ICustomerTypeProvider>(); _lineProvider = ModulesRegistrations.RegisterCRMModule().Resolve <ILineProvider>(); _packageIncludeProvider = ModulesRegistrations.RegisterCRMModule().Resolve <IPackageIncludeProvider>(); _selectedNumberProvider = ModulesRegistrations.RegisterCRMModule().Resolve <ISelectedNumberProvider>(); _smsProvider = ModulesRegistrations.RegisterCRMModule().Resolve <ISmsProvider>(); _callProvider = ModulesRegistrations.RegisterCRMModule().Resolve <ICallProvider>(); }
public ChooseLineViewModel(IExpandedNavigation navigationService, ILineProvider lineProvider) { _navigationService = navigationService; _lineProvider = lineProvider; Lines = new ObservableCollection<Line>(); NavigateToLineDetails = new RelayCommand(ExecuteNavigateToLineDetails); DownloadTickets(); }
public static ParseResult <GedcomEvent> Parse(GedcomLine first, ILineProvider lineProvider) { GedcomEvent gedcomEvent = new GedcomEvent(); var initialLevel = first.Level; GedcomLine line = default; ReadOnlySpan <char> currentRawLine; while ((currentRawLine = lineProvider.ReadLine()).Length > 0) { line = ParserHelper.ParseLine(currentRawLine); if (line.Level <= first.Level) { break; } ReadOnlySpan <char> tag = line.GetFirstItem(); if (ParserHelper.Equals(tag, "DATE")) { // If checks we're parsing actual date and not // CREA or CHAN tags // TODO: should actually put CREA and CHAN into different parser if (line.Level == initialLevel + 1) { var dateContent = line.GetLineContent(4); gedcomEvent.Date = dateContent.Length == 0 ? null : dateContent.ToString(); } } else if (ParserHelper.Equals(tag, "PLAC")) { // If checks we're parsing actual date and not // CREA or CHAN tags // TODO: should actually put CREA and CHAN into different parser if (line.Level == initialLevel + 1) { var placContent = line.GetLineContent(4); gedcomEvent.Location = placContent.Length == 0 ? null : placContent.ToString(); } } } return(ParseResult.Create(gedcomEvent, line)); }
public static ParseResult <GedcomEvent> Parse(GedcomLine first, ILineProvider lineProvider) { GedcomEvent gedcomEvent = new GedcomEvent(); var initialLevel = first.Level; GedcomLine line = default; string currentRawLine; while ((currentRawLine = lineProvider.ReadLine()) != null) { line = ParserHelper.ParseLine(currentRawLine); if (line.Level <= first.Level) { break; } switch (line.GetTagOrRef()) { case "DATE": // If checks we're parsing actual date and not // CREA or CHAN tags // TODO: should actually put CREA and CHAN into different parser if (line.Level == initialLevel + 1) { gedcomEvent.Date = line.GetLineContent(); } break; case "PLAC": // If checks we're parsing actual date and not // CREA or CHAN tags // TODO: should actually put CREA and CHAN into different parser if (line.Level == initialLevel + 1) { gedcomEvent.Location = line.GetLineContent(); } break; } } return(ParseResult.Create(gedcomEvent, line)); }
public GedcomInfo Import(ILineProvider lineProvider) { var individuals = new List <Individual>(); var families = new List <Family>(); var images = new List <Image>(); var notes = new List <Note>(); GedcomHeader gedcomHeader = null; GedcomStreamingParser gedcomStreamingParser = new GedcomStreamingParser( header => gedcomHeader = header, individual => individuals.Add(individual), family => families.Add(family), image => images.Add(image), note => notes.Add(note)); gedcomStreamingParser.Parse(lineProvider); var gedcomInfo = new GedcomInfo(individuals, families, images, notes, gedcomHeader, new List <string>()); return(gedcomInfo); }
public static ParseResult <Note> Parse(GedcomLine first, ILineProvider lineProvider) { string id = ParserHelper.ParseID(first.GetTagOrRef()); string text = null; var initialLevel = first.Level; GedcomLine line = default; string currentRawLine; while ((currentRawLine = lineProvider.ReadLine()) != null) { line = ParserHelper.ParseLine(currentRawLine); if (line.Level == first.Level) { break; } switch (line.GetTagOrRef()) { case "CONT": string contText = line.GetLineContent(); text += Environment.NewLine + contText; break; case "CONC": // TODO: is GenesReunited maintaining the trailing space? // If so, is this correct? string concText = line.GetLineContent(); text += concText; break; } } return(ParseResult.Create(new Note(id, text), line)); }
public static ParseResult <Note> Parse(GedcomLine first, ILineProvider lineProvider) { string id = ParserHelper.ParseID(first.GetFirstItem()).ToString(); string text = null; var initialLevel = first.Level; GedcomLine line = default; ReadOnlySpan <char> currentRawLine; while ((currentRawLine = lineProvider.ReadLine()).Length > 0) { line = ParserHelper.ParseLine(currentRawLine); if (line.Level == first.Level) { break; } ReadOnlySpan <char> tag = line.GetFirstItem(); if (ParserHelper.Equals(tag, "CONT")) { string contText = line.GetLineContent(4).ToString(); text += Environment.NewLine + contText; } else if (ParserHelper.Equals(tag, "CONC")) { // TODO: is GenesReunited maintaining the trailing space? // If so, is this correct? string concText = line.GetLineContent(4).ToString(); text += concText; } } return(ParseResult.Create(new Note(id, text), line)); }
public static ParseResult <Image> Parse(GedcomLine first, ILineProvider lineProvider) { var image = new Image(); image.ID = ParserHelper.ParseID(first.GetTagOrRef()); var initialLevel = first.Level; GedcomLine line = default; string currentRawLine; while ((currentRawLine = lineProvider.ReadLine()) != null) { line = ParserHelper.ParseLine(currentRawLine); if (line.Level == first.Level) { break; } switch (line.GetTagOrRef()) { case "TITL": var title = line.GetLineContent(); image.Title = title; break; case "FILE": var filePath = line.GetLineContent(); image.FilePath = filePath; break; } } return(ParseResult.Create(image, line)); }
public static ParseResult <Family> Parse(GedcomLine first, ILineProvider lineProvider) { var family = new Family(); family.ID = ParserHelper.ParseID(first.GetFirstItem()).ToString(); bool inMarriage = false; var initialLevel = first.Level; GedcomLine line = default; ReadOnlySpan <char> currentRawLine; while ((currentRawLine = lineProvider.ReadLine()).Length > 0) { line = ParserHelper.ParseLine(currentRawLine); if (line.Level == first.Level) { break; } var tag = line.GetFirstItem(); if (ParserHelper.Equals(tag, "MARR")) { inMarriage = true; } else if (ParserHelper.Equals(tag, "DATE")) { if (inMarriage) // TODO: should have MARR parser { var date = line.GetLineContent(4); if (family.Marriage == null) { family.Marriage = new GedcomEvent(); } family.Marriage.Date = date.ToString(); } } else if (ParserHelper.Equals(tag, "PLAC")) { if (inMarriage) // Assume level + 1 is MARR { var place = line.GetLineContent(4); if (family.Marriage == null) { family.Marriage = new GedcomEvent(); } family.Marriage.Location = place.ToString(); } } else if (ParserHelper.Equals(tag, "HUSB")) { // Ignore any husband and wife information in the middle of a marriage tag. // Present for torture test files - and info redundant? // can have e.g. "2 HUSB", with no additional info var husbContent = line.GetLineContent(4); if (husbContent.Length > 0) { family.HusbandID = ParserHelper.ParseID(husbContent).ToString(); } } else if (ParserHelper.Equals(tag, "WIFE")) { var wifeContent = line.GetLineContent(4); // Ignore any husband and wife information in the middle of a marriage tag. // Present for torture test files - and info redundant? // can have e.g. "2 HUSB", with no additional info if (wifeContent.Length > 0) { family.WifeID = ParserHelper.ParseID(wifeContent).ToString(); } } else if (ParserHelper.Equals(tag, "CHIL")) { var childContent = line.GetLineContent(4); family.ChildIDs.Add(ParserHelper.ParseID(childContent).ToString()); } else { inMarriage = false; } } return(ParseResult.Create(family, line)); }
/// <summary> /// finds the optimal breakpoints in the item sequence /// </summary> /// <param name="tolerance"> indicates the tolerance for suboptimal lines </param> /// <param name="lineProvider"> the line provider </param> /// <param name="isOverfullAllowed"> indicates whether overfull lines are permitted </param> /// <returns> <c>true</c> if the sequence of items was successfully broken into lines; otherwise, <c>false</c> </returns> private bool FindBreakpointsInternal( double tolerance, ILineProvider lineProvider, bool isOverfullAllowed) { Contract.Requires(Check.IsFinite(tolerance)); Contract.Requires(tolerance >= 1.0); Contract.Requires(lineProvider != null); _Active.AddFirst(Breakpoint.Empty); _RunningWidthSum = 0.0; _RunningStretchSum = 0.0; _RunningShrinkSum = 0.0; for(int i = 0; i < _Items.Count; ++i) { LineItem item = _Items[i]; if(ExaminingItem != null) { ExaminingItem(ref item); } // analyze each possible breaking point if(IsFeasibleBreakpoint(i)) { AnalyzeBreakpoint(i, tolerance, lineProvider); } if(ItemExamined != null) { ItemExamined(ref item); } _RunningWidthSum += !item.IsPenalty ? item.Width : 0.0; _RunningStretchSum += item.IsGlue ? item.Stretch : 0.0; _RunningShrinkSum += item.IsGlue ? item.Shrink : 0.0; } Breakpoint breakpoint; if(_Active.Count == 0) { if(isOverfullAllowed) { // panic by using the last known breaking point breakpoint = _LastDeactivated; } else { // no possible breaking points with the given tolerance _Indices.Clear(); return false; } } else { LinkedListNode<Breakpoint> activeNode = _Active.First; for(var node = _Active.First; node != null; node = node.Next) { // select the tree-line having the least demerits if(node.Value.Demerits < activeNode.Value.Demerits) { activeNode = node; } } breakpoint = activeNode.Value; } _Active.Clear(); _Indices.Clear(); while(breakpoint != null) { // add each breaking point in the chain _Indices.Add(new BreakIndex(breakpoint.Position, breakpoint.Ratio)); breakpoint = breakpoint.Previous; } _Indices.Reverse(); _LastDeactivated = null; return true; }
/// <summary> /// computes the ratio for the given line and node /// </summary> /// <param name="indexItem"> indicates the index of the line item </param> /// <param name="activeNode"> the active breakpoint node </param> /// <param name="lineNumber"> indicates the active line number </param> /// <param name="lineProvider"> the line provider </param> /// <returns> the ratio of the line. </returns> private double ComputeRatio( ref LineItem indexItem, LinkedListNode<Breakpoint> activeNode, int lineNumber, ILineProvider lineProvider) { Contract.Requires(lineNumber >= 0); Contract.Requires(activeNode != null); Contract.Requires(lineProvider != null); double length = _RunningWidthSum - activeNode.Value.TotalWidth; if(indexItem.IsPenalty) { length = length + indexItem.Width; } double availableLength = lineProvider.ProduceLine(lineNumber); if(length < availableLength) { double y = _RunningStretchSum - activeNode.Value.TotalStretch; return y > 0.0 ? (availableLength - length) / y : LineItem.Infinity; } if(length > availableLength) { double z = _RunningShrinkSum - activeNode.Value.TotalShrink; return z > 0.0 ? (availableLength - length) / z : LineItem.Infinity; } return 0.0; }
/// <summary> /// analyzes a node /// </summary> /// <param name="activeNode"> the active node </param> /// <param name="index"> indicates the index of the item </param> /// <param name="tolerance"> indicates the tolerance for badness </param> /// <param name="lineProvider"> the line provider </param> /// <returns> the next node </returns> private LinkedListNode<Breakpoint> AnalyzeNode( LinkedListNode<Breakpoint> activeNode, int index, double tolerance, ILineProvider lineProvider) { Contract.Requires(activeNode != null); Contract.Requires(index >= 0); Contract.Requires(Check.IsFinite(tolerance)); Contract.Requires(tolerance >= 1.0); Contract.Requires(lineProvider != null); LinkedListNode<Breakpoint> nextNode = activeNode.Next; int currentLine = activeNode.Value.Line; LineItem indexItem = _Items[index]; double ratio = ComputeRatio( ref indexItem, activeNode, currentLine, lineProvider); if(ratio < -1.0 || indexItem.IsForcedBreak) { _Active.Remove(activeNode); _LastDeactivated = activeNode.Value; } if(ratio >= -1.0 && ratio <= tolerance) { Demerits demerits = indexItem.ComputeDemerits(ratio / tolerance); demerits = indexItem.CombineFlaggedDemerits( _Items[activeNode.Value.Position], demerits); LineFitness fitness = LineFitness.FromLineRatio(ratio / tolerance); if(fitness.MeasureFitnessGap(activeNode.Value.Fitness) > 1) { demerits += Demerits.FitnessPenalty; } demerits += activeNode.Value.Demerits; if(demerits < _Candidates[fitness].Demerits) { double totalWidth; double totalShrink; double totalStretch; ComputeSum(index, out totalWidth, out totalShrink, out totalStretch); _Candidates[fitness] = new Breakpoint( index, currentLine + 1, fitness, totalWidth, totalStretch, totalShrink, demerits, ratio, activeNode.Value); _MinimumCandidate = Math.Min(_MinimumCandidate.Value, demerits.Value); } } return nextNode; }
/// <summary> /// analyzes a breaking point /// </summary> /// <param name="index"> indicates the index of the breaking point </param> /// <param name="tolerance"> indicates the tolerance for badness </param> /// <param name="lineProvider"> the line provider </param> private void AnalyzeBreakpoint( int index, double tolerance, ILineProvider lineProvider) { Contract.Requires(index >= 0); Contract.Requires(Check.IsFinite(tolerance)); Contract.Requires(tolerance >= 1.0); Contract.Requires(lineProvider != null); LinkedListNode<Breakpoint> activeNode = _Active.First; while(activeNode != null) { _MinimumCandidate = Demerits.Infinity; _Candidates[0] = Breakpoint.MaxDemerits; _Candidates[1] = Breakpoint.MaxDemerits; _Candidates[2] = Breakpoint.MaxDemerits; _Candidates[3] = Breakpoint.MaxDemerits; while(activeNode != null) { activeNode = AnalyzeNode(activeNode, index, tolerance, lineProvider); } if(_MinimumCandidate < Demerits.Infinity) { Demerits limit = _MinimumCandidate + Demerits.FitnessPenalty; foreach(Breakpoint candidate in _Candidates) { if(candidate.Demerits <= limit) { _Active.AddLast(candidate); } } } } }
/// <summary> /// finds the optimal breakpoints in the item sequence /// </summary> /// <param name="tolerance"> indicates the tolerance for suboptimal lines </param> /// <param name="lineProvider"> the line provider </param> /// <param name="isOverfullAllowed"> indicates whether overfull lines are permitted </param> /// <returns> <c>true</c> if the sequence of items was successfully broken into lines; otherwise, <c>false</c> </returns> public bool FindBreakpoints( double tolerance, ILineProvider lineProvider, bool isOverfullAllowed) { Contract.Requires(Check.IsFinite(tolerance)); Contract.Requires(tolerance >= 1.0); Contract.Requires(lineProvider != null); Contract.Assert(_IsActive); if(_Items.Count > 0) { return FindBreakpointsInternal(tolerance, lineProvider, isOverfullAllowed); } return false; }
//TODO: tolerance should probably be a property //TODO: emergency stretch should probably be a property /// <summary> /// finds the optimal breakpoints in the item sequence /// </summary> /// <param name="tolerance"> indicates the tolerance for suboptimal lines </param> /// <param name="lineProvider"> the line provider </param> /// <returns> <c>true</c> if the sequence of items was successfully broken into lines; otherwise, <c>false</c> </returns> public bool FindBreakpoints(double tolerance, ILineProvider lineProvider) { Contract.Requires(Check.IsFinite(tolerance)); Contract.Requires(tolerance >= 1.0); Contract.Requires(lineProvider != null); Contract.Assert(_IsActive); return FindBreakpoints(tolerance, lineProvider, false); }
internal StationInfosProvider(IStationsProvider stationsProvider, ILineProvider lineProvider) { _stationsProvider = stationsProvider; _lineProvider = lineProvider; }
public static ParseResult <GedcomHeader> Parse(GedcomLine first, ILineProvider lineProvider) { CurrentLevel currentLevel = CurrentLevel.None; var header = new GedcomHeader(); GedcomLine line = default; string currentRawLine; while ((currentRawLine = lineProvider.ReadLine()) != null) { line = ParserHelper.ParseLine(currentRawLine); if (line.Level == 0) { break; } if (line.Level == 1) { switch (line.GetTagOrRef()) { case "SOUR": currentLevel = CurrentLevel.Sour; break; case "GEDC": currentLevel = CurrentLevel.Gedc; break; case "CHAR": header.GedcomCharacterSet = line.GetLineContent(); break; } } else if (line.Level == 2) { if (currentLevel == CurrentLevel.Sour) { switch (line.GetTagOrRef()) { case "NAME": header.SourceName = line.GetLineContent(); break; case "VERS": header.SourceVers = line.GetLineContent(); break; case "CORP": header.SourceCorp = line.GetLineContent(); break; } } else if (currentLevel == CurrentLevel.Gedc) { if (line.GetTagOrRef() == "VERS") { header.GedcomVers = line.GetLineContent(); } } } } return(ParseResult.Create(header, line)); }
public static ParseResult <GedcomHeader> Parse(GedcomLine first, ILineProvider lineProvider) { CurrentLevel currentLevel = CurrentLevel.None; var header = new GedcomHeader(); GedcomLine line = default; ReadOnlySpan <char> currentRawLine; while ((currentRawLine = lineProvider.ReadLine()).Length > 0) { line = ParserHelper.ParseLine(currentRawLine); if (line.Level == 0) { break; } if (line.Level == 1) { var tag = line.GetFirstItem(); if (ParserHelper.Equals(tag, "SOUR")) { currentLevel = CurrentLevel.Sour; } else if (ParserHelper.Equals(tag, "GEDC")) { currentLevel = CurrentLevel.Gedc; } else if (ParserHelper.Equals(tag, "CHAR")) { header.GedcomCharacterSet = line.GetLineContent(4).ToString(); } } else if (line.Level == 2) { if (currentLevel == CurrentLevel.Sour) { var tag = line.GetFirstItem(); if (ParserHelper.Equals(tag, "NAME")) { header.SourceName = line.GetLineContent(4).ToString(); } else if (ParserHelper.Equals(tag, "VERS")) { header.SourceVers = line.GetLineContent(4).ToString(); } else if (ParserHelper.Equals(tag, "CORP")) { header.SourceCorp = line.GetLineContent(4).ToString(); } } else if (currentLevel == CurrentLevel.Gedc) { if (ParserHelper.Equals(line.GetFirstItem(), "VERS")) { header.GedcomVers = line.GetLineContent(4).ToString(); } } } } return(ParseResult.Create(header, line)); }
public void Parse(ILineProvider lineProvider) { GedcomLine lastLine = default; var firstRawLine = lineProvider.ReadLine(); if (firstRawLine == null) { throw new InvalidOperationException("File empty"); } var firstLine = ParserHelper.ParseLine(firstRawLine); if (firstLine.Level != 0 && !ParserHelper.Equals(firstLine.GetFirstItem(), "HEAD")) { throw new InvalidOperationException("GEDCOM Header Not Found"); } var gedcomHeaderParse = HeaderParser.Parse(firstLine, lineProvider); _headerCallback?.Invoke(gedcomHeaderParse.Result); var newLine = gedcomHeaderParse.Line; lastLine = newLine; while (newLine.LineContent.Length > 0) { var content = newLine.GetLineContent(); if (content.Length == 0) { var unrecognisedRawLine = lineProvider.ReadLine(); if (unrecognisedRawLine != null) { newLine = ParserHelper.ParseLine(unrecognisedRawLine); lastLine = newLine; } else { newLine = default; } continue; } var unknown = false; if (ParserHelper.Equals(content, "INDI")) { var individualParseResult = IndividualParser.Parse(newLine, lineProvider); _individualCallback?.Invoke(individualParseResult.Result); newLine = individualParseResult.Line; lastLine = newLine; } else if (ParserHelper.Equals(content, "FAM")) { var familyParseResult = FamilyParser.Parse(newLine, lineProvider); _familyCallback?.Invoke(familyParseResult.Result); newLine = familyParseResult.Line; lastLine = newLine; } else if (ParserHelper.Equals(content, "NOTE")) { var noteParseResult = NoteParser.Parse(newLine, lineProvider); _noteCallback?.Invoke(noteParseResult.Result); newLine = noteParseResult.Line; lastLine = newLine; } else if (ParserHelper.Equals(content, "OBJE")) { var objParserResult = ObjectParser.Parse(newLine, lineProvider); _imageCallback?.Invoke(objParserResult.Result); newLine = objParserResult.Line; lastLine = newLine; } else { var unrecognisedRawLine = lineProvider.ReadLine(); if (unrecognisedRawLine != null) { newLine = ParserHelper.ParseLine(unrecognisedRawLine); lastLine = newLine; } else { newLine = default; } unknown = true; } if (unknown) { continue; } } if (lastLine.LineContent.Length == 0) { throw new InvalidOperationException("file contains no content"); } if (lastLine.Level != 0 || !ParserHelper.Equals(lastLine.GetFirstItem(), "TRLR")) { throw new InvalidOperationException("GEDCOM TRLR not found"); } }
public static ParseResult <Individual> Parse(GedcomLine first, ILineProvider lineProvider) { var individual = new Individual(); individual.ID = ParserHelper.ParseID(first.GetTagOrRef()); GedcomLine line = default; string currentRawLine; var newLine = false; while (true) { // TODO: this loop is really messy, as some of the parsing // works on lines as retrieved from the parser, where some // other iterations call onto a sub-parser which return a final // line. Should split this logic if (!newLine) { currentRawLine = lineProvider.ReadLine(); if (currentRawLine == null) { break; } line = ParserHelper.ParseLine(currentRawLine); } newLine = false; if (line.Level == 0) { break; } switch (line.GetTagOrRef()) { case "NAME": if (individual.LastName != null || individual.FirstNames != null) { break; } ParseNames(line, individual); break; case "SEX": individual.Gender = (line.GetLineContent() == "M") ? Gender.Male : Gender.Female; break; case "FAMS": individual.FamilyIDSpouse = ParserHelper.ParseID(line.GetLineContent()); break; case "FAMC": individual.FamilyIDChild = ParserHelper.ParseID(line.GetLineContent()); break; case "OBJE": var objeContent = line.GetLineContent(); if (!string.IsNullOrEmpty(objeContent)) // TODO: test for this - currently don't support Images directly in Individual // should fix this { individual.ImageID = ParserHelper.ParseID(objeContent); } break; case "NOTE": string noteText = line.GetLineContent() ?? string.Empty; // My be an empty NOTE tag, but will be concatenated onto if (noteText.StartsWith("@")) { string noteId = ParserHelper.ParseID(noteText); individual.NoteID = noteId; } else { individual.Note = noteText; } break; case "CONT": string contText = line.GetLineContent() ?? string.Empty; individual.Note += Environment.NewLine + contText; break; case "CONC": // TODO: is GenesReunited maintaining the trailing space? // If so, is this correct? var concText = line.GetLineContent(); individual.Note += concText; break; case "BIRT": var birthParseResult = EventParser.Parse(line, lineProvider); if (individual.Birth == null) { individual.Birth = birthParseResult.Result; } line = birthParseResult.Line; newLine = true; break; case "DEAT": var deathParseResult = EventParser.Parse(line, lineProvider); if (individual.Death == null) { individual.Death = deathParseResult.Result; } line = deathParseResult.Line; newLine = true; break; case "BAPM": var baptismParseResult = EventParser.Parse(line, lineProvider); if (individual.Baptism == null) { individual.Baptism = baptismParseResult.Result; } line = baptismParseResult.Line; newLine = true; break; case "RESI": var residenceParseResult = EventParser.Parse(line, lineProvider); individual.Residences.Add(residenceParseResult.Result); line = residenceParseResult.Line; newLine = true; break; case "CENS": var censusParseResult = EventParser.Parse(line, lineProvider); individual.Census.Add(censusParseResult.Result); line = censusParseResult.Line; newLine = true; break; case "MARR": var marriageParseResult = EventParser.Parse(line, lineProvider); if (marriageParseResult.Result != null) { individual.Marriages.Add(marriageParseResult.Result); } line = marriageParseResult.Line; newLine = true; // TODO: cope with multiple marriage records // It seems that ancestry only outputs multiple marriage records in an individual // if there's conflicting information, not for multiple marriages // Multiple marriages for an individual are put into the FAMs tag break; //case "ENGA": // // TODO: // // individual.Engagement = EventParser.Parse(parserLinesEnga); // break; } if (line.Level == 0) { break; } } if (individual.LastName == null) { individual.LastName = string.Empty; } if (individual.FirstName == null) { individual.FirstName = string.Empty; } if (individual.FirstNames == null) { individual.FirstNames = string.Empty; } return(ParseResult.Create(individual, line)); }
public static ParseResult <Family> Parse(GedcomLine first, ILineProvider lineProvider) { var family = new Family(); family.ID = ParserHelper.ParseID(first.GetTagOrRef()); bool inMarriage = false; var initialLevel = first.Level; GedcomLine line = default; string currentRawLine; while ((currentRawLine = lineProvider.ReadLine()) != null) { line = ParserHelper.ParseLine(currentRawLine); if (line.Level == first.Level) { break; } switch (line.GetTagOrRef()) { case "MARR": { inMarriage = true; break; } case "DATE": if (inMarriage) // TODO: should have MARR parser { var date = line.GetLineContent(); if (family.Marriage == null) { family.Marriage = new GedcomEvent(); } family.Marriage.Date = date; } break; case "PLAC": if (inMarriage) // Assume level + 1 is MARR { var place = line.GetLineContent(); if (family.Marriage == null) { family.Marriage = new GedcomEvent(); } family.Marriage.Location = place; } break; case "HUSB": // Ignore any husband and wife information in the middle of a marriage tag. // Present for torture test files - and info redundant? // can have e.g. "2 HUSB", with no additional info var contentHusb = line.GetLineContent(); if (!string.IsNullOrEmpty(contentHusb)) { family.HusbandID = ParserHelper.ParseID(contentHusb); } break; case "WIFE": // Ignore any husband and wife information in the middle of a marriage tag. // Present for torture test files - and info redundant? // can have e.g. "2 HUSB", with no additional info var contentWife = line.GetLineContent(); if (!string.IsNullOrEmpty(contentWife)) { family.WifeID = ParserHelper.ParseID(contentWife); } break; case "CHIL": family.ChildIDs.Add(ParserHelper.ParseID(line.GetLineContent())); break; default: inMarriage = false; break; } } return(ParseResult.Create(family, line)); }
// IoC - Inversion of Control public ShareProvider(ILineProvider provider, ICsvLineParser lineParser) { this.lineParser = lineParser; lineProvider = provider; }
public static ParseResult <Individual> Parse(GedcomLine first, ILineProvider lineProvider) { var individual = new Individual(); individual.ID = ParserHelper.ParseID(first.GetFirstItem()).ToString(); GedcomLine line = default; ReadOnlySpan <char> currentRawLine; var newLine = false; while (true) { // TODO: this loop is really messy, as some of the parsing // works on lines as retrieved from the parser, where some // other iterations call onto a sub-parser which return a final // line. Should split this logic if (!newLine) { currentRawLine = lineProvider.ReadLine(); if (currentRawLine == null) { break; } line = ParserHelper.ParseLine(currentRawLine); } newLine = false; if (line.Level == 0) { break; } var tag = line.GetFirstItem(); if (ParserHelper.Equals(tag, "NAME") && individual.LastName == null && individual.FirstNames == null) { ParseNames(line, individual); } else if (ParserHelper.Equals(tag, "SEX")) { individual.Gender = ParserHelper.Equals(line.GetLineContent(3), "M") ? Gender.Male : Gender.Female; } else if (ParserHelper.Equals(tag, "FAMS")) { individual.FamilyIDSpouse = ParserHelper.ParseID(line.GetLineContent(4)).ToString(); } else if (ParserHelper.Equals(tag, "FAMC")) { individual.FamilyIDChild = ParserHelper.ParseID(line.GetLineContent(4)).ToString(); } else if (ParserHelper.Equals(tag, "OBJE")) { var content = line.GetLineContent(4); if (content.Length > 0) { individual.ImageID = ParserHelper.ParseID(content).ToString(); } } else if (ParserHelper.Equals(tag, "NOTE")) { var noteContent = line.GetLineContent(4); if (noteContent.Length > 0) { if (noteContent[0] == '@') { individual.NoteID = ParserHelper.ParseID(noteContent).ToString(); } else { individual.Note = noteContent.ToString(); } } } else if (ParserHelper.Equals(tag, "CONT")) { var contContent = line.GetLineContent(4); individual.Note += Environment.NewLine + contContent.ToString(); } else if (ParserHelper.Equals(tag, "CONC")) { // TODO: is GenesReunited maintaining the trailing space? // If so, is this correct? var concContent = line.GetLineContent(4); if (concContent.Length > 0) { individual.Note += concContent.ToString(); } } else if (ParserHelper.Equals(tag, "BIRT")) { var birthParseResult = EventParser.Parse(line, lineProvider); if (individual.Birth == null) { individual.Birth = birthParseResult.Result; } line = birthParseResult.Line; newLine = true; } else if (ParserHelper.Equals(tag, "DEAT")) { var deathParseResult = EventParser.Parse(line, lineProvider); if (individual.Death == null) { individual.Death = deathParseResult.Result; } line = deathParseResult.Line; newLine = true; } else if (ParserHelper.Equals(tag, "BAPM")) { var baptismParseResult = EventParser.Parse(line, lineProvider); if (individual.Baptism == null) { individual.Baptism = baptismParseResult.Result; } line = baptismParseResult.Line; newLine = true; } else if (ParserHelper.Equals(tag, "RESI")) { var residenceParseResult = EventParser.Parse(line, lineProvider); individual.Residences.Add(residenceParseResult.Result); line = residenceParseResult.Line; newLine = true; } else if (ParserHelper.Equals(tag, "CENS")) { var censusParseResult = EventParser.Parse(line, lineProvider); individual.Census.Add(censusParseResult.Result); line = censusParseResult.Line; newLine = true; } else if (ParserHelper.Equals(tag, "MARR")) { var marriageParseResult = EventParser.Parse(line, lineProvider); if (marriageParseResult.Result != null) { individual.Marriages.Add(marriageParseResult.Result); } line = marriageParseResult.Line; newLine = true; // TODO: cope with multiple marriage records // It seems that ancestry only outputs multiple marriage records in an individual // if there's conflicting information, not for multiple marriages // Multiple marriages for an individual are put into the FAMs tag } //case "ENGA": // // TODO: // // individual.Engagement = EventParser.Parse(parserLinesEnga); // break; if (line.Level == 0) { break; } } if (individual.LastName == null) { individual.LastName = string.Empty; } if (individual.FirstName == null) { individual.FirstName = string.Empty; } if (individual.FirstNames == null) { individual.FirstNames = string.Empty; } return(ParseResult.Create(individual, line)); }