31 Commits

Author SHA1 Message Date
2276435fc8 Issue 9: save 2026-01-04 13:23:54 +01:00
4445209f55 Issue 8: save 2025-05-11 17:38:21 +02:00
c73800bbd1 Issue 7: save 2025-05-11 17:38:11 +02:00
0b6cd9491c Issue 6: save 2025-05-11 17:38:00 +02:00
ec10fcb015 Issue 5: save 2025-05-11 17:37:43 +02:00
d3491f36a2 Issue 4: save 2025-05-11 17:35:15 +02:00
af63d2bd07 Issue 3: save 2025-05-11 17:34:42 +02:00
e7d15e432d Issue 2: save 2025-05-11 08:25:57 +02:00
dbc24654a6 Issue 1: save 2025-05-11 08:23:36 +02:00
fd9088e017 Issue 1: save 2025-05-11 08:23:28 +02:00
c816f81948 Initialize issues branch 2025-05-11 08:20:41 +02:00
6afee1c570 Code cleanup 2024-11-17 13:54:09 +01:00
711d20bf72 Remove unused nuget JetBrains.Annotations 2024-11-16 22:19:05 +01:00
13d9218944 CsvFieldIndexer: Fix handling of escaped characters 2024-02-19 02:47:29 +01:00
52cb729c0e CsvFieldIndexer: Add tests to Save and Load 2024-02-18 16:30:45 +01:00
9429751e65 CsvLib.Tests: Fix root namespace 2024-02-18 16:04:56 +01:00
afcd404dfc Tests for CsvParser 2024-02-18 15:57:59 +01:00
66536657e2 Migrate to dotnet8 and fix warnings 2024-02-18 02:02:50 +01:00
a688f2a692 Add UI for the search feature.
Fixes #3
2023-08-21 04:41:02 +02:00
a0010593f6 CsvFieldIndexer.Search: Naive search implementation. 2023-08-21 04:40:50 +02:00
0c05215b94 Add ByteArraySearcher to CsvLib. 2023-08-21 04:25:10 +02:00
1c291807c8 CsvFieldIndexer: Fix bug saving field indexes. 2023-08-20 20:35:36 +02:00
ffc5a546c9 Replace CsvIndexer with CsvFieldIndexer. 2023-08-20 20:20:51 +02:00
aac075bb4f CsvFieldIndexer: Implement saving and loading of field indexes. 2023-08-20 20:19:41 +02:00
e38222597a Migrate CsvLib to net 7.0 2023-08-20 19:52:11 +02:00
6ed9718abb CsvFieldIndexer: Fix calculation of offsets with unicode characters.
Fixes #4
2023-08-18 15:48:11 +02:00
fb6d8d76a1 Fix some warnings 2023-08-18 02:57:36 +02:00
ddd49a0d80 CsvView: Remove unused method Index_LoadReg 2023-08-18 02:48:18 +02:00
eb5a353b74 CsvView: Allow selection of texts
Instead of disabling textboxes, we use the readonly feature.
2023-08-17 18:34:25 +02:00
21feb41598 Update Copyright dates 2023-08-17 14:48:12 +02:00
aa99fa3848 Merge AvalonaUI port
Fixes #1
2023-08-17 14:30:23 +02:00
36 changed files with 60 additions and 1221 deletions

View File

