aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tool/PGListUtil/src/common/CErrorList.cpp171
-rw-r--r--tool/PGListUtil/src/common/CErrorList.h43
-rw-r--r--tool/PGListUtil/src/common/CFilter.cpp125
-rw-r--r--tool/PGListUtil/src/common/CFilter.h34
-rw-r--r--tool/PGListUtil/src/common/CIpList.cpp355
5 files changed, 728 insertions, 0 deletions
diff --git a/tool/PGListUtil/src/common/CErrorList.cpp b/tool/PGListUtil/src/common/CErrorList.cpp
new file mode 100644
index 00000000..4dce97bc
--- /dev/null
+++ b/tool/PGListUtil/src/common/CErrorList.cpp
@@ -0,0 +1,171 @@
+#include <stdio.h>
+#include <boost/xpressive/xpressive.hpp>
+#include "CErrorList.h"
+
+namespace pglu {
+namespace error {
+
+CErrorList::CErrorList() :
+ m_pool(sizeof(CError)),
+ m_errFoot(&m_errHead),
+ m_errNext(&m_errHead),
+ m_count(0)
+{
+ m_errHead.line = 0;
+ m_errHead.kind = SYNTAX;
+ m_errHead.next = NULL;
+}
+
+CErrorList::~CErrorList() {
+ Clear();
+}
+
+void CErrorList::Clear() {
+ m_pool.purge_memory();
+ m_errHead.next = NULL;
+ m_errFoot = &m_errHead;
+ m_errNext = &m_errHead;
+ m_count = 0;
+}
+
+bool CErrorList::LoadListFile(const char *path) {
+ char buf[PGLU_LENGTH_FILELINE];
+ uint ip_begin1, ip_begin2, ip_begin3, ip_begin4;
+ uint ip_end1, ip_end2, ip_end3, ip_end4;
+ FILE *fp;
+ CError *err = m_errFoot;
+
+ using namespace boost::xpressive;
+
+ static cmatch match;
+ static mark_tag tagIp1(1), tagIp2(2), tagIp3(3), tagIp4(4), tagIp5(5), tagIp6(6), tagIp7(7), tagIp8(8);
+ static mark_tag tagSep(9), tagMask(10);
+
+ static cregex reSyntax =
+ as_xpr(':') >> *_s >>
+ (tagIp1 = repeat<1, 3>(_d)) >> as_xpr('.') >>
+ (tagIp2 = repeat<1, 3>(_d)) >> as_xpr('.') >>
+ (tagIp3 = repeat<1, 3>(_d)) >> as_xpr('.') >>
+ (tagIp4 = repeat<1, 3>(_d)) >>
+ *_s >> as_xpr('-') >> *_s >>
+ (tagIp5 = repeat<1, 3>(_d)) >> as_xpr('.') >>
+ (tagIp6 = repeat<1, 3>(_d)) >> as_xpr('.') >>
+ (tagIp7 = repeat<1, 3>(_d)) >> as_xpr('.') >>
+ (tagIp8 = repeat<1, 3>(_d)) >>
+ *_s >> (_ln | eos);
+
+ static cregex reSyntaxRestorable =
+ (tagIp1 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
+ (tagIp2 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
+ (tagIp3 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
+ (tagIp4 = repeat<1, 3>(_d)) >> *_s >> (
+ (tagSep = +as_xpr('-')) >> *_s >>
+ (tagIp5 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
+ (tagIp6 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
+ (tagIp7 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
+ (tagIp8 = repeat<1, 3>(_d))
+ |
+ (tagSep = +(set = '/', '\\')) >> *_s >>
+ (tagMask = repeat<1, 2>(_d))
+ ) >> *_s >> (_ln | eos);
+
+#define reIpError repeat<3>(+_d >> *_s >> (set = '.', ',') >> *_s) >> +_d
+
+ static cregex reSyntaxError =
+ reIpError >> *_s >> (
+ *as_xpr('-') >> *_s >> reIpError |
+ +(set = '/', '\\') >> *_s >> +_d
+ );
+
+ fp = fopen(path, "r");
+ if(fp == NULL)
+ return false;
+
+ for(int line = 1; fgets(buf, PGLU_LENGTH_FILELINE, fp); ++line) {
+
+ if(regex_search(buf, match, reSyntax)) {
+ if(!(
+ (ip_begin1 = ParseDigit3(match[1].first, match[1].second)) < 256 &&
+ (ip_begin2 = ParseDigit3(match[2].first, match[2].second)) < 256 &&
+ (ip_begin3 = ParseDigit3(match[3].first, match[3].second)) < 256 &&
+ (ip_begin4 = ParseDigit3(match[4].first, match[4].second)) < 256 &&
+ (ip_end1 = ParseDigit3(match[5].first, match[5].second)) < 256 &&
+ (ip_end2 = ParseDigit3(match[6].first, match[6].second)) < 256 &&
+ (ip_end3 = ParseDigit3(match[7].first, match[7].second)) < 256 &&
+ (ip_end4 = ParseDigit3(match[8].first, match[8].second)) < 256 &&
+ (uint)((ip_begin1 << 24) | (ip_begin2 << 16) | (ip_begin3 << 8) | ip_begin4) <=
+ (uint)((ip_end1 << 24) | (ip_end2 << 16) | (ip_end3 << 8) | ip_end4)
+ )) {
+ ++m_count;
+ err->next = (CError*)m_pool.malloc();
+ err = err->next;
+ err->line = line;
+ err->kind = IP;
+ }
+
+ } else if(regex_search(buf, match, reSyntaxRestorable)) {
+ ++m_count;
+ err->next = (CError*)m_pool.malloc();
+ err = err->next;
+ err->line = line;
+ if(*(match[9].first) == '-') {
+ if(
+ (ip_begin1 = ParseDigit3(match[1].first, match[1].second)) < 256 &&
+ (ip_begin2 = ParseDigit3(match[2].first, match[2].second)) < 256 &&
+ (ip_begin3 = ParseDigit3(match[3].first, match[3].second)) < 256 &&
+ (ip_begin4 = ParseDigit3(match[4].first, match[4].second)) < 256 &&
+ (ip_end1 = ParseDigit3(match[5].first, match[5].second)) < 256 &&
+ (ip_end2 = ParseDigit3(match[6].first, match[6].second)) < 256 &&
+ (ip_end3 = ParseDigit3(match[7].first, match[7].second)) < 256 &&
+ (ip_end4 = ParseDigit3(match[8].first, match[8].second)) < 256 &&
+ (uint)((ip_begin1 << 24) | (ip_begin2 << 16) | (ip_begin3 << 8) | ip_begin4) <=
+ (uint)((ip_end1 << 24) | (ip_end2 << 16) | (ip_end3 << 8) | ip_end4)
+ ) {
+ err->kind = SYNTAX_RESTORABLE;
+ } else {
+ err->kind = SYNTAX;
+ }
+ } else {
+ uint mask = ParseDigit3(match[10].first, match[10].second);
+ if(
+ ParseDigit3(match[1].first, match[1].second) < 256 &&
+ ParseDigit3(match[2].first, match[2].second) < 256 &&
+ ParseDigit3(match[3].first, match[3].second) < 256 &&
+ ParseDigit3(match[4].first, match[4].second) < 256 &&
+ mask < 33
+ ) {
+ err->kind = SYNTAX_RESTORABLE;
+ } else {
+ err->kind = SYNTAX;
+ }
+ }
+ } else if(regex_search(buf, reSyntaxError)) {
+ ++m_count;
+ err->next = (CError*)m_pool.malloc();
+ err = err->next;
+ err->line = line;
+ err->kind = SYNTAX;
+ }
+#ifdef __MINGW32__
+ ZeroString(buf);
+#endif
+ }
+
+ fclose(fp);
+ err->next = NULL;
+ m_errFoot = err;
+ return true;
+}
+
+int CErrorList::Count() {
+ return m_count;
+}
+
+CError * CErrorList::GetNext() {
+ if(m_errNext)
+ m_errNext = m_errNext->next;
+ return m_errNext;
+}
+
+} // namespace error
+} // namespace pglu
diff --git a/tool/PGListUtil/src/common/CErrorList.h b/tool/PGListUtil/src/common/CErrorList.h
new file mode 100644
index 00000000..5583bb8d
--- /dev/null
+++ b/tool/PGListUtil/src/common/CErrorList.h
@@ -0,0 +1,43 @@
+#ifndef CERRLIST_H
+#define CERRLIST_H
+
+#include <boost/pool/pool.hpp>
+#include "common.h"
+
+namespace pglu {
+namespace error {
+
+typedef enum _EErrKind {
+ SYNTAX,
+ IP,
+ SYNTAX_RESTORABLE
+} EErrKind;
+
+typedef struct _CError {
+ int line;
+ EErrKind kind;
+ _CError * next;
+} CError;
+
+class CErrorList {
+private:
+ boost::pool<> m_pool;
+ CError m_errHead;
+ CError * m_errFoot;
+ CError * m_errNext;
+ int m_count;
+
+public:
+ CErrorList();
+ ~CErrorList();
+
+ void Clear();
+ bool LoadListFile(const char *path);
+ int Count();
+ CError * GetNext();
+};
+
+} // namespace error
+} // namespace pglu
+
+#endif // CERRLIST_H
diff --git a/tool/PGListUtil/src/common/CFilter.cpp b/tool/PGListUtil/src/common/CFilter.cpp
new file mode 100644
index 00000000..a6235547
--- /dev/null
+++ b/tool/PGListUtil/src/common/CFilter.cpp
@@ -0,0 +1,125 @@
+#include <ctype.h>
+#include <string.h>
+#include "CFilter.h"
+
+namespace pglu {
+namespace filter {
+
+namespace {
+
+char *strichr(const char *str, int chr) {
+ const char *p = str;
+ chr = tolower((unsigned char)chr);
+ for(; tolower((unsigned char)(*p)) != chr; ++p)
+ if(*p == '\0')
+ return NULL;
+ return (char*)p;
+}
+
+char *stristr(const char *str, const char *pattern) {
+ if(*pattern == '\0')
+ return (char*)str;
+
+ const char *p = str;
+ size_t len = strlen(pattern);
+ for(; (p = strichr(p, pattern[0])) != NULL; ++p)
+ if(!strnicmp(p, pattern, len))
+ return (char*)p;
+ return NULL;
+}
+
+bool search_and(const char *str, const char *terms, const bool del) {
+ do {
+ if(!stristr(str, terms))
+ return del; // not found
+ while(*terms != '\0')
+ ++terms;
+ ++terms;
+ } while(*terms != '\0');
+ return !del; // found all
+}
+
+bool search_or(const char *str, const char *terms, const bool del) {
+ do {
+ if(stristr(str, terms))
+ return !del; // found
+ while(*terms != '\0')
+ ++terms;
+ ++terms;
+ } while(*terms != '\0');
+ return del; // not found
+}
+
+} // namespace
+
+//--------------------------------------
+// CFilter class
+//--------------------------------------
+
+CFilter::CFilter() :
+ m_terms(NULL)
+{
+}
+
+CFilter::CFilter(const char *strFilter, const EFilterMode mode, const bool del) :
+ m_terms(NULL)
+{
+ Assign(strFilter, mode, del);
+}
+
+CFilter::~CFilter() {
+ Clear();
+}
+
+void CFilter::Assign(const char *strFilter, const EFilterMode mode, const bool del) {
+ Clear();
+
+ if(mode == AND)
+ m_search = search_and;
+ else if(mode == OR)
+ m_search = search_or;
+ else
+ return;
+
+ m_mode = mode;
+ m_del = del;
+
+ m_terms = new char[strlen(strFilter) + 2];
+
+ while(*strFilter == ' ' || *strFilter == '\t')
+ ++strFilter;
+
+ char *strTerms = m_terms;
+ while(*strFilter != '\0') {
+ *(strTerms++) = *(strFilter++);
+ if(*strFilter == ' ' || *strFilter == '\t') {
+ *(strTerms++) = '\0';
+ do {
+ ++strFilter;
+ } while(*strFilter == ' ' || *strFilter == '\t');
+ }
+ }
+ *strTerms = '\0';
+ *(strTerms + 1) = '\0';
+}
+
+void CFilter::Clear() {
+ if(m_terms) {
+ delete[] m_terms;
+ m_terms = NULL;
+ }
+}
+
+bool CFilter::IsEmpty() {
+ if(m_terms)
+ return *m_terms == '\0';
+ else
+ return true;
+}
+
+bool CFilter::IsMatch(const char *str) {
+ return m_search(str, m_terms, m_del);
+}
+
+} // namespace filter
+} // namespace pglu
diff --git a/tool/PGListUtil/src/common/CFilter.h b/tool/PGListUtil/src/common/CFilter.h
new file mode 100644
index 00000000..5f52db28
--- /dev/null
+++ b/tool/PGListUtil/src/common/CFilter.h
@@ -0,0 +1,34 @@
+#ifndef CFILTER_H
+#define CFILTER_H
+
+namespace pglu {
+namespace filter {
+
+typedef enum _EFilterMode {
+ AND,
+ OR
+} EFilterMode;
+
+class CFilter {
+private:
+ char * m_terms;
+ EFilterMode m_mode;
+ bool m_del;
+
+ bool (* m_search)(const char *, const char *, const bool);
+
+public:
+ CFilter();
+ CFilter(const char *strFilter, const EFilterMode mode, const bool del);
+ ~CFilter();
+
+ void Assign(const char *strFilter, const EFilterMode mode, const bool del);
+ void Clear();
+ bool IsEmpty();
+ bool IsMatch(const char *str);
+};
+
+} // namespace filter
+} // namespace pglu
+
+#endif // CFILTER_H
diff --git a/tool/PGListUtil/src/common/CIpList.cpp b/tool/PGListUtil/src/common/CIpList.cpp
new file mode 100644
index 00000000..b9eaf800
--- /dev/null
+++ b/tool/PGListUtil/src/common/CIpList.cpp
@@ -0,0 +1,355 @@
+#include <stdio.h>
+#include <string.h>
+#include "CIpList.h"
+
+namespace pglu {
+namespace ip {
+
+namespace {
+
+inline void Ip_Swap(CIp **ipA, CIp **ipB) {
+ CIp *ip = *ipA;
+ *ipA = *ipB;
+ *ipB = ip;
+}
+
+void Ip_SortByIpQuick(CIp **ipBegin, CIp **ipEnd) {
+ CIp **ipA;
+ CIp **ipB;
+ int nGap = ipEnd - ipBegin;
+
+ if(nGap < 64)
+ return;
+
+ ipA = ipBegin + ((int)(nGap / 2));
+ if((*ipBegin)->ip64 > (*ipA)->ip64)
+ Ip_Swap(ipBegin, ipA);
+ if((*ipBegin)->ip64 > (*ipEnd)->ip64)
+ Ip_Swap(ipBegin, ipEnd);
+ if((*ipA)->ip64 > (*ipEnd)->ip64)
+ Ip_Swap(ipA, ipEnd);
+ ulong ip64 = (*ipA)->ip64;
+
+ ipB = ipEnd - 1;
+ Ip_Swap(ipA, ipB);
+ ipA = ipBegin;
+
+ for(; ; ) {
+ while((*(++ipA))->ip64 < ip64);
+ while((*(--ipB))->ip64 > ip64);
+ if(ipA > ipB)
+ break;
+ Ip_Swap(ipA, ipB);
+ }
+ Ip_Swap(ipA, ipEnd - 1);
+
+ Ip_SortByIpQuick(ipBegin, ipB);
+ Ip_SortByIpQuick(ipA + 1, ipEnd);
+}
+
+void Ip_SortByIpInsert(CIp **ipBegin, CIp **ipEnd) {
+ CIp **ipA = ipBegin + 1;
+ CIp **ipB;
+ CIp **ipAEnd = ipEnd + 1;
+ CIp **ipBEnd = ipBegin - 1;
+ ulong ip64;
+ for(; ipA != ipAEnd; ++ipA) {
+ ip64 = (*ipA)->ip64;
+ for(ipB = ipA - 1; ipB != ipBEnd && (*ipB)->ip64 > ip64; --ipB)
+ Ip_Swap(ipB, ipB + 1);
+ }
+}
+
+void Ip_SortByIp(CIp **ipBegin, CIp **ipEnd) {
+ Ip_SortByIpQuick(ipBegin, ipEnd);
+ Ip_SortByIpInsert(ipBegin, ipEnd);
+}
+
+CIp * Ip_SortByCaption(CIp *ipHeadA) {
+ if(!ipHeadA || !(ipHeadA->next))
+ return ipHeadA;
+
+ // split ipBを2倍で進めることでipAを中間位置に持っていく
+ CIp *ipA = ipHeadA;
+ CIp *ipB = ipHeadA->next->next;
+ while(ipB) {
+ ipA = ipA->next;
+ ipB = ipB->next;
+ if(ipB)
+ ipB = ipB->next;
+ }
+ CIp *ipHeadB = ipA->next;
+ ipA->next = NULL;
+
+ ipHeadA = Ip_SortByCaption(ipHeadA);
+ ipHeadB = Ip_SortByCaption(ipHeadB);
+
+ // merge
+ CIp ipMerged;
+ ipA = &ipMerged;
+ while(ipHeadA || ipHeadB) {
+ if(((ipHeadA && ipHeadB) && stricmp(ipHeadA->caption, ipHeadB->caption) <= 0) || !ipHeadB) {
+ ipA->next = ipHeadA;
+ ipHeadA = ipHeadA->next;
+ } else {
+ ipA->next = ipHeadB;
+ ipHeadB = ipHeadB->next;
+ }
+ ipA = ipA->next;
+ }
+ ipA->next = NULL;
+
+ return ipMerged.next;
+}
+
+} // namespace
+
+//--------------------------------------
+// CIpList class
+//--------------------------------------
+
+CIpList::CIpList() :
+ m_poolIp(sizeof(CIp)),
+ m_ipFoot(&m_ipHead),
+ m_count(0),
+ m_countDisabled(0)
+{
+ m_ipHead.caption = NULL;
+ m_ipHead.ip64 = 0L;
+ m_ipHead.next = NULL;
+}
+
+CIpList::~CIpList() {
+ Clear();
+}
+
+void CIpList::Clear() {
+ for(CIp *ip = m_ipHead.next; ip; ip = ip->next)
+ delete[] ip->caption;
+ m_poolIp.purge_memory();
+ m_ipHead.next = NULL;
+ m_ipFoot = &m_ipHead;
+ m_count = 0;
+ m_countDisabled = 0;
+ UnSetFilter();
+}
+
+void CIpList::SetFilter(const char *filter, const filter::EFilterMode mode, const bool del) {
+ m_filter.Assign(filter, mode, del);
+}
+
+void CIpList::UnSetFilter() {
+ m_filter.Clear();
+}
+
+CIp * CIpList::CreateIp(boost::xpressive::cmatch & match) {
+ CIp *ip = (CIp*)m_poolIp.malloc();
+
+ const char *capBegin = match.prefix().first;
+ const char *capEnd = match[9].first;
+ size_t lenCap = capEnd - capBegin;
+ char *chunk = new char[lenCap + 1];
+ memcpy(chunk, capBegin, lenCap);
+ *(chunk + lenCap) = '\0';
+ ip->caption = chunk;
+
+ uchar *ip8 = ip->ip8;
+ ip8[4] = ParseDigit3(match[4].first, match[4].second);
+ ip8[5] = ParseDigit3(match[3].first, match[3].second);
+ ip8[6] = ParseDigit3(match[2].first, match[2].second);
+ ip8[7] = ParseDigit3(match[1].first, match[1].second);
+
+ if(*(match[10].first) == '-') {
+ ip8[0] = ParseDigit3(match[8].first, match[8].second);
+ ip8[1] = ParseDigit3(match[7].first, match[7].second);
+ ip8[2] = ParseDigit3(match[6].first, match[6].second);
+ ip8[3] = ParseDigit3(match[5].first, match[5].second);
+ } else {
+ ip->ip32[0] = ip->ip32[1] | (0xFFFFFFFF >> ParseDigit3(match[11].first, match[11].second));
+ }
+
+ return ip;
+}
+
+bool CIpList::LoadListFile(const char *path) {
+ char buf[PGLU_LENGTH_FILELINE];
+ char colon;
+ char *colon_p;
+
+ using namespace boost::xpressive;
+
+ static cmatch match;
+ static mark_tag tagIp1(1), tagIp2(2), tagIp3(3), tagIp4(4), tagIp5(5), tagIp6(6), tagIp7(7), tagIp8(8);
+ static mark_tag tagColon(9), tagSep(10), tagMask(11);
+
+ static cregex reSyntax = // bos >> (tag = *_) >> // slower
+ (tagColon = as_xpr(':')) >> *_s >>
+ (tagIp1 = repeat<1, 3>(_d)) >> as_xpr('.') >>
+ (tagIp2 = repeat<1, 3>(_d)) >> as_xpr('.') >>
+ (tagIp3 = repeat<1, 3>(_d)) >> as_xpr('.') >>
+ (tagIp4 = repeat<1, 3>(_d)) >>
+ *_s >> (tagSep = as_xpr('-')) >> *_s >>
+ (tagIp5 = repeat<1, 3>(_d)) >> as_xpr('.') >>
+ (tagIp6 = repeat<1, 3>(_d)) >> as_xpr('.') >>
+ (tagIp7 = repeat<1, 3>(_d)) >> as_xpr('.') >>
+ (tagIp8 = repeat<1, 3>(_d)) >>
+ *_s >> (_ln | eos);
+
+ static cregex reSyntaxRestorable =
+ (tagColon = !as_xpr(':')) >> *_s >>
+ (tagIp1 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
+ (tagIp2 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
+ (tagIp3 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
+ (tagIp4 = repeat<1, 3>(_d)) >> *_s >> (
+ (tagSep = +as_xpr('-')) >> *_s >>
+ (tagIp5 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
+ (tagIp6 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
+ (tagIp7 = repeat<1, 3>(_d)) >> (set = '.', ',') >>
+ (tagIp8 = repeat<1, 3>(_d))
+ |
+ (tagSep = +(set = '/', '\\')) >> *_s >>
+ (tagMask = repeat<1, 2>(_d))
+ ) >> *_s >> (_ln | eos);
+
+ FILE *fp = fopen(path, "r");
+ if(fp == NULL)
+ return false;
+
+ CIp *ip = m_ipFoot;
+
+ if(m_filter.IsEmpty()) {
+ while(fgets(buf, PGLU_LENGTH_FILELINE, fp)) {
+
+ if(regex_search(buf, match, reSyntax) || regex_search(buf, match, reSyntaxRestorable)) {
+ ++m_count;
+ ip->next = CreateIp(match);
+ ip = ip->next;
+ }
+#ifdef __MINGW32__
+ ZeroString(buf);
+#endif
+ }
+ } else {
+ while(fgets(buf, PGLU_LENGTH_FILELINE, fp)) {
+
+ if(regex_search(buf, match, reSyntax) || regex_search(buf, match, reSyntaxRestorable)) {
+ colon_p = (char*)(match[9].first);
+ colon = *colon_p;
+ *colon_p = '\0';
+
+ if(m_filter.IsMatch(buf)) {
+ ++m_count;
+ ip->next = CreateIp(match);
+ ip = ip->next;
+ }
+ *colon_p = colon;
+ }
+#ifdef __MINGW32__
+ ZeroString(buf);
+#endif
+ }
+ }
+ fclose(fp);
+ ip->next = NULL;
+ m_ipFoot = ip;
+ return true;
+}
+
+bool CIpList::SaveListFile(const char *path, const bool append) {
+ uchar *ip8;
+
+ FILE *fp = fopen(path, (append ? "a" : "w"));
+ if(fp == NULL)
+ return false;
+
+ for(CIp *ip = m_ipHead.next; ip; ip = ip->next) {
+ // IPが0Lなら書き出さない
+ if(ip->ip64 != 0L) {
+ ip8 = ip->ip8;
+ fprintf(fp,
+ "%s:%u.%u.%u.%u-%u.%u.%u.%u\n",
+ ip->caption,
+ ip8[7], ip8[6], ip8[5], ip8[4],
+ ip8[3], ip8[2], ip8[1], ip8[0]
+ );
+ }
+ }
+ fclose(fp);
+ return true;
+}
+
+void CIpList::CheckAndSort(const bool sortCap, const bool sortIp, const bool delDupIp) {
+ CIp **ipBegin;
+ CIp **ipEnd;
+ CIp *ip;
+
+ if(m_count < 2)
+ return;
+
+ if(sortIp || delDupIp) {
+ // リストから配列を複製
+ CIp **ipSort = new CIp*[m_count];
+ ipBegin = ipSort;
+ for(ip = m_ipHead.next; ip; ip = ip->next)
+ *(ipBegin++) = ip;
+
+ // 配列をソート
+ Ip_SortByIp(ipSort, ipSort + m_count - 1);
+
+ if(delDupIp) {
+ // すでにIPが0Lなものを無効としてカウント
+ ipBegin = ipSort;
+ ipEnd = ipBegin + m_count;
+
+ for(; ipBegin != ipEnd && (*ipBegin)->ip64 == 0L; ++ipBegin)
+ ++m_countDisabled;
+ if(ipBegin == ipEnd)
+ goto END_SORT; // 全てのIPが0L
+
+ // 重複したIPは0Lにして無効としてカウント
+ for(--ipEnd; ipBegin != ipEnd; ++ipBegin)
+ if((*ipBegin)->ip64 == (*(ipBegin + 1))->ip64) {
+ (*ipBegin)->ip64 = 0L;
+ ++m_countDisabled;
+ }
+ }
+ if(sortIp) {
+ // 配列の中身を連結
+ ipBegin = ipSort;
+ ipEnd = ipSort + m_count;
+ ip = &m_ipHead;
+ while(ipBegin != ipEnd) {
+ ip->next = *(ipBegin++);
+ ip = ip->next;
+ }
+ ip->next = NULL;
+ }
+ END_SORT:
+ delete[] ipSort;
+ }
+
+ if(sortCap)
+ m_ipHead.next = Ip_SortByCaption(m_ipHead.next);
+
+ if(sortIp || sortCap) {
+ // m_ipFootを再設定
+ ip = m_ipHead.next;
+ if(ip) {
+ for(; ip->next; ip = ip->next);
+ m_ipFoot = ip;
+ } else {
+ m_ipFoot = &m_ipHead;
+ }
+ }
+}
+
+int CIpList::Count() {
+ return m_count;
+}
+
+int CIpList::CountDisabled() {
+ return m_countDisabled;
+}
+
+} // namespace ip
+} // namespace pglu