diff Source/Mapping/TextDataReader.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/Mapping/TextDataReader.cs	Thu Mar 27 21:46:09 2014 +0400
@@ -0,0 +1,381 @@
+using System;
+using System.Data;
+#if !SILVERLIGHT
+using System.Data.Common;
+#endif
+using System.IO;
+using System.Text;
+
+namespace BLToolkit.Mapping
+{
+	public class TextDataReader : IDataReader
+	{
+		#region Constructors
+
+		public TextDataReader(Stream stream)
+			: this(stream, Map.DefaultSchema)
+		{
+		}
+
+		public TextDataReader(Stream stream, MappingSchema mappingSchema)
+		{
+			GC.SuppressFinalize(this);
+
+			if (mappingSchema == null) throw new ArgumentNullException("mappingSchema");
+
+			_reader        = new StreamReader(stream);
+			_mappingSchema = mappingSchema;
+
+			ReadHeader();
+		}
+
+		#endregion
+
+		#region Protected Members
+
+		private readonly StreamReader  _reader;
+		private readonly MappingSchema _mappingSchema;
+		private          string        _line       = string.Empty;
+		private          string[]      _names      = _empty;
+		private          string[]      _values     = _empty;
+		private          int           _lineNumber = 0;
+
+		private static readonly string[] _empty = new string[0];
+
+		private bool IsEof
+		{
+			get { return _line == null; }
+		}
+
+		private bool ReadNextLine()
+		{
+			while (!IsEof)
+			{
+				_line = _reader.ReadLine();
+				_lineNumber++;
+
+				if (!string.IsNullOrEmpty(_line) && _line[0] == '*')
+					return true;
+			}
+
+			return false;
+		}
+
+		private void ReadHeader()
+		{
+			while (ReadNextLine())
+			{
+				if (_line.StartsWith("*:"))
+				{
+					_names  = _line.Substring(2).Split(':');
+					_values = new string[_names.Length];
+
+					for (int i = 0; i < _names.Length; i++)
+						_names[i] = _names[i].Trim();
+				}
+				else if (_line.StartsWith("**") || _line.StartsWith("*-"))
+					break;
+			}
+		}
+
+		static string Encode(string value)
+		{
+			var arr = Convert.FromBase64String(value.Substring(1));
+
+#if SILVERLIGHT
+			return new UnicodeEncoding(false, true).GetString(arr, 0, arr.Length);
+#else
+			return Encoding.Unicode.GetString(arr);
+#endif
+		}
+
+		bool ReadRecord()
+		{
+			if (!IsEof)
+			{
+				if (_line.StartsWith("*-"))
+					return false;
+
+				if (_line.StartsWith("**") && _line.Length > 3)
+				{
+					var values = _line.Substring(3).Split(_line[2]);
+
+					for (var i = 0; i < _values.Length && i < values.Length; i++)
+					{
+						var value = values[i];
+
+						_values[i] =
+							value.Length == 0? null:
+							value[0] == '*'?   value.Substring(1):
+							value[0] == '+'?   Encode(value.Substring(1)) : value;
+					}
+
+					ReadNextLine();
+
+					return true;
+				}
+
+				throw new MappingException(
+					string.Format("Invalid data format in the line {0}.", _lineNumber));
+			}
+
+			return false;
+		}
+
+		#endregion
+
+		#region IDataReader Members
+
+		public virtual void Close()
+		{
+			_line = null;
+		}
+
+		public virtual int Depth
+		{
+			get { return 0; }
+		}
+
+		public virtual Type GetFieldType(int index)
+		{
+			return typeof(string);
+		}
+
+		public virtual string GetName(int index)
+		{
+			return _names[index];
+		}
+
+#if !SILVERLIGHT
+		private DataTable _schemaTable;
+
+		public virtual DataTable GetSchemaTable()
+		{
+			if (_schemaTable == null)
+			{
+				_schemaTable = new DataTable("SchemaTable");
+
+				_schemaTable.Columns.AddRange(new DataColumn[]
+				{
+					new DataColumn(SchemaTableColumn.ColumnName,               typeof(string)),
+					new DataColumn(SchemaTableColumn.ColumnOrdinal,            typeof(int)),
+					new DataColumn(SchemaTableColumn.ColumnSize,               typeof(int)),
+					new DataColumn(SchemaTableColumn.NumericPrecision,         typeof(short)),
+					new DataColumn(SchemaTableColumn.NumericScale,             typeof(short)),
+					new DataColumn(SchemaTableColumn.DataType,                 typeof(Type)),
+					new DataColumn(SchemaTableColumn.NonVersionedProviderType, typeof(int)),
+					new DataColumn(SchemaTableColumn.ProviderType,             typeof(int)),
+					new DataColumn(SchemaTableColumn.IsLong,                   typeof(bool)),
+					new DataColumn(SchemaTableColumn.AllowDBNull,              typeof(bool)),
+					new DataColumn(SchemaTableColumn.IsUnique,                 typeof(bool)),
+					new DataColumn(SchemaTableColumn.IsKey,                    typeof(bool)),
+					new DataColumn(SchemaTableColumn.BaseSchemaName,           typeof(string)),
+					new DataColumn(SchemaTableColumn.BaseTableName,            typeof(string)),
+					new DataColumn(SchemaTableColumn.BaseColumnName,           typeof(string)),
+					new DataColumn(SchemaTableColumn.IsAliased,                typeof(bool)),
+					new DataColumn(SchemaTableColumn.IsExpression,             typeof(bool)),
+				});
+
+				for (int i = 0; i < _names.Length; i++)
+				{
+					DataRow row = _schemaTable.NewRow();
+
+					row[SchemaTableColumn.ColumnName]               = _names[i];
+					row[SchemaTableColumn.ColumnOrdinal]            = i;
+					row[SchemaTableColumn.ColumnSize]               = (int)byte.MaxValue;
+					row[SchemaTableColumn.NumericPrecision]         = (short)0;
+					row[SchemaTableColumn.NumericScale]             = (short)0;
+					row[SchemaTableColumn.DataType]                 = typeof(string);
+					row[SchemaTableColumn.NonVersionedProviderType] = 1;
+					row[SchemaTableColumn.ProviderType]             = 1;
+					row[SchemaTableColumn.IsLong]                   = false;
+					row[SchemaTableColumn.AllowDBNull]              = true;
+					row[SchemaTableColumn.IsUnique]                 = false;
+					row[SchemaTableColumn.IsKey]                    = false;
+					row[SchemaTableColumn.BaseSchemaName]           = string.Empty;
+					row[SchemaTableColumn.BaseTableName]            = string.Empty;
+					row[SchemaTableColumn.BaseColumnName]           = string.Empty;
+					row[SchemaTableColumn.IsAliased]                = false;
+					row[SchemaTableColumn.IsExpression]             = false;
+
+					_schemaTable.Rows.Add(row);
+				}
+			}
+
+			return _schemaTable;
+		}
+
+#endif
+
+		public virtual int FieldCount
+		{
+			get { return _names.Length; }
+		}
+
+		public virtual bool IsClosed
+		{
+			get { return IsEof; }
+		}
+
+		public virtual bool NextResult()
+		{
+			ReadHeader();
+			return !IsEof;
+		}
+
+		public virtual bool Read()
+		{
+			return ReadRecord();
+		}
+
+		public virtual int RecordsAffected
+		{
+			get { return -1; }
+		}
+
+		#endregion
+
+		#region IDisposable Members
+
+		public virtual void Dispose()
+		{
+		}
+
+		#endregion
+
+		#region IDataRecord Members
+
+		public virtual bool GetBoolean(int i)
+		{
+			return _mappingSchema.ConvertToBoolean(_values[i]);
+		}
+
+		public virtual byte GetByte(int i)
+		{
+			return _mappingSchema.ConvertToByte(_values[i]);
+		}
+
+		public virtual long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
+		{
+			throw new Exception("The method or operation is not implemented.");
+		}
+
+		public virtual char GetChar(int i)
+		{
+			return _mappingSchema.ConvertToChar(_values[i]);
+		}
+
+		public virtual long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
+		{
+			throw new Exception("The method or operation is not implemented.");
+		}
+
+		public virtual IDataReader GetData(int i)
+		{
+			throw new Exception("The method or operation is not implemented.");
+		}
+
+		public virtual string GetDataTypeName(int i)
+		{
+			return typeof(string).FullName;
+		}
+
+		public virtual DateTime GetDateTime(int i)
+		{
+			return _mappingSchema.ConvertToDateTime(_values[i]);
+		}
+
+		public virtual DateTimeOffset GetDateTimeOffset(int i)
+		{
+			return _mappingSchema.ConvertToDateTimeOffset(_values[i]);
+		}
+
+		public virtual decimal GetDecimal(int i)
+		{
+			return _mappingSchema.ConvertToDecimal(_values[i]);
+		}
+
+		public virtual double GetDouble(int i)
+		{
+			return _mappingSchema.ConvertToDouble(_values[i]);
+		}
+
+		public virtual float GetFloat(int i)
+		{
+			return _mappingSchema.ConvertToSingle(_values[i]);
+		}
+
+		public virtual Guid GetGuid(int i)
+		{
+			return _mappingSchema.ConvertToGuid(_values[i]);
+		}
+
+		public virtual short GetInt16(int i)
+		{
+			return _mappingSchema.ConvertToInt16(_values[i]);
+		}
+
+		public virtual int GetInt32(int i)
+		{
+			return _mappingSchema.ConvertToInt32(_values[i]);
+		}
+
+		public virtual long GetInt64(int i)
+		{
+			return _mappingSchema.ConvertToInt64(_values[i]);
+		}
+
+		public virtual int GetOrdinal(string name)
+		{
+			for (int i = 0; i < _names.Length; i++)
+				if (_names[i] == name)
+					return i;
+
+			return -1;
+		}
+
+		public virtual string GetString(int i)
+		{
+			return _values[i];
+		}
+
+		public virtual object GetValue(int i)
+		{
+			return _values[i];
+		}
+
+		public virtual int GetValues(object[] values)
+		{
+			int n = Math.Min(values.Length, _values.Length);
+
+			for (int i = 0; i < n; i++)
+				values[i] = _values[i];
+
+			return n;
+		}
+
+		public virtual bool IsDBNull(int i)
+		{
+			return _values[i] == null;
+		}
+
+		public virtual object this[string name]
+		{
+			get
+			{
+				for (int i = 0; i < _names.Length; i++)
+					if (_names[i] == name)
+						return _values[i];
+
+				throw new ArgumentException(string.Format("Invalid field name '{0}'", name));
+			}
+		}
+
+		public virtual object this[int i]
+		{
+			get { return _values[i]; }
+		}
+
+		#endregion
+	}
+}