@@ -1,34 +0,0 @@
[*]
# Microsoft .NET properties
csharp_new_line_before_members_in_object_initializers = false
csharp_preferred_modifier_order = private, protected, public, internal, file, new, override, abstract, virtual, sealed, readonly, static, extern, unsafe, volatile, async, required:suggestion
csharp_preserve_single_line_blocks = true
csharp_style_var_elsewhere = false:suggestion
csharp_style_var_for_built_in_types = false:suggestion
csharp_style_var_when_type_is_apparent = false:suggestion
# ReSharper properties
resharper_accessor_owner_body = accessors_with_block_body
resharper_align_multiline_argument = true
resharper_align_multiline_binary_expressions_chain = false
resharper_blank_lines_after_block_statements = 0
resharper_blank_lines_around_single_line_property = 1
resharper_braces_for_for = required
resharper_braces_for_ifelse = not_required
resharper_braces_for_using = not_required
resharper_braces_redundant = false
resharper_csharp_blank_lines_around_invocable = 0
resharper_csharp_insert_final_newline = true
resharper_csharp_max_line_length = 198
resharper_csharp_remove_blank_lines_near_braces_in_declarations = false
resharper_default_internal_modifier = implicit
resharper_instance_members_qualify_declared_in =
resharper_keep_existing_enum_arrangement = false
resharper_parentheses_non_obvious_operations = none, multiplicative, additive, arithmetic, shift, bitwise_and, bitwise_exclusive_or, bitwise_inclusive_or, bitwise
resharper_parentheses_redundancy_style = remove
resharper_place_accessorholder_attribute_on_same_line = false
resharper_trailing_comma_in_multiline_lists = true
resharper_wrap_chained_binary_expressions = chop_if_long
resharper_wrap_object_and_collection_initializer_style = chop_always

27
.gitignore vendored
View File

@@ -1,27 +0,0 @@
#ignorar miniaturas creadas por windows
Thumbs.db
#Ignorar archivos construidos por Visual Studio
*.obj
*.exe
*.pdb
*.user
*.aps
*.pch
*.vspscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.cache
*.ilk
*.log
[Bb]in
[Dd]ebug*/
*.lib
*.sbr
obj/
[Rr]elease*/
_ReSharper*/

13
.idea/.idea.CsvView/.idea/.gitignore generated vendored
View File

@@ -1,13 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/projectSettingsUpdater.xml
/.idea.CsvView.iml
/contentModel.xml
/modules.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -1,142 +0,0 @@
using CsvLib;
namespace CvsLib;
public class CsvFieldIndexerTests
{
#region GenerateIndex
[Fact]
public void GenerateIndex__Empty()
{
// --- Arrange
StringReader sr = new(string.Empty);
// --- Act
CsvFieldIndexer indexer = new();
indexer.GenerateIndex(sr);
// --- Assert
Assert.Single(indexer.Index);
Assert.Equal(0, indexer.Index[0]);
Assert.Empty(indexer.FieldIndex);
}
[Fact]
public void GenerateIndex__PlainText__OneRow()
{
// --- Arrange
StringReader sr = new("Hello World");
// --- Act
CsvFieldIndexer indexer = new();
indexer.GenerateIndex(sr);
// --- Assert
Assert.Equal(2, indexer.Index.Count);
Assert.Equal(0, indexer.Index[0]);
Assert.Equal(12, indexer.Index[1]);
Assert.Single(indexer.FieldIndex);
Assert.Equal(0, indexer.FieldIndex[0][0]);
Assert.Equal(10, indexer.FieldIndex[0][1]);
}
[Fact]
public void GenerateIndex__TwoLinesOfPainText__TwoRows()
{
// --- Arrange
StringReader sr = new("""
Hello World
Hello World
""");
// --- Act
CsvFieldIndexer indexer = new();
indexer.GenerateIndex(sr);
// --- Assert
Assert.Equal(3, indexer.Index.Count);
Assert.Equal(0, indexer.Index[0]);
Assert.Equal(12, indexer.Index[1]);
Assert.Equal(24, indexer.Index[2]);
Assert.Equal(2, indexer.FieldIndex.Count);
Assert.Equal(2, indexer.FieldIndex[0].Count);
Assert.Equal(0, indexer.FieldIndex[0][0]);
Assert.Equal(10, indexer.FieldIndex[0][1]);
Assert.Equal(2, indexer.FieldIndex[1].Count);
Assert.Equal(12, indexer.FieldIndex[1][0]);
Assert.Equal(22, indexer.FieldIndex[1][1]);
}
[Fact]
public void GenerateIndex__TwoLinesOfQuotedText__TwoRows()
{
// --- Arrange
StringReader sr = new("""
"Hello World"
"Hello World"
""");
// --- Act
CsvFieldIndexer indexer = new();
indexer.GenerateIndex(sr);
// --- Assert
Assert.Equal(3, indexer.Index.Count);
Assert.Equal(0, indexer.Index[0]);
Assert.Equal(14, indexer.Index[1]);
Assert.Equal(28, indexer.Index[2]);
Assert.Equal(2, indexer.FieldIndex.Count);
Assert.Equal(2, indexer.FieldIndex[0].Count);
Assert.Equal(1, indexer.FieldIndex[0][0]);
Assert.Equal(11, indexer.FieldIndex[0][1]);
Assert.Equal(2, indexer.FieldIndex[1].Count);
Assert.Equal(15, indexer.FieldIndex[1][0]);
Assert.Equal(25, indexer.FieldIndex[1][1]);
}
[Fact]
public void GenerateIndex__TwoLinesWithTwoQuotedColumns__TwoRowsTwoFields()
{
// --- Arrange
StringReader sr = new("""
"Hello","World"
"Hello","World"
""");
// --- Act
CsvFieldIndexer indexer = new();
indexer.GenerateIndex(sr);
// --- Assert
Assert.Equal(3, indexer.Index.Count);
Assert.Equal(0, indexer.Index[0]);
Assert.Equal(16, indexer.Index[1]);
Assert.Equal(32, indexer.Index[2]);
Assert.Equal(2, indexer.FieldIndex.Count);
Assert.Equal(4, indexer.FieldIndex[0].Count);
Assert.Equal(1, indexer.FieldIndex[0][0]);
Assert.Equal(5, indexer.FieldIndex[0][1]);
Assert.Equal(9, indexer.FieldIndex[0][2]);
Assert.Equal(13, indexer.FieldIndex[0][3]);
Assert.Equal(4, indexer.FieldIndex[1].Count);
Assert.Equal(17, indexer.FieldIndex[1][0]);
Assert.Equal(21, indexer.FieldIndex[1][1]);
Assert.Equal(25, indexer.FieldIndex[1][2]);
Assert.Equal(29, indexer.FieldIndex[1][3]);
}
#endregion GenerateIndex
}

