简单的INI解析封装

简单封装的一个ini解析处理类(支持跨平台)。支持功能:

  1. 加载并解析指定ini文件中的配置;
  2. 读取指定 section 下的指定 key 的值。提示:支持按数值型读取,或按文本类型读取;
    使用示例:

    1 auto fWidth         = 480.0f;
    2 auto fHeight        = 320.0f;
    3
    4 ns_ini::IniParser ini;
    5 ini.open(strConfigFile.c_str());
    6 fWidth              = ini.readFloat("glview", "screen_width", fWidth);
    7 fHeight             = ini.readFloat("glview", "screen_height", fHeight);
  3. 支持新段、项、值写入;提示:如果写入的项是已经存在的,则为修改旧项值;
    示例:

     1 auto fWidth         = 480.0f;
     2 auto fHeight        = 320.0f;
     3
     4 ns_ini::IniParser ini;
     5 ini.open(strConfigFile.c_str());
     6 fWidth              = ini.readFloat("glview", "screen_width", fWidth);
     7 fHeight             = ini.readFloat("glview", "screen_height", fHeight);
     8
     9 ini.writeFloat("glview", "screen_height, 777.77f); // 将旧值修改为 777.77f
    10 ini.writeInt("glview", "screen_height, 666); // 再次将旧值修改为 666
    11 ini.writeText("glview", "screen_height, "jacc.kim"); // 再次将旧值修改为 文本"jacc.kim"

源码如下:

 1 /******************************************************************************
 2
 3                              I‘m jacc.kim
 4
 5     CreateDate: 2017-06-13 17:12:16
 6     FileName  : JKIniParser.h
 7     Version   : 1.00
 8     Author    : jacc.kim
 9     Summary   : ini parser wrapper
10
11 ******************************************************************************/
12 #pragma once
13
14 #include <list>
15 #include <map>
16
17 namespace ns_ini
18 {
19
20 class Section;
21
22 /******************************************************************************
23  * create   : (jacc.kim) [06-13-2017]
24  * summary  : class IniParser
25 ******************************************************************************/
26 class IniParser
27 {
28 public:
29     void                                        setIniFile(const char* const pcszIniFile);
30     bool                                        open(const char* const pcszIniFile = nullptr);
31     bool                                        save(const char* const pcszIniFile = nullptr);
32     void                                        close();
33
34     unsigned int                                getSectionAmount() const;
35     bool                                        isSectionExisted(const char* const pcszSection) const;
36     bool                                        isParameterExisted(const char* const pcszSection, const char* const pcszParameter) const;
37
38     int                                         readInt(const char* const pcszSection, const char* const pcszKey, const int def = 0) const;
39     unsigned int                                readUnsignedInt(const char* const pcszSection, const char* const pcszKey, const unsigned int def = 0u) const;
40     bool                                        readBool(const char* const pcszSection, const char* const pcszKey, const bool def = false) const;
41     float                                       readFloat(const char* const pcszSection, const char* const pcszKey, const float def = 0.0f) const;
42     double                                      readDouble(const char* const pcszSection, const char* const pcszKey, const double def = 0.0) const;
43     const char*                                 readText(const char* const pcszSection, const char* const pcszKey, const char* const def = nullptr) const;
44
45     // !!!note: write existed section & key, the old value will be replaced.
46     void                                        writeInt(const char* const pcszSection, const char* const pcszKey, const int value);
47     void                                        writeUnsignedInt(const char* const pcszSection, const char* const pcszKey, const unsigned int value);
48     void                                        writeBool(const char* const pcszSection, const char* const pcszKey, const bool value);
49     void                                        writeFloat(const char* const pcszSection, const char* const pcszKey, const float value);
50     void                                        writeDouble(const char* const pcszSection, const char* const pcszKey, const double value);
51     void                                        writeText(const char* const pcszSection, const char* const pcszKey, const char* const value);
52
53     bool                                        remove(const char* const pcszSection, const char* const pcszKey);
54     bool                                        remove(const char* const pcszSection);
55     void                                        clear();
56
57 public:
58     IniParser();
59     ~IniParser();
60
61     Section*                                    getSection(const char* const pcszSection) const;
62     Section&                                    operator[](const char* const pcszSection) const;
63
64 private:
65     IniParser(const IniParser& rhs)/* = delete*/;
66     IniParser& operator=(const IniParser& rhs)/* = delete*/;
67
68     void                                        trimLeft(char*& p, char*& q);
69     void                                        trimRight(char*& p, char*& q);
70     void                                        trim(char*& p, char*& q);
71     void                                        trimRN0(char*& p, char*& q);
72     bool                                        isEndWithN(const char* p, const size_t nLength);
73     bool                                        stringEqual(const char* p, const char* q, int nChar = INT_MAX) const;
74     bool                                        isSectionName(char* p, char* q);
75     char*                                       splitKeyValue(char* p, char* q);
76     void                                        parseIniLine(char* szIniLine);
77     void                                        addSection(char* szSectionName);
78     void                                        addParameter(char* szKey, char* szValue);
79
80 private:
81     typedef std::list<Section*>                 SectionList;
82     typedef SectionList::iterator               SectionListIter;
83
84     // key = section name, value = section‘s ptr
85     typedef std::map <std::string, SectionListIter> SectionMap;
86
87 private:
88     std::string                                 m_strIniFile;       // ini file name
89     SectionList                                 m_listSections;     // all sections.
90     SectionMap                                  m_mapSectionName;   // section <--> index mapping.(only reference.)
91
92 };//class IniParser
93
94 }//namespace ns_ini

IniParser.h 文件

  1 #include "JKIniParser.h"
  2
  3 namespace ns_ini
  4 {
  5
  6 /******************************************************************************
  7  * create   : (jacc.kim) [06-13-2017]
  8  * summary  : class Section
  9 ******************************************************************************/
 10 class Section
 11 {
 12 public:
 13     struct Parameter
 14     {
 15         std::string                             key;
 16         std::string                             value;
 17     };//struct Parameter
 18
 19     typedef std::list<Parameter>                ParameterList;
 20     typedef ParameterList::iterator             ParameterListIter;
 21     typedef std::map<std::string, ParameterListIter>    ParameterMap;
 22
 23 public:
 24     Section(const char* pcszSectionName) : m_strSectionName  (pcszSectionName)
 25                                          , m_listParameters  ()
 26                                          , m_mapParameterKeys()
 27     {}
 28
 29     ~Section() {
 30         this->clear();
 31     }
 32
 33     const char* getSectionName() const {
 34         return m_strSectionName.c_str();
 35     }
 36
 37     bool isParameterExisted(const char* const pcszKey) const {
 38         return m_mapParameterKeys.find(pcszKey) != m_mapParameterKeys.end();
 39     }
 40
 41     Parameter& operator[](const char* const pcszKey) const {
 42         auto iter                               = m_mapParameterKeys.find(pcszKey);
 43         return *(iter->second);
 44     }
 45
 46     const char* read(const char* const pcszKey) {
 47         const char* pcszRetValue                = nullptr;
 48         if (nullptr != pcszKey) {
 49             auto iter                           = m_mapParameterKeys.find(pcszKey);;
 50             if (m_mapParameterKeys.end() != iter) {
 51                 pcszRetValue                    = (*(iter->second)).value.c_str();
 52             }
 53         }
 54         return pcszRetValue;
 55     }
 56
 57     bool write(const char* const pcszKey, const char* const pcszValue) {
 58         auto iter = m_mapParameterKeys.find(pcszKey);
 59         if (m_mapParameterKeys.end() == iter) {
 60             Parameter param = { pcszKey, pcszValue };
 61             m_listParameters.emplace_back(param);
 62             m_mapParameterKeys[pcszKey] = --m_listParameters.end();
 63             return true;
 64         }
 65         (*this)[pcszKey].value                  = pcszValue;
 66         return true;
 67     }
 68
 69     bool remove(const char* pcszKey) {
 70         auto bIsSuccess                         = false;
 71         if (nullptr != pcszKey) {
 72             auto iter                           = m_mapParameterKeys.find(pcszKey);
 73             if (m_mapParameterKeys.end() != iter) {
 74                 m_listParameters.erase(iter->second);
 75                 m_mapParameterKeys.erase(iter);
 76                 bIsSuccess                      = true;
 77             }
 78         }
 79         return bIsSuccess;
 80     }
 81
 82     void clear() {
 83         m_listParameters.clear();
 84         m_mapParameterKeys.clear();
 85     }
 86
 87     ParameterList& getAllParameters() {
 88         return m_listParameters;
 89     }
 90
 91 private:
 92     std::string                                 m_strSectionName;
 93     ParameterList                               m_listParameters;
 94     ParameterMap                                m_mapParameterKeys;
 95
 96 };//class Section
 97
 98 ///////////////////////////////////////////////////////////////////////////////
 99 // class IniParser
100 IniParser::IniParser() : m_strIniFile    ("")
101                        , m_listSections  ()
102                        , m_mapSectionName()
103 {
104
105 }
106
107 IniParser::~IniParser() {
108     this->clear();
109 }
110
111 void IniParser::setIniFile(const char* const pcszIniFile) {
112     if (nullptr == pcszIniFile) {
113         return;
114     }
115     m_strIniFile                    = pcszIniFile;
116 }
117
118 bool IniParser::open(const char* const pcszIniFile/* = nullptr*/) {
119     auto bIsSuccess                 = false;
120     const char* pcszOpenFile        = nullptr != pcszIniFile ? pcszIniFile : m_strIniFile.c_str();
121     if (nullptr == pcszOpenFile) {
122         return bIsSuccess;
123     }
124     if (nullptr != pcszIniFile) {
125         this->setIniFile(pcszIniFile);
126     }
127     this->clear();
128     auto pINIFile                   = fopen(pcszIniFile, "rb");
129     if (nullptr != pINIFile) {
130         bIsSuccess = true;
131         const size_t nBUFF_SIZE     = 2048;
132         char szBuff[nBUFF_SIZE];
133         while (!feof(pINIFile)) {
134             memset((void*)szBuff, 0x0L, nBUFF_SIZE);
135             fgets(szBuff, nBUFF_SIZE, pINIFile);
136             this->parseIniLine(szBuff);
137         }
138         fclose(pINIFile);
139         pINIFile                    = nullptr;
140     }
141
142     return bIsSuccess;
143 }
144
145 bool IniParser::save(const char* const pcszIniFile/* = nullptr*/) {
146     auto bIsSuccess                 = false;
147     const char* pcszSaveFile        = nullptr != pcszIniFile ? pcszIniFile : m_strIniFile.c_str();
148     if (nullptr == pcszSaveFile) {
149         return bIsSuccess;  // 没有可保存的路径
150     }
151     ::remove(pcszSaveFile);
152     auto pINIFile                   = fopen(pcszSaveFile, "ab+");
153     if (nullptr != pINIFile) {
154         bIsSuccess                  = true;
155         auto iter                   = m_listSections.begin();
156         const auto iterend          = m_listSections.end();
157         const size_t nBUFF_SIZE     = 2048;
158         char szBuffer[nBUFF_SIZE];
159         Section* pSection           = nullptr;
160         for (; iterend != iter;/* ++iter*/) {
161             pSection                = *iter;
162             const char* pcszSectionName = pSection->getSectionName();
163             fputs("[", pINIFile);
164             fputs(pcszSectionName, pINIFile);
165             fputs("]\r\n", pINIFile);
166             auto& allParameters     = (*iter)->getAllParameters();
167             auto listiter           = allParameters.begin();
168             const auto listiterend  = allParameters.end();
169             for (; listiterend != listiter; ++listiter) {
170                 auto& param         = *listiter;
171                 memset((void*)szBuffer, 0x0L, nBUFF_SIZE);
172                 memcpy(szBuffer, param.key.c_str(), param.key.length());
173                 szBuffer[param.key.length()] = ‘=‘;
174                 memcpy(szBuffer + param.key.length() + 1, param.value.c_str(), param.value.length());
175                 const auto nEndPos    = param.key.length() + 1 + param.value.length();
176                 szBuffer[nEndPos + 1] = ‘\0‘;
177                 fputs(szBuffer, pINIFile);
178                 if (!this->isEndWithN(szBuffer, nEndPos + 1)) {
179                     fputs("\r\n", pINIFile);
180                 }
181             }
182             if (iterend != ++iter) {
183                 fputs("\r\n", pINIFile);
184             }
185         }
186         fclose(pINIFile);
187         pINIFile = nullptr;
188     }
189
190     return bIsSuccess;
191 }
192
193 void IniParser::close() {
194     this->save();
195     this->clear();
196     this->setIniFile(nullptr);
197 }
198
199 unsigned int IniParser::getSectionAmount() const {
200     return static_cast<unsigned int>(m_listSections.size());
201 }
202
203 bool IniParser::isSectionExisted(const char* const pcszSection) const {
204     return nullptr != this->getSection(pcszSection);
205 }
206
207 bool IniParser::isParameterExisted(const char* const pcszSection, const char* const pcszParameter) const {
208     auto pSection = this->getSection(pcszSection);
209     return nullptr != pSection && pSection->isParameterExisted(pcszParameter);
210 }
211
212 int IniParser::readInt(const char* const pcszSection, const char* const pcszKey, const int def/* = 0*/) const {
213     int retValue                    = def;
214     const char* pcszText            = this->readText(pcszSection, pcszKey, nullptr);
215     if (nullptr != pcszText) {
216         if (1 != sscanf(pcszText, "%d", &retValue)) {
217             retValue                = def; // 读取失败.
218         }
219     }
220     return retValue;
221 }
222
223 unsigned int IniParser::readUnsignedInt(const char* const pcszSection, const char* const pcszKey, const unsigned int def/* = 0u*/) const {
224     unsigned int retValue           = def;
225     const char* pcszText            = this->readText(pcszSection, pcszKey, nullptr);
226     if (nullptr != pcszText) {
227         if (1 != sscanf(pcszText, "%u", &retValue)) {
228             retValue                = def; // 读取失败.
229         }
230     }
231     return retValue;
232 }
233
234 bool IniParser::readBool(const char* const pcszSection, const char* const pcszKey, const bool def/* = false*/) const {
235     bool retValue                   = def;
236     const char* pcszText            = this->readText(pcszSection, pcszKey, nullptr);
237     if (nullptr != pcszText) {
238         int iTempVal = 0;
239         if (1 == sscanf(pcszText, "%d", &iTempVal)) {
240             return 0 == iTempVal ? false : true;
241         } else if (this->stringEqual(pcszText, "true")) {
242             return true;
243         } else {
244             return false;
245         }
246     }
247     return retValue;
248 }
249
250 float IniParser::readFloat(const char* const pcszSection, const char* const pcszKey, const float def/* = 0.0f*/) const {
251     float retValue                  = def;
252     const char* pcszText            = this->readText(pcszSection, pcszKey, nullptr);
253     if (nullptr != pcszText) {
254         if (1 != sscanf(pcszText, "%f", &retValue)) {
255             retValue                = def; // 读取失败.
256         }
257     }
258     return retValue;
259 }
260
261 double IniParser::readDouble(const char* const pcszSection, const char* const pcszKey, const double def/* = 0.0*/) const {
262     double retValue                 = def;
263     const char* pcszText            = this->readText(pcszSection, pcszKey, nullptr);
264     if (nullptr != pcszText) {
265         if (1 != sscanf(pcszText, "%lf", &retValue)) {
266             retValue                = def; // 读取失败.
267         }
268     }
269     return retValue;
270 }
271
272 const char* IniParser::readText(const char* const pcszSection, const char* const pcszKey, const char* const def/* = nullptr*/) const {
273     const char* pcszRetValue        = def;
274     auto pSection                   = this->getSection(pcszSection);
275     if (nullptr != pSection) {
276         pcszRetValue                = pSection->read(pcszKey);
277     }
278     return pcszRetValue;
279 }
280
281 void IniParser::writeInt(const char* const pcszSection, const char* const pcszKey, const int value) {
282     const size_t nBUFF_SIZE         = 256;
283     char szBuff[nBUFF_SIZE];
284     memset((void*)szBuff, 0x0L, nBUFF_SIZE);
285     sprintf(szBuff, "%d", value);
286     this->writeText(pcszSection, pcszKey, szBuff);
287 }
288
289 void IniParser::writeUnsignedInt(const char* const pcszSection, const char* const pcszKey, const unsigned int value) {
290     const size_t nBUFF_SIZE         = 256;
291     char szBuff[nBUFF_SIZE];
292     memset((void*)szBuff, 0x0L, nBUFF_SIZE);
293     sprintf(szBuff, "%u", value);
294     this->writeText(pcszSection, pcszKey, szBuff);
295 }
296
297 void IniParser::writeBool(const char* const pcszSection, const char* const pcszKey, const bool value) {
298     const size_t nBUFF_SIZE         = 256;
299     char szBuff[nBUFF_SIZE];
300     memset((void*)szBuff, 0x0L, nBUFF_SIZE);
301     sprintf(szBuff, "%d", value ? 1 : 0);
302     this->writeText(pcszSection, pcszKey, szBuff);
303 }
304
305 void IniParser::writeFloat(const char* const pcszSection, const char* const pcszKey, const float value) {
306     const size_t nBUFF_SIZE         = 256;
307     char szBuff[nBUFF_SIZE];
308     memset((void*)szBuff, 0x0L, nBUFF_SIZE);
309     sprintf(szBuff, "%g", value);
310     this->writeText(pcszSection, pcszKey, szBuff);
311 }
312
313 void IniParser::writeDouble(const char* const pcszSection, const char* const pcszKey, const double value) {
314     const size_t nBUFF_SIZE         = 256;
315     char szBuff[nBUFF_SIZE];
316     memset((void*)szBuff, 0x0L, nBUFF_SIZE);
317     sprintf(szBuff, "%g", value);
318     this->writeText(pcszSection, pcszKey, szBuff);
319 }
320
321 void IniParser::writeText(const char* const pcszSection, const char* const pcszKey, const char* const value) {
322     if (nullptr != pcszSection && nullptr != pcszKey && nullptr != value) {
323         auto iter                   = m_mapSectionName.find(pcszSection);
324         Section* pSection           = nullptr;
325         if (m_mapSectionName.end() == iter) {
326             pSection                = new (std::nothrow) Section(pcszSection);
327             if (nullptr == pSection) {
328                 return;
329             }
330             m_listSections.emplace_back(pSection);
331             m_mapSectionName[pcszSection] = --m_listSections.end();
332         } else {
333             pSection                = *(iter->second);
334         }
335         pSection->write(pcszKey, value);
336     }
337 }
338
339 bool IniParser::remove(const char* const pcszSection, const char* const pcszKey) {
340     auto bIsSuccess                 = false;
341     if (nullptr != pcszSection) {
342         auto iter                   = m_mapSectionName.find(pcszSection);
343         if (m_mapSectionName.end() != iter) {
344             auto pSection           = *(iter->second);
345             if (nullptr != pSection) {
346                 bIsSuccess          = pSection->remove(pcszKey);
347             }
348         }
349     }
350     return bIsSuccess;
351 }
352
353 bool IniParser::remove(const char* const pcszSection) {
354     auto bIsSuccess                 = false;
355     if (nullptr != pcszSection) {
356         auto iter                   = m_mapSectionName.find(pcszSection);
357         if (m_mapSectionName.end() != iter) {
358             auto list_iter          = iter->second;
359             Section* pSection       = *list_iter;
360             if (nullptr != pSection) {
361                 delete pSection;
362                 pSection            = nullptr;
363             }
364             m_listSections.erase(list_iter);
365             m_mapSectionName.erase(iter);
366             bIsSuccess              = true;
367         }
368     }
369     return bIsSuccess;
370 }
371
372 void IniParser::clear() {
373     auto iter                       = m_listSections.begin();
374     const auto iterend              = m_listSections.end();
375     Section* pSection               = nullptr;
376     for (; iterend != iter; ++iter) {
377         pSection                    = *iter;
378         if (nullptr != pSection) {
379             delete pSection;
380             pSection                = nullptr;
381         }
382     }
383     m_listSections.clear();
384     m_mapSectionName.clear();
385 }
386
387 Section* IniParser::getSection(const char* const pcszSection) const {
388     Section* pRetSection            = nullptr;
389     auto iter                       = m_mapSectionName.find(pcszSection);
390     if (m_mapSectionName.end() != iter) {
391         pRetSection                 = *(iter->second);
392     }
393     return pRetSection;
394 }
395
396 Section& IniParser::operator[](const char* const pcszSection) const {
397     auto iter                       = m_mapSectionName.find(pcszSection);
398     return *(*(iter->second));
399 }
400
401 void IniParser::trimLeft(char*& p, char*& q) {
402     if (nullptr != p) {
403         while (‘ ‘ == *p && ++p <= q);
404     }
405 }
406
407 void IniParser::trimRight(char*& p, char*& q) {
408     if (nullptr != q) {
409         while (‘ ‘ == *q && --q >= p);
410     }
411 }
412
413 void IniParser::trim(char*& p, char*& q) {
414     this->trimLeft(p, q);
415     this->trimRight(p, q);
416 }
417
418 void IniParser::trimRN0(char*& p, char*& q) {
419     if (nullptr != q) {
420         while ((‘\0‘ == *q || ‘\r‘ == *q || ‘\n‘ == *q) && --q >= p);
421     }
422 }
423
424 bool IniParser::isEndWithN(const char* p, const size_t nLength) {
425     if (0 == nLength) {
426         return false;
427     }
428     const char* q = p + nLength;
429     while (‘\0‘ == *q && --q >= p);
430     return (q >= p) && (‘\n‘ == *q);
431 }
432
433 bool IniParser::stringEqual(const char* p, const char* q, int nChar/* = INT_MAX*/) const {
434     int n = 0;
435     if (p == q) {
436         return true;
437     }
438     while (*p && *q && *p == *q && n < nChar) {
439         ++p;
440         ++q;
441         ++n;
442     }
443     if ((n == nChar) || (*p == 0 && *q == 0)) {
444         return true;
445     }
446     return false;
447 }
448
449 bool IniParser::isSectionName(char* p, char* q) {
450     if (nullptr == p || nullptr == q) {
451         return false;
452     }
453     return ‘[‘ == *p && ‘]‘ == *q;
454 }
455
456 char* IniParser::splitKeyValue(char* p, char* q) {
457     char* pRetEqualSignPos = p;
458     while (‘=‘ != *pRetEqualSignPos && ++pRetEqualSignPos < q);
459     return pRetEqualSignPos;
460 }
461
462 void IniParser::parseIniLine(char* szIniLine) {
463     char* p = szIniLine;
464     char* q = p + strlen(p);
465     this->trimRN0(p, q);
466     this->trim(p, q);
467     if (p < q) {
468         // 只有这种情况才需要处理.因为 p > q,肯定不需要处理,说明全都是空格.如果p = q也不需要处理,因为只有一个字符还需要处理什么?
469         *(q + 1) = ‘\0‘;
470         if (this->isSectionName(p, q)) {
471             *q = ‘\0‘;
472             ++p;
473             this->addSection(p);
474         } else {
475             char* szEqualSignPos = this->splitKeyValue(p, q);
476             if (szEqualSignPos > p && szEqualSignPos < q) {
477                 *szEqualSignPos = ‘\0‘;
478                 ++szEqualSignPos;
479                 this->addParameter(p, szEqualSignPos);
480             }
481         }
482     }
483 }
484
485 void IniParser::addSection(char* szSectionName) {
486     auto iter                       = m_mapSectionName.find(szSectionName);
487     if (m_mapSectionName.end() != iter) {
488         // 已存在
489         auto listiter               = iter->second;
490         m_listSections.emplace_back(*listiter);
491         m_listSections.erase(listiter);
492         m_mapSectionName.erase(iter);
493         m_mapSectionName[szSectionName] = --m_listSections.end();
494         return;
495     }
496     Section* pSection               = new (std::nothrow) Section(szSectionName);
497     if (nullptr == pSection) {
498         return;
499     }
500     m_listSections.emplace_back(pSection);
501     m_mapSectionName[szSectionName] = --m_listSections.end();
502 }
503
504 void IniParser::addParameter(char* szKey, char* szValue) {
505     if (m_listSections.empty()) {
506         return;
507     }
508     auto pSection                   = m_listSections.back();
509     pSection->write(szKey, szValue);
510 }
511
512 }//namespace ns_ini

IniParser.cpp 文件

如果对该封装有改进或不当之处,欢迎指定、交流!

时间: 2024-10-16 10:25:18

简单的INI解析封装的相关文章

自己动手实现一个简单的JSON解析器

1. 背景 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.相对于另一种数据交换格式 XML,JSON 有着诸多优点.比如易读性更好,占用空间更少等.在 web 应用开发领域内,得益于 JavaScript 对 JSON 提供的良好支持,JSON 要比 XML 更受开发人员青睐.所以作为开发人员,如果有兴趣的话,还是应该深入了解一下 JSON 相关的知识.本着探究 JSON 原理的目的,我将会在这篇文章中详细向大家介绍一个简单的JSON解析器的解析流

委托IL解析-----封装逻辑和代码复用

委托IL解析-----封装逻辑和代码复用 1.委托的本质 委托大家都不陌生吧,我们经常都会接触到或用到.LINQ查询就是基于委托来实现的. 我们常常这样定义委托: public delegate void SayHiDelegate(string name); 那么委托的本质是什么呢? 在介绍委托的本质前,我们先来认识一下IL,IL是中间语言,是我们在VS写的代码和计算机二进制代码的中间语言.我们的代码编译生成IL,IL通过GIT最终编译成计算机能识别的计算机二进制代码.IL可以看到真正原生的C

Javac源码简单分析之解析和填充符号表

一.说明 符号表是由一组符号地址和符号信息构成的表格.符号表中所登记的信息在编译的不同阶段都要用到,在语义分析(后面的步骤)中,符号表所登记的内容将用于语义检查和产生中间代码,在目标代码生成阶段,党对符号名进行地址分配时,符号表是地址分配的依据. 二.主要的类与方法 解析和填充符号表这个过程主要由com.sun.tools.javac.comp.Entry及com.sun.tools.javac.comp.MemberEnter两个类来实现的. com.sun.tools.javac.comp.

简单的JS运动封装实例---侧栏分享到

1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 5 <title>无标题文档</title> 6 <style> 7 #div1 {width: 100px; height: 200px; background: red;

非常简单的XML解析(SAX解析、pull解析)

这里只是把解析的数据当日志打出来了 非常简单的xml解析方式 1 package com.example.demo.service; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 6 import javax.xml.parsers.DocumentBuilder; 7 import javax.xml.parsers.DocumentBuilderFactory; 8 import javax.xml.parse

简单的URL解析

简单的URL解析,直接举例说明了 function getUrl(){ //如果存在则取到来后面的参数,注意,?不需要取出,substring从1开始,否则取""; var qs = location.search.length>0?location.search.substring(1):""; //保存数据对象 name=iwen var args = {}; var item = []; var name = null; var value = null

一种基于简单递归思想的易操控xml解析封装(C++)

技术要点: 1.基础xml解析库:tinyxml 2.XmlTree类 3.重载[],返回XmlTree类 4.实现Count函数,返回本级目录子节点的数目 针对如下的CMyString strRequestXml:(为了说明功能,把request结点分成两部分写) <?xml version='1.0' encoding='utf-8'?> <request version = '1.0' name = 'updateMainView'> <request> <

【FFMpeg视频开发与应用基础】四、调用FFmpeg SDK解析封装格式的视频为音频流和视频流

<FFMpeg视频开发与应用基础--使用FFMpeg工具与SDK>视频教程已经在"CSDN学院"上线,视频中包含了从0开始逐行代码实现FFMpeg视频开发的过程,欢迎观看!链接地址:FFMpeg视频开发与应用基础--使用FFMpeg工具与SDK 工程代码地址:FFmpeg_Tutorial 我们平常最常用的音视频文件通常不是单独的音频信号和视频信号,而是一个整体的文件.这个文件会在其中包含音频流和视频流,并通过某种方式进行同步播放.通常,文件的音频和视频通过某种标准格式进行

FFmpeg的HEVC解码器源代码简单分析:解析器(Parser)部分

上篇文章概述了FFmpeg中HEVC(H.265)解码器的结构:从这篇文章开始,具体研究HEVC解码器的源代码.本文分析HEVC解码器中解析器(Parser)部分的源代码.这部分的代码用于分割HEVC的NALU,并且解析SPS.PPS.SEI等信息.解析HEVC码流(对应AVCodecParser结构体中的函数)和解码HEVC码流(对应AVCodec结构体中的函数)的时候都会调用该部分的代码完成相应的功能. 函数调用关系图 FFmpeg HEVC解析器(Parser)部分在整个HEVC解码器中的