Skip to content

Commit bbddc69

Browse files
committed
v0.2.1.3 iniファイル読み込みを自前にしてエラー排除
1 parent d757216 commit bbddc69

File tree

8 files changed

+365
-90
lines changed

8 files changed

+365
-90
lines changed

GhostDist/GhostDist.csproj

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,6 @@
6161
<Reference Include="ICSharpCode.SharpZipLib, Version=1.3.3.11, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
6262
<HintPath>..\packages\SharpZipLib.1.3.3\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
6363
</Reference>
64-
<Reference Include="INIFileParser, Version=2.5.2.0, Culture=neutral, PublicKeyToken=79af7b307b65cf3c, processorArchitecture=MSIL">
65-
<HintPath>..\packages\ini-parser.2.5.2\lib\net20\INIFileParser.dll</HintPath>
66-
</Reference>
6764
<Reference Include="System" />
6865
<Reference Include="System.Core" />
6966
<Reference Include="System.IO.Compression" />
@@ -89,6 +86,8 @@
8986
<Compile Include="Utilities\Md5Helper.cs" />
9087
<Compile Include="Utilities\FilePatternMatcher.cs" />
9188
<Compile Include="Utilities\FileListBuilder.cs" />
89+
<Compile Include="Utilities\SimpleIniData.cs" />
90+
<Compile Include="Utilities\SimpleIniParser.cs" />
9291
<Compile Include="Services\ConfigurationService.cs" />
9392
<Compile Include="Services\FileFilterPreviewService.cs" />
9493
<Compile Include="Services\FtpService.cs" />

GhostDist/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@
1515

1616
[assembly: Guid("a1b2c3d4-e5f6-7890-abcd-ef1234567890")]
1717

18-
[assembly: AssemblyVersion("0.2.1.1")]
19-
[assembly: AssemblyFileVersion("0.2.1.1")]
18+
[assembly: AssemblyVersion("0.2.1.3")]
19+
[assembly: AssemblyFileVersion("0.2.1.3")]

GhostDist/Services/ConfigurationService.cs

Lines changed: 8 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
using System.Linq;
55
using System.Text;
66
using GhostDist.Models;
7-
using IniParser;
8-
using IniParser.Model;
9-
using IniParser.Parser;
7+
using GhostDist.Utilities;
108

