IniLikeFile

Ini-like file.

Constructors

this
this()

Construct empty IniLikeFile, i.e. without any groups or values

this
this(string fileName)

Read from file.

this
this(IniLikeReader reader, string fileName)

Read from range of IniLikeLines. Note: All exceptions thrown within constructor are turning into IniLikeException.

Members

Functions

addCommentForGroup
void addCommentForGroup(string comment, IniLikeGroup currentGroup, string groupName)

Add comment for group. This function is called only in constructor and can be reimplemented in derived classes.

addGroup
IniLikeGroup addGroup(string groupName)

Create new group using groupName.

addKeyValueForGroup
void addKeyValueForGroup(string key, string value, IniLikeGroup currentGroup, string groupName)

Add key/value pair for group. This function is called only in constructor and can be reimplemented in derived classes.

addLeadingComment
void addLeadingComment(string line)
Undocumented in source. Be warned that the author may not have intended to support it.
byGroup
auto byGroup()

Range of groups in order how they were defined in file.

createGroup
IniLikeGroup createGroup(string groupName)

Create iniLikeGroup by groupName. This function is called only in constructor and can be reimplemented in derived classes, e.g. to insert additional checks or create specific derived class depending on groupName. Returned value is later passed to addCommentForGroup and addKeyValueForGroup methods as currentGroup. Reimplemented method also is allowd to return null. Default implementation just returns empty IniLikeGroup with name set to groupName.

fileName
string fileName()

File path where the object was loaded from.

group
inout(IniLikeGroup) group(string groupName)

Get group by name.

leadingComments
auto leadingComments()
Undocumented in source. Be warned that the author may not have intended to support it.
removeGroup
void removeGroup(string groupName)

Remove group by name.

save
void save(OutRange sink)

Use Output range or delegate to retrieve strings line by line. Those strings can be written to the file or be showed in text area. Note: returned strings don't have trailing newline character.

saveToFile
void saveToFile(string fileName)

Save object to the file using .ini-like format.

saveToString
string saveToString()

Save object to string using .ini like format.

Static functions

createEmptyGroup
createEmptyGroup(string groupName)

Can be used in derived classes to create instance of IniLikeGroup.

Examples