View File

@@ -1,29 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>CvsLib</RootNamespace>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CsvLib\CsvLib.csproj" />
</ItemGroup>
</Project>

View File

@@ -1 +0,0 @@
global using Xunit;

View File

@@ -1,54 +0,0 @@
using System;
using System.IO;
using System.Text;
namespace CsvLib
{
public class BufferedTextReader : TextReader
{
private readonly TextReader _baseReader;
private int _position;
private readonly StringBuilder _sbBuffer = new StringBuilder();
public BufferedTextReader(TextReader baseReader)
{
_baseReader = baseReader;
}
public override int Read()
{
_position++;
int read = _baseReader.Read();
if (read != -1)
{
_sbBuffer.Append((char)read);
}
return read;
}
public override int Read(char[] buffer, int index, int count)
{
throw new NotImplementedException("Read buffered method on BufferedTextReader");
}
public override int Peek()
{
return _baseReader.Peek();
}
public int Position
{
get { return _position; }
}
public string GetBuffer()
{
return _sbBuffer.ToString();
}
public void CleanBuffer()
{
_sbBuffer.Clear();
}
}
}

View File

@@ -1,205 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace CsvLib
{
public class CsvFieldIndexer
{
private bool _insideString;
private readonly char _separator;
private readonly char _quoteChar;
private readonly char _escapeChar;
public CsvFieldIndexer(char separator = ',', char quoteChar = '"', char escapeChar = '\\')
{
_separator = separator;
_quoteChar = quoteChar;
_escapeChar = escapeChar;
}
private List<long> _index = new List<long>();
public List<long> Index { get { return _index; } }
private List<List<long>> _fieldIndex = new List<List<long>>();
public List<List<long>> FieldIndex { get { return _fieldIndex; } }
private void DummyParser(string line)
{
for (int i = 0; i < line.Length; i++)
{
char c = line[i];
if (c == _separator && _insideString == false)
{
continue;
}
if (c == _quoteChar && _insideString == false)
{
_insideString = true;
continue;
}
if (c == _quoteChar && _insideString)
{
_insideString = false;
continue;
}
if (c == _escapeChar && _insideString)
{
i++;
c = line[i];
}
}
}
private List<long> ParseLineIndex(string line, long lineOffset)
{
List<long> fieldPositions = new List<long>();
long? fieldStartPosition = null;
long? fieldEndPosition = null;
for (int i = 0; i < line.Length; i++)
{
char c = line[i];
if (c == _separator && _insideString == false)
{
if (fieldStartPosition != null)
{
fieldPositions.Add((long)fieldStartPosition);
fieldPositions.Add((long)fieldEndPosition);
}
fieldStartPosition = null;
fieldEndPosition = null;
}
else if (c == _quoteChar && _insideString == false)
{
_insideString = true;
}
else if (c == _quoteChar && _insideString)
{
_insideString = false;
}
else if (c == _escapeChar && _insideString)
{
i++;
c = line[i];
}
else if ((c == '\n' || c == '\r') && _insideString == false)
{
break;
}
else
{
long absolutePosition = lineOffset + i;
if (fieldStartPosition == null) { fieldStartPosition = absolutePosition; }
fieldEndPosition = absolutePosition;
}
}
if (_insideString == false)
{
if (fieldStartPosition != null)
{
fieldPositions.Add((long)fieldStartPosition);
fieldPositions.Add((long)fieldEndPosition);
}
}
return fieldPositions;
}
public void GenerateIndex(string file)
{
using (FileStream stream = new FileStream(file, FileMode.Open))
using (StreamReader streamReader = new StreamReader(stream, Encoding.Default, true, 4096))
{
GenerateIndex(streamReader);
}
}
public void GenerateIndex(TextReader textReader)
{
_insideString = false;
_index.Clear();
_index.Add(0);
int idxRow = 0;
using (BufferedTextReader reader = new BufferedTextReader(textReader))
{
string currentLine;
while ((currentLine = reader.ReadLine()) != null)
{
DummyParser(currentLine);
if (_insideString) { continue; }
string fullLine = reader.GetBuffer();
reader.CleanBuffer();
List<long> fieldIndexes = ParseLineIndex(fullLine, _index[idxRow]);
_fieldIndex.Add(fieldIndexes);
_index.Add(reader.Position);
idxRow++;
}
}
}
private void Index_SaveFile(string indexFile)
{
if (File.Exists(indexFile))
{
File.Delete(indexFile);
}
Stream streamOut = File.Open(indexFile, FileMode.Create);
using (BinaryWriter binWriter = new BinaryWriter(streamOut))
{
binWriter.Write(_index.Count);
for (int i = 0; i < _index.Count; i++)
{
binWriter.Write(_index[i]);
}
}
streamOut.Close();
}
private static List<long> Index_LoadFile(string indexFile)
{
List<long> tempIndex = new List<long>();
Stream streamIn = File.Open(indexFile, FileMode.Open);
using (BinaryReader binReader = new BinaryReader(streamIn))
{
int numRegs = binReader.ReadInt32();
for (int i = 0; i < numRegs; i++)
{
long value = binReader.ReadInt64();
tempIndex.Add(value);
}
}
streamIn.Close();
return tempIndex;
}
public void LoadIndexOfFile(string file)
{
DateTime dtFile = File.GetCreationTime(file);
string indexFile = $"{file}.idx";
if (File.Exists(indexFile) && File.GetCreationTime(indexFile) > dtFile)
{
_index = Index_LoadFile(indexFile);
}
else
{
// Generate index
DateTime dtNow = DateTime.UtcNow;
GenerateIndex(file);
TimeSpan tsGenIndex = DateTime.UtcNow - dtNow;
// Save Index if expensive generation
if (tsGenIndex.TotalSeconds > 2)
{
Index_SaveFile(indexFile);
}
}
}
}
}

