Skip to content

Commit f7361b5

Browse files
committed
Fixed issue with Quoting Control not modifying setting.
FIxed issue with file modification showing many dialog boxes Fixed issue with leading spaces if no trimming is selected Ignoring rows with single column if we expect more than 3 columns Changed GetIdFromFileName Supporting LongPath in improved stream
1 parent 1bf0083 commit f7361b5

20 files changed

+406
-248
lines changed

Application/FormMain.Designer.cs

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Application/FormMain.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,9 @@ private void DisableIgnoreRead()
227227
private void Display_Activated(object sender, EventArgs e)
228228
{
229229
if (!m_FileChanged) return;
230-
231-
if (MessageBox.Show(this, "The displayed file has changed do you want to reload the data?", "File changed", MessageBoxButtons.YesNo) == DialogResult.Yes) OpenDataReader(true);
230+
m_FileChanged = false;
231+
if (_MessageBox.Show(this, "The displayed file has changed do you want to reload the data?", "File changed", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
232+
OpenDataReader(true);
232233
}
233234

234235
private void Display_FormClosing(object sender, FormClosingEventArgs e)
@@ -294,7 +295,6 @@ private void Display_Shown(object sender, EventArgs e)
294295
}
295296

296297
if (doClose) return;
297-
fileSystemWatcher.EnableRaisingEvents = Settings.Default.DetectFileChanges;
298298
OpenDataReader(false);
299299
}
300300

@@ -528,9 +528,11 @@ private bool InitFileSettings()
528528
/// </summary>
529529
private void OpenDataReader(bool clear)
530530
{
531-
m_SettingsChangedTimerChange.Stop();
532531
if (m_FileSetting == null) return;
533532

533+
m_SettingsChangedTimerChange.Stop();
534+
fileSystemWatcher.EnableRaisingEvents = false;
535+
534536
var oldCursor = Cursor.Current == Cursors.WaitCursor ? Cursors.WaitCursor : Cursors.Default;
535537
Cursor.Current = Cursors.WaitCursor;
536538

@@ -610,6 +612,7 @@ private void OpenDataReader(bool clear)
610612
col.PropertyChanged += FileSetting_PropertyChanged;
611613
}
612614
m_ConfigChanged = false;
615+
fileSystemWatcher.EnableRaisingEvents = Settings.Default.DetectFileChanges;
613616
m_FileChanged = false;
614617
// Re enable event watching
615618
m_FileSetting.PropertyChanged += FileSetting_PropertyChanged;
@@ -621,7 +624,7 @@ private void SaveSetting()
621624
try
622625
{
623626
var pathSetting = m_FileSetting.FileName + CsvFile.cCsvSettingExtension;
624-
m_FileSetting.FileName = m_FileSetting.FileName.Substring(m_FileSetting.FileName.LastIndexOf('\\'));
627+
m_FileSetting.FileName = FileSystemUtils.SplitPath(m_FileSetting.FileName).FileName;
625628
var answer = DialogResult.No;
626629

627630
if (FileSystemUtils.FileExists(pathSetting))

Library/ClassLibraryCSV/BaseFileWriter.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,23 @@ public virtual IDataReader GetOpenDataReader(uint recordLimit)
215215
return null;
216216
}
217217

218+
public virtual IDataReader GetOpenSourceReader(uint recordLimit)
219+
{
220+
var sourceSetting = GetSourceSetting();
221+
if (sourceSetting == null)
222+
{
223+
// Using the connection string
224+
if (string.IsNullOrEmpty(m_FileSetting.SqlStatement)) return null;
225+
return ApplicationSetting.SQLDataReader(m_FileSetting.SqlStatement);
226+
}
227+
else
228+
{
229+
var reader = sourceSetting.GetFileReader();
230+
reader.Open(m_CancellationToken, true);
231+
return reader;
232+
}
233+
}
234+
218235
/// <summary>
219236
/// Gets the source data table.
220237
/// </summary>

