4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file ini_type.h Types related to reading/writing '*.ini' files. */
17 #include "core/pointer.h"
18 #include "core/forward_list.h"
20 #include "fileio_type.h"
22 /** Base class for named entities (items, groups) in an ini file. */
25 const ttd_unique_free_ptr
<char> name
; ///< the name of this item
28 IniName (const char *name
, size_t len
= 0);
30 const char *get_name (void) const
35 bool is_name (const char *name
) const
37 return strcmp (this->name
.get(), name
) == 0;
40 bool is_name (const char *name
, size_t len
) const
42 return strncmp (this->name
.get(), name
, len
) == 0 && this->name
.get()[len
] == 0;
46 const char *const name
;
49 NamePred (const char *name
, size_t len
)
50 : name(name
), len(len
)
54 bool operator() (const IniName
*item
) const
56 return item
->is_name (this->name
, this->len
);
62 /** Base class for entity lists (items, groups) in an ini file. */
64 struct IniList
: ForwardList
<T
, true> {
65 /** Clear this IniList. */
68 T
*p
= this->detach_all();
76 /** IniList destructor. */
83 * Find an entry by name.
84 * @param name the name to search for
85 * @return the item by that name, or NULL if none was found
87 T
*find (const char *name
)
89 return this->find_pred (std::bind2nd (std::mem_fun (&T::IniName::is_name
), name
));
92 const T
*find (const char *name
) const
94 return const_cast<IniList
*>(this)->find (name
);
98 * Find an entry by name.
99 * @param name the name to search for
100 * @param len use only this many chars of name
101 * @return the item by that name, or NULL if none was found
103 T
*find (const char *name
, size_t len
)
105 return this->find_pred (typename
T::IniName::NamePred (name
, len
));
108 const T
*find (const char *name
, size_t len
) const
110 return const_cast<IniList
*>(this)->find (name
, len
);
114 * Remove an entry by name.
115 * @param name the name to remove
117 T
*remove (const char *name
)
119 return this->remove_pred (std::bind2nd (std::mem_fun (&T::IniName::is_name
), name
));
124 /** Types of groups */
126 IGT_VARIABLES
= 0, ///< Values of the form "landscape = hilly".
127 IGT_LIST
= 1, ///< A list of values, separated by \n and terminated by the next group block.
128 IGT_SEQUENCE
= 2, ///< A list of uninterpreted lines, terminated by the next group block.
131 /** A single "line" in an ini file. */
132 struct IniItem
: ForwardListLink
<IniItem
>, IniName
{
133 typedef ForwardList
<IniItem
>::iterator iterator
;
134 typedef ForwardList
<IniItem
>::const_iterator const_iterator
;
136 char *value
; ///< The value of this item
137 char *comment
; ///< The comment associated with this item
139 IniItem (const char *name
, size_t len
= 0);
142 void SetValue(const char *value
);
145 /** A group within an ini file. */
146 struct IniGroup
: ForwardListLink
<IniGroup
>, IniName
, IniList
<IniItem
> {
147 typedef ForwardList
<IniGroup
>::iterator iterator
;
148 typedef ForwardList
<IniGroup
>::const_iterator const_iterator
;
150 const IniGroupType type
; ///< type of group
151 char *comment
; ///< comment for group
153 IniGroup (IniGroupType type
, const char *name
, size_t len
= 0);
156 IniItem
*get_item (const char *name
);
158 IniItem
*append (const char *name
, size_t len
= 0)
160 IniItem
*item
= new IniItem (name
, len
);
161 this->IniList
<IniItem
>::append (item
);
166 /** Ini file that only supports loading. */
167 struct IniLoadFile
: IniList
<IniGroup
> {
168 char *comment
; ///< last comment in file
169 const char * const *const list_group_names
; ///< NULL terminated list with group names that are lists
170 const char * const *const seq_group_names
; ///< NULL terminated list with group names that are sequences.
172 IniLoadFile(const char * const *list_group_names
= NULL
, const char * const *seq_group_names
= NULL
);
173 virtual ~IniLoadFile();
175 IniGroupType
get_group_type (const char *name
, size_t len
) const;
177 IniGroup
*get_group (const char *name
, size_t len
= 0);
179 IniGroup
*append (const char *name
, size_t len
)
181 IniGroupType type
= this->get_group_type (name
, len
);
182 IniGroup
*group
= new IniGroup (type
, name
, len
);
183 this->IniList
<IniGroup
>::append (group
);
187 void LoadFromDisk(const char *filename
, Subdirectory subdir
);
191 * @param filename Name of the INI file.
192 * @param subdir The subdir to load the file from.
193 * @param size [out] Size of the opened file.
194 * @return File handle of the opened file, or \c NULL.
196 virtual FILE *OpenFile(const char *filename
, Subdirectory subdir
, size_t *size
) = 0;
199 * Report an error about the file contents.
200 * @param pre Prefix text of the \a buffer part.
201 * @param buffer Part of the file with the error.
202 * @param post Suffix text of the \a buffer part.
204 virtual void ReportFileError(const char * const pre
, const char * const buffer
, const char * const post
) = 0;
207 /** Ini file that supports both loading and saving. */
208 struct IniFile
: IniLoadFile
{
209 IniFile (const char *filename
, Subdirectory subdir
, const char * const *list_group_names
= NULL
);
211 bool SaveToDisk(const char *filename
);
213 virtual FILE *OpenFile(const char *filename
, Subdirectory subdir
, size_t *size
);
214 virtual void ReportFileError(const char * const pre
, const char * const buffer
, const char * const post
);
217 #endif /* INI_TYPE_H */