View File

@@ -1,137 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace CsvLib
{
public class CsvIndexer
{
private bool _insideString;
private readonly char _separator;
private readonly char _quoteChar;
private readonly char _escapeChar;
public CsvIndexer(char separator = ',', char quoteChar = '"', char escapeChar = '\\')
{
_separator = separator;
_quoteChar = quoteChar;
_escapeChar = escapeChar;
}
private List<long> _index = new List<long>();
public List<long> Index { get { return _index; } }
private void DummyParser(string line)
{
for (int i = 0; i < line.Length; i++)
{
char c = line[i];
if (c == _separator && _insideString == false)
{
continue;
}
if (c == _quoteChar && _insideString == false)
{
_insideString = true;
continue;
}
if (c == _quoteChar && _insideString)
{
_insideString = false;
continue;
}
if (c == _escapeChar && _insideString)
{
i++;
c = line[i];
}
}
}
public void GenerateIndex(string file)
{
_insideString = false;
_index.Clear();
using (FileStream stream = new FileStream(file, FileMode.Open))
using (StreamReader streamReader = new StreamReader(stream, Encoding.Default, true, 4096))
using (TrackingTextReader reader = new TrackingTextReader(streamReader))
{
string currentLine;
if (_insideString == false)
{
_index.Add(reader.Position);
}
while ((currentLine = reader.ReadLine()) != null)
{
DummyParser(currentLine);
if (_insideString == false)
{
_index.Add(reader.Position);
}
}
}
}
private void Index_SaveFile(string indexFile)
{
if (File.Exists(indexFile))
{
File.Delete(indexFile);
}
Stream streamOut = File.Open(indexFile, FileMode.Create);
using (BinaryWriter binWriter = new BinaryWriter(streamOut))
{
binWriter.Write(_index.Count);
for (int i = 0; i < _index.Count; i++)
{
binWriter.Write(_index[i]);
}
}
streamOut.Close();
}
private static List<long> Index_LoadFile(string indexFile)
{
List<long> tempIndex = new List<long>();
Stream streamIn = File.Open(indexFile, FileMode.Open);
using (BinaryReader binReader = new BinaryReader(streamIn))
{
int numRegs = binReader.ReadInt32();
for (int i = 0; i < numRegs; i++)
{
long value = binReader.ReadInt64();
tempIndex.Add(value);
}
}
streamIn.Close();
return tempIndex;
}
public void LoadIndexOfFile(string file)
{
DateTime dtFile = File.GetCreationTime(file);
string indexFile = $"{file}.idx";
if (File.Exists(indexFile) && File.GetCreationTime(indexFile) > dtFile)
{
_index = Index_LoadFile(indexFile);
}
else
{
// Generate index
DateTime dtNow = DateTime.UtcNow;
GenerateIndex(file);
TimeSpan tsGenIndex = DateTime.UtcNow - dtNow;
// Save Index if expensive generation
if (tsGenIndex.TotalSeconds > 2)
{
Index_SaveFile(indexFile);
}
}
}
}
}