Library/ClassLibraryCSV/CsvFileReader.cs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -706,11 +706,10 @@ private bool GetNextRecord()
706706
bool hasWarningCombinedWrning = false;
707707
Restart2:
708708
var rowLength = CurrentRowColumnText.Length;
709-
710709
if (rowLength == FieldCount)
711710
{
712711
// Check if we have row that matches the header row
713-
if (m_HeaderRow != null && m_CsvFile.HasFieldHeader)
712+
if (m_HeaderRow != null && m_CsvFile.HasFieldHeader && !hasWarningCombinedWrning)
714713
{
715714
bool isRepeatedHeader = true;
716715
for (int col = 0; col < FieldCount; col++)
@@ -740,11 +739,11 @@ private bool GetNextRecord()
740739
var oldPos = m_BufferPos;
741740
var startLine = StartLineNumber;
742741
// get the next row
743-
var nextRow = ReadNextRow(true, true);
742+
var nextLine = ReadNextRow(true, true);
744743
StartLineNumber = startLine;
745744

746745
// allow up to two extra columns they can be combined later
747-
if (nextRow.Length > 0 && nextRow.Length + rowLength < FieldCount + 4)
746+
if (nextLine.Length > 0 && nextLine.Length + rowLength < FieldCount + 4)
748747
{
749748
var combined = new List<string>(CurrentRowColumnText);
750749

@@ -753,14 +752,14 @@ private bool GetNextRecord()
753752
m_NumWarningsLinefeed++;
754753
HandleWarning(rowLength - 1,
755754
$"Added first column from line {EndLineNumber}, assuming a linefeed has split the rows into an additional line.");
756-
combined[rowLength - 1] += ' ' + nextRow[0];
755+
combined[rowLength - 1] += ' ' + nextLine[0];
757756

758-
for (int col = 1; col < nextRow.Length; col++)
759-
combined.Add(nextRow[col]);
757+
for (int col = 1; col < nextLine.Length; col++)
758+
combined.Add(nextLine[col]);
760759

761760
if (!hasWarningCombinedWrning)
762761
{
763-
HandleWarning(-1, $"Line {StartLineNumber}{cLessColumns}. Rows have been combined.");
762+
HandleWarning(-1, $"Line {StartLineNumber}-{EndLineNumber - 1}{cLessColumns}. Lines have been combined.");
764763
hasWarningCombinedWrning = true;
765764
}
766765

@@ -775,14 +774,23 @@ private bool GetNextRecord()
775774
else
776775
{
777776
// return to the old position so reading the next row did not matter
778-
HandleWarning(-1, $"Line {StartLineNumber}{cLessColumns}({rowLength}/{FieldCount}).");
777+
if (!hasWarningCombinedWrning)
778+
HandleWarning(-1, $"Line {StartLineNumber}{cLessColumns}({rowLength}/{FieldCount}).");
779779
m_BufferPos = oldPos;
780780
}
781781
}
782782
}
783783
}
784-
else if (rowLength > FieldCount && m_CsvFile.WarnEmptyTailingColumns)
784+
785+
// if we still have only one column and we should have a number of columns assume this was nonsense like a report footer
786+
if (rowLength == 1 && FieldCount > 3)
787+
{
788+
RecordNumber--;
789+
goto Restart;
790+
}
791+
785792
// If more columns are present...
793+
if (rowLength > FieldCount && (m_CsvFile.WarnEmptyTailingColumns || m_RealignColumns != null))
786794
{
787795
// check if the additional columns have contents
788796
var hasContens = false;
@@ -1014,7 +1022,7 @@ private string ReadNextColumn(int columnNo, bool storeWarnings)
10141022
if (IsWhiteSpace(character))
10151023
{
10161024
// Store the white spaces if we do any kind of trimming
1017-
if (m_CsvFile.TrimmingOption != TrimmingOption.None)
1025+
if (m_CsvFile.TrimmingOption == TrimmingOption.None)
10181026
// Values will be trimmed later but we need to find out, if the filed is quoted first
10191027
stringBuilder.Append(character);
10201028
continue;
@@ -1285,7 +1293,7 @@ private void ReadToEOL()
12851293
private void ResetPositionToStart()
12861294
{
12871295
if (m_ImprovedStream == null)
1288-
m_ImprovedStream = ImprovedStream.OpenRead(m_CsvFile, ProcessDisplay);
1296+
m_ImprovedStream = ImprovedStream.OpenRead(m_CsvFile);
12891297
m_ImprovedStream.ResetToStart(delegate (Stream str)
12901298
{
12911299
// in case we can not seek need to reopen the stream reader

Library/ClassLibraryCSV/CsvHelper.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ public static void GuessCodePage(ICsvFile setting)
195195
// Read 256 kBytes
196196
var buff = new byte[262144];
197197
int length;
198-
using (var fileStream = ImprovedStream.OpenRead(setting, null))
198+
using (var fileStream = ImprovedStream.OpenRead(setting))
199199
{
200200
length = fileStream.Stream.Read(buff, 0, buff.Length);
201201
}
@@ -237,7 +237,7 @@ public static string GuessDelimiter(ICsvFile setting)
237237
{
238238
Contract.Requires(setting != null);
239239
Contract.Ensures(Contract.Result<string>() != null);
240-
using (var improvedStream = ImprovedStream.OpenRead(setting, null))
240+
using (var improvedStream = ImprovedStream.OpenRead(setting))
241241
using (var streamReader = new StreamReader(improvedStream.Stream, setting.GetEncoding(), setting.ByteOrderMark))
242242
{
243243
for (int i = 0; i < setting.SkipRows; i++)
@@ -300,7 +300,7 @@ public static bool GuessHasHeader(ICsvFile setting, IProcessDisplay processDispl
300300
public static string GuessNewline(ICsvFile setting)
301301
{
302302
Contract.Requires(setting != null);
303-
using (var improvedStream = ImprovedStream.OpenRead(setting, null))
303+
using (var improvedStream = ImprovedStream.OpenRead(setting))
304304
using (var streamReader = new StreamReader(improvedStream.Stream, setting.GetEncoding(), setting.ByteOrderMark))
305305
{
306306
for (int i = 0; i < setting.SkipRows; i++)
@@ -317,7 +317,7 @@ public static string GuessNewline(ICsvFile setting)
317317
public static bool GuessNotADelimitedFile(ICsvFile setting)
318318
{
319319
Contract.Requires(setting != null);
320-
using (var improvedStream = ImprovedStream.OpenRead(setting, null))
320+
using (var improvedStream = ImprovedStream.OpenRead(setting))
321321
using (var streamReader = new StreamReader(improvedStream.Stream, setting.GetEncoding(), setting.ByteOrderMark))
322322
{
323323
for (int i = 0; i < setting.SkipRows; i++)
@@ -346,7 +346,7 @@ public static bool GuessNotADelimitedFile(ICsvFile setting)
346346
public static int GuessStartRow(ICsvFile setting)
347347
{
348348
Contract.Requires(setting != null);
349-
using (var improvedStream = ImprovedStream.OpenRead(setting, null))
349+
using (var improvedStream = ImprovedStream.OpenRead(setting))
350350
using (var streamReader = new StreamReader(improvedStream.Stream, setting.GetEncoding(), setting.ByteOrderMark))
351351
{
352352
return GuessStartRow(streamReader, setting.FileFormat.FieldDelimiterChar,
@@ -369,7 +369,7 @@ public static bool HasUsedQualifier(ICsvFile setting, CancellationToken token)
369369
if (string.IsNullOrEmpty(setting.FileFormat.FieldQualifier) || token.IsCancellationRequested)
370370
return false;
371371

372-
using (var improvedStream = ImprovedStream.OpenRead(setting, null))
372+
using (var improvedStream = ImprovedStream.OpenRead(setting))
373373
using (var streamReader = new StreamReader(improvedStream.Stream, setting.GetEncoding(), setting.ByteOrderMark))
374374
{
375375
for (int i = 0; i < setting.SkipRows; i++)

Library/ClassLibraryCSV/Extensions.cs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
using System.Diagnostics.CodeAnalysis;
2020
using System.Diagnostics.Contracts;
2121
using System.Globalization;
22-
using System.IO;
2322
using System.Linq;
2423
using System.Text;
24+
using System.Text.RegularExpressions;
2525
using System.Threading;
2626

2727
namespace CsvTools
@@ -305,7 +305,7 @@ public static string DataTypeDisplay(this DataType dt)
305305
return "Text Part";
306306

307307
case DataType.TextToHtml:
308-
return "Encode HTML (Linefeeds and CData Tags)";
308+
return "Encode HTML (Linefeed and CData Tags)";
309309

310310
case DataType.TextToHtmlFull:
311311
return "Encode HTML ('<' -> '&lt;')";
@@ -418,20 +418,33 @@ public static string GetIdFromFileName(this string path)
418418
Contract.Requires(path != null);
419419
Contract.Ensures(Contract.Result<string>() != null);
420420

421-
var fileName = Path.GetFileNameWithoutExtension(path);
422-
if (path.AssumePgp() || path.AssumeGZip())
423-
fileName = Path.GetFileNameWithoutExtension(fileName);
424-
425-
// get rid of _PM and _AM
426-
if (fileName != null && (fileName.EndsWith("_PM", StringComparison.OrdinalIgnoreCase) ||
427-
fileName.EndsWith("_AM", StringComparison.OrdinalIgnoreCase)))
428-
fileName = fileName.Substring(0, fileName.Length - 3);
429-
430-
return StringUtils.ProcessByCategory(fileName, x =>
431-
x == UnicodeCategory.UppercaseLetter || x == UnicodeCategory.LowercaseLetter
432-
|| x == UnicodeCategory.ConnectorPunctuation ||
433-
x == UnicodeCategory.DashPunctuation)
434-
.Trim('_', '-').Replace("__", "_").Replace("__", "_").Replace("--", "-").Replace("--", "-");
421+
var fileName = StringUtils.ProcessByCategory(FileSystemUtils.SplitPath(path).FileName, x =>
422+
x == UnicodeCategory.UppercaseLetter || x == UnicodeCategory.LowercaseLetter || x == UnicodeCategory.OtherLetter ||
423+
x == UnicodeCategory.ConnectorPunctuation || x == UnicodeCategory.DashPunctuation || x == UnicodeCategory.OtherPunctuation ||
424+
x == UnicodeCategory.DecimalDigitNumber);
425+
426+
const string T = @"(:|-|_)";
427+
const string HH = @"(2[0-3]|((0|1)?\d))"; // 0-9 10-19 20-23
428+
const string MS = @"([0-5][0-9])"; // 00-59
429+
const string TT = @"((_| )?(AM|PM))?";
430+
const string S = @"(\/|.|-|_)?";
431+
const string YYYY = @"((19\d{2})|(2\d{3}))"; // 1900 - 2999
432+
const string MM = @"([0,1]?\d{1})";
433+
const string DD = @"(([0-2]?\d{1})|([3][0,1]{1}))";
434+
// Replace Times 3_53_34_AM
435+
fileName = Regex.Replace(fileName, T + "?" + HH + T + MS + T + "?" + MS + "?" + TT, string.Empty, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant);
436+
437+
// Replace Dates YYYYMMDDHHMMSS
438+
fileName = Regex.Replace(fileName, S + YYYY + S + MM + S + DD + T + "?" + HH + T + MS + T + "?" + MS + "?" + TT, string.Empty, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant);
439+
440+
// Replace Dates DDMMYYYY
441+
fileName = Regex.Replace(fileName, S + YYYY + S + MM + S + DD, string.Empty, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant);
442+
// Replace Dates MMDDYYYY
443+
fileName = Regex.Replace(fileName, S + MM + S + DD + S + YYYY, string.Empty, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant);
444+
// Replace Dates DDMMYYYY
445+
fileName = Regex.Replace(fileName, S + DD + S + MM + S + YYYY, string.Empty, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant);
446+
447+
return fileName.Trim('_', '-', ' ', '\t').Replace("__", "_").Replace("__", "_").Replace("--", "-").Replace("--", "-");
435448
}
436449

437450
/// <summary>

Library/ClassLibraryCSV/ImprovedStream.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
using System;
1616
using System.IO;
17+
using File = Pri.LongPath.File;
18+
using FileInfo = Pri.LongPath.FileInfo;
1719

1820
namespace CsvTools
1921
{
@@ -114,16 +116,15 @@ public void ResetToStart(Action<Stream> AfterInit)
114116
/// </summary>
115117
/// <param name="path">The path.</param>
116118
/// <param name="decryptedPassphrase">The decrypted passphrase.</param>
117-
/// <param name="processDisplay">The process display.</param>
118119
/// <returns></returns>
119120
/// <exception cref="ArgumentException">Path must be set - path</exception>
120-
public static ImprovedStream OpenRead(string path, Func<string> encryptedPassphrase = null, IProcessDisplay processDisplay = null)
121+
public static ImprovedStream OpenRead(string path, Func<string> encryptedPassphrase = null)
121122
{
122123
if (string.IsNullOrEmpty(path))
123124
{
124125
throw new ArgumentException("Path must be set", nameof(path));
125126
}
126-
var retVal = OpenBaseStream(path, encryptedPassphrase, processDisplay);
127+
var retVal = OpenBaseStream(path, encryptedPassphrase);
127128
retVal.ResetToStart(null);
128129
return retVal;
129130
}
@@ -132,16 +133,15 @@ public static ImprovedStream OpenRead(string path, Func<string> encryptedPassphr
132133
/// Opens the a setting for reading
133134
/// </summary>
134135
/// <param name="setting">The setting.</param>
135-
/// <param name="processDisplay">The process display.</param>
136136
/// <returns></returns>
137137
/// <exception cref="ApplicationException">
138138
/// Please provide a passphrase.
139139
/// or
140140
/// Please reenter the passphrase, the passphrase could not be decrypted.
141141
/// </exception>
142-
public static ImprovedStream OpenRead(IFileSetting setting, IProcessDisplay processDisplay)
142+
public static ImprovedStream OpenRead(IFileSetting setting)
143143
{
144-
var retVal = OpenBaseStream(setting.FullPath, setting.GetEncryptedPassphraseFunction, processDisplay);
144+
var retVal = OpenBaseStream(setting.FullPath, setting.GetEncryptedPassphraseFunction);
145145

146146
retVal.ResetToStart(delegate (Stream sr)
147147
{
@@ -193,7 +193,6 @@ public static ImprovedStream OpenWrite(string path, IProcessDisplay processDispl
193193
/// <summary>
194194
/// Closes the stream in case of a file opened for writing it would be uploaded to the sFTP
195195
/// </summary>
196-
/// <param name="processDisplay">The display.</param>
197196
public void Close()
198197
{
199198
if (Stream != null)
@@ -216,9 +215,11 @@ public void Close()
216215
/// Opens the base stream, handling sFTP access
217216
/// </summary>
218217
/// <param name="path">The path.</param>
219-
/// <param name="processDisplay">The process display.</param>
220-
/// <returns>An improved stream where the base stream is set</returns>
221-
private static ImprovedStream OpenBaseStream(string path, Func<string> encryptedPassphraseFunc, IProcessDisplay processDisplay = null)
218+
/// <param name="encryptedPassphraseFunc">The encrypted passphrase function.</param>
219+
/// <returns>
220+
/// An improved stream where the base stream is set
221+
/// </returns>
222+
private static ImprovedStream OpenBaseStream(string path, Func<string> encryptedPassphraseFunc)
222223
{
223224
var retVal = new ImprovedStream
224225
{
@@ -231,8 +232,8 @@ private static ImprovedStream OpenBaseStream(string path, Func<string> encrypted
231232
}
232233
try
233234
{
234-
retVal.BasePath = path.LongPathPrefix();
235-
retVal.BaseStream = File.OpenRead(path.LongPathPrefix());
235+
retVal.BasePath = path;
236+
retVal.BaseStream = File.OpenRead(path);
236237
return retVal;
237238
}
238239
catch (Exception)
@@ -291,7 +292,7 @@ private void CloseWrite()
291292
else if (WritePath.AssumePgp())
292293
{
293294
using (FileStream inputStream = new FileInfo(TempFile).OpenRead(),
294-
output = new FileStream(WritePath, FileMode.Create))
295+
output = new FileStream(WritePath.LongPathPrefix(), FileMode.Create))
295296
{
296297
ApplicationSetting.ToolSetting.PGPInformation.PgpEncrypt(inputStream, output, Recipient, ProcessDisplay);
297298
}

0 commit comments

Comments
 (0)