Click here to Skip to main content
15,895,709 members
Articles / Desktop Programming / Windows Forms

Flexible CSV reader/writer with progress reporting

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
3 Aug 2011CPOL4 min read 34.6K   2.9K   38  
Flexible CSV reader/writer with progress reporting and many file format variations.
// Copyright © Transeric Solutions 2011.  All rights reserved.
// Licensed under Code Project Open License (see http://www.codeproject.com/info/cpol10.aspx).
// Author: Eric David Lynch.
using System;
using System.Collections.Generic;
using System.Data;

namespace Extended.Data
{
    /// <summary>
    /// A simple name space provider.
    /// </summary>
    public class SimpleNameSpace : INameSpace
    {
        #region Constructors
        /// <summary>
        /// Construct a simple case-sensitive name space.
        /// </summary>
        public SimpleNameSpace()
            : this(DefaultCapacity, false)
        {
        }

        /// <summary>
        /// Construct a simple case-sensitive name space with the specified initial capacity.
        /// </summary>
        /// <param name="capacity">The initial capacity of the name space dictionary.</param>
        public SimpleNameSpace(
            int capacity)
            : this(capacity, false)
        {
        }

        /// <summary>
        /// Construct a simple name space with the specified case-sensitivity.
        /// </summary>
        /// <param name="noCase">A value indicating if the dictionary is case-insensitive.</param>
        public SimpleNameSpace(
            bool noCase)
            : this(DefaultCapacity, noCase)
        {
        }

        /// <summary>
        /// Construct a simple name space with the specified case-sensitivity and initial capacity.
        /// </summary>
        /// <param name="capacity">The initial capacity of the name space dictionary.</param>
        /// <param name="noCase">A value indicating if the dictionary is case-insensitive.</param>
        public SimpleNameSpace(
            int capacity,
            bool noCase)
            : this(capacity, noCase ? StringComparer.CurrentCultureIgnoreCase : StringComparer.CurrentCulture)
        {
        }

        /// <summary>
        /// Construct a simple name space with the specified key comparer and initial capacity.
        /// </summary>
        /// <param name="capacity">The initial capacity of the name space dictionary.</param>
        /// <param name="comparer">The method used to compare to key values in the dictionary.</param>
        public SimpleNameSpace(
            int capacity,
            IEqualityComparer<string> comparer)
        {
            names = new Dictionary<string, bool>(capacity, comparer);
            DefaultBaseName = "Column";
        }
        #endregion // Constructors

        #region Constants
        /// <summary>
        /// The default initial capacity for this name space.
        /// </summary>
        public const int DefaultCapacity = 1023;
        #endregion // Constants

        #region Private data
        /// <summary>
        /// The keys for this name space.
        /// </summary>
        private Dictionary<string, bool> names;

        /// <summary>
        /// The next tie breaker value to use when names are not unique.
        /// </summary>
        private int tieBreaker;
        #endregion // Private data

        #region Properties
        /// <summary>
        /// Gets the default base name to use when no base name is provided.
        /// </summary>
        public string DefaultBaseName { get; protected set; }

        /// <summary>
        /// Gets 
        /// </summary>
        public int GeneratedCount { get; private set; }
        #endregion // Properties

        #region INameSpace Members
        /// <summary>
        /// Gets a collection of names in the name space (the order of the collection is undefined).
        /// </summary>
        public ICollection<string> Names
        {
            get { return names.Keys; }
        }

        /// <summary>
        /// Clean a name so that is safe for usage.
        /// </summary>
        /// <param name="name">The name to be cleaned.</param>
        /// <returns>The safe name.</returns>
        public virtual string CleanName(
            string name)
        {
            return name;
        }

        /// <summary>
        /// Gets a value indicating if the specified name is in use.
        /// </summary>
        /// <param name="name">The name to be tested.</param>
        /// <returns>True, if the name exists in the namespace; otherwise, false.</returns>
        public bool ContainsName(
            string name)
        {
            return names.ContainsKey(name);
        }

        /// <summary>
        /// Create a unique name.
        /// </summary>
        public string CreateName()
        {
            return CreateName(null);
        }

        /// <summary>
        /// Create a unique name.
        /// </summary>
        /// <param name="baseName">The base name used during creation (or null).</param>
        /// <returns>A unique name.</returns>
        public virtual string CreateName(
            string baseName)
        {
            // Start at the beginning
            string name = baseName;

            // If no base name...
            if (baseName == null)
            {
                // Use default base name
                baseName = DefaultBaseName;

                // Use the first name
                name = String.Format("{0}-{1}",
                    DefaultBaseName, ++tieBreaker);
            } // If no base name...

            // Loop to create a unique name...
            while (names.ContainsKey(name))
                name = String.Format("{0}-{1}",
                    baseName, ++tieBreaker);

            // Add the name to the keys
            names.Add(name, true);

            // Return the generated name
            return name;
        }
        #endregion // INameSpace Members
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Eric is a Senior Software Engineer with 30+ years of experience working with enterprise systems, both in the US and internationally. Over the years, he’s worked for a number of Fortune 500 companies (current and past), including Thomson Reuters, Verizon, MCI WorldCom, Unidata Incorporated, Digital Equipment Corporation, and IBM. While working for Northeastern University, he received co-author credit for six papers published in the Journal of Chemical Physics. Currently, he’s enjoying a little time off to work on some of his own software projects, explore new technologies, travel, and write the occasional article for CodeProject or ContentLab.

Comments and Discussions