XMLパーサーによるメモリ利用を安全かつ高速にするために、スレッド毎に別々のメモリ空間を利用するように実装されています。 どれか1つのスレッドで動作するXMLパーサーがメモリを使いすぎた等の場合でも、他のスレッドのXMLパーサーを道連れにしない、といったメリットがあります。
#include <string.h>
using nlib_ns::threading::Thread;
using nlib_ns::exi::XmlStreamWriter;
using nlib_ns::exi::XmlStreamReader;
using nlib_ns::exi::XmlStreamReaderSettings;
using nlib_ns::exi::ExiAllocator;
#define M(x) NLIB_EXI_UTF8(x)
static void ParseXml(XmlStreamReader* reader) {
while (reader->HasNext()) {
XmlStreamReader::XmlStreamConstants e = reader->Next();
switch (e) {
case XmlStreamReader::START_ELEMENT:
nlib_printf(
"[thread=%d]: StartElement(%s)\n", tid, M(reader->GetLocalName()));
break;
case XmlStreamReader::END_ELEMENT:
nlib_printf(
"[thread=%d]: EndElement(%s)\n", tid, M(reader->GetLocalName()));
break;
case XmlStreamReader::CHARACTERS:
nlib_printf(
"[thread=%d]: Characters(%s)\n", tid, M(reader->GetText()));
break;
default:
break;
}
}
}
static void ThreadA() {
const char myxml[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
"<ROOT>"
" <ITEM1>TEXT1</ITEM1>"
" <ITEM2>"
" <SUB1>TEXT2</SUB1>"
" <SUB2>TEXT3</SUB2>"
" </ITEM2>"
"</ROOT>";
void* buffer = malloc(1024 * 128);
if (!buffer) return;
if (ExiAllocator::Init(buffer, 1024 * 128) != 0) return;
MemoryInputStream istr(myxml, strlen(myxml));
XmlStreamReaderSettings is;
UniquePtr<XmlStreamReader> r(XmlStreamReader::Create(&istr, is));
if (!r.get()) {
ExiAllocator::Finalize();
free(buffer);
return;
}
ParseXml(r.get());
r->Close();
r.reset();
ExiAllocator::Finalize();
free(buffer);
}
static void ThreadB() {
const char myxml[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
"<root>"
" <item1>text1</item1>"
" <item2>"
" <sub1>text2</sub1>"
" <sub2>text3</sub2>"
" </item2>"
"</root>";
void* buffer = malloc(1024 * 128);
if (!buffer) return;
if (ExiAllocator::Init(buffer, 1024 * 128) != 0) return;
MemoryInputStream istr(myxml, strlen(myxml));
XmlStreamReaderSettings is;
UniquePtr<XmlStreamReader> r(XmlStreamReader::Create(&istr, is));
if (!r.get()) {
ExiAllocator::Finalize();
free(buffer);
return;
}
ParseXml(r.get());
r->Close();
r.reset();
ExiAllocator::Finalize();
free(buffer);
}
bool SampleMain(int, char**) {
nlib_printf(
"Two threads read different XMLs independently\n\n");
Thread thA, thB;
thA.Start(&ThreadA);
thB.Start(&ThreadB);
thA.Join();
thB.Join();
return true;
}
NLIB_MAINFUNC