View File

@@ -1,7 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
</Project>

View File

@@ -1,109 +0,0 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace CsvLib
{
public class CsvParser
{
private bool _insideString;
private readonly char _separator;
private readonly char _quoteChar;
private readonly char _escapeChar;
public CsvParser(char separator = ',', char quoteChar = '"', char escapeChar = '\\')
{
_separator = separator;
_quoteChar = quoteChar;
_escapeChar = escapeChar;
}
private List<List<string>> _data = new List<List<string>>();
private List<string> _currentReg;
StringBuilder _currentCell;
public List<List<string>> Data
{
get { return _data; }
}
public void ParseLine(string line)
{
if (_currentReg == null)
{
_currentReg = new List<string>();
}
if (_currentCell == null)
{
_currentCell = new StringBuilder();
}
for (int i = 0; i < line.Length; i++)
{
char c = line[i];
if (c == _separator && _insideString == false)
{
_currentReg.Add(_currentCell.ToString());
_currentCell.Clear();
continue;
}
if (c == _quoteChar && _insideString == false)
{
_insideString = true;
continue;
}
if (c == _quoteChar && _insideString)
{
_insideString = false;
continue;
}
if (c == _escapeChar && _insideString)
{
i++;
if (i == line.Length) { break; }
c = line[i];
}
_currentCell.Append(c);
}
if (_insideString)
{
_currentCell.Append('\n');
}
else
{
_currentReg.Add(_currentCell.ToString());
_currentCell.Clear();
_data.Add(_currentReg);
_currentReg = null;
}
}
public void ParseFile(string file, long offset = 0, int count = 0)
{
_insideString = false;
_data = new List<List<string>>();
_currentReg = null;
FileStream stream = new FileStream(file, FileMode.Open);
stream.Seek(offset, SeekOrigin.Begin);
using (StreamReader reader = new StreamReader(stream, Encoding.Default, true, 4096))
{
string currentLine;
while ((currentLine = reader.ReadLine()) != null)
{
ParseLine(currentLine);
if (count > 0 && Data.Count == count)
{
break;
}
}
}
stream.Close();
}
}
}

