Created
August 20, 2013 01:09
-
-
Save kveratis/6276018 to your computer and use it in GitHub Desktop.
My T4 Templates for String and File Handling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<#@ template debug="false" hostspecific="false" language="C#" #> | |
<#@ output extension=".generated.cs" #> | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Text; | |
#region TextBlock | |
public partial class TextBlock : List<string> | |
{ | |
#region Private fields | |
private string tag; | |
#endregion | |
#region Ctors | |
public TextBlock() | |
{ | |
tag = string.Empty; | |
} | |
public TextBlock(string tag) | |
{ | |
this.tag = tag; | |
} | |
#endregion | |
#region Public Properties | |
public string Tag | |
{ | |
get { return tag; } | |
} | |
#endregion | |
public override string ToString() | |
{ | |
StringBuilder sb = new StringBuilder(); | |
foreach (string str in this) | |
{ | |
sb.AppendFormat("{0}{1}",str,Environment.NewLine); | |
} | |
return sb.ToString(); | |
} | |
} | |
#endregion | |
#region IFileSystem | |
public interface IFileSystem | |
{ | |
bool Exists(string filePath); | |
long FileLength(string filePath); | |
void Delete(string filePath); | |
void Copy(string sourceFilePath, string destinationFilePath); | |
void Move(string sourceFilePath, string destinationFilePath); | |
string FileName(string filePath); | |
string FileExtension(string filePath); | |
string FileFullName(string filePath); | |
StreamReader FileOpenTextReader(string filePath); | |
StreamWriter FileOpenTextWriter(string filePath); | |
string[] GetFiles(string sourceDirectory, string fileExtension); | |
} | |
#endregion | |
#region FileSystem | |
public sealed class FileSystem : IFileSystem | |
{ | |
public bool Exists(string filePath) | |
{ | |
return File.Exists(filePath); | |
} | |
public long FileLength(string filePath) | |
{ | |
if (File.Exists(filePath)) | |
{ | |
FileInfo info = new FileInfo(filePath); | |
return info.Length; | |
} | |
else | |
{ | |
return 0; | |
} | |
} | |
public void Delete(string filePath) | |
{ | |
if (File.Exists(filePath)) | |
{ | |
File.Delete(filePath); | |
} | |
} | |
public void Copy(string sourceFilePath, string destinationFilePath) | |
{ | |
if (File.Exists(sourceFilePath)) | |
{ | |
if (File.Exists(destinationFilePath)) | |
{ | |
File.Delete(destinationFilePath); | |
} | |
File.Copy(sourceFilePath, destinationFilePath); | |
} | |
} | |
public void Move(string sourceFilePath, string destinationFilePath) | |
{ | |
if (File.Exists(sourceFilePath)) | |
{ | |
if (File.Exists(destinationFilePath)) | |
{ | |
File.Delete(destinationFilePath); | |
} | |
File.Move(sourceFilePath, destinationFilePath); | |
} | |
} | |
public string FileFullName(string filePath) | |
{ | |
if (string.IsNullOrWhiteSpace(filePath)) | |
throw new ArgumentNullException("filePath"); | |
int start = filePath.Trim().LastIndexOf("\\"); | |
if (start < 0) | |
{ | |
start = 0; | |
} | |
else | |
{ | |
start += 1; | |
} | |
return filePath.Substring(start); | |
} | |
public string FileName(string filePath) | |
{ | |
if (string.IsNullOrWhiteSpace(filePath)) | |
throw new ArgumentNullException("filePath"); | |
string fileName = FileFullName(filePath); | |
int start = 0; | |
int end = fileName.LastIndexOf("."); | |
if (end < 0) | |
throw new ArgumentException("The file name is missing an extension or is not a valid file."); | |
return fileName.Substring(start, end - start); | |
} | |
public string FileExtension(string filePath) | |
{ | |
if (string.IsNullOrWhiteSpace(filePath)) | |
throw new ArgumentNullException("filePath"); | |
int start = filePath.LastIndexOf("."); | |
if (start < 0) | |
throw new ArgumentException("The file name is missing an extension or is not a valid file."); | |
return filePath.Substring(start).ToLower(); | |
} | |
public StreamReader FileOpenTextReader(string filePath) | |
{ | |
if (string.IsNullOrWhiteSpace(filePath)) | |
throw new ArgumentNullException("filePath"); | |
return File.OpenText(filePath); | |
} | |
public StreamWriter FileOpenTextWriter(string filePath) | |
{ | |
if (string.IsNullOrWhiteSpace(filePath)) | |
throw new ArgumentNullException("filePath"); | |
return new StreamWriter(filePath, true); | |
} | |
public string[] GetFiles(string sourceDirectory, string fileExtension) | |
{ | |
return Directory.GetFiles(sourceDirectory, fileExtension); | |
} | |
} | |
#endregion | |
#region IFileProcessor | |
public partial interface IFileProcessor | |
{ | |
IFileSystem File { get; } | |
void ReadFile<T>(string filePath, Func<TextBlock, T> mapper, Action<T> onSuccess, Action<Exception> onFailure) where T : class; | |
void ReadFile<T>(string filePath, string delimeter, Func<TextBlock, T> mapper, Action<T> onSuccess, Action<Exception> onFailure) where T : class; | |
void ReadFile<T>(string filePath, Func<StreamReader, List<TextBlock>> parser, Func<TextBlock, T> mapper, Action<T> onSuccess, Action<Exception> onFailure) where T : class; | |
void WriteFile<T>(string filePath, IEnumerable<T> entities, Func<T, TextBlock> mapper, Action<T> onSuccess, Action<T, Exception> onFailure) where T : class; | |
void WriteFile<T>(string filePath, IEnumerable<T> entities, string header, Func<T, string> mapper); | |
bool ValidateFile(string filePath); | |
void Copy(string filePath, string destinationFolder); | |
void Copy(string filePath, string destinationFolder, Func<string, string> translateFileName); | |
void CopyToArchive(string filePath, string destinationFolder); | |
void Move(string filePath, string destinationFolder); | |
void Move(string filePath, string destinationFolder, Func<string, string> translateFileName); | |
void MoveToArchive(string filePath, string destinationFolder); | |
List<TextBlock> Parse(string filePath); | |
List<TextBlock> Parse(string filePath, string delimeter); | |
void WriteLine(string filePath, string line); | |
string GenerateArchiveFileName(string filePath); | |
string PrepareDirectory(string directory); | |
} | |
#endregion | |
#region FileProcessor | |
public sealed partial class FileProcessor : IFileProcessor | |
{ | |
#region Private Fields | |
IFileSystem file; | |
#endregion | |
#region Ctors | |
public FileProcessor() | |
{ | |
file = new FileSystem(); | |
} | |
public FileProcessor(IFileSystem fileSystem) | |
{ | |
if (fileSystem == null) | |
throw new ArgumentNullException("fileSystem"); | |
this.file = fileSystem; | |
} | |
#endregion | |
#region Properties | |
public IFileSystem File | |
{ | |
get { return this.file; } | |
} | |
#endregion | |
/// <summary> | |
/// Read the contents of the specified file and use the mapper function to | |
/// translate TextBlocks into T entities. This function assumes that each | |
/// line is its own text block. Each entity is then sent to the | |
/// onSuccess method for further processing. Any failures are sent to the | |
/// onFailure method for processing. | |
/// </summary> | |
/// <remarks> | |
/// <para> | |
/// If an exception occurs in the mapper function it is expected to throw a | |
/// <see cref="FormatException"/>. In the case of an exception occuring in | |
/// the onSuccess method it is expected to throw a <see cref="InvalidOperationException"/>. | |
/// Exceptions need only be thrown if they cannot be handled by the function directly. | |
/// </para> | |
/// <para> | |
/// If the function encounters a problem with the file being in use by another | |
/// program, it will wait for 1 minute then try again until the file is available. | |
/// </para> | |
/// </remarks> | |
/// <typeparam name="T">The type of entity that is created from the contents of the file.</typeparam> | |
/// <param name="filePath">The path of the file to read from.</param> | |
/// <param name="mapper">The function that maps the contents of a <see cref="TextBlock"/> to the entity T.</param> | |
/// <param name="onSuccess">The function that each entity is passed to after it has been successfully mapped.</param> | |
/// <param name="onFailure">The function that handles any failures resulting from either invalid format or an exception in the onSuccess method.</param> | |
public void ReadFile<T>(string filePath, Func<TextBlock, T> mapper, Action<T> onSuccess, Action<Exception> onFailure) where T : class | |
{ | |
ReadFile<T>(filePath, Environment.NewLine, mapper, onSuccess, onFailure); | |
} | |
/// <summary> | |
/// Read the contents of the specified file and use the mapper function to | |
/// translate TextBlocks into T entities. Each entity is then sent to the | |
/// onSuccess method for further processing. Any failures are sent to the | |
/// onFailure method for processing. | |
/// </summary> | |
/// <remarks> | |
/// <para> | |
/// If an exception occurs in the mapper function it is expected to throw a | |
/// <see cref="FormatException"/>. In the case of an exception occuring in | |
/// the onSuccess method it is expected to throw a <see cref="InvalidOperationException"/>. | |
/// Exceptions need only be thrown if they cannot be handled by the function directly. | |
/// </para> | |
/// <para> | |
/// If the function encounters a problem with the file being in use by another | |
/// program, it will wait for 1 minute then try again until the file is available. | |
/// </para> | |
/// </remarks> | |
/// <typeparam name="T">The type of entity that is created from the contents of the file.</typeparam> | |
/// <param name="filePath">The path of the file to read from.</param> | |
/// <param name="parser">The function used to parse the contents of the file into a list of <see cref="TextBlock"/>.</param> | |
/// <param name="mapper">The function that maps the contents of a <see cref="TextBlock"/> to the entity T.</param> | |
/// <param name="onSuccess">The function that each entity is passed to after it has been successfully mapped.</param> | |
/// <param name="onFailure">The function that handles any failures resulting from either invalid format or an exception in the onSuccess method.</param> | |
public void ReadFile<T>(string filePath, Func<StreamReader, List<TextBlock>> parser, Func<TextBlock, T> mapper, Action<T> onSuccess, Action<Exception> onFailure) where T : class | |
{ | |
if (ValidateFile(filePath)) | |
{ | |
try | |
{ | |
using (StreamReader reader = file.FileOpenTextReader(filePath)) | |
{ | |
List<TextBlock> messages = parser(reader); | |
foreach (TextBlock m in messages) | |
{ | |
T entity = null; | |
try | |
{ | |
entity = mapper(m); | |
onSuccess(entity); | |
} | |
catch (FormatException ex) | |
{ | |
onFailure(ex); | |
} | |
catch (InvalidOperationException ex) | |
{ | |
onFailure(ex); | |
} | |
} | |
} | |
} | |
catch (IOException) | |
{ | |
System.Threading.Thread.Sleep(50000); //wait for 1min | |
ReadFile<T>(filePath, parser, mapper, onSuccess, onFailure); | |
} | |
} | |
} | |
/// <summary> | |
/// Read the contents of the specified file and use the mapper function to | |
/// translate TextBlocks into T entities. Each entity is then sent to the | |
/// onSuccess method for further processing. Any failures are sent to the | |
/// onFailure method for processing. | |
/// </summary> | |
/// <remarks> | |
/// <para> | |
/// If an exception occurs in the mapper function it is expected to throw a | |
/// <see cref="FormatException"/>. In the case of an exception occuring in | |
/// the onSuccess method it is expected to throw a <see cref="InvalidOperationException"/>. | |
/// Exceptions need only be thrown if they cannot be handled by the function directly. | |
/// </para> | |
/// <para> | |
/// If the function encounters a problem with the file being in use by another | |
/// program, it will wait for 1 minute then try again until the file is available. | |
/// </para> | |
/// </remarks> | |
/// <typeparam name="T">The type of entity that is created from the contents of the file.</typeparam> | |
/// <param name="filePath">The path of the file to read from.</param> | |
/// <param name="delimeter">Either a specific string that denotes where texblocks start, or <see cref="Environment.NewLine"/> if each line is a text block.</param> | |
/// <param name="mapper">The function that maps the contents of a <see cref="TextBlock"/> to the entity T.</param> | |
/// <param name="onSuccess">The function that each entity is passed to after it has been successfully mapped.</param> | |
/// <param name="onFailure">The function that handles any failures resulting from either invalid format or an exception in the onSuccess method.</param> | |
public void ReadFile<T>(string filePath, string delimeter, Func<TextBlock, T> mapper, Action<T> onSuccess, Action<Exception> onFailure) where T : class | |
{ | |
if (ValidateFile(filePath)) | |
{ | |
if(string.IsNullOrEmpty(delimeter)) | |
{ | |
delimeter = Environment.NewLine; | |
} | |
try | |
{ | |
using (StreamReader reader = file.FileOpenTextReader(filePath)) | |
{ | |
List<TextBlock> messages = Parse(reader, delimeter); | |
foreach (TextBlock m in messages) | |
{ | |
T entity = null; | |
try | |
{ | |
entity = mapper(m); | |
onSuccess(entity); | |
} | |
catch (FormatException ex) | |
{ | |
onFailure(ex); | |
} | |
catch (InvalidOperationException ex) | |
{ | |
onFailure(ex); | |
} | |
} | |
} | |
} | |
catch (IOException) | |
{ | |
System.Threading.Thread.Sleep(50000); //wait for 1min | |
ReadFile<T>(filePath, delimeter, mapper, onSuccess, onFailure); | |
} | |
} | |
} | |
/// <summary> | |
/// Writes the entities to the file specified using the mapper to define how | |
/// the entities are represented in text. Once an entity is successfully | |
/// written the onSuccess method is called, and if an exception is thrown | |
/// during this process the onFailure method is called. | |
/// </summary> | |
/// <remarks> | |
/// /// <para> | |
/// If an exception occurs in the mapper function it is expected to throw a | |
/// <see cref="FormatException"/>. In the case of an exception occuring in | |
/// the onSuccess method it is expected to throw a <see cref="InvalidOperationException"/>. | |
/// Exceptions need only be thrown if they cannot be handled by the function directly. | |
/// </para> | |
/// <para> | |
/// If the function encounters a problem with the file being in use by another | |
/// program, it will wait for 1 minute then try again until the file is available. | |
/// </para> | |
/// </remarks> | |
/// <typeparam name="T">The type of entity that is created from the contents of the file.</typeparam> | |
/// <param name="filePath">The path of the file to read from.</param> | |
/// <param name="entities">The list of entities to write out to the file.</param> | |
/// <param name="mapper">The function that maps the entities to their text representation.</param> | |
/// <param name="onSuccess">The function that each entity is passed to after it has been successfully written.</param> | |
/// <param name="onFailure">The function that handles any failures resulting from either invalid format or an exception in the onSuccess method.</param> | |
public void WriteFile<T>(string filePath, IEnumerable<T> entities, Func<T, TextBlock> mapper, Action<T> onSuccess, Action<T, Exception> onFailure) where T : class | |
{ | |
using (StreamWriter writer = file.FileOpenTextWriter(filePath)) | |
{ | |
foreach (T entity in entities) | |
{ | |
try | |
{ | |
writer.Write(mapper(entity).ToString()); | |
onSuccess(entity); | |
} | |
catch (FormatException fex) | |
{ | |
onFailure(entity, fex); | |
} | |
catch (InvalidOperationException iopex) | |
{ | |
onFailure(entity, iopex); | |
} | |
catch (IOException ioex) | |
{ | |
onFailure(entity, ioex); | |
} | |
} | |
} | |
} | |
/// <summary> | |
/// Writes entities to the specified file with the specified header if any. | |
/// </summary> | |
/// <typeparam name="T">The type of entity that is created from the contents of the file.</typeparam> | |
/// <param name="filePath">The path of the file to read from.</param> | |
/// <param name="entities">The list of entities to write out to the file.</param> | |
/// <param name="header">The text header that goes at the beginning of the file.</param> | |
/// <param name="mapper">The function that maps the entities to their text representation.</param> | |
public void WriteFile<T>(string filePath, IEnumerable<T> entities, string header, Func<T, string> mapper) | |
{ | |
using (StreamWriter writer = file.FileOpenTextWriter(filePath)) | |
{ | |
if (!string.IsNullOrWhiteSpace(header)) | |
writer.WriteLine(header); | |
foreach (T entity in entities) | |
{ | |
writer.WriteLine(mapper(entity)); | |
} | |
} | |
} | |
/// <summary> | |
/// Checks that a file exists and is not blank. If the file is blank it is | |
/// deleted. | |
/// </summary> | |
/// <param name="filePath">The path of the file to validate.</param> | |
/// <returns>False if the file does not exist or is blank, otherwise True.</returns> | |
public bool ValidateFile(string filePath) | |
{ | |
bool flag = false; | |
if (file.Exists(filePath)) | |
{ | |
if (file.FileLength(filePath) > 0) | |
{ | |
flag = true; | |
} | |
else | |
{ | |
file.Delete(filePath); | |
} | |
} | |
return flag; | |
} | |
/// <summary> | |
/// Copies the specified file to the destination folder. | |
/// </summary> | |
/// <remarks> | |
/// If the destination folder does not exist, it is created before proceeding. | |
/// </remarks> | |
/// <param name="filePath">The path of the file to copy.</param> | |
/// <param name="destinationFolder">The folder to copy the file to.</param> | |
public void Copy(string filePath, string destinationFolder) | |
{ | |
if (string.IsNullOrWhiteSpace(filePath)) | |
throw new ArgumentNullException("filePath"); | |
if (string.IsNullOrWhiteSpace(destinationFolder)) | |
throw new ArgumentNullException("destinationFolder"); | |
string destinationFilePath = PrepareDirectory(destinationFolder) + file.FileFullName(filePath); | |
file.Copy(filePath, destinationFilePath); | |
} | |
/// <summary> | |
/// Copies the specified file to the destination folder using the function to | |
/// translate the name of the file to another name. | |
/// </summary> | |
/// <remarks> | |
/// If the destination folder does not exist, it is created before proceeding. | |
/// </remarks> | |
/// <param name="filePath">The path of the file to copy.</param> | |
/// <param name="destinationFolder">The folder to copy the file to.</param> | |
/// <param name="translateFileName">The function that generates the new file name that will exist in the destination folder.</param> | |
public void Copy(string filePath, string destinationFolder, Func<string, string> translateFileName) | |
{ | |
if (string.IsNullOrWhiteSpace(filePath)) | |
throw new ArgumentNullException("filePath"); | |
if (string.IsNullOrWhiteSpace(destinationFolder)) | |
throw new ArgumentNullException("destinationFolder"); | |
string destinationFilePath = PrepareDirectory(destinationFolder) + translateFileName(filePath); | |
file.Copy(filePath, destinationFilePath); | |
} | |
/// <summary> | |
/// Copies the specified file to the destination folder with a timestamp appended | |
/// onto the file name. | |
/// </summary> | |
/// <remarks> | |
/// If the destination folder does not exist, it is created before proceeding. | |
/// </remarks> | |
/// <param name="filePath">The path of the file to archive.</param> | |
/// <param name="destinationFolder">The folder to move the file to.</param> | |
public void CopyToArchive(string filePath, string destinationFolder) | |
{ | |
Copy(filePath, destinationFolder, GenerateArchiveFileName); | |
} | |
/// <summary> | |
/// Moves the specified file to the destination folder. | |
/// </summary> | |
/// <remarks> | |
/// If the destination folder does not exist, it is created before proceeding. | |
/// </remarks> | |
/// <param name="filePath">The path of the file to move.</param> | |
/// <param name="destinationFolder">The folder to move the file to.</param> | |
public void Move(string filePath, string destinationFolder) | |
{ | |
if (string.IsNullOrWhiteSpace(filePath)) | |
throw new ArgumentNullException("filePath"); | |
if (string.IsNullOrWhiteSpace(destinationFolder)) | |
throw new ArgumentNullException("destinationFolder"); | |
string destinationFilePath = PrepareDirectory(destinationFolder) + file.FileFullName(filePath); | |
file.Move(filePath, destinationFilePath); | |
} | |
/// <summary> | |
/// Moves the specified file to the destination folder using the function to | |
/// translate the name of the file to another name. | |
/// </summary> | |
/// <remarks> | |
/// If the destination folder does not exist, it is created before proceeding. | |
/// </remarks> | |
/// <param name="filePath">The path of the file to move.</param> | |
/// <param name="destinationFolder">The folder to move the file to.</param> | |
/// <param name="translateFileName">The function that generates the new file name that will exist in the destination folder.</param> | |
public void Move(string filePath, string destinationFolder, Func<string, string> translateFileName) | |
{ | |
if (string.IsNullOrWhiteSpace(filePath)) | |
throw new ArgumentNullException("filePath"); | |
if (string.IsNullOrWhiteSpace(destinationFolder)) | |
throw new ArgumentNullException("destinationFolder"); | |
string destinationFilePath = PrepareDirectory(destinationFolder) + translateFileName(filePath); | |
file.Move(filePath, destinationFilePath); | |
} | |
/// <summary> | |
/// Moves the specified file to the destination folder with a timestamp appended | |
/// onto the file name. | |
/// </summary> | |
/// <remarks> | |
/// If the destination folder does not exist, it is created before proceeding. | |
/// </remarks> | |
/// <param name="filePath">The path of the file to archive.</param> | |
/// <param name="destinationFolder">The folder to move the file to.</param> | |
public void MoveToArchive(string filePath, string destinationFolder) | |
{ | |
Move(filePath, destinationFolder, GenerateArchiveFileName); | |
} | |
/// <summary> | |
/// Parses the text in the stream into <see cref="TextBlock"/> with each line | |
/// interpreted as a single text block. | |
/// </summary> | |
/// <param name="filePath">The path of the file to parse.</param> | |
/// <returns>List of all the text blocks in the stream.</returns> | |
public List<TextBlock> Parse(string filePath) | |
{ | |
return Parse(filePath, null); | |
} | |
/// <summary> | |
/// Parses the text in the specified file into <see cref="TextBlock"/> with one or | |
/// more lines based on the delimeter sent in. | |
/// </summary> | |
/// <param name="filePath">The path of the file to parse.</param> | |
/// <param name="delimeter">Either a specific string that denotes where texblocks start, or <see cref="Environment.NewLine"/> if each line is a text block.</param> | |
/// <returns>List of all the text blocks in the stream.</returns> | |
public List<TextBlock> Parse(string filePath, string delimeter) | |
{ | |
if (string.IsNullOrWhiteSpace(filePath)) | |
throw new ArgumentNullException("filePath"); | |
using (StreamReader reader = file.FileOpenTextReader(filePath)) | |
{ | |
return Parse(reader, delimeter); | |
} | |
} | |
/// <summary> | |
/// Appends a single line of text the specified file, creating the file if necessary. | |
/// </summary> | |
/// <param name="filePath">The path of the file to append text to.</param> | |
/// <param name="line">The line of text to add.</param> | |
public void WriteLine(string filePath, string line) | |
{ | |
using (StreamWriter writer = file.FileOpenTextWriter(filePath)) | |
{ | |
writer.WriteLine(line); | |
} | |
} | |
/// <summary> | |
/// Creates a new file name based on the one entered in with the date tagged | |
/// on the end to prevent file name conflicts in the archive folder. | |
/// </summary> | |
/// <param name="filePath">The name of the file to archive.</param> | |
/// <returns>The name of the achive file in the format of example-yyyyMMddHHmmss.txt</returns> | |
public string GenerateArchiveFileName(string filePath) | |
{ | |
if (string.IsNullOrWhiteSpace(filePath)) | |
throw new ArgumentNullException("filePath"); | |
return string.Format("{0}-{1}{2}", file.FileName(filePath), DateTime.Now.ToString("yyyyMMddHHmmss"), file.FileExtension(filePath)); | |
} | |
#region Private Helpers | |
/// <summary> | |
/// Removes unwanted characters and newlines from a string. | |
/// </summary> | |
/// <param name="line">The raw string to be cleaned up.</param> | |
/// <returns>The string passed in without the unwanted characters and newlines.</returns> | |
private string Clean(string line) | |
{ | |
if (string.IsNullOrWhiteSpace(line)) | |
{ | |
return string.Empty; | |
} | |
else | |
{ | |
return line.Replace("'", "`").Replace(Environment.NewLine, " "); | |
} | |
} | |
/// <summary> | |
/// Parses the text in the stream into <see cref="TextBlock"/> with one or | |
/// more lines based on the delimeter sent in. | |
/// </summary> | |
/// <param name="reader">The text stream to read from, usually a file.</param> | |
/// <param name="delimeter">Either a specific string that denotes where texblocks start, or <see cref="Environment.NewLine"/> if each line is a text block.</param> | |
/// <returns>List of all the text blocks in the stream.</returns> | |
private List<TextBlock> Parse(StreamReader reader, string delimeter) | |
{ | |
if (reader == null) | |
throw new ArgumentNullException("reader"); | |
if(string.IsNullOrEmpty(delimeter)) | |
delimeter = Environment.NewLine; | |
List<TextBlock> messages = new List<TextBlock>(); | |
TextBlock msg = null; | |
bool isLineDelimeter = (delimeter == Environment.NewLine); | |
while (!reader.EndOfStream) | |
{ | |
string line = Clean(reader.ReadLine()); | |
if (line.Contains(delimeter) || isLineDelimeter) | |
{ | |
if (msg != null) | |
{ | |
messages.Add(msg); | |
} | |
msg = new TextBlock(); | |
} | |
if (msg != null) | |
{ | |
msg.Add(line); | |
} | |
} | |
if (msg != null) | |
{ | |
messages.Add(msg); | |
} | |
return messages; | |
} | |
/// <summary> | |
/// Create a directory if it does not already exist. | |
/// </summary> | |
/// <remarks> | |
/// If the directory was passed in as C:\Test it will be automatically | |
/// corrected to C:\Test\ | |
/// </remarks> | |
/// <param name="directory"></param> | |
/// <returns>Name of the directory, corrected according to remarks if necessary.</returns> | |
public string PrepareDirectory(string directory) | |
{ | |
//Correct in case the user forgot the ending back slash. | |
if (!directory.EndsWith("\\")) | |
{ | |
directory = directory + "\\"; | |
} | |
if (!Directory.Exists(directory)) | |
{ | |
Directory.CreateDirectory(directory); | |
} | |
return directory; | |
} | |
#endregion | |
} | |
#endregion |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<#@ template debug="false" hostspecific="false" language="C#" #> | |
<#@ output extension=".generated.cs" #> | |
using System; | |
using System.Collections.Generic; | |
/// <summary> | |
/// Extension functions that cover string parsing functionality that is common when porting from legacy VB6 applications | |
/// or supporting structured text file parsing. | |
/// </summary> | |
public static class StringHelperExtensions | |
{ | |
/// <summary> | |
/// Find the substring starting at the index and going for the specified length. | |
/// </summary> | |
/// <remarks> | |
/// This function will do bounds checking and will return an emptry string if the index is greater than the lenght | |
/// of the string, or if the length of param is less than the specified length it will use that length instead. The | |
/// index is 1 based for converting legacy VB6 code. The trim function is already applied to the output as well. | |
/// </remarks> | |
/// <param name="param">String to parse</param> | |
/// <param name="startIndex">1 based index of where to start parsing.</param> | |
/// <param name="length">Number of characters to parse.</param> | |
/// <returns>Substring or String.Empty</returns> | |
public static string Mid(this string param, int startIndex, int length) | |
{ | |
if (string.IsNullOrEmpty(param)) | |
{ | |
return string.Empty; | |
} | |
else | |
{ | |
startIndex = (startIndex < 1 ? 0 : startIndex - 1); | |
if (startIndex > param.Length) | |
{ | |
return string.Empty; | |
} | |
else | |
{ | |
length = (length < 0 ? 0 : length); | |
length = ((startIndex + length) > param.Length ? param.Length - startIndex : length); | |
return param.Substring(startIndex, length).Trim(); | |
} | |
} | |
} | |
/// <summary> | |
/// Find the substring starting at the index and going for the end of the string. | |
/// </summary> | |
/// <remarks> | |
/// This function will do bounds checking and will return an emptry string if the index is greater than the lenght | |
/// of the string The index is 1 based for converting legacy VB6 code. The trim function is already applied to the | |
/// output as well. | |
/// </remarks> | |
/// <param name="param">String to parse</param> | |
/// <param name="startIndex">1 based index of where to start parsing.</param> | |
/// <returns>Substring or String.Empty</returns> | |
public static string Mid(this string param, int startIndex) | |
{ | |
if (string.IsNullOrEmpty(param)) | |
{ | |
return string.Empty; | |
} | |
else | |
{ | |
startIndex = (startIndex < 1 ? 0 : startIndex - 1); | |
if (startIndex > param.Length) | |
{ | |
return string.Empty; | |
} | |
else | |
{ | |
return param.Substring(startIndex).Trim(); | |
} | |
} | |
} | |
/// <summary> | |
/// Splits the string using the specified text delimeter. | |
/// </summary> | |
/// <remarks> | |
/// Leaves blank fields open. | |
/// </remarks> | |
/// <param name="param"></param> | |
/// <param name="delimeter"></param> | |
/// <returns></returns> | |
public static List<string> Split(this string param, string delimeter) | |
{ | |
List<string> data = null; | |
if(string.IsNullOrEmpty(param) || string.IsNullOrEmpty(delimeter)) | |
{ | |
return data; | |
} | |
else | |
{ | |
data = new List<string>(); | |
if (param.Contains(delimeter)) | |
{ | |
string[] temp = param.Split(new string[] { delimeter }, StringSplitOptions.None); | |
data.AddRange(temp); | |
} | |
return data; | |
} | |
} | |
public static string Left(this string param, int length) | |
{ | |
return param.Mid(1,length); | |
} | |
public static string Right(this string param, int length) | |
{ | |
if (string.IsNullOrEmpty(param)) | |
{ | |
return string.Empty; | |
} | |
else | |
{ | |
if (param.Length < length) | |
{ | |
length = param.Length; | |
} | |
return param.Mid(param.Length - length + 1, length); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment