Skip to content

Commit b1da390

Browse files
authored
Optimized getLayerOfType, getNextLayerOfType and getPrevLayerOfType. (#1942)
* Optimized getLayerOfType, getNextLayerOfType and getPrevLayerOfType. - Reworked search algorithm to use a single dynamic cast per layer instance. * Fixed function name.
1 parent 0a710c4 commit b1da390

File tree

1 file changed

+25
-22
lines changed

1 file changed

+25
-22
lines changed

Packet++/header/Packet.h

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,9 @@ namespace pcpp
332332
std::string printPacketInfo(bool timeAsLocalTime) const;
333333

334334
Layer* createFirstLayer(LinkLayerType linkType);
335+
336+
template <typename TLayer, typename NextLayerFn>
337+
static TLayer* searchLayerStackForType(Layer* startLayer, NextLayerFn nextLayerFn, bool skipFirst);
335338
}; // class Packet
336339

337340
// implementation of inline methods
@@ -340,45 +343,45 @@ namespace pcpp
340343
{
341344
if (!reverse)
342345
{
343-
if (dynamic_cast<TLayer*>(getFirstLayer()) != nullptr)
344-
return dynamic_cast<TLayer*>(getFirstLayer());
345-
346-
return getNextLayerOfType<TLayer>(getFirstLayer());
346+
return searchLayerStackForType<TLayer>(
347+
m_FirstLayer, [](Layer* layer) { return layer->getNextLayer(); }, false);
347348
}
348349

349350
// lookup in reverse order
350-
if (dynamic_cast<TLayer*>(getLastLayer()) != nullptr)
351-
return dynamic_cast<TLayer*>(getLastLayer());
352-
353-
return getPrevLayerOfType<TLayer>(getLastLayer());
351+
return searchLayerStackForType<TLayer>(m_LastLayer, [](Layer* layer) { return layer->getPrevLayer(); }, false);
354352
}
355353

356354
template <class TLayer> TLayer* Packet::getNextLayerOfType(Layer* curLayer) const
357355
{
358-
if (curLayer == nullptr)
359-
return nullptr;
360-
361-
curLayer = curLayer->getNextLayer();
362-
while ((curLayer != nullptr) && (dynamic_cast<TLayer*>(curLayer) == nullptr))
363-
{
364-
curLayer = curLayer->getNextLayer();
365-
}
366-
367-
return dynamic_cast<TLayer*>(curLayer);
356+
return searchLayerStackForType<TLayer>(curLayer, [](Layer* layer) { return layer->getNextLayer(); }, true);
368357
}
369358

370359
template <class TLayer> TLayer* Packet::getPrevLayerOfType(Layer* curLayer) const
360+
{
361+
return searchLayerStackForType<TLayer>(curLayer, [](Layer* layer) { return layer->getPrevLayer(); }, true);
362+
}
363+
364+
template <typename TLayer, typename NextLayerFn>
365+
TLayer* Packet::searchLayerStackForType(Layer* curLayer, NextLayerFn nextLayerFn, bool skipFirst)
371366
{
372367
if (curLayer == nullptr)
373368
return nullptr;
374369

375-
curLayer = curLayer->getPrevLayer();
376-
while (curLayer != nullptr && dynamic_cast<TLayer*>(curLayer) == nullptr)
370+
if (skipFirst)
377371
{
378-
curLayer = curLayer->getPrevLayer();
372+
curLayer = nextLayerFn(curLayer);
373+
}
374+
375+
while (curLayer != nullptr)
376+
{
377+
auto* curLayerCasted = dynamic_cast<TLayer*>(curLayer);
378+
if (curLayerCasted != nullptr)
379+
return curLayerCasted;
380+
381+
curLayer = nextLayerFn(curLayer);
379382
}
380383

381-
return dynamic_cast<TLayer*>(curLayer);
384+
return nullptr;
382385
}
383386

384387
inline std::ostream& operator<<(std::ostream& os, const pcpp::Packet& packet)

0 commit comments

Comments
 (0)