View File

@@ -1,37 +0,0 @@
using System;
using System.IO;
namespace CsvLib
{
public class TrackingTextReader : TextReader
{
private readonly TextReader _baseReader;
private int _position;
public TrackingTextReader(TextReader baseReader)
{
_baseReader = baseReader;
}
public override int Read()
{
_position++;
return _baseReader.Read();
}
public override int Read(char[] buffer, int index, int count)
{
throw new NotImplementedException("Read buffered method on TrackingTextReader");
}
public override int Peek()
{
return _baseReader.Peek();
}
public int Position
{
get { return _position; }
}
}
}

View File

@@ -1,42 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsvLib", "CsvLib\CsvLib.csproj", "{EB0FDB60-8B9D-401C-85A8-4CF4105D5063}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsvLib.Tests", "CsvLib.Tests\CsvLib.Tests.csproj", "{EC5C84D8-1CDE-4AED-9C16-6C4086A20893}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsvView", "CsvView\CsvView.csproj", "{65A0A7DA-5884-4DFE-8223-C8F5DBD881A8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{94D4A247-9453-45F4-8552-0D106801C9F0}"
ProjectSection(SolutionItems) = preProject
README.md = README.md
LICENSE.txt = LICENSE.txt
.editorconfig = .editorconfig
.gitignore = .gitignore
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EB0FDB60-8B9D-401C-85A8-4CF4105D5063}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EB0FDB60-8B9D-401C-85A8-4CF4105D5063}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB0FDB60-8B9D-401C-85A8-4CF4105D5063}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB0FDB60-8B9D-401C-85A8-4CF4105D5063}.Release|Any CPU.Build.0 = Release|Any CPU
{EC5C84D8-1CDE-4AED-9C16-6C4086A20893}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EC5C84D8-1CDE-4AED-9C16-6C4086A20893}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EC5C84D8-1CDE-4AED-9C16-6C4086A20893}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EC5C84D8-1CDE-4AED-9C16-6C4086A20893}.Release|Any CPU.Build.0 = Release|Any CPU
{65A0A7DA-5884-4DFE-8223-C8F5DBD881A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{65A0A7DA-5884-4DFE-8223-C8F5DBD881A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65A0A7DA-5884-4DFE-8223-C8F5DBD881A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65A0A7DA-5884-4DFE-8223-C8F5DBD881A8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -1,3 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue">/usr/share/dotnet/sdk/7.0.107/MSBuild.dll</s:String>
<s:Int64 x:Key="/Default/Environment/Hierarchy/Build/BuildTool/MsbuildVersion/@EntryValue">4294967293</s:Int64></wpf:ResourceDictionary>

View File

@@ -1,10 +0,0 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="CsvView.App"
RequestedThemeVariant="Default">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
<Application.Styles>
<FluentTheme />
</Application.Styles>
</Application>

View File

@@ -1,23 +0,0 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace CsvView;
public partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
}
base.OnFrameworkInitializationCompleted();
}
}

View File

