Сообщение от Tim4ukys Official
Делал class лично для себя, для облегчения работы с mINI. Не нужно быть ♂dungeon master♂ чтобы разобраться в его работе, но для настоящих ♂boss of the gym♂ оставил пример по работе с ним.
Цитата:
Сообщение от Спойлер
CConfig.h:
Код:
#pragma once
// #include
#include
class
CConfig
{
public
:
// Инициализация класса
void
Init
(
std
::
string iniName
)
;
/////////// read ///////////
// Возращает число
int
GetInt
(
std
::
string stKey1
,
std
::
string stKey2
)
;
// Возращает дробное число
float
GetFloat
(
std
::
string stKey1
,
std
::
string stKey2
)
;
// Возращает true или false
bool
GetBool
(
std
::
string stKey1
,
std
::
string stKey2
)
;
// Возращает std::string
std
::
string
GetString
(
std
::
string stKey1
,
std
::
string stKey2
)
;
// Возращает const char*
const
char
*
GetConstChar
(
std
::
string stKey1
,
std
::
string stKey2
)
;
// Возращает char
char
GetChar
(
std
::
string stKey1
,
std
::
string stKey2
)
;
/////////// write ///////////
// Записывает число в ini файл
void
WriteInt
(
std
::
string stKey1
,
std
::
string stKey2
,
int
iInt
)
;
// Записывает дробное число в ini файл
void
WriteFloat
(
std
::
string stKey1
,
std
::
string stKey2
,
float
fFloat
)
;
// Записывает true или false в ini файл
void
WriteBool
(
std
::
string stKey1
,
std
::
string stKey2
,
bool
bBool
)
;
// Записывает std::string в ini файл
void
WriteString
(
std
::
string stKey1
,
std
::
string stKey2
,
std
::
string stString
)
;
// Записывает const char* в ini файл
void
WriteString
(
std
::
string stKey1
,
std
::
string stKey2
,
const
char
*
cnhString
)
;
// Записывает char в ini файл
void
WriteString
(
std
::
string stKey1
,
std
::
string stKey2
,
char
chString
)
;
private
:
// Сохраняет ini структуру в файл
void
Save
(
)
;
// Загружает ini структуру в переменную
void
Refresh
(
)
;
}
;
CConfig.cpp:
Код:
#include "CConfig.h"
#include "ini.h"
std
::
string stIniNameFile
;
mINI
::
INIStructure ini
;
void
CConfig
::
Init
(
std
::
string iniName
)
{
stIniNameFile
=
iniName
;
this
->
Refresh
(
)
;
}
/////// private ////////
void
CConfig
::
Refresh
(
)
{
mINI
::
INIFile
fileInstance
(
stIniNameFile
)
;
fileInstance
.
read
(
ini
)
;
}
void
CConfig
::
Save
(
)
{
mINI
::
INIFile
fileInstance
(
stIniNameFile
)
;
fileInstance
.
write
(
ini
)
;
}
/////// public ////////
/////// read ///////
int
CConfig
::
GetInt
(
std
::
string stKey1
,
std
::
string stKey2
)
{
this
->
Refresh
(
)
;
int
iReturnInteger
=
NULL
;
int
iErrorCode
=
sscanf
(
ini
[
stKey1
]
[
stKey2
]
.
c_str
(
)
,
"%d"
,
&
iReturnInteger
)
;
if
(
iErrorCode
!=
EOF
&&
iErrorCode
!=
NULL
)
return
iReturnInteger
;
return
-
1
;
}
float
CConfig
::
GetFloat
(
std
::
string stKey1
,
std
::
string stKey2
)
{
this
->
Refresh
(
)
;
float
fReturnFloat
=
NULL
;
int
iErrorCode
=
sscanf
(
ini
[
stKey1
]
[
stKey2
]
.
c_str
(
)
,
"%f"
,
&
fReturnFloat
)
;
if
(
iErrorCode
!=
EOF
&&
iErrorCode
!=
NULL
)
return
fReturnFloat
;
return
-
1
;
}
bool
CConfig
::
GetBool
(
std
::
string stKey1
,
std
::
string stKey2
)
{
this
->
Refresh
(
)
;
int
iReturnBool
=
NULL
;
int
iErrorCode
=
sscanf
(
ini
[
stKey1
]
[
stKey2
]
.
c_str
(
)
,
"%d"
,
&
iReturnBool
)
;
if
(
iErrorCode
!=
EOF
&&
iErrorCode
!=
NULL
)
if
(
iReturnBool
==
1
)
return
true
;
return
false
;
}
std
::
string CConfig
::
GetString
(
std
::
string stKey1
,
std
::
string stKey2
)
{
this
->
Refresh
(
)
;
return
ini
[
stKey1
]
[
stKey2
]
;
}
const
char
*
CConfig
::
GetConstChar
(
std
::
string stKey1
,
std
::
string stKey2
)
{
this
->
Refresh
(
)
;
return
ini
[
stKey1
]
[
stKey2
]
.
c_str
(
)
;
}
char
CConfig
::
GetChar
(
std
::
string stKey1
,
std
::
string stKey2
)
{
this
->
Refresh
(
)
;
std
::
string stGetString
=
ini
[
stKey1
]
[
stKey2
]
;
char
*
chReturnChar
;
strcpy
(
chReturnChar
,
stGetString
.
c_str
(
)
)
;
return
*
chReturnChar
;
}
/////// write ///////
#include
void
CConfig
::
WriteInt
(
std
::
string stKey1
,
std
::
string stKey2
,
int
iInt
)
{
ini
[
stKey1
]
[
stKey2
]
=
std
::
to_string
(
iInt
)
;
this
->
Save
(
)
;
}
void
CConfig
::
WriteFloat
(
std
::
string stKey1
,
std
::
string stKey2
,
float
fFloat
)
{
ini
[
stKey1
]
[
stKey2
]
=
std
::
to_string
(
fFloat
)
;
this
->
Save
(
)
;
}
void
CConfig
::
WriteBool
(
std
::
string stKey1
,
std
::
string stKey2
,
bool
bBool
)
{
if
(
bBool
)
ini
[
stKey1
]
[
stKey2
]
=
std
::
to_string
(
1
)
;
else
ini
[
stKey1
]
[
stKey2
]
=
std
::
to_string
(
0
)
;
this
->
Save
(
)
;
}
void
CConfig
::
WriteString
(
std
::
string stKey1
,
std
::
string stKey2
,
std
::
string stString
)
{
ini
[
stKey1
]
[
stKey2
]
=
stString
;
this
->
Save
(
)
;
}
void
CConfig
::
WriteString
(
std
::
string stKey1
,
std
::
string stKey2
,
const
char
*
cnhString
)
{
ini
[
stKey1
]
[
stKey2
]
=
cnhString
;
this
->
Save
(
)
;
}
void
CConfig
::
WriteString
(
std
::
string stKey1
,
std
::
string stKey2
,
char
chString
)
{
ini
[
stKey1
]
[
stKey2
]
=
chString
;
this
->
Save
(
)
;
}
ini.h:
[CODE]
/*
* The MIT License (MIT)
* Copyright (c) 2018 Danijel Durakovic
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
///////////////////////////////////////////////////////////////////////////////
//
// /mINI/ v0.9.7
// An INI file reader and writer for the modern age.
//
///////////////////////////////////////////////////////////////////////////////
//
// A tiny utility library for manipulating INI files with a straightforward
// API and a minimal footprint. It conforms to the (somewhat) standard INI
// format - sections and keys are case insensitive and all leading and
// trailing whitespace is ignored. Comments are lines that begin with a
// semicolon. Trailing comments are allowed on section lines.
//
// Files are read on demand, upon which data is kept in memory and the file
// is closed. This utility supports lazy writing, which only writes changes
// and updates to a file and preserves custom formatting and comments. A lazy
// write invoked by a write() call will read the output file, find what
// changes have been made and update the file accordingly. If you only need to
// generate files, use generate() instead. Section and key order is preserved
// on read, write and insert.
//
///////////////////////////////////////////////////////////////////////////////
//
// /* BASIC USAGE EXAMPLE: */
//
// /* read from file */
// mINI::INIFile file("myfile.ini");
// mINI::INIStructure ini;
// file.read(ini);
//
// /* read value; gets a reference to actual value in the structure.
// if key or section don't exist, a new empty value will be created */
// std::string& value = ini["section"]["key"];
//
// /* read value safely; gets a copy of value in the structure.
// does not alter the structure */
// std::string value = ini.get("section").get("key");
//
// /* set or update values */
// ini["section"]["key"] = "value";
//
// /* set multiple values */
// ini["section2"].set({
// {"key1", "value1"},
// {"key2", "value2"}
// });
//
// /* write updates back to file, preserving comments and formatting */
// file.write(ini);
//
// /* or generate a file (overwrites the original) */
// file.generate(ini);
//
///////////////////////////////////////////////////////////////////////////////
//
// Long live the INI file!!!
//
///////////////////////////////////////////////////////////////////////////////
#ifndef MINI_INI_H_
#define MINI_INI_H_
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace
mINI
{
namespace
INIStringUtil
{
const
std
::
string whitespaceDelimiters
=
" \t\n\r\f\v"
;
inline
void
trim
(
std
::
string
&
str
)
{
str
.
erase
(
str
.
find_last_not_of
(
whitespaceDelimiters
)
+
1
)
;
str
.
erase
(
0
,
str
.
find_first_not_of
(
whitespaceDelimiters
)
)
;
}
#ifndef MINI_CASE_SENSITIVE
inline
void
toLower
(
std
::
string
&
str
)
{
std
::
transform
(
str
.
begin
(
)
,
str
.
end
(
)
,
str
.
begin
(
)
,
::
tolower
)
;
}
#endif
inline
void
replace
(
std
::
string
&
str
,
std
::
string
const
&
a
,
std
::
string
const
&
b
)
{
if
(
!
a
.
empty
(
)
)
{
std
::
size_t pos
=
0
;
while
(
(
pos
=
str
.
find
(
a
,
pos
)
)
!=
std
::
string
::
npos
)
{
str
.
replace
(
pos
,
a
.
size
(
)
,
b
)
;
pos
+=
b
.
size
(
)
;
}
}
}
#ifdef _WIN32
const
std
::
string endl
=
"\r\n"
;
#else
const
std
::
string endl
=
"\n"
;
#endif
}
;
template
class
INIMap
{
private
:
using
T_DataIndexMap
=
std
::
unordered_map
;
using
T_DataItem
=
std
::
pair
;
using
T_DataContainer
=
std
::
vector
;
using
T_MultiArgs
=
typename
std
::
vector
>
;
T_DataIndexMap dataIndexMap
;
T_DataContainer data
;
inline
std
::
size_t
setEmpty
(
std
::
string
&
key
)
{
std
::
size_t index
=
data
.
size
(
)
;
dataIndexMap
[
key
]
=
index
;
data
.
emplace_back
(
key
,
T
(
)
)
;
return
index
;
}
public
:
using
const_iterator
=
typename
T_DataContainer
::
const_iterator
;
INIMap
(
)
{
}
INIMap
(
INIMap
const
&
other
)
{
std
::
size_t data_size
=
other
.
data
.
size
(
)
;
for
(
std
::
size_t i
=
0
;
i
second
:
setEmpty
(
key
)
;
return
data
[
index
]
.
second
;
}
T
get
(
std
::
string key
)
const
{
INIStringUtil
::
trim
(
key
)
;
#ifndef MINI_CASE_SENSITIVE
INIStringUtil
::
toLower
(
key
)
;
#endif
auto
it
=
dataIndexMap
.
find
(
key
)
;
if
(
it
==
dataIndexMap
.
end
(
)
)
{
return
T
(
)
;
}
return
T
(
data
[
it
->
second
]
.
second
)
;
}
bool
has
(
std
::
string key
)
const
{
INIStringUtil
::
trim
(
key
)
;
#ifndef MINI_CASE_SENSITIVE
INIStringUtil
::
toLower
(
key
)
;
#endif
return
(
dataIndexMap
.
count
(
key
)
==
1
)
;
}
void
set
(
std
::
string key
,
T obj
)
{
INIStringUtil
::
trim
(
key
)
;
#ifndef MINI_CASE_SENSITIVE
INIStringUtil
::
toLower
(
key
)
;
#endif
auto
it
=
dataIndexMap
.
find
(
key
)
;
if
(
it
!=
dataIndexMap
.
end
(
)
)
{
data
[
it
->
second
]
.
second
=
obj
;
}
else
{
dataIndexMap
[
key
]
=
data
.
size
(
)
;
data
.
emplace_back
(
key
,
obj
)
;
}
}
void
set
(
T_MultiArgs
const
&
multiArgs
)
{
for
(
auto
const
&
it
:
multiArgs
)
{
auto
const
&
key
=
it
.
first
;
auto
const
&
obj
=
it
.
second
;
set
(
key
,
obj
)
;
}
}
bool
remove
(
std
::
string key
)
{
INIStringUtil
::
trim
(
key
)
;
#ifndef MINI_CASE_SENSITIVE
INIStringUtil
::
toLower
(
key
)
;
#endif
auto
it
=
dataIndexMap
.
find
(
key
)
;
if
(
it
!=
dataIndexMap
.
end
(
)
)
{
std
::
size_t index
=
it
->
second
;
data
.
erase
(
data
.
begin
(
)
+
index
)
;
dataIndexMap
.
erase
(
it
)
;
for
(
auto
&
it2
:
dataIndexMap
)
{
auto
&
vi
=
it2
.
second
;
if
(
vi
>
index
)
{
vi
--
;
}
}
return
true
;
}
return
false
;
}
void
clear
(
)
{
data
.
clear
(
)
;
dataIndexMap
.
clear
(
)
;
}
std
::
size_t
size
(
)
const
{
return
data
.
size
(
)
;
}
const_iterator
begin
(
)
const
{
return
data
.
begin
(
)
;
}
const_iterator
end
(
)
const
{
return
data
.
end
(
)
;
}
}
;
using
INIStructure
=
INIMap
>
;
namespace
INIParser
{
using
T_ParseValues
=
std
::
pair
;
enum
class
PDataType
:
char
{
PDATA_NONE
,
PDATA_COMMENT
,
PDATA_SECTION
,
PDATA_KEYVALUE
,
PDATA_UNKNOWN
}
;
inline
PDataType
parseLine
(
std
::
string line
,
T_ParseValues
&
parseData
)
{
parseData
.
first
.
clear
(
)
;
parseData
.
second
.
clear
(
)
;
INIStringUtil
::
trim
(
line
)
;
if
(
line
.
empty
(
)
)
{
return
PDataType
::
PDATA_NONE
;
}
char
firstCharacter
=
line
[
0
]
;
if
(
firstCharacter
==
';'
)
{
return
PDataType
::
PDATA_COMMENT
;
}
if
(
firstCharacter
==
'['
)
{
auto
commentAt
=
line
.
find_first_of
(
';'
)
;
if
(
commentAt
!=
std
::
string
::
npos
)
{
line
=
line
.
substr
(
0
,
commentAt
)
;
}
auto
closingBracketAt
=
line
.
find_last_of
(
']'
)
;
if
(
closingBracketAt
!=
std
::
string
::
npos
)
{
auto
section
=
line
.
substr
(
1
,
closingBracketAt
-
1
)
;
INIStringUtil
::
trim
(
section
)
;
parseData
.
first
=
section
;
return
PDataType
::
PDATA_SECTION
;
}
}
auto
lineNorm
=
line
;
INIStringUtil
::
replace
(
lineNorm
,
"\\="
,
" "
)
;
auto
equalsAt
=
lineNorm
.
find_first_of
(
'='
)
;
if
(
equalsAt
!=
std
::
string
::
npos
)
{
auto
key
=
line
.
substr
(
0
,
equalsAt
)
;
INIStringUtil
::
trim
(
key
)
;
INIStringUtil
::
replace
(
key
,
"\\="
,
"="
)
;
auto
value
=
line
.
substr
(
equalsAt
+
1
)
;
INIStringUtil
::
trim
(
value
)
;
parseData
.
first
=
key
;
parseData
.
second
=
value
;
return
PDataType
::
PDATA_KEYVALUE
;
}
return
PDataType
::
PDATA_UNKNOWN
;
}
}
;
class
INIReader
{
public
:
using
T_LineData
=
std
::
vector
;
using
T_LineDataPtr
=
std
::
shared_ptr
;
private
:
std
::
ifstream fileReadStream
;
T_LineDataPtr lineData
;
T_LineData
readFile
(
)
{
std
::
string fileContents
;
fileReadStream
.
seekg
(
0
,
std
::
ios
::
end
)
;
fileContents
.
resize
(
fileReadStream
.
tellg
(
)
)
;
fileReadStream
.
seekg
(
0
,
std
::
ios
::
beg
)
;
std
::
size_t fileSize
=
fileContents
.
size
(
)
;
fileReadStream
.
read
(
&
fileContents
[
0
]
,
fileSize
)
;
fileReadStream
.
close
(
)
;
T_LineData output
;
if
(
fileSize
==
0
)
{
return
output
;
}
std
::
string buffer
;
buffer
.
reserve
(
50
)
;
for
(
std
::
size_t i
=
0
;
i
(
)
;
}
}
~
INIReader
(
)
{
}
bool
operator
>>
(
INIStructure
&
data
)
{
if
(
!
fileReadStream
.
is_open
(
)
)
{
return
false
;
}
T_LineData fileLines
=
readFile
(
)
;
std
::
string section
;
bool
inSection
=
false
;
INIParser
::
T_ParseValues parseData
;
for
(
auto
const
&
line
:
fileLines
)
{
auto
parseResult
=
INIParser
::
parseLine
(
line
,
parseData
)
;
if
(
parseResult
==
INIParser
::
PDataType
::
PDATA_SECTION
)
{
inSection
=
true
;
data
[
section
=
parseData
.
first
]
;
}
else
if
(
inSection
&&
parseResult
==
INIParser
::
PDataType
::
PDATA_KEYVALUE
)
{
auto
const
&
key
=
parseData
.
first
;
auto
const
&
value
=
parseData
.
second
;
data
[
section
]
[
key
]
=
value
;
}
if
(
lineData
&&
parseResult
!=
INIParser
::
PDataType
::
PDATA_UNKNOWN
)
{
if
(
parseResult
==
INIParser
::
PDataType
::
PDATA_KEYVALUE
&&
!
inSection
)
{
continue
;
}
lineData
->
emplace_back
(
line
)
;
}
}
return
true
;
}
T_LineDataPtr
getLines
(
)
{
return
lineData
;
}
}
;
class
INIGenerator
{
private
:
std
::
ofstream fileWriteStream
;
public
:
bool
prettyPrint
=
false
;
INIGenerator
(
std
::
string
const
&
filename
)
{
fileWriteStream
.
open
(
filename
,
std
::
ios
::
out
|
std
::
ios
::
binary
)
;
}
~
INIGenerator
(
)
{
}
bool
operator
first
;
auto
const
&
collection
=
it
->
second
;
fileWriteStream
first
;
INIStringUtil
::
replace
(
key
,
"="
,
"\\="
)
;
auto
value
=
it2
->
second
;
INIStringUtil
::
trim
(
value
)
;
fileWriteStream
;
using
T_LineDataPtr
=
std
::
shared_ptr
;
std
::
string filename
;
T_LineData
getLazyOutput
(
T_LineDataPtr
const
&
lineData
,
INIStructure
&
data
,
INIStructure
&
original
)
{
T_LineData output
;
INIParser
::
T_ParseValues parseData
;
std
::
string sectionCurrent
;
bool
parsingSection
=
false
;
bool
continueToNextSection
=
false
;
bool
discardNextEmpty
=
false
;
bool
writeNewKeys
=
false
;
std
::
size_t lastKeyLine
=
0
;
for
(
auto
line
=
lineData
->
begin
(
)
;
line
!=
lineData
->
end
(
)
;
++
line
)
{
if
(
!
writeNewKeys
)
{
auto
parseResult
=
INIParser
::
parseLine
(
*
line
,
parseData
)
;
if
(
parseResult
==
INIParser
::
PDataType
::
PDATA_SECTION
)
{
if
(
parsingSection
)
{
writeNewKeys
=
true
;
parsingSection
=
false
;
--
line
;
continue
;
}
sectionCurrent
=
parseData
.
first
;
if
(
data
.
has
(
sectionCurrent
)
)
{
parsingSection
=
true
;
continueToNextSection
=
false
;
discardNextEmpty
=
false
;
output
.
emplace_back
(
*
line
)
;
lastKeyLine
=
output
.
size
(
)
;
}
else
{
continueToNextSection
=
true
;
discardNextEmpty
=
true
;
continue
;
}
}
else
if
(
parseResult
==
INIParser
::
PDataType
::
PDATA_KEYVALUE
)
{
if
(
continueToNextSection
)
{
continue
;
}
if
(
data
.
has
(
sectionCurrent
)
)
{
auto
&
collection
=
data
[
sectionCurrent
]
;
auto
const
&
key
=
parseData
.
first
;
auto
const
&
value
=
parseData
.
second
;
if
(
collection
.
has
(
key
)
)
{
auto
outputValue
=
collection
[
key
]
;
if
(
value
==
outputValue
)
{
output
.
emplace_back
(
*
line
)
;
}
else
{
INIStringUtil
::
trim
(
outputValue
)
;
auto
lineNorm
=
*
line
;
INIStringUtil
::
replace
(
lineNorm
,
"\\="
,
" "
)
;
auto
equalsAt
=
lineNorm
.
find_first_of
(
'='
)
;
auto
valueAt
=
lineNorm
.
find_first_not_of
(
INIStringUtil
::
whitespaceDelimiters
,
equalsAt
+
1
)
;
std
::
string outputLine
=
line
->
substr
(
0
,
valueAt
)
;
if
(
prettyPrint
&&
equalsAt
+
1
==
valueAt
)
{
outputLine
+=
" "
;
}
outputLine
+=
outputValue
;
output
.
emplace_back
(
outputLine
)
;
}
lastKeyLine
=
output
.
size
(
)
;
}
}
}
else
{
if
(
discardNextEmpty
&&
line
->
empty
(
)
)
{
discardNextEmpty
=
false
;
}
else
if
(
parseResult
!=
INIParser
::
PDataType
::
PDATA_UNKNOWN
)
{
output
.
emplace_back
(
*
line
)
;
}
}
}
if
(
writeNewKeys
||
std
::
next
(
line
)
==
lineData
->
end
(
)
)
{
T_LineData linesToAdd
;
if
(
data
.
has
(
sectionCurrent
)
&&
original
.
has
(
sectionCurrent
)
)
{
auto
const
&
collection
=
data
[
sectionCurrent
]
;
auto
const
&
collectionOriginal
=
original
[
sectionCurrent
]
;
for
(
auto
const
&
it
:
collection
)
{
auto
key
=
it
.
first
;
if
(
collectionOriginal
.
has
(
key
)
)
{
continue
;
}
auto
value
=
it
.
second
;
INIStringUtil
::
replace
(
key
,
"="
,
"\\="
)
;
INIStringUtil
::
trim
(
value
)
;
linesToAdd
.
emplace_back
(
key
+
(
(
prettyPrint
)
?
" = "
:
"="
)
+
value
)
;
}
}
if
(
!
linesToAdd
.
empty
(
)
)
{
output
.
insert
(
output
.
begin
(
)
+
lastKeyLine
,
linesToAdd
.
begin
(
)
,
linesToAdd
.
end
(
)
)
;
}
if
(
writeNewKeys
)
{
writeNewKeys
=
false
;
--
line
;
}
}
}
for
(
auto
const
&
it
:
data
)
{
auto
const
&
section
=
it
.
first
;
if
(
original
.
has
(
section
)
)
{
continue
;
}
if
(
prettyPrint
&&
output
.
size
(
)
>
0
&&
!
output
.
back
(
)
.
empty
(
)
)
{
output
.
emplace_back
(
)
;
}
output
.
emplace_back
(
"["
+
section
+
"]"
)
;
auto
const
&
collection
=
it
.
second
;
for
(
auto
const
&
it2
:
collection
)
{
auto
key
=
it2
.
first
;
auto
value
=
it2
.
second
;
INIStringUtil
::
replace
(
key
,
"="
,
"\\="
)
;
INIStringUtil
::
trim
(
value
)
;
output
.
emplace_back
(
key
+
(
(
prettyPrint
)
?
" = "
:
"="
)
+
value
)
;
}
}
return
output
;
}
public
:
bool
prettyPrint
=
false
;
INIWriter
(
std
::
string
const
&
filename
)
:
filename
(
filename
)
{
}
~
INIWriter
(
)
{
}
bool
operator
>
originalData
)
)
{
lineData
=
reader
.
getLines
(
)
;
}
}
if
(
!
readSuccess
)
{
return
false
;
}
T_LineData output
=
getLazyOutput
(
lineData
,
data
,
originalData
)
;
std
::
ofstream
fileWriteStream
(
filename
,
std
::
ios
::
out
|
std
::
ios
::
binary
)
;
if
(
fileWriteStream
.
is_open
(
)
)
{
if
(
output
.
size
(
)
)
{
auto
line
=
output
.
begin
(
)
;
for
(
;
;
)
{
fileWriteStream
>
data
;
}
bool
generate
(
INIStructure
const
&
data
,
bool
pretty
=
false
)
const
{
if
(
filename
.
empty
(
)
)
{
return
false
;
}
INIGenerator
generator
(
filename
)
;
generator
.
prettyPrint
=
pretty
;
return
generator
|
Цитата:
Сообщение от Спойлер
DLLMain.cpp:
Код:
#include "DLLMain.hpp"
CConfig
*
pConfig
;
int
WINAPI
vExample
(
void
*
p
)
{
/*
Вроде бы, если ini файла нет, то он создаться сам. (но это не точно)
Полный путь до ini файла вписывать не нужно, а можно просто вписать имя.
Лучше использовать не ini файл, а реестр.
Его можно взять тута - https://github.com/KiN4StAt/BulletTracer/tree/master/fast
*/
pConfig
->
Init
(
"Example.ini"
)
;
std
::
cout
GetBool
(
"MAIN"
,
"bState"
)
)
std
::
cout
(
vExample
)
,
hModule
,
0
,
nullptr
)
;
break
;
}
}
return
TRUE
;
}
DLLMain.hpp:
Код:
#include
#include "CConfig.h"
extern
CConfig
*
pConfig
;
Example.ini:
|
|