mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 11:33:38 +00:00
Less back and forths by returning semi count in page
This commit is contained in:
@@ -138,6 +138,8 @@ class StatsCollector:
|
|||||||
|
|
||||||
counters: list
|
counters: list
|
||||||
|
|
||||||
|
num_semis: int = 0
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.streamer = ifcopenshell_wrapper.InstanceStreamer()
|
self.streamer = ifcopenshell_wrapper.InstanceStreamer()
|
||||||
self.needs_data = True
|
self.needs_data = True
|
||||||
@@ -151,17 +153,19 @@ class StatsCollector:
|
|||||||
def feed(self, data: str):
|
def feed(self, data: str):
|
||||||
self.streamer.pushPage(data)
|
self.streamer.pushPage(data)
|
||||||
self.needs_data = False
|
self.needs_data = False
|
||||||
|
self.num_semis = self.streamer.semicolonCount()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fromFilePath(fn, page_size: int = 4096):
|
def fromFilePath(fn, page_size: int = 102400):
|
||||||
collector = StatsCollector()
|
collector = StatsCollector()
|
||||||
collector.page_size = page_size
|
collector.page_size = page_size
|
||||||
collector.feedFromFile(open(str(fn), encoding="ascii"))
|
collector.feedFromFile(open(str(fn), encoding="ascii"))
|
||||||
return collector
|
return collector
|
||||||
|
|
||||||
def next(self):
|
def next(self):
|
||||||
if self.streamer.hasSemicolon():
|
if self.num_semis > 0:
|
||||||
if inst := self.streamer.readInstancePy(True):
|
if inst := self.streamer.readInstancePy(True):
|
||||||
|
self.num_semis -= 1
|
||||||
return inst["type"], dict(list(inst.items())[2:])
|
return inst["type"], dict(list(inst.items())[2:])
|
||||||
else:
|
else:
|
||||||
self.finalized = True
|
self.finalized = True
|
||||||
|
|||||||
@@ -139,7 +139,9 @@ private:
|
|||||||
|
|
||||||
bool hasSemicolon() const;
|
bool hasSemicolon() const;
|
||||||
|
|
||||||
void pushPage(const std::string& page);
|
size_t semicolonCount() const;
|
||||||
|
|
||||||
|
void pushPage(const std::string& page);
|
||||||
|
|
||||||
InstanceStreamer();
|
InstanceStreamer();
|
||||||
|
|
||||||
|
|||||||
@@ -1371,6 +1371,30 @@ bool IfcParse::InstanceStreamer::hasSemicolon() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t IfcParse::InstanceStreamer::semicolonCount() const {
|
||||||
|
auto local_stream = stream_->clone();
|
||||||
|
auto local_lexer = IfcSpfLexer(&local_stream);
|
||||||
|
Token t;
|
||||||
|
size_t count = 0;
|
||||||
|
try {
|
||||||
|
t = local_lexer.Next();
|
||||||
|
} catch (const std::out_of_range&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while (t.type != Token_NONE) {
|
||||||
|
if (TokenFunc::isOperator(t, ';')) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
t = local_lexer.Next();
|
||||||
|
} catch (const std::out_of_range&) {
|
||||||
|
// This most likely happens when a page boundary is contained within a string
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
void IfcParse::InstanceStreamer::pushPage(const std::string& page)
|
void IfcParse::InstanceStreamer::pushPage(const std::string& page)
|
||||||
{
|
{
|
||||||
stream_->pushNextPage(page);
|
stream_->pushNextPage(page);
|
||||||
|
|||||||
Reference in New Issue
Block a user