@@ -1,25 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.0.2"/>
<PackageReference Include="Avalonia.Desktop" Version="11.0.2"/>
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.2"/>
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.2"/>
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.2"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CsvLib\CsvLib.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,38 +0,0 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:csvView="clr-namespace:CsvView"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
x:Class="CsvView.MainWindow"
x:DataType="csvView:MainWindowViewModel"
Width="800"
Height="600"
Title="CsvView">
<Grid RowDefinitions="Auto,Auto,*">
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Button Name="BtnLoad" Click="BtnLoad_OnClick">...</Button>
<TextBlock Name="TxtFileName" />
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<Button Name="BtnFirst" Click="BtnFirst_OnClick">|◁</Button>
<Button Name="BtnPrevious" Click="BtnPrevious_OnClick">◁</Button>
<TextBox Name="TxtIndex" Text="{Binding Index}" TextChanged="TxtIndex_OnTextChanged" ></TextBox>
<TextBlock>/</TextBlock>
<TextBox Name="TxtMaxIndex" Text="{Binding MaxIndex}" IsEnabled="false"></TextBox>
<Button Name="BtnNext" Click="BtnNext_OnClick">▷</Button>
<Button Name="BtnLast" Click="BtnLast_OnClick">▷|</Button>
</StackPanel>
<ScrollViewer Grid.Row="2" >
<StackPanel Orientation="Vertical" >
<ItemsControl ItemsSource="{Binding Fields}">
<ItemsControl.DataTemplates>
<DataTemplate x:DataType="csvView:FieldViewModel">
<TextBox Text="{Binding Text}" IsEnabled="False"/>
</DataTemplate>
</ItemsControl.DataTemplates>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</Grid>
</Window>

View File

@@ -1,171 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using CsvLib;
namespace CsvView;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
RenderReg(0);
}
private async void BtnLoad_OnClick(object? sender, RoutedEventArgs e)
{
TopLevel? topLevel = GetTopLevel(this);
if (topLevel == null) { return; }
IReadOnlyList<IStorageFile> files = await topLevel.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = "Open CSV File",
AllowMultiple = false,
FileTypeFilter = new List<FilePickerFileType>
{
new("CSV Files") { Patterns = new[] { "*.csv" } },
new("Any File") { Patterns = new[] { "*" } },
},
});
if (files.Count <= 0) { return; }
LoadFile(files[0].Path.LocalPath);
}
private void BtnFirst_OnClick(object? sender, RoutedEventArgs e)
{
RenderReg(0);
}
private void BtnPrevious_OnClick(object? sender, RoutedEventArgs e)
{
RenderReg(_currentReg - 1);
}
private void TxtIndex_OnTextChanged(object? sender, TextChangedEventArgs e)
{
RenderReg(int.TryParse(TxtIndex.Text, out int newReg) ? newReg : _currentReg);
}
private void BtnNext_OnClick(object? sender, RoutedEventArgs e)
{
RenderReg(_currentReg + 1);
}
private void BtnLast_OnClick(object? sender, RoutedEventArgs e)
{
RenderReg(_totalRegs - 1);
}
private string _loadedFile = string.Empty;
private long _currentReg;
private int _totalRegs;
private List<long> _index = new();
private void LoadFile(string fileName)
{
_loadedFile = fileName;
TxtFileName.Text = fileName;
CsvIndexer csvIndexer = new();
csvIndexer.LoadIndexOfFile(_loadedFile);
_index = csvIndexer.Index;
_totalRegs = _index.Count - 1;
RenderReg(0);
}
private MainWindowViewModel Index_LoadReg(int idx, int maxIndex)
{
CsvParser csvParser = new();
csvParser.ParseFile(_loadedFile, _index[idx], 1);
MainWindowViewModel viewModel = new()
{
Index = idx,
MaxIndex = maxIndex,
Fields = csvParser.Data[0].Select(f => new FieldViewModel { Text = f, }).ToList(),
};
return viewModel;
}
bool _rendering;
private void RenderReg(long currentReg)
{
if (_rendering) { return; }
_rendering = true;
if (_index.Count <= 0)
{
_currentReg = -1;
BtnFirst.IsEnabled = false;
BtnPrevious.IsEnabled = false;
TxtIndex.IsEnabled = false;
BtnNext.IsEnabled = false;
BtnLast.IsEnabled = false;
DataContext = new MainWindowViewModel { Index = 0, Fields = new(), };
_rendering = false;
return;
}
bool first = false;
bool last = false;
if (currentReg <= 0)
{
currentReg = 0;
first = true;
}
if (currentReg >= (_totalRegs - 1))
{
currentReg = _totalRegs - 1;
last = true;
}
BtnFirst.IsEnabled = (first == false);
BtnPrevious.IsEnabled = (first == false);
TxtIndex.IsEnabled = true;
BtnNext.IsEnabled = (last == false);
BtnLast.IsEnabled = (last == false);
if (_currentReg == currentReg)
{
_rendering = false;
return;
}
_currentReg = currentReg;
CsvParser csvParser = new();
csvParser.ParseFile(_loadedFile, _index[(int)currentReg], 1);
MainWindowViewModel viewModel = new()
{
Index = (int)currentReg,
MaxIndex = _totalRegs,
Fields = csvParser.Data[0].Select(f => new FieldViewModel { Text = f, }).ToList(),
};
DataContext = viewModel;
_rendering = false;
}
}
public class FieldViewModel
{
public string Text { get; set; } = string.Empty;
}
public class MainWindowViewModel
{
public int? Index { get; set; }
public int? MaxIndex { get; set; }
public List<FieldViewModel>? Fields { get; set; }
}

View File

@@ -1,21 +0,0 @@
using Avalonia;
using System;
namespace CsvView;
class Program
{
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.WithInterFont()
.LogToTrace();
}

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<!-- This manifest is used on Windows only.
Don't remove it as it might cause problems with window transparency and embeded controls.
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
<assemblyIdentity version="1.0.0.0" name="CsvView.Desktop"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on
and is designed to work with. Uncomment the appropriate elements
and Windows will automatically select the most compatible environment. -->
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
</assembly>

View File

@@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2014-2015 Valeriano Alfonso Rodriguez
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,36 +0,0 @@
# CsvView
CSV file viewer, for use with large files.
## Contributing
1. Fork it!
2. Create your feature branch: `git checkout -b my-new-feature`
3. Commit your changes: `git commit -am 'Add some feature'`
4. Push to the branch: `git push origin my-new-feature`
5. Submit a pull request :D
## Credits
* Valeriano Alfonso Rodriguez.
## License
The MIT License (MIT)
Copyright (c) 2014-2015 Valeriano Alfonso Rodriguez
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

0
issues/.keep Normal file
View File

10
issues/1.yaml Normal file
View File

@@ -0,0 +1,10 @@
id: 1
title: Portar a Dotnet y GtkSharp
state: closed
tags: enhancement
----
Creo que mejor opción es AvaloniaUI
https://avaloniaui.net/

6
issues/2.yaml Normal file
View File

@@ -0,0 +1,6 @@
id: 2
title: Implementar indexado de campos
state: closed
tags: enhancement
`CvsIndexer` implementa un indexado de registros. Para poder realizar búsquedas de forma eficiente, seria bueno tener también un indexado de campos.

6
issues/3.yaml Normal file
View File

@@ -0,0 +1,6 @@
id: 3
title: Implementar busquedas
state: closed
tags: enhancement

6
issues/4.yaml Normal file
View File

@@ -0,0 +1,6 @@
id: 4
title: Genera indices con offsets incorrectos, cuando hay caracteres unicode
state: closed
tags: bug

8
issues/5.yaml Normal file
View File

@@ -0,0 +1,8 @@
id: 5
title: Escapado de comillas dobles
state: open
tags: bug
Escapado de comillas dobles.
Este se hace duplicando. p.e:
`001,"Texto ""Texto entrecomillado"""`

6
issues/6.yaml Normal file
View File

@@ -0,0 +1,6 @@
id: 6
title: Resaltar el texto buscado
state: open
tags: enhancement

6
issues/7.yaml Normal file
View File

@@ -0,0 +1,6 @@
id: 7
title: Animacion de carga o barra de progreso
state: open
tags: enhancement

6
issues/8.yaml Normal file
View File

@@ -0,0 +1,6 @@
id: 8
title: Permitir indicar que la primera fila es la cabecera
state: open
tags: enhancement

6
issues/9.yaml Normal file
View File

@@ -0,0 +1,6 @@
id: 9
title: Comparar CsvView con Tabmega
state: open
tags: enhancement
https://tabmega.com/