チェンジセット 1370 (default)
- 日時:
- 2018/08/30 15:50:04 (6年前)
- 場所:
- framework/trunk
- ファイル:
-
- 8個の更新
凡例:
- 未変更
- 追加
- 削除
-
framework/trunk/CoreLibrary/Sources/Csv/CsvBeanInfo.cs
r1368 r1370 100 100 101 101 // カラムのインデックスに合わせて調整する 102 List<CsvColumnInfo> lineNumberColumnInfos = null; 102 103 int maxIndex = 0; 103 foreach (CsvColumnInfo column in columns)104 { 105 if (maxIndex < column.Index)104 foreach (CsvColumnInfo columnInfo in columns) 105 { 106 switch (columnInfo.MemberType) 106 107 { 107 maxIndex = column.Index; 108 case CsvMemberType.LineNumber: 109 if (lineNumberColumnInfos == null) 110 { 111 lineNumberColumnInfos = new List<CsvColumnInfo>(); 112 } 113 114 lineNumberColumnInfos.Add(columnInfo); 115 break; 116 117 case CsvMemberType.Value: 118 if (maxIndex < columnInfo.Index) 119 { 120 maxIndex = columnInfo.Index; 121 } 122 123 break; 108 124 } 109 125 } 110 126 111 CsvColumnInfo[] organizedFields = new CsvColumnInfo[maxIndex + 1]; 112 foreach (CsvColumnInfo column in columns) 113 { 114 if (organizedFields[column.Index] != null) 127 int columnIndexOffset = lineNumberColumnInfos != null ? lineNumberColumnInfos.Count : 0; 128 CsvColumnInfo[] organizedFields = new CsvColumnInfo[columnIndexOffset + maxIndex + 1]; 129 130 // 行番号を設定するのメンバを先頭に配置 131 if (lineNumberColumnInfos != null) 132 { 133 for (int i = 0; i < lineNumberColumnInfos.Count; i++) 134 { 135 organizedFields[i] = lineNumberColumnInfos[i]; 136 } 137 } 138 139 // 値を設定するメンバをカラムのインデックスを元に設定 140 foreach (CsvColumnInfo columnInfo in columns) 141 { 142 if (columnInfo.MemberType != CsvMemberType.Value) 143 { 144 continue; 145 } 146 147 if (organizedFields[columnIndexOffset + columnInfo.Index] != null) 115 148 { 116 149 Logging.Csv.Warning( … … 118 151 Logging.CsvCsvBeanInfoDuplicateIndex, 119 152 Resources.Log_Csv_CsvBeanInfo_DuplicateIndex, 120 column .Index,153 columnInfo.Index, 121 154 type.FullName); 122 155 continue; 123 156 } 124 157 125 organizedFields[column .Index] = column;158 organizedFields[columnIndexOffset + columnInfo.Index] = columnInfo; 126 159 } 127 160 … … 255 288 /// <param name="lineNumber"> 256 289 /// 行番号。 257 /// 行番号が不明の場合は <see langword="null"/>。258 290 /// </param> 259 291 /// <param name="columnValues"> … … 277 309 /// </exception> 278 310 internal object Create( 279 int ?lineNumber,311 int lineNumber, 280 312 IList<string> columnValues, 281 313 int index, … … 314 346 foreach (CsvColumnInfo columnInfo in ColumnInfos) 315 347 { 316 if (columnFilter(beanInfo.Type, columnInfo.Label, columnInfo.MemberAttribute)) 348 // メンバーの種類が値以外の物は必ず対象にする 349 if (columnInfo.MemberType != CsvMemberType.Value 350 || columnFilter(beanInfo.Type, columnInfo.Label, columnInfo.MemberAttribute)) 317 351 { 318 352 filteredColumnInfos.Add(columnInfo); -
framework/trunk/CoreLibrary/Sources/Csv/CsvColumnInfo.cs
r1368 r1370 25 25 using System; 26 26 using System.ComponentModel; 27 using System.Diagnostics; 27 28 using System.Reflection; 28 29 using FCSoft.SilverFrost.Framework.ComponentModel; … … 33 34 /// CSV のビーンのカラムを保持するクラスです。 34 35 /// </summary> 36 [DebuggerDisplay(@"\{Type = {MemberType} Index = {Index} Label = {Label}\}")] 35 37 public class CsvColumnInfo : 36 38 AttributeMemberInfo<CsvColumnAttribute> … … 46 48 /// 作成するインスタンスの型。 47 49 /// </summary> 50 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 48 51 private readonly Type instanceType; 49 52 … … 56 59 /// ジェネリック型パラメータの型。 57 60 /// </summary> 61 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 58 62 private readonly Type underlyingType; 59 63 -
framework/trunk/CoreLibrary/Sources/Csv/CsvReader.cs
r1368 r1370 39 39 /// </summary> 40 40 public class CsvReader : 41 FilterTextReader41 LineReader 42 42 { 43 43 /// <summary> … … 64 64 /// </summary> 65 65 private readonly CsvReaderSettings settings; 66 67 /// <summary>68 /// 行番号。69 /// </summary>70 private int lineNumber;71 66 72 67 /// <summary> … … 140 135 /// </exception> 141 136 public CsvReader(TextReader reader, CsvReaderSettings settings, bool leaveOpen) 142 : base( 143 reader != null && !(reader is LineReader) ? new LineReader(reader) : reader, 144 leaveOpen) 137 : base(reader, leaveOpen) 145 138 { 146 139 this.settings = settings ?? new CsvReaderSettings(); … … 159 152 { 160 153 return settings; 161 }162 }163 164 /// <summary>165 /// 現在の行番号を取得します。166 /// </summary>167 /// <value>168 /// 現在の行番号を表す <c>1</c> からの番号。169 /// まだ読み込んでいない場合は <c>0</c>。170 /// </value>171 public virtual int LineNumber172 {173 get174 {175 return BaseReader.LineNumber;176 154 } 177 155 } … … 210 188 } 211 189 212 /// <summary>213 /// ラップしているリーダを返します。214 /// </summary>215 /// <value>216 /// ラップしているリーダ。217 /// リソースが破棄されている場合は <see langword="null"/> 参照。218 /// </value>219 private new LineReader BaseReader220 {221 get222 {223 return (LineReader)base.BaseReader;224 }225 }226 227 190 228 191 /// <summary> … … 445 408 List<CsvColumnInfo> columnInfos = new List<CsvColumnInfo>(beanInfo.ColumnInfos.Count); 446 409 410 // 値以外のメンバーを追加 411 foreach (CsvColumnInfo columnInfo in beanInfo.ColumnInfos) 412 { 413 if (columnInfo.MemberType != CsvMemberType.Value) 414 { 415 columnInfos.Add(columnInfo); 416 } 417 } 418 447 419 int savedColumnIndex = columnIndex; 448 420 … … 460 432 foreach (CsvColumnInfo columnInfo in beanInfo.ColumnInfos) 461 433 { 434 // 値以外のメンバーは無視 435 if (columnInfo.MemberType != CsvMemberType.Value) 436 { 437 continue; 438 } 439 462 440 // 大文字小文字を区別しないで検索 463 441 // FIXME 国際化対応, 複数の名前での解析 … … 571 549 572 550 // 行を読み込む 573 string line = BaseReader.ReadLine();551 string line = base.ReadLine(); 574 552 if (line == null) 575 553 { … … 578 556 } 579 557 580 lineNumber++;581 558 if (columns == null) 582 559 { … … 595 572 if (match.Success) 596 573 { 597 throw new CsvFormatException( lineNumber, match.Index + 1);574 throw new CsvFormatException(LineNumber, match.Index + 1); 598 575 } 599 576 } … … 667 644 if (position >= length) 668 645 { 669 buffer.Append( "\r\n");646 buffer.Append(LastLineEnd); 670 647 671 648 // 次の行を読み込む 672 line = BaseReader.ReadLine();649 line = base.ReadLine(); 673 650 if (line == null) 674 651 { … … 777 754 778 755 int columnCount; 779 T result = (T)beanInfo.Create( lineNumber, columns, columnIndex, columnInfos, out columnCount);756 T result = (T)beanInfo.Create(LineNumber, columns, columnIndex, columnInfos, out columnCount); 780 757 columnIndex += columnCount; 781 758 -
framework/trunk/CoreLibrary/Sources/Csv/CsvWriter.cs
r1368 r1370 1132 1132 foreach (CsvColumnInfo columnInfo in columnInfos) 1133 1133 { 1134 WriteColumn(resolver(beanInfo.Type, columnInfo.Label, columnInfo.MemberAttribute)); 1134 // 空のカラムを出力 1135 if (columnInfo == null) 1136 { 1137 WriteEmptyColumn(); 1138 continue; 1139 } 1140 1141 // 値のメンバーのみ出力 1142 if (columnInfo.MemberType == CsvMemberType.Value) 1143 { 1144 WriteColumn(resolver(beanInfo.Type, columnInfo.Label, columnInfo.MemberAttribute)); 1145 } 1135 1146 } 1136 1147 } … … 1249 1260 IFormatProvider formatProvider = BaseWriter.FormatProvider; 1250 1261 1251 foreach (CsvColumnInfo csvColumnInfo in columnInfos) 1252 { 1253 WriteColumn(csvColumnInfo.GetValueAsString(bean, formatProvider)); 1262 foreach (CsvColumnInfo columnInfo in columnInfos) 1263 { 1264 // 空のカラムを出力 1265 if (columnInfo == null) 1266 { 1267 WriteEmptyColumn(); 1268 continue; 1269 } 1270 1271 // 値のメンバーのみ出力 1272 if (columnInfo.MemberType == CsvMemberType.Value) 1273 { 1274 WriteColumn(columnInfo.GetValueAsString(bean, formatProvider)); 1275 } 1254 1276 } 1255 1277 -
framework/trunk/CoreLibrary/Sources/IO/LineReader.cs
r1365 r1370 30 30 /// 行単位で読み込む為のリーダです。 31 31 /// </summary> 32 /// <remarks> 33 /// 元にするリーダに <see cref="LineReader"/>、またはその継承クラスを指定すると、 34 /// このクラスの行番号は、元にしたリーダの行番号を返すようになります。 35 /// </remarks> 32 36 public class LineReader : 33 37 FilterTextReader … … 48 52 private const string LineFeed = "\n"; 49 53 54 55 /// <summary> 56 /// <see cref="ReadLine()"/> で読み込んだ、現在の行番号を取得するデリゲート。 57 /// </summary> 58 private readonly GetLineNumberDelegate getLineNumber; 59 60 /// <summary> 61 /// 最後に <see cref="ReadLine()"/> を実行したときの行末を表す文字列を取得するデリゲート。 62 /// </summary> 63 private readonly GetLastLineEndDelegate getLastLineEnd; 64 65 /// <summary> 66 /// 1 行分の文字を読み取り、そのデータを文字列として返すデリゲート。 67 /// </summary> 68 private readonly ReadLineDelegate readLine; 50 69 51 70 /// <summary> … … 82 101 : base(reader, leaveOpen) 83 102 { 84 // AVOID 85 } 103 LineReader lineReader = reader as LineReader; 104 if (lineReader != null) 105 { 106 // 親が LineReader の場合、親の行番号を使用 107 getLineNumber = lineReader.getLineNumber; 108 getLastLineEnd = lineReader.getLastLineEnd; 109 readLine = lineReader.readLine; 110 } 111 else 112 { 113 getLineNumber = GetLineNumber; 114 getLastLineEnd = GetLastLineEnd; 115 readLine = ReadLineImpl; 116 } 117 } 118 119 120 121 /// <summary> 122 /// <see cref="ReadLine()"/> で読み込んだ、現在の行番号を取得するデリゲートです。 123 /// </summary> 124 /// <returns> 125 /// <see cref="ReadLine()"/> 現在の行番号を表す <c>1</c> からの番号。 126 /// まだ読み込んでいない場合は <c>0</c>。 127 /// </returns> 128 /// <remarks> 129 /// <see cref="ReadLine()"/> で読み込んだ行のみカウントされます。 130 /// </remarks> 131 private delegate int GetLineNumberDelegate(); 132 133 /// <summary> 134 /// 最後に <see cref="ReadLine()"/> を実行したときの行末を表す文字列を取得するデリゲートです。 135 /// </summary> 136 /// <returns> 137 /// 最後に <see cref="ReadLine()"/> を実行したときの行末を表す文字列。 138 /// <see cref="ReadLine()"/> を呼び出していない場合や、末尾に達した場合は空文字列。 139 /// </returns> 140 private delegate string GetLastLineEndDelegate(); 141 142 /// <summary> 143 /// 現在のストリームから 1 行分の文字を読み取り、そのデータを文字列として返すデリゲートです。 144 /// </summary> 145 /// <returns> 146 /// リーダの次の行。またはすべての文字が読み取られた場合は <see langword="null"/>。 147 /// </returns> 148 /// <exception cref="IOException"> 149 /// I/O エラーが発生しました。 150 /// </exception> 151 /// <exception cref="ObjectDisposedException"> 152 /// <see cref="TextReader"/> が閉じています。 153 /// </exception> 154 /// <exception cref="ArgumentOutOfRangeException"> 155 /// 次の行の文字数が、<see cref="Int32.MaxValue"/> を超えています。 156 /// </exception> 157 private delegate string ReadLineDelegate(); 86 158 87 159 … … 127 199 get 128 200 { 129 return lineNumber;201 return getLineNumber(); 130 202 } 131 203 } … … 143 215 get 144 216 { 145 switch (lineEndType) 146 { 147 case LineEndType.CarriageReturnAndLineFeed: 148 return CarriageReturnAndLineFeed; 149 150 case LineEndType.CarriageReturn: 151 return CarriageReturn; 152 153 case LineEndType.LineFeed: 154 return LineFeed; 155 156 default: 157 return string.Empty; 158 } 217 return getLastLineEnd(); 159 218 } 160 219 } … … 177 236 /// </exception> 178 237 public override string ReadLine() 238 { 239 return readLine(); 240 } 241 242 243 /// <summary> 244 /// <see cref="ReadLine()"/> で読み込んだ、現在の行番号を取得します。 245 /// </summary> 246 /// <returns> 247 /// <see cref="ReadLine()"/> 現在の行番号を表す <c>1</c> からの番号。 248 /// まだ読み込んでいない場合は <c>0</c>。 249 /// </returns> 250 /// <remarks> 251 /// <see cref="ReadLine()"/> で読み込んだ行のみカウントされます。 252 /// </remarks> 253 private int GetLineNumber() 254 { 255 return lineNumber; 256 } 257 258 /// <summary> 259 /// 最後に <see cref="ReadLine()"/> を実行したときの行末を表す文字列を取得するデリゲートです。 260 /// </summary> 261 /// <returns> 262 /// 最後に <see cref="ReadLine()"/> を実行したときの行末を表す文字列。 263 /// <see cref="ReadLine()"/> を呼び出していない場合や、末尾に達した場合は空文字列。 264 /// </returns> 265 private string GetLastLineEnd() 266 { 267 switch (lineEndType) 268 { 269 case LineEndType.CarriageReturnAndLineFeed: 270 return CarriageReturnAndLineFeed; 271 272 case LineEndType.CarriageReturn: 273 return CarriageReturn; 274 275 case LineEndType.LineFeed: 276 return LineFeed; 277 278 default: 279 return string.Empty; 280 } 281 } 282 283 /// <summary> 284 /// 現在のストリームから 1 行分の文字を読み取り、そのデータを文字列として返します。 285 /// </summary> 286 /// <returns> 287 /// リーダの次の行。またはすべての文字が読み取られた場合は <see langword="null"/>。 288 /// </returns> 289 /// <exception cref="IOException"> 290 /// I/O エラーが発生しました。 291 /// </exception> 292 /// <exception cref="ObjectDisposedException"> 293 /// <see cref="TextReader"/> が閉じています。 294 /// </exception> 295 /// <exception cref="ArgumentOutOfRangeException"> 296 /// 次の行の文字数が、<see cref="Int32.MaxValue"/> を超えています。 297 /// </exception> 298 private string ReadLineImpl() 179 299 { 180 300 StringBuilder builder = new StringBuilder(); -
framework/trunk/CoreTest/Csv/CsvBeanReaderTest.cs
r1368 r1370 25 25 { 26 26 using System; 27 using System.Collections.Generic;28 27 using System.Globalization; 29 28 using System.IO; … … 98 97 Is.EqualTo(DateTime.Parse("2009/01/03 12:34:56", CultureInfo.InvariantCulture)), 99 98 "List[0].NullableDate"); 99 Assert.That( 100 bean.LineNumber, 101 Is.EqualTo(lineNumber), 102 "List[0].LineNumber"); 100 103 break; 101 104 … … 121 124 Is.Null, 122 125 "List[1].NullableDate"); 126 Assert.That( 127 bean.LineNumber, 128 Is.EqualTo(lineNumber), 129 "List[1].LineNumber"); 123 130 break; 124 131 … … 144 151 Is.EqualTo(DateTime.Parse("2009/01/05 12:34:56", CultureInfo.InvariantCulture)), 145 152 "List[2].NullableDate"); 153 Assert.That( 154 bean.LineNumber, 155 Is.EqualTo(lineNumber), 156 "List[2].LineNumber"); 146 157 break; 147 158 } … … 180 191 Assert.That(bean.No, Is.EqualTo(11), "CsvStringBean[0].Value0"); 181 192 Assert.That(bean.Label, Is.EqualTo("C_Label_11"), "CsvStringBean[0].Value3"); 193 Assert.That(bean.LineNumber, Is.EqualTo(2), "CsvStringBean[0].LineNumber"); 182 194 } 183 195 … … 190 202 Assert.That(bean.Value1, Is.EqualTo("V01"), "CsvStringBean[0].Value1"); 191 203 Assert.That(bean.Value3, Is.EqualTo("V03"), "CsvStringBean[0].Value3"); 204 Assert.That(bean.LineNumber1, Is.EqualTo(4), "CsvStringBean[0].LineNumber1"); 205 Assert.That(bean.LineNumber2, Is.EqualTo(4), "CsvStringBean[0].LineNumber2"); 192 206 Assert.That(beanReader.ReadColumnsLine(out bean), Is.True, "2.2.ReadColumnsLine"); 193 207 Assert.That(bean.Value1, Is.EqualTo("V11"), "CsvStringBean[1].Value1"); 194 208 Assert.That(bean.Value3, Is.EqualTo("V13"), "CsvStringBean[1].Value3"); 209 Assert.That(bean.LineNumber1, Is.EqualTo(5), "CsvStringBean[1].LineNumber1"); 210 Assert.That(bean.LineNumber2, Is.EqualTo(5), "CsvStringBean[1].LineNumber2"); 195 211 Assert.That(beanReader.ReadColumnsLine(out bean), Is.False, "2.3.ReadColumnsLine"); 196 212 } -
framework/trunk/CoreTest/Sources/Csv/CsvNormalBean.cs
r1366 r1370 24 24 { 25 25 using System; 26 using System.Diagnostics; 26 27 27 28 … … 30 31 /// </summary> 31 32 [CsvBean] 33 [DebuggerDisplay(@"\{No = {no}\}")] 32 34 public class CsvNormalBean 33 35 { 34 36 /// <summary> 35 /// ラベル。 36 /// </summary> 37 /// 行番号。 38 /// </summary> 39 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 40 private int lineNumber; 41 42 /// <summary> 43 /// ラベル。 44 /// </summary> 45 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 37 46 private string label; 38 47 … … 40 49 /// No. 41 50 /// </summary> 51 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 42 52 private int no; 43 53 … … 45 55 /// 日付。 46 56 /// </summary> 57 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 47 58 private DateTime date; 48 59 … … 50 61 /// <see langword="null"/> 付きの No. 51 62 /// </summary> 63 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 52 64 private int? nullableNo; 53 65 … … 55 67 /// <see langword="null"/> 付きの日付。 56 68 /// </summary> 69 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 57 70 private DateTime? nullableDate; 58 71 … … 100 113 101 114 /// <summary> 115 /// 行番号を取得または設定します。 116 /// </summary> 117 /// <value> 118 /// 行番号。 119 /// </value> 120 [CsvColumn(CsvMemberType.LineNumber)] 121 public int LineNumber 122 { 123 get 124 { 125 return lineNumber; 126 } 127 128 set 129 { 130 lineNumber = value; 131 } 132 } 133 134 /// <summary> 102 135 /// ラベルを取得または設定します。 103 136 /// </summary> -
framework/trunk/CoreTest/Sources/Csv/CsvStringBean.cs
r864 r1370 23 23 namespace FCSoft.SilverFrost.Framework.Csv 24 24 { 25 using System.Diagnostics; 26 27 25 28 /// <summary> 26 29 /// CSV の文字列を格納するビーンです。 … … 30 33 { 31 34 /// <summary> 35 /// 行番号。 36 /// </summary> 37 [CsvColumn(CsvMemberType.LineNumber)] 38 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 39 private int lineNumber1; 40 41 /// <summary> 42 /// 行番号。 43 /// </summary> 44 [CsvColumn(CsvMemberType.LineNumber)] 45 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 46 private int lineNumber2; 47 48 /// <summary> 32 49 /// 文字列値0です。 33 50 /// </summary> 34 51 [CsvColumn(0)] 52 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 35 53 private string value0; 36 54 … … 39 57 /// </summary> 40 58 [CsvColumn(1)] 59 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 41 60 private string value1; 42 61 … … 45 64 /// </summary> 46 65 [CsvColumn(2)] 66 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 47 67 private string value2; 48 68 … … 51 71 /// </summary> 52 72 [CsvColumn(3)] 73 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 53 74 private string value3; 54 75 … … 57 78 /// </summary> 58 79 [CsvColumn(4)] 80 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 59 81 private string value4; 60 82 … … 63 85 /// </summary> 64 86 [CsvColumn(5)] 87 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 65 88 private string value5; 66 89 … … 69 92 /// </summary> 70 93 [CsvColumn(6)] 94 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 71 95 private string value6; 72 96 … … 75 99 /// </summary> 76 100 [CsvColumn(7)] 101 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 77 102 private string value7; 78 103 … … 81 106 /// </summary> 82 107 [CsvColumn(8)] 108 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 83 109 private string value8; 84 110 … … 87 113 /// </summary> 88 114 [CsvColumn(9)] 115 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 89 116 private string value9; 90 117 … … 98 125 } 99 126 127 128 /// <summary> 129 /// 行番号を取得または設定します。 130 /// </summary> 131 /// <value> 132 /// 行番号。 133 /// </value> 134 public int LineNumber1 135 { 136 get 137 { 138 return lineNumber1; 139 } 140 141 set 142 { 143 lineNumber1 = value; 144 } 145 } 146 147 /// <summary> 148 /// 行番号を取得または設定します。 149 /// </summary> 150 /// <value> 151 /// 行番号。 152 /// </value> 153 public int LineNumber2 154 { 155 get 156 { 157 return lineNumber2; 158 } 159 160 set 161 { 162 lineNumber2 = value; 163 } 164 } 100 165 101 166 /// <summary>
※ 詳しい使い方は
TracChangeset を参照してください。