/// <summary>
        /// Constructs a new writer
        /// </summary>
        /// <param name="fileWrapper">The file wrapper to use as the underlying file stream</param>
        /// <param name="fileName">Name of the file to write to</param>
        /// <param name="maxCharsToStore">Maximum number of characters to store for long text fields</param>
        /// <param name="maxXmlCharsToStore">Maximum number of characters to store for XML fields</param>
        public ServiceBufferFileStreamWriter(IFileStreamWrapper fileWrapper, string fileName, int maxCharsToStore, int maxXmlCharsToStore)
        {
            // open file for reading/writing
            fileStream = fileWrapper;
            fileStream.Init(fileName, DefaultBufferLength, FileAccess.ReadWrite);

            // create internal buffer
            byteBuffer = new byte[DefaultBufferLength];

            // Create internal buffers for blockcopy of contents to byte array
            // Note: We create them now to avoid the overhead of creating a new array for every write call
            shortBuffer  = new short[1];
            intBuffer    = new int[1];
            longBuffer   = new long[1];
            charBuffer   = new char[1];
            doubleBuffer = new double[1];
            floatBuffer  = new float[1];

            // Store max chars to store
            this.maxCharsToStore    = maxCharsToStore;
            this.maxXmlCharsToStore = maxXmlCharsToStore;

            // Define what methods to use to write a type to the file
            writeMethods = new Dictionary <Type, Func <object, int> >
            {
                { typeof(string), val => WriteString((string)val) },
                { typeof(short), val => WriteInt16((short)val) },
                { typeof(int), val => WriteInt32((int)val) },
                { typeof(long), val => WriteInt64((long)val) },
                { typeof(byte), val => WriteByte((byte)val) },
                { typeof(char), val => WriteChar((char)val) },
                { typeof(bool), val => WriteBoolean((bool)val) },
                { typeof(double), val => WriteDouble((double)val) },
                { typeof(float), val => WriteSingle((float)val) },
                { typeof(decimal), val => WriteDecimal((decimal)val) },
                { typeof(DateTime), val => WriteDateTime((DateTime)val) },
                { typeof(DateTimeOffset), val => WriteDateTimeOffset((DateTimeOffset)val) },
                { typeof(TimeSpan), val => WriteTimeSpan((TimeSpan)val) },
                { typeof(byte[]), val => WriteBytes((byte[])val) },

                { typeof(SqlString), val => WriteNullable((SqlString)val, obj => WriteString((string)obj)) },
                { typeof(SqlInt16), val => WriteNullable((SqlInt16)val, obj => WriteInt16((short)obj)) },
                { typeof(SqlInt32), val => WriteNullable((SqlInt32)val, obj => WriteInt32((int)obj)) },
                { typeof(SqlInt64), val => WriteNullable((SqlInt64)val, obj => WriteInt64((long)obj)) },
                { typeof(SqlByte), val => WriteNullable((SqlByte)val, obj => WriteByte((byte)obj)) },
                { typeof(SqlBoolean), val => WriteNullable((SqlBoolean)val, obj => WriteBoolean((bool)obj)) },
                { typeof(SqlDouble), val => WriteNullable((SqlDouble)val, obj => WriteDouble((double)obj)) },
                { typeof(SqlSingle), val => WriteNullable((SqlSingle)val, obj => WriteSingle((float)obj)) },
                { typeof(SqlDecimal), val => WriteNullable((SqlDecimal)val, obj => WriteSqlDecimal((SqlDecimal)obj)) },
                { typeof(SqlDateTime), val => WriteNullable((SqlDateTime)val, obj => WriteDateTime((DateTime)obj)) },
                { typeof(SqlBytes), val => WriteNullable((SqlBytes)val, obj => WriteBytes((byte[])obj)) },
                { typeof(SqlBinary), val => WriteNullable((SqlBinary)val, obj => WriteBytes((byte[])obj)) },
                { typeof(SqlGuid), val => WriteNullable((SqlGuid)val, obj => WriteGuid((Guid)obj)) },
                { typeof(SqlMoney), val => WriteNullable((SqlMoney)val, obj => WriteMoney((SqlMoney)obj)) }
            };
        }
        /// <summary>
        /// Returns list of T based on *.xlsx worksheet.
        /// </summary>
        public IEnumerable <T> Import(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentException("Path cannot be null or empty");
            }

            IEnumerable <T> collectionToReturn = new List <T>();

            using (FileStream fileStream = _fileStreamWrapper.Init(path, FileMode.Open))
                using (IExcelFile excelFile = _excelCreator.Create(fileStream))
                {
                    collectionToReturn = new List <T>(excelFile.ConvertToObjects <T>());
                }
            return(collectionToReturn);
        }
        /// <summary>
        /// Constructs a new ServiceBufferFileStreamReader and initializes its state
        /// </summary>
        /// <param name="fileWrapper">The filestream wrapper to read from</param>
        /// <param name="fileName">The name of the file to read from</param>
        public ServiceBufferFileStreamReader(IFileStreamWrapper fileWrapper, string fileName)
        {
            // Open file for reading/writing
            fileStream = fileWrapper;
            fileStream.Init(fileName, DefaultBufferSize, FileAccess.Read);

            // Create internal buffer
            buffer = new byte[DefaultBufferSize];

            // Create the methods that will be used to read back
            readMethods = new Dictionary <Type, Func <long, FileStreamReadResult> >
            {
                { typeof(string), ReadString },
                { typeof(short), ReadInt16 },
                { typeof(int), ReadInt32 },
                { typeof(long), ReadInt64 },
                { typeof(byte), ReadByte },
                { typeof(char), ReadChar },
                { typeof(bool), ReadBoolean },
                { typeof(double), ReadDouble },
                { typeof(float), ReadSingle },
                { typeof(decimal), ReadDecimal },
                { typeof(DateTime), ReadDateTime },
                { typeof(DateTimeOffset), ReadDateTimeOffset },
                { typeof(TimeSpan), ReadTimeSpan },
                { typeof(byte[]), ReadBytes },

                { typeof(SqlString), ReadString },
                { typeof(SqlInt16), ReadInt16 },
                { typeof(SqlInt32), ReadInt32 },
                { typeof(SqlInt64), ReadInt64 },
                { typeof(SqlByte), ReadByte },
                { typeof(SqlBoolean), ReadBoolean },
                { typeof(SqlDouble), ReadDouble },
                { typeof(SqlSingle), ReadSingle },
                { typeof(SqlDecimal), ReadSqlDecimal },
                { typeof(SqlDateTime), ReadDateTime },
                { typeof(SqlBytes), ReadBytes },
                { typeof(SqlBinary), ReadBytes },
                { typeof(SqlGuid), ReadGuid },
                { typeof(SqlMoney), ReadMoney },
            };
        }