Skip to content

Instantly share code, notes, and snippets.

@kveratis
Created August 20, 2013 01:09
Show Gist options
  • Save kveratis/6276018 to your computer and use it in GitHub Desktop.
Save kveratis/6276018 to your computer and use it in GitHub Desktop.
My T4 Templates for String and File Handling
<#@ 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
<#@ 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