private DataRow ParseCSVRow(CSVParsingContext pc, string[] rgszRow, int iRow) { int cColExpected = rgszRow.Length + pc.derivedColumnCount; if (cColExpected < ParsedData.Columns.Count) { throw new MyFlightbookException(String.Format(CultureInfo.CurrentCulture, Resources.FlightData.errNotEnoughColumns, iRow)); } if (cColExpected > ParsedData.Columns.Count) { throw new MyFlightbookException(String.Format(CultureInfo.CurrentCulture, Resources.FlightData.errTooManyColumns, iRow)); } DataRow dr = ParsedData.NewRow(); for (int j = 0; j < rgszRow.Length; j++) { dr[j] = pc.ColumnList[j].ParseToType(rgszRow[j].Trim()); } // derive time, if necessary if (pc.fDeriveDateTime) { DateTime dtNakedDate = (DateTime)dr[KnownColumnNames.NakedDate]; DateTime dtNakedTime = (DateTime)dr[KnownColumnNames.NakedTime]; int tzOffset = (pc.fHasTimezone) ? (int)dr[ParsedData.TimeZoneHeader] : 0; dr[KnownColumnNames.UTCDateTime] = DateTime.SpecifyKind(new DateTime(dtNakedDate.Year, dtNakedDate.Month, dtNakedDate.Day, dtNakedTime.Hour, dtNakedTime.Minute, dtNakedTime.Second, pc.fHasTimezone ? DateTimeKind.Unspecified : DateTimeKind.Utc).AddMinutes(tzOffset), DateTimeKind.Utc); } if (pc.fDeriveUTCDateTime) { DateTime dt = (DateTime)dr[pc.szDateCol]; dr[KnownColumnNames.UTCDateTime] = DateTime.SpecifyKind(dt.AddMinutes((int)dr[ParsedData.TimeZoneHeader]), DateTimeKind.Utc); } // derive speed, if necessary if (pc.fDeriveSpeed) { Position samp = new Position(Convert.ToDouble(dr[KnownColumnNames.LAT], CultureInfo.CurrentCulture), Convert.ToDouble(dr[KnownColumnNames.LON], CultureInfo.CurrentCulture), Convert.ToDateTime(dr[pc.szDateCol], CultureInfo.CurrentCulture)); pc.SamplesList.Add(samp); } return(dr); }
public override bool Parse(string szData) { StringBuilder sbErr = new StringBuilder(); TelemetryDataTable m_dt = ParsedData; m_dt.Clear(); Boolean fResult = true; string flightData = FixedFlightData(szData); using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(flightData))) { using (CSVReader csvr = new CSVReader(ms)) { try { string[] rgszHeader = null; // Find the first row that looks like columns. try { do { rgszHeader = csvr.GetCSVLine(true); } while (rgszHeader != null && (rgszHeader.Length < 2 || rgszHeader[0].StartsWith("#", StringComparison.OrdinalIgnoreCase) || rgszHeader[0].Contains("Date (yyyy-mm-dd)"))); } catch (CSVReaderInvalidCSVException ex) { throw new MyFlightbookException(ex.Message); } if (rgszHeader == null) // no valid CSV header found { sbErr.Append(Resources.FlightData.errNoCSVHeaderRowFound); return(false); } CSVParsingContext pc = new CSVParsingContext(); SetUpContextFromHeaderRow(pc, rgszHeader); string[] rgszRow = null; int iRow = 0; while ((rgszRow = csvr.GetCSVLine()) != null) { iRow++; try { m_dt.Rows.Add(ParseCSVRow(pc, FixRowHack(rgszRow, rgszHeader), iRow)); } catch (MyFlightbookException ex) { sbErr.Append(String.Format(CultureInfo.CurrentCulture, Resources.FlightData.errInRow, iRow, ex.Message)); fResult = false; } catch (System.FormatException ex) { sbErr.Append(String.Format(CultureInfo.CurrentCulture, Resources.FlightData.errInRow, iRow, ex.Message)); fResult = false; } } // Go back and put the derived speeds in. if (pc.fDeriveSpeed) { Position.DeriveSpeed(pc.SamplesList); for (int i = 0; i < m_dt.Rows.Count && i < pc.SamplesList.Count; i++) { if (pc.SamplesList[i].HasSpeed) { m_dt.Rows[i][KnownColumnNames.DERIVEDSPEED] = pc.SamplesList[i].Speed; } } } } catch (MyFlightbookException ex) { sbErr.Append(String.Format(CultureInfo.CurrentCulture, Resources.FlightData.errGeneric, ex.Message)); fResult = false; } catch (System.Data.DuplicateNameException ex) { sbErr.Append(String.Format(CultureInfo.CurrentCulture, Resources.FlightData.errGeneric, ex.Message)); fResult = false; } finally { } } } ErrorString = sbErr.ToString(); return(fResult); }
private void SetUpContextFromHeaderRow(CSVParsingContext pc, string[] rgszHeader) { // This is a hack for JPI date, which has a "DATE" and a "TIME" column, which are actually both naked. So effectively re-name them to indicate naked int iDateCol = -1; int iTimeCol = -1; for (int i = 0; i < rgszHeader.Length; i++) { if (String.Compare(rgszHeader[i], KnownColumnNames.DATE, StringComparison.CurrentCultureIgnoreCase) == 0) { iDateCol = i; } if (String.Compare(rgszHeader[i], KnownColumnNames.TIME, StringComparison.CurrentCultureIgnoreCase) == 0) { iTimeCol = i; } } if (iDateCol >= 0 && iTimeCol >= 0) { rgszHeader[iDateCol] = "LOCAL DATE"; rgszHeader[iTimeCol] = "LOCAL TIME"; } for (int i = 0; i < rgszHeader.Length; i++) { KnownColumn kc = KnownColumn.GetKnownColumn(rgszHeader[i].Trim()); pc.ColumnList.Add(kc); if (kc.Type == KnownColumnTypes.ctNakedDate) { pc.fHasNakedDate = true; } if (kc.Type == KnownColumnTypes.ctNakedTime) { pc.fHasNakedTime = true; } ParsedData.Columns.Add(new DataColumn(kc.ColumnHeaderName, KnownColumn.ColumnDataType(kc.Type))); } pc.fDeriveDateTime = pc.fHasNakedTime && pc.fHasNakedDate && !ParsedData.HasDateTime; if (pc.fDeriveDateTime) { KnownColumn kc = KnownColumn.GetKnownColumn(KnownColumnNames.UTCDateTime); pc.ColumnList.Add(kc); DataColumn dc = new DataColumn(kc.Column, KnownColumn.ColumnDataType(kc.Type)); ParsedData.Columns.Add(dc); dc.DateTimeMode = DataSetDateTime.Utc; pc.derivedColumnCount++; } pc.fHasDateTime = ParsedData.HasDateTime; pc.fHasTimezone = ParsedData.HasTimezone; pc.szDateCol = ParsedData.DateColumn; // Set this before deriving a UTCDateTime so that when we derive UTCDateTime, we don't try to read from it. if (pc.fHasDateTime && pc.fHasTimezone && !ParsedData.HasUTCDateTime) // add a UTC time as well { pc.fDeriveUTCDateTime = true; KnownColumn kc = KnownColumn.GetKnownColumn(KnownColumnNames.UTCDateTime); pc.ColumnList.Add(kc); ParsedData.Columns.Add(new DataColumn(kc.Column, KnownColumn.ColumnDataType(kc.Type))); pc.derivedColumnCount++; } pc.fDeriveSpeed = (ParsedData.HasLatLongInfo && pc.fHasDateTime && !ParsedData.HasSpeed); if (pc.fDeriveSpeed) { KnownColumn kc = KnownColumn.GetKnownColumn(KnownColumnNames.DERIVEDSPEED); pc.ColumnList.Add(kc); ParsedData.Columns.Add(new DataColumn(kc.Column, KnownColumn.ColumnDataType(kc.Type))); pc.derivedColumnCount++; } }