119
namespace GhostDist.Services
1210
{
@@ -68,19 +66,9 @@ public void LoadAll(out bool isLog, out bool noLogWindow, out FtpConfiguration c
6866

6967
try
7068
{
71-
// ファイルを共有読み取りモードで読み込み
72-
string iniContent;
73-
var encoding = Encoding.GetEncoding("Shift_JIS");
74-
75-
using (var fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
76-
using (var reader = new StreamReader(fileStream, encoding))
77-
{
78-
iniContent = reader.ReadToEnd();
79-
}
80-
81-
// 文字列からパース
82-
var parser = new IniDataParser();
83-
var data = parser.Parse(iniContent);
69+
// 独自のINIパーサで読み込み(ファイル末尾のゴミ対策)
70+
var parser = new SimpleIniParser();
71+
var data = parser.ParseFile(fullPath);
8472

8573
// 一般設定
8674
if (data.Sections.ContainsSection("General"))
@@ -160,14 +148,6 @@ public void LoadAll(out bool isLog, out bool noLogWindow, out FtpConfiguration c
160148
$"ネットワークドライブの場合は接続を確認してください。\n" +
161149
$"詳細: {ex.Message}", ex);
162150
}
163-
catch (IniParser.Exceptions.ParsingException ex)
164-
{
165-
throw new Exception(
166-
$"設定ファイルの形式が不正です。\n" +
167-
$"パス: {fullPath}\n" +
168-
$"サイズ: {fileInfo.Length:N0} bytes\n" +
169-
$"詳細: {ex.Message}", ex);
170-
}
171151
catch (Exception ex)
172152
{
173153
throw new Exception(
@@ -186,7 +166,7 @@ public void SaveProjects(List<ProjectSettings> projects, FtpConfiguration common
186166
{
187167
try
188168
{
189-
var data = new IniData();
169+
var data = new SimpleIniData();
190170

191171
// FTP共通設定
192172
data["FTP"]["Server"] = commonFtp.Server;
@@ -231,8 +211,9 @@ public void SaveProjects(List<ProjectSettings> projects, FtpConfiguration common
231211
data[section]["UploadGhostID"] = project.NarNaLoaderGhostId;
232212
}
233213

234-
// カスタムINI書き込み("="前後の空白を入れない)
235-
WriteIniFile(_iniPath, data);
214+
// 独自のINIパーサで書き込み("="前後の空白を入れない)
215+
var parser = new SimpleIniParser();
216+
parser.WriteFile(_iniPath, data);
236217
}
237218
catch (Exception ex)
238219
{
@@ -309,54 +290,5 @@ private string ConvertLinesToCommaText(string lines)
309290
return string.Join(",", parts.Select(p => p.Trim()).Where(p => !string.IsNullOrEmpty(p)));
310291
}
311292

312-
/// <summary>
313-
/// INIファイルをカスタム形式で書き込み("="前後の空白なし)
314-
/// </summary>
315-
private void WriteIniFile(string filePath, IniData data)
316-
{
317-
var encoding = Encoding.GetEncoding("Shift_JIS");
318-
using (var writer = new StreamWriter(filePath, false, encoding))
319-
{
320-
foreach (var section in data.Sections)
321-
{
322-
// セクションヘッダー
323-
writer.WriteLine($"[{section.SectionName}]");
324-
325-
// キー=値のペア(空白なし)
326-
foreach (var key in section.Keys)
327-
{
328-
// 安全性のため、keyから改行と"="を削除、valueから改行を削除
329-
var safeKey = SanitizeIniKey(key.KeyName);
330-
var safeValue = SanitizeIniValue(key.Value);
331-
writer.WriteLine($"{safeKey}={safeValue}");
332-
}
333-
334-
// セクション間の空行
335-
writer.WriteLine();
336-
}
337-
}
338-
}
339-
340-
/// <summary>
341-
/// INIキー名をサニタイズ(改行と"="を削除)
342-
/// </summary>
343-
private string SanitizeIniKey(string key)
344-
{
345-
if (string.IsNullOrEmpty(key))
346-
return "";
347-
348-
return key.Replace("\r", "").Replace("\n", "").Replace("=", "");
349-
}
350-
351-
/// <summary>
352-
/// INI値をサニタイズ(改行を削除)
353-
/// </summary>
354-
private string SanitizeIniValue(string value)
355-
{
356-
if (string.IsNullOrEmpty(value))
357-
return "";
358-
359-
return value.Replace("\r", "").Replace("\n", "");
360-
}
361293
}
362294
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace GhostDist.Utilities
6+
{
7+
/// <summary>
8+
/// INIデータを保持するクラス(IniDataの代替)
9+
/// </summary>
10+
public class SimpleIniData
11+
{
12+
private Dictionary<string, Dictionary<string, string>> _sections;
13+
14+
public SimpleIniData()
15+
{
16+
_sections = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
17+
}
18+
19+
/// <summary>
20+
/// セクションコレクションを取得
21+
/// </summary>
22+
public IniSections Sections => new IniSections(_sections);
23+
24+
/// <summary>
25+
/// セクションとキーを指定して値を取得・設定
26+
/// </summary>
27+
public string this[string section, string key]
28+
{
29+
get
30+
{
31+
if (_sections.TryGetValue(section, out var sectionData))
32+
{
33+
if (sectionData.TryGetValue(key, out var value))
34+
{
35+
return value;
36+
}
37+
}
38+
return null;
39+
}
40+
set
41+
{
42+
if (!_sections.ContainsKey(section))
43+
{
44+
_sections[section] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
45+
}
46+
_sections[section][key] = value;
47+
}
48+
}
49+
50+
/// <summary>
51+
/// セクションを指定してキー-値のディクショナリを取得
52+
/// </summary>
53+
public IniSection this[string section]
54+
{
55+
get
56+
{
57+
if (!_sections.ContainsKey(section))
58+
{
59+
_sections[section] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
60+
}
61+
return new IniSection(_sections[section]);
62+
}
63+
}
64+
65+
/// <summary>
66+
/// セクションを追加
67+
/// </summary>
68+
internal void AddSection(string sectionName)
69+
{
70+
if (!_sections.ContainsKey(sectionName))
71+
{
72+
_sections[sectionName] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
73+
}
74+
}
75+
76+
/// <summary>
77+
/// キー-値のペアを追加
78+
/// </summary>
79+
internal void AddKeyValue(string sectionName, string key, string value)
80+
{
81+
if (!_sections.ContainsKey(sectionName))
82+
{
83+
_sections[sectionName] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
84+
}
85+
_sections[sectionName][key] = value;
86+
}
87+
88+
/// <summary>
89+
/// すべてのセクションを取得
90+
/// </summary>
91+
internal Dictionary<string, Dictionary<string, string>> GetAllSections()
92+
{
93+
return _sections;
94+
}
95+
}
96+
97+
/// <summary>
98+
/// INIセクションのコレクション
99+
/// </summary>
100+
public class IniSections
101+
{
102+
private Dictionary<string, Dictionary<string, string>> _sections;
103+
104+
internal IniSections(Dictionary<string, Dictionary<string, string>> sections)
105+
{
106+
_sections = sections;
107+
}
108+
109+
/// <summary>
110+
/// セクションが存在するかチェック
111+
/// </summary>
112+
public bool ContainsSection(string sectionName)
113+
{
114+
return _sections.ContainsKey(sectionName);
115+
}
116+
117+
/// <summary>
118+
/// すべてのセクション名を取得
119+
/// </summary>
120+
public IEnumerable<string> GetSectionNames()
121+
{
122+
return _sections.Keys;
123+
}
124+
}
125+
126+
/// <summary>
127+
/// INIセクション(キー-値のペアを保持)
128+
/// </summary>
129+
public class IniSection
130+
{
131+
private Dictionary<string, string> _keyValues;
132+
133+
internal IniSection(Dictionary<string, string> keyValues)
134+
{
135+
_keyValues = keyValues;
136+
}
137+
138+
/// <summary>
139+
/// キーを指定して値を取得・設定
140+
/// </summary>
141+
public string this[string key]
142+
{
143+
get
144+
{
145+
if (_keyValues.TryGetValue(key, out var value))
146+
{
147+
return value;
148+
}
149+
return null;
150+
}
151+
set
152+
{
153+
_keyValues[key] = value;
154+
}
155+
}
156+
157+
/// <summary>
158+
/// すべてのキーを取得
159+
/// </summary>
160+
public IEnumerable<KeyValuePair<string, string>> GetKeyValues()
161+
{
162+
return _keyValues;
163+
}
164+
}
165+
}

0 commit comments

Comments
 (0)