1     import std.file;
2     import std.path;
3 
4     string contents = 
5 `# The first comment
6 [First Entry]
7 # Comment
8 GenericName=File manager
9 GenericName[ru]=Файловый менеджер
10 # Another comment
11 [Another Group]
12 Name=Commander
13 Comment=Manage files
14 # The last comment`;
15 
16     auto ilf = new IniLikeFile(iniLikeStringReader(contents), "contents.ini");
17     assert(ilf.fileName() == "contents.ini");
18     assert(equal(ilf.leadingComments(), ["# The first comment"]));
19     assert(ilf.group("First Entry"));
20     assert(ilf.group("Another Group"));
21     assert(ilf.saveToString() == contents);
22     
23     string tempFile = buildPath(tempDir(), "inilike-unittest-tempfile");
24     try {
25         assertNotThrown!IniLikeException(ilf.saveToFile(tempFile));
26         auto fileContents = cast(string)std.file.read(tempFile);
27         static if( __VERSION__ < 2067 ) {
28             assert(equal(fileContents.splitLines, contents.splitLines), "Contents should be preserved as is");
29         } else {
30             assert(equal(fileContents.lineSplitter, contents.lineSplitter), "Contents should be preserved as is");
31         }
32         
33         IniLikeFile filf; 
34         assertNotThrown!IniLikeException(filf = new IniLikeFile(tempFile));
35         assert(filf.fileName() == tempFile);
36         remove(tempFile);
37     } catch(Exception e) {
38         //environmental error in unittests
39     }
40     
41     auto firstEntry = ilf.group("First Entry");
42     
43     assert(!firstEntry.contains("NonExistent"));
44     assert(firstEntry.contains("GenericName"));
45     assert(firstEntry.contains("GenericName[ru]"));
46     assert(firstEntry["GenericName"] == "File manager");
47     assert(firstEntry.value("GenericName") == "File manager");
48     firstEntry["GenericName"] = "Manager of files";
49     assert(firstEntry["GenericName"] == "Manager of files");
50     firstEntry["Authors"] = "Unknown";
51     assert(firstEntry["Authors"] == "Unknown");
52     
53     assert(firstEntry.localizedValue("GenericName", "ru") == "Файловый менеджер");
54     firstEntry.setLocalizedValue("GenericName", "ru", "Менеджер файлов");
55     assert(firstEntry.localizedValue("GenericName", "ru") == "Менеджер файлов");
56     firstEntry.setLocalizedValue("Authors", "ru", "Неизвестны");
57     assert(firstEntry.localizedValue("Authors", "ru") == "Неизвестны");
58     
59     firstEntry.removeEntry("GenericName");
60     assert(!firstEntry.contains("GenericName"));
61     firstEntry["GenericName"] = "File Manager";
62     assert(firstEntry["GenericName"] == "File Manager");
63     
64     assert(ilf.group("Another Group")["Name"] == "Commander");
65     assert(equal(ilf.group("Another Group").byKeyValue(), [ keyValueTuple("Name", "Commander"), keyValueTuple("Comment", "Manage files") ]));
66     assert(equal(
67         ilf.group("Another Group").byIniLine(), 
68         [IniLikeLine.fromKeyValue("Name", "Commander"), IniLikeLine.fromKeyValue("Comment", "Manage files"), IniLikeLine.fromComment("# The last comment")]
69     ));
70     
71     assert(equal(ilf.byGroup().map!(g => g.name), ["First Entry", "Another Group"]));
72     
73     ilf.removeGroup("Another Group");
74     assert(!ilf.group("Another Group"));
75     assert(equal(ilf.byGroup().map!(g => g.name), ["First Entry"]));
76     
77     ilf.addGroup("Another Group");
78     assert(ilf.group("Another Group"));
79     assert(ilf.group("Another Group").byIniLine().empty);
80     assert(ilf.group("Another Group").byKeyValue().empty);
81     
82     ilf.addGroup("Other Group");
83     assert(equal(ilf.byGroup().map!(g => g.name), ["First Entry", "Another Group", "Other Group"]));
84     
85     const IniLikeFile cilf = ilf;
86     static assert(is(typeof(cilf.byGroup())));
87     static assert(is(typeof(cilf.group("First Entry").byKeyValue())));
88     static assert(is(typeof(cilf.group("First Entry").byIniLine())));
89     
90     contents = 
91 `[Group]
92 GenericName=File manager
93 [Group]
94 GenericName=Commander`;
95 
96     auto shouldThrow = collectException!IniLikeException(new IniLikeFile(iniLikeStringReader(contents), "config.ini"));
97     assert(shouldThrow !is null, "Duplicate groups should throw");
98     assert(shouldThrow.lineNumber == 3);
99     assert(shouldThrow.lineIndex == 2);
100     assert(shouldThrow.fileName == "config.ini");
101     
102     contents = 
103 `[Group]
104 Key=Value1
105 Key=Value2`;
106 
107     shouldThrow = collectException!IniLikeException(new IniLikeFile(iniLikeStringReader(contents)));
108     assert(shouldThrow !is null, "Duplicate key should throw");
109     assert(shouldThrow.lineNumber == 3);
110     
111     contents =
112 `[Group]
113 Key=Value
114 =File manager`;
115 
116     shouldThrow = collectException!IniLikeException(new IniLikeFile(iniLikeStringReader(contents)));
117     assert(shouldThrow !is null, "Empty key should throw");
118     assert(shouldThrow.lineNumber == 3);
119     
120     contents = 
121 `[Group]
122 #Comment
123 Valid=Key
124 NotKeyNotGroupNotComment`;
125 
126     shouldThrow = collectException!IniLikeException(new IniLikeFile(iniLikeStringReader(contents)));
127     assert(shouldThrow !is null, "Invalid entry should throw");
128     assert(shouldThrow.lineNumber == 4);
129     
130     contents = 
131 `#Comment
132 NotComment
133 [Group]
134 Valid=Key`;
135     shouldThrow = collectException!IniLikeException(new IniLikeFile(iniLikeStringReader(contents)));
136     assert(shouldThrow !is null, "Invalid comment should throw");
137     assert(shouldThrow.lineNumber == 2);

Meta