struct data { WString Key; WString Value; }; struct section { typedef struct data data_type; WString Name; WString Line; List<data_type> *Data; // 소멸자를 만들면 안된다. section() : Data(nullptr) { } size_t Count() const { return Data->Size(); } bool Exist(const WString& refer) const { bool search = false; Data->EachBreak([&](struct data key) { if (key.Key == refer) { search = true; return true; } return false; }); return search; }
void Create() { if ( nullptr List<data_type> ; }
void Clear() { delete Data; } }; List < section > secs; void Open(const WString& addr) { WString::Lines lines = FileIO::ReadFile(addr).LineSplit(); for ( size_t i = 0; i < lines.Size(); i++) { WString& now = *lines[i]; wchar_t f = now[ now.TrimStartPos() ]; if ( f == L';' || now.Empty() ) { section sec; sec.Line = now; continue; } if ( f == L'[' ) { section sec; sec.Create(); sec.Line = now; // 주석이 없음을 보장할 수 없다. sec.Name = now.Slice(now.FindFirst(L'[') + 1, now.FindFirst(L']') - 1); // 다음 섹션이 나올 때까지 진행한다. for ( size_t j = i + 1; j < lines.Size(); j++) { WString now = *lines[j]; if (now.Empty()) continue; wchar_t tspch = now[now.TrimStartPos()]; if ( tspch == L'[' ) break; if ( tspch == L';' ) continue; // equal 문자를 찾는다. size_t equal = now.FindFirst(L'='); if ( equal != WString::error && equal ) { if ( now[equal - 1] == L'\' ) { do { equal = now.FindFirst(L'=', equal + 1); if (equal != WString::error) if ( now[equal - 1] != L'\' ) break; } while ( equal != WString::error ); // 뭔가 이상한 구문이다. if ( equal == WString::error ) continue; } // trim없이, comment 처리 없이 순수하게 처리함 auto check_text = [&] (size_t start, size_t end) { WStringBuffer wb(end - start + 1); // 파싱 First const wchar_t *ptr = now.Reference(); bool inbig = false; // 큰 따옴표 안을 검색하고 있나요? for ( size_t i = start; i < end; i++ ) { switch ( ptr[i] ) { case L'\': i++; switch (ptr[i]) { case L'0': goto exit_equal_for; case L't': wb.Append(L' '); break; case L'r': wb.Append(L' '); break; case L'n': wb.Append(L' '); break; case L'b': wb.Append(L''); break; case L'\': case L';': case L':': case L'=': wb.Append(ptr[i]); break; } break; case L'"': inbig != true; break; default: wb.Append(ptr[i]); break; } } exit_equal_for: return wb.ToString(); }; data put; put.Key = check_text(0, equal); put.Value = check_text(equal + 1, now.Length()); sec.Data->Append(put); } } secs.Append(sec); } } }
이거 보시면 또 욕하실듯
코드는 길어서 안읽었고 ini면 걍 줄 단위로 '='를 기준으로 split한다음에 왼쪽은 변수 오른쪽은 값으로 하면 될텐데
저것도 규칙이 있어서 split를 안쓰는 거죠. 주석에다가 수학 식 계산, 특수문자 취급, 오른쪽에 \\=있으면 문자로 취급하고 etc ...
=를 이스케이프 해서 쓰는 경우도 있구나 실제론 못본듯한데
윈도우 분석함수 뜯어보시거나 위키만 가도 나옵니다. 저것도 핵심기능만 구현한 정도
물론 문법은 위키로 확인했음 \\=를 지금 알았다는거지
IniXxx 계열 API 쓰지 뭐하러 직접 만듦.