_ZNK4pcpp13EnumClassHashINS_12Asn1TagClassELb0EEclES1_:
  123|      8|		{
  124|      8|			return static_cast<std::underlying_type_t<EnumClass>>(value);
  125|      8|		}
_ZNK4pcpp13EnumClassHashINS_20Asn1UniversalTagTypeELb0EEclES1_:
  123|     76|		{
  124|     76|			return static_cast<std::underlying_type_t<EnumClass>>(value);
  125|     76|		}

_ZN4pcpp6Logger11getInstanceEv:
  369|  3.37k|		{
  370|  3.37k|			static Logger instance;
  371|  3.37k|			return instance;
  372|  3.37k|		}
_ZN4pcpp6Logger12suppressLogsEv:
  321|  3.31k|		{
  322|  3.31k|			m_LogsEnabled = false;
  323|  3.31k|		}
_ZN4pcpp9LogSourceC2ENS_9LogModuleEPKcS3_i:
  139|     57|		    : file(file), function(function), line(line), logModule(logModule)
  140|     57|		{}
_ZN4pcpp8internal10LogContext4initENS_8LogLevelERKNS_9LogSourceE:
  189|     57|			{
  190|     57|				m_Source = source;
  191|     57|				m_Level = level;
  192|     57|				m_Stream.clear();
  193|     57|				m_Stream.str({});
  194|     57|			}
_ZNK4pcpp6Logger9shouldLogENS_8LogLevelENS_9LogModuleE:
  289|     57|		{
  290|     57|			return level != LogLevel::Off && m_LogModulesArray[module] >= level;
  ------------------
  |  Branch (290:11): [True: 57, False: 0]
  |  Branch (290:37): [True: 57, False: 0]
  ------------------
  291|     57|		}
_ZN4pcpp8internal10LogContextlsIA28_cEERS1_RKT_:
  200|      4|			{
  201|      4|				m_Stream << value;
  202|      4|				return *this;
  203|      4|			}
_ZN4pcpp8internal10LogContextlsIA38_cEERS1_RKT_:
  200|     53|			{
  201|     53|				m_Stream << value;
  202|     53|				return *this;
  203|     53|			}
_ZN4pcpp9LogSourceC2Ev:
  126|      2|		constexpr LogSource() = default;
_ZN4pcpp8internal10LogContextC2Ev:
  177|      2|			LogContext() = default;

_ZN4pcpp8internal17DynamicObjectPoolINS0_10LogContextELb1EED2Ev:
   57|      1|			{
   58|      1|				clear();
   59|      1|			}
_ZN4pcpp8internal17DynamicObjectPoolINS0_10LogContextELb1EE5clearEv:
  175|      1|			{
  176|      1|				std::unique_lock<std::mutex> lock(m_Mutex);
  177|      3|				while (!m_Pool.empty())
  ------------------
  |  Branch (177:12): [True: 2, False: 1]
  ------------------
  178|      2|				{
  179|      2|					delete m_Pool.top();
  180|      2|					m_Pool.pop();
  181|      2|				}
  182|      1|			}
_ZN4pcpp8internal17DynamicObjectPoolINS0_10LogContextELb1EE11preallocateEm:
  158|      1|			{
  159|      1|				std::unique_lock<std::mutex> lock(m_Mutex);
  160|       |
  161|      1|				if (m_MaxPoolSize < count)
  ------------------
  |  Branch (161:9): [True: 0, False: 1]
  ------------------
  162|      0|				{
  163|      0|					throw std::invalid_argument("Preallocated objects cannot exceed the maximum pool size");
  164|      0|				}
  165|       |
  166|       |				// If the pool is already larger than the requested count, we don't need to do anything.
  167|      3|				for (std::size_t i = m_Pool.size(); i < count; i++)
  ------------------
  |  Branch (167:41): [True: 2, False: 1]
  ------------------
  168|      2|				{
  169|      2|					m_Pool.push(new T());
  170|      2|				}
  171|      1|			}
_ZN4pcpp8internal17DynamicObjectPoolINS0_10LogContextELb1EEC2Emm:
   36|      1|			    : m_MaxPoolSize(maxPoolSize)
   37|      1|			{
   38|      1|				if (initialSize > maxPoolSize)
  ------------------
  |  Branch (38:9): [True: 0, False: 1]
  ------------------
   39|      0|				{
   40|      0|					throw std::invalid_argument("Preallocated objects cannot exceed the maximum pool size");
   41|      0|				}
   42|       |
   43|      1|				if (initialSize > 0)
  ------------------
  |  Branch (43:9): [True: 1, False: 0]
  ------------------
   44|      1|				{
   45|      1|					this->preallocate(initialSize);
   46|      1|				}
   47|      1|			}
_ZN4pcpp8internal17DynamicObjectPoolINS0_10LogContextELb1EE13acquireObjectEv:
   68|     57|			{
   69|     57|				return std::unique_ptr<T>(acquireObjectRaw());
   70|     57|			}
_ZN4pcpp8internal17DynamicObjectPoolINS0_10LogContextELb1EE16acquireObjectRawEv:
   79|     57|			{
   80|     57|				std::unique_lock<std::mutex> lock(m_Mutex);
   81|       |
   82|     57|				if (m_Pool.empty())
  ------------------
  |  Branch (82:9): [True: 0, False: 57]
  ------------------
   83|      0|				{
   84|       |					// We don't need the lock anymore, so release it.
   85|      0|					lock.unlock();
   86|      0|					return new T();
   87|      0|				}
   88|       |
   89|     57|				T* obj = m_Pool.top();
   90|     57|				m_Pool.pop();
   91|     57|				return obj;
   92|     57|			}
_ZN4pcpp8internal17DynamicObjectPoolINS0_10LogContextELb1EE13releaseObjectENSt3__110unique_ptrIS2_NS4_14default_deleteIS2_EEEE:
  101|     57|			{
  102|     57|				releaseObjectRaw(obj.release());
  103|     57|			}
_ZN4pcpp8internal17DynamicObjectPoolINS0_10LogContextELb1EE16releaseObjectRawEPS2_:
  112|     57|			{
  113|     57|				std::unique_lock<std::mutex> lock(m_Mutex);
  114|       |
  115|     57|				if (m_MaxPoolSize == INFINITE_POOL_SIZE || m_Pool.size() < m_MaxPoolSize)
  ------------------
  |  Branch (115:9): [True: 0, False: 57]
  |  Branch (115:48): [True: 57, False: 0]
  ------------------
  116|     57|				{
  117|     57|					m_Pool.push(obj);
  118|     57|				}
  119|      0|				else
  120|      0|				{
  121|       |					// We don't need the lock anymore, so release it.
  122|      0|					lock.unlock();
  123|      0|					delete obj;
  124|      0|				}
  125|     57|			}

_ZNK4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEE2atEi:
  319|  74.8k|		{
  320|  74.8k|			return m_Vector.at(index);
  321|  74.8k|		}
_ZN4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEE5beginEv:
  188|  4.72k|		{
  189|  4.72k|			return m_Vector.begin();
  190|  4.72k|		}
_ZN4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEE3endEv:
  202|  4.72k|		{
  203|  4.72k|			return m_Vector.end();
  204|  4.72k|		}
_ZNK4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEE4sizeEv:
  216|  6.79k|		{
  217|  6.79k|			return m_Vector.size();
  218|  6.79k|		}
_ZN4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEEC2Ev:
   59|  52.1k|		PointerVector() = default;
_ZN4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEED2Ev:
   78|  52.1k|		{
   79|  52.1k|			freeVectorUnsafe(m_Vector);
   80|  52.1k|		}
_ZN4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEE16freeVectorUnsafeERKNS2_6vectorIPS1_NS2_9allocatorIS7_EEEE:
  362|  52.1k|		{
  363|  52.1k|			for (auto& obj : origin)
  ------------------
  |  Branch (363:19): [True: 1.39M, False: 52.1k]
  ------------------
  364|  1.39M|			{
  365|  1.39M|				Deleter{}(obj);
  366|  1.39M|			}
  367|  52.1k|		}
_ZN4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEE8pushBackENS2_10unique_ptrIS1_S4_EE:
  172|  1.39M|		{
  173|  1.39M|			if (!element)
  ------------------
  |  Branch (173:8): [True: 0, False: 1.39M]
  ------------------
  174|      0|			{
  175|      0|				throw std::invalid_argument("Element is nullptr");
  176|      0|			}
  177|       |
  178|       |			// Release is called after the raw pointer is already inserted into the vector to prevent
  179|       |			// a memory leak if push_back throws.
  180|       |			// cppcheck-suppress danglingLifetime
  181|  1.39M|			m_Vector.push_back(element.get());
  182|  1.39M|			element.release();
  183|  1.39M|		}

_ZN4pcpp20byteArrayToHexStringEPKhmi:
   17|  19.2k|	{
   18|  19.2k|		if (stringSizeLimit <= 0)
  ------------------
  |  Branch (18:7): [True: 19.2k, False: 0]
  ------------------
   19|  19.2k|		{
   20|  19.2k|			stringSizeLimit = static_cast<int>(byteArrSize);
   21|  19.2k|		}
   22|       |
   23|  19.2k|		std::stringstream dataStream;
   24|  19.2k|		dataStream << std::hex;
   25|  1.07M|		for (size_t i = 0; i < byteArrSize; ++i)
  ------------------
  |  Branch (25:22): [True: 1.05M, False: 19.2k]
  ------------------
   26|  1.05M|		{
   27|  1.05M|			if (i >= static_cast<size_t>(stringSizeLimit))
  ------------------
  |  Branch (27:8): [True: 0, False: 1.05M]
  ------------------
   28|      0|			{
   29|      0|				break;
   30|      0|			}
   31|       |
   32|  1.05M|			dataStream << std::setw(2) << std::setfill('0') << static_cast<int>(byteArr[i]);
   33|  1.05M|		}
   34|       |
   35|  19.2k|		return dataStream.str();
   36|  19.2k|	}
_ZN4pcpp20hexStringToByteArrayERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEPhm:
   56|  1.35k|	{
   57|  1.35k|		if (hexString.size() % 2 != 0)
  ------------------
  |  Branch (57:7): [True: 4, False: 1.35k]
  ------------------
   58|      4|		{
   59|      4|			PCPP_LOG_ERROR("Input string is in odd size");
  ------------------
  |  |  445|      4|#	define PCPP_LOG_ERROR(message) PCPP_LOG(pcpp::LogLevel::Error, message)
  |  |  ------------------
  |  |  |  |  414|      4|	do                                                                                                                 \
  |  |  |  |  415|      4|	{                                                                                                                  \
  |  |  |  |  416|      4|		auto& logger = pcpp::Logger::getInstance();                                                                    \
  |  |  |  |  417|      4|		if (logger.shouldLog(level, LOG_MODULE))                                                                       \
  |  |  |  |  ------------------
  |  |  |  |  |  |    1|      4|#define LOG_MODULE CommonLogModuleGenericUtils
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (417:7): [True: 4, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  418|      4|		{                                                                                                              \
  |  |  |  |  419|      4|			auto ctx =                                                                                                 \
  |  |  |  |  420|      4|			    logger.createLogContext(level, pcpp::LogSource(LOG_MODULE, PCAPPP_FILENAME, __FUNCTION__, __LINE__));  \
  |  |  |  |  ------------------
  |  |  |  |  |  |    1|      4|#define LOG_MODULE CommonLogModuleGenericUtils
  |  |  |  |  ------------------
  |  |  |  |               			    logger.createLogContext(level, pcpp::LogSource(LOG_MODULE, PCAPPP_FILENAME, __FUNCTION__, __LINE__));  \
  |  |  |  |  ------------------
  |  |  |  |  |  |   20|       |#	define PCAPPP_FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  421|      4|			(*ctx) << message;                                                                                         \
  |  |  |  |  422|      4|			logger.emit(std::move(ctx));                                                                               \
  |  |  |  |  423|      4|		}                                                                                                              \
  |  |  |  |  424|      4|	} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (424:11): [Folded, False: 4]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   60|      4|			return 0;
   61|      4|		}
   62|       |
   63|  1.35k|		memset(resultByteArr, 0, resultByteArrSize);
   64|  31.0k|		for (size_t i = 0; i < hexString.length(); i += 2)
  ------------------
  |  Branch (64:22): [True: 29.7k, False: 1.29k]
  ------------------
   65|  29.7k|		{
   66|  29.7k|			if (i >= resultByteArrSize * 2)
  ------------------
  |  Branch (66:8): [True: 0, False: 29.7k]
  ------------------
   67|      0|			{
   68|      0|				return resultByteArrSize;
   69|      0|			}
   70|       |
   71|  29.7k|			const int firstChar = char2int(hexString[i]);
   72|  29.7k|			const int secondChar = char2int(hexString[i + 1]);
   73|  29.7k|			if (firstChar < 0 || secondChar < 0)
  ------------------
  |  Branch (73:8): [True: 26, False: 29.7k]
  |  Branch (73:25): [True: 27, False: 29.6k]
  ------------------
   74|     53|			{
   75|     53|				PCPP_LOG_ERROR("Input string has an illegal character");
  ------------------
  |  |  445|     53|#	define PCPP_LOG_ERROR(message) PCPP_LOG(pcpp::LogLevel::Error, message)
  |  |  ------------------
  |  |  |  |  414|     53|	do                                                                                                                 \
  |  |  |  |  415|     53|	{                                                                                                                  \
  |  |  |  |  416|     53|		auto& logger = pcpp::Logger::getInstance();                                                                    \
  |  |  |  |  417|     53|		if (logger.shouldLog(level, LOG_MODULE))                                                                       \
  |  |  |  |  ------------------
  |  |  |  |  |  |    1|     53|#define LOG_MODULE CommonLogModuleGenericUtils
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (417:7): [True: 53, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  418|     53|		{                                                                                                              \
  |  |  |  |  419|     53|			auto ctx =                                                                                                 \
  |  |  |  |  420|     53|			    logger.createLogContext(level, pcpp::LogSource(LOG_MODULE, PCAPPP_FILENAME, __FUNCTION__, __LINE__));  \
  |  |  |  |  ------------------
  |  |  |  |  |  |    1|     53|#define LOG_MODULE CommonLogModuleGenericUtils
  |  |  |  |  ------------------
  |  |  |  |               			    logger.createLogContext(level, pcpp::LogSource(LOG_MODULE, PCAPPP_FILENAME, __FUNCTION__, __LINE__));  \
  |  |  |  |  ------------------
  |  |  |  |  |  |   20|       |#	define PCAPPP_FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  421|     53|			(*ctx) << message;                                                                                         \
  |  |  |  |  422|     53|			logger.emit(std::move(ctx));                                                                               \
  |  |  |  |  423|     53|		}                                                                                                              \
  |  |  |  |  424|     53|	} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (424:11): [Folded, False: 53]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   76|     53|				resultByteArr[0] = '\0';
   77|     53|				return 0;
   78|     53|			}
   79|       |
   80|  29.6k|			resultByteArr[i / 2] = (firstChar << 4) | secondChar;
   81|  29.6k|		}
   82|       |
   83|  1.29k|		return hexString.length() / 2;
   84|  1.35k|	}
GeneralUtils.cpp:_ZN4pcppL8char2intEc:
   39|  59.4k|	{
   40|  59.4k|		if (input >= '0' && input <= '9')
  ------------------
  |  Branch (40:7): [True: 59.4k, False: 9]
  |  Branch (40:23): [True: 47.7k, False: 11.6k]
  ------------------
   41|  47.7k|		{
   42|  47.7k|			return input - '0';
   43|  47.7k|		}
   44|  11.6k|		if (input >= 'A' && input <= 'F')
  ------------------
  |  Branch (44:7): [True: 11.6k, False: 24]
  |  Branch (44:23): [True: 273, False: 11.3k]
  ------------------
   45|    273|		{
   46|    273|			return input - 'A' + 10;
   47|    273|		}
   48|  11.3k|		if (input >= 'a' && input <= 'f')
  ------------------
  |  Branch (48:7): [True: 11.3k, False: 42]
  |  Branch (48:23): [True: 11.3k, False: 19]
  ------------------
   49|  11.3k|		{
   50|  11.3k|			return input - 'a' + 10;
   51|  11.3k|		}
   52|     61|		return -1;
   53|  11.3k|	}

_ZN4pcpp6LoggerC2Ev:
   55|      1|	Logger::Logger() : m_LogsEnabled(true), m_LogPrinter(&printToCerr)
   56|      1|	{
   57|      1|		m_LogModulesArray.fill(LogLevel::Info);
   58|      1|	}
_ZN4pcpp6Logger16createLogContextENS_8LogLevelERKNS_9LogSourceE:
   89|     57|	{
   90|     57|		if (m_UseContextPooling)
  ------------------
  |  Branch (90:7): [True: 57, False: 0]
  ------------------
   91|     57|		{
   92|     57|			auto ctx = m_LogContextPool.acquireObject();
   93|     57|			ctx->init(level, source);
   94|     57|			return ctx;
   95|     57|		}
   96|      0|		return std::make_unique<internal::LogContext>(level, source);
   97|     57|	}
_ZN4pcpp6Logger4emitENSt3__110unique_ptrINS_8internal10LogContextENS1_14default_deleteIS4_EEEE:
  100|     57|	{
  101|     57|		emit(message->m_Source, message->m_Level, message->m_Stream.str());
  102|       |		// Pushes the message back to the pool if pooling is enabled. Otherwise, the message is deleted.
  103|     57|		if (m_UseContextPooling)
  ------------------
  |  Branch (103:7): [True: 57, False: 0]
  ------------------
  104|     57|		{
  105|     57|			m_LogContextPool.releaseObject(std::move(message));
  106|     57|		}
  107|     57|	}
_ZN4pcpp6Logger4emitERKNS_9LogSourceENS_8LogLevelERKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEE:
  110|     57|	{
  111|       |		// If the log level is an error, save the error to the last error message variable.
  112|     57|		if (logLevel == LogLevel::Error)
  ------------------
  |  Branch (112:7): [True: 57, False: 0]
  ------------------
  113|     57|		{
  114|     57|			static_assert(m_LastError.size() >= 1,
  115|     57|			              "Last error buffer size must be at least 1 to hold a null terminator");
  116|       |
  117|       |			// Copy the message to the last error buffer, leaving space for null terminator
  118|     57|			auto const copied = message.copy(m_LastError.data(), m_LastError.size() - 1);
  119|     57|			m_LastError[copied] = '\0';
  120|     57|		}
  121|     57|		if (m_LogsEnabled)
  ------------------
  |  Branch (121:7): [True: 0, False: 57]
  ------------------
  122|      0|		{
  123|      0|			m_LogPrinter(logLevel, message, source.file, source.function, source.line);
  124|      0|		}
  125|     57|	}

_ZN4pcpp9mkUtcTimeER2tm:
  222|  12.2k|	{
  223|       |#if defined(_WIN32)
  224|       |		return _mkgmtime(&time);
  225|       |#else
  226|  12.2k|		return timegm(&time);
  227|  12.2k|#endif
  228|  12.2k|	}

_ZNK4pcpp10Asn1Record11getTagClassEv:
  148|  4.12k|		{
  149|  4.12k|			return m_TagClass;
  150|  4.12k|		}
_ZNK4pcpp10Asn1Record13isConstructedEv:
  154|  1.59k|		{
  155|  1.59k|			return m_IsConstructed;
  156|  1.59k|		}
_ZNK4pcpp10Asn1Record10getTagTypeEv:
  164|  3.16k|		{
  165|  3.16k|			return m_TagType;
  166|  3.16k|		}
_ZNK4pcpp10Asn1Record14getTotalLengthEv:
  176|  2.78M|		{
  177|  2.78M|			return m_TotalLength;
  178|  2.78M|		}
_ZN4pcpp21Asn1ConstructedRecord13getSubRecordsEv:
  313|  87.4k|		{
  314|  87.4k|			decodeValueIfNeeded();
  315|  87.4k|			return m_SubRecords;
  316|  87.4k|		};
_ZNK4pcpp17Asn1IntegerRecord16getValueAsStringEb:
  441|  1.99k|		{
  442|  1.99k|			decodeValueIfNeeded();
  443|  1.99k|			return m_Value.toString(removeLeadingZeros);
  444|  1.99k|		}
_ZNK4pcpp17Asn1BooleanRecord8getValueEv:
  659|  1.26k|		{
  660|  1.26k|			decodeValueIfNeeded();
  661|  1.26k|			return m_Value;
  662|  1.26k|		};
_ZNK4pcpp14Asn1NullRecord11decodeValueEPKh:
  688|  1.02k|		{}
_ZNK4pcpp26Asn1ObjectIdentifierRecord8getValueEv:
  765|  16.1k|		{
  766|  16.1k|			decodeValueIfNeeded();
  767|  16.1k|			return m_Value;
  768|  16.1k|		}
_ZNK4pcpp14Asn1TimeRecord8getValueERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  793|  1.48k|		{
  794|  1.48k|			decodeValueIfNeeded();
  795|  1.48k|			return adjustTimezones(m_Value, "Z", timezone);
  796|  1.48k|		};
_ZN4pcpp19Asn1BitStringRecord8getValueEv:
  881|    364|		{
  882|    364|			decodeValueIfNeeded();
  883|    364|			return m_Value.toString();
  884|    364|		};
_ZN4pcpp19Asn1BitStringRecord11getVecValueEv:
  888|  3.16k|		{
  889|  3.16k|			decodeValueIfNeeded();
  890|  3.16k|			return m_Value.toBytes();
  891|  3.16k|		}
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE4EE11decodeValueEPKh:
  553|  2.97k|		{
  554|  2.97k|			m_Value = std::string(reinterpret_cast<char const*>(data), m_ValueLength);
  555|  2.97k|		}
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE4EE8getValueEv:
  537|  4.81k|		{
  538|  4.81k|			decodeValueIfNeeded();
  539|  4.81k|			return m_Value;
  540|  4.81k|		};
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE12EE11decodeValueEPKh:
  553|  7.08k|		{
  554|  7.08k|			m_Value = std::string(reinterpret_cast<char const*>(data), m_ValueLength);
  555|  7.08k|		}
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE12EE8getValueEv:
  537|  3.95k|		{
  538|  3.95k|			decodeValueIfNeeded();
  539|  3.95k|			return m_Value;
  540|  3.95k|		};
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE19EE11decodeValueEPKh:
  553|  5.19k|		{
  554|  5.19k|			m_Value = std::string(reinterpret_cast<char const*>(data), m_ValueLength);
  555|  5.19k|		}
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE19EE8getValueEv:
  537|  2.66k|		{
  538|  2.66k|			decodeValueIfNeeded();
  539|  2.66k|			return m_Value;
  540|  2.66k|		};
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE22EE11decodeValueEPKh:
  553|  5.26k|		{
  554|  5.26k|			m_Value = std::string(reinterpret_cast<char const*>(data), m_ValueLength);
  555|  5.26k|		}
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE22EE8getValueEv:
  537|    613|		{
  538|    613|			decodeValueIfNeeded();
  539|    613|			return m_Value;
  540|    613|		};
_ZN4pcpp10Asn1Record6castAsINS_17Asn1IntegerRecordEEEPT_v:
  188|  3.63k|		{
  189|  3.63k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  3.63k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 57, False: 3.57k]
  ------------------
  191|     57|			{
  192|     57|				throw std::bad_cast();
  193|     57|			}
  194|  3.57k|			return result;
  195|  3.63k|		}
_ZNK4pcpp17Asn1IntegerRecord11getIntValueIhTnNSt3__19enable_ifIXaasr3std11is_integralIT_EE5valuesr3std11is_unsignedIS4_EE5valueEiE4typeELi0EEES4_v:
  425|  1.58k|		{
  426|  1.58k|			decodeValueIfNeeded();
  427|  1.58k|			return m_Value.getInt<T>();
  428|  1.58k|		}
_ZNK4pcpp17Asn1IntegerRecord6BigInt6getIntIhTnNSt3__19enable_ifIXaasr3std11is_integralIT_EE5valuesr3std11is_unsignedIS5_EE5valueEiE4typeELi0EEES5_v:
  476|  1.58k|			{
  477|  1.58k|				if (!canFit<T>())
  ------------------
  |  Branch (477:9): [True: 8, False: 1.57k]
  ------------------
  478|      8|				{
  479|      8|					throw std::overflow_error("Value cannot fit into requested int type");
  480|      8|				}
  481|       |
  482|  1.57k|				std::stringstream sstream;
  483|  1.57k|				sstream << std::hex << m_Value;
  484|       |
  485|  1.57k|				uint64_t result;
  486|  1.57k|				sstream >> result;
  487|  1.57k|				return static_cast<T>(result);
  488|  1.58k|			}
_ZNK4pcpp17Asn1IntegerRecord6BigInt6canFitIhTnNSt3__19enable_ifIXaasr3std11is_integralIT_EE5valuesr3std11is_unsignedIS5_EE5valueEiE4typeELi0EEEbv:
  491|  1.58k|			{
  492|  1.58k|				return sizeof(T) >= (m_Value.size() + 1) / 2;
  493|  1.58k|			}
_ZN4pcpp10Asn1Record6castAsINS_26Asn1ObjectIdentifierRecordEEEPT_v:
  188|  16.1k|		{
  189|  16.1k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  16.1k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 24, False: 16.1k]
  ------------------
  191|     24|			{
  192|     24|				throw std::bad_cast();
  193|     24|			}
  194|  16.1k|			return result;
  195|  16.1k|		}
_ZN4pcpp10Asn1Record6castAsINS_25Asn1PrintableStringRecordEEEPT_v:
  188|  2.67k|		{
  189|  2.67k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  2.67k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 1, False: 2.66k]
  ------------------
  191|      1|			{
  192|      1|				throw std::bad_cast();
  193|      1|			}
  194|  2.66k|			return result;
  195|  2.67k|		}
_ZN4pcpp10Asn1Record6castAsINS_19Asn1IA5StringRecordEEEPT_v:
  188|    614|		{
  189|    614|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|    614|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 1, False: 613]
  ------------------
  191|      1|			{
  192|      1|				throw std::bad_cast();
  193|      1|			}
  194|    613|			return result;
  195|    614|		}
_ZN4pcpp10Asn1Record6castAsINS_20Asn1UTF8StringRecordEEEPT_v:
  188|  3.95k|		{
  189|  3.95k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  3.95k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 1, False: 3.95k]
  ------------------
  191|      1|			{
  192|      1|				throw std::bad_cast();
  193|      1|			}
  194|  3.95k|			return result;
  195|  3.95k|		}
_ZN4pcpp10Asn1Record6castAsINS_13Asn1SetRecordEEEPT_v:
  188|  7.69k|		{
  189|  7.69k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  7.69k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 12, False: 7.68k]
  ------------------
  191|     12|			{
  192|     12|				throw std::bad_cast();
  193|     12|			}
  194|  7.68k|			return result;
  195|  7.69k|		}
_ZN4pcpp10Asn1Record6castAsINS_14Asn1TimeRecordEEEPT_v:
  188|  3.45k|		{
  189|  3.45k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  3.45k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 15, False: 3.44k]
  ------------------
  191|     15|			{
  192|     15|				throw std::bad_cast();
  193|     15|			}
  194|  3.44k|			return result;
  195|  3.45k|		}
_ZN4pcpp10Asn1Record6castAsINS_19Asn1BitStringRecordEEEPT_v:
  188|  3.56k|		{
  189|  3.56k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  3.56k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 34, False: 3.52k]
  ------------------
  191|     34|			{
  192|     34|				throw std::bad_cast();
  193|     34|			}
  194|  3.52k|			return result;
  195|  3.56k|		}
_ZN4pcpp10Asn1Record6castAsINS_17Asn1BooleanRecordEEEPT_v:
  188|  1.28k|		{
  189|  1.28k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  1.28k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 11, False: 1.26k]
  ------------------
  191|     11|			{
  192|     11|				throw std::bad_cast();
  193|     11|			}
  194|  1.26k|			return result;
  195|  1.28k|		}
_ZN4pcpp10Asn1Record6castAsINS_21Asn1OctetStringRecordEEEPT_v:
  188|  4.84k|		{
  189|  4.84k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  4.84k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 37, False: 4.81k]
  ------------------
  191|     37|			{
  192|     37|				throw std::bad_cast();
  193|     37|			}
  194|  4.81k|			return result;
  195|  4.84k|		}
_ZN4pcpp10Asn1Record6castAsINS_18Asn1SequenceRecordEEEPT_v:
  188|  43.0k|		{
  189|  43.0k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  43.0k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 717, False: 42.3k]
  ------------------
  191|    717|			{
  192|    717|				throw std::bad_cast();
  193|    717|			}
  194|  42.3k|			return result;
  195|  43.0k|		}
_ZN4pcpp10Asn1Record6castAsINS_21Asn1ConstructedRecordEEEPT_v:
  188|  2.23k|		{
  189|  2.23k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  2.23k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 0, False: 2.23k]
  ------------------
  191|      0|			{
  192|      0|				throw std::bad_cast();
  193|      0|			}
  194|  2.23k|			return result;
  195|  2.23k|		}
_ZN4pcpp18Asn1SequenceRecordC2Ev:
  368|  32.9k|		Asn1SequenceRecord() = default;
_ZN4pcpp21Asn1ConstructedRecordC2Ev:
  319|  52.1k|		Asn1ConstructedRecord() = default;
_ZN4pcpp13Asn1SetRecordC2Ev:
  387|  8.06k|		Asn1SetRecord() = default;
_ZN4pcpp17Asn1IntegerRecordC2Ev:
  447|  8.41k|		Asn1IntegerRecord() = default;
_ZN4pcpp19Asn1PrimitiveRecordC2Ev:
  398|  51.9k|		Asn1PrimitiveRecord() = default;
_ZN4pcpp20Asn1EnumeratedRecordC2Ev:
  526|  2.12k|		Asn1EnumeratedRecord() = default;
_ZN4pcpp21Asn1OctetStringRecordC2Ev:
  593|  13.9k|		Asn1OctetStringRecord() = default;
_ZN4pcpp20Asn1UTF8StringRecordC2Ev:
  611|  7.09k|		Asn1UTF8StringRecord() = default;
_ZN4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE12EEC2Ev:
  543|  7.09k|		Asn1StringRecord() : Asn1PrimitiveRecord(TagType)
  544|  7.09k|		{}
_ZN4pcpp25Asn1PrintableStringRecordC2Ev:
  627|  5.21k|		Asn1PrintableStringRecord() = default;
_ZN4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE19EEC2Ev:
  543|  5.21k|		Asn1StringRecord() : Asn1PrimitiveRecord(TagType)
  544|  5.21k|		{}
_ZN4pcpp19Asn1IA5StringRecordC2Ev:
  643|  5.28k|		Asn1IA5StringRecord() = default;
_ZN4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE22EEC2Ev:
  543|  5.28k|		Asn1StringRecord() : Asn1PrimitiveRecord(TagType)
  544|  5.28k|		{}
_ZN4pcpp17Asn1BooleanRecordC2Ev:
  671|  3.96k|		Asn1BooleanRecord() = default;
_ZN4pcpp19Asn1BitStringRecordC2Ev:
  924|  4.54k|		Asn1BitStringRecord() = default;
_ZN4pcpp26Asn1ObjectIdentifierRecordC2Ev:
  779|  22.4k|		Asn1ObjectIdentifierRecord() = default;
_ZN4pcpp17Asn1UtcTimeRecordC2Ev:
  839|  6.45k|		Asn1UtcTimeRecord() = default;
_ZN4pcpp14Asn1TimeRecordC2Ev:
  808|  12.6k|		Asn1TimeRecord() = default;
_ZN4pcpp25Asn1GeneralizedTimeRecordC2Ev:
  863|  6.17k|		Asn1GeneralizedTimeRecord() = default;
_ZN4pcpp17Asn1GenericRecordC2Ev:
  278|  1.26M|		Asn1GenericRecord() = default;
_ZN4pcpp10Asn1RecordC2Ev:
  207|  1.40M|		Asn1Record() = default;
_ZN4pcpp10Asn1RecordD2Ev:
  197|  1.40M|		virtual ~Asn1Record() = default;
_ZN4pcpp17Asn1IntegerRecord6BigIntC2Ev:
  458|  8.41k|			BigInt() = default;
_ZN4pcpp20Asn1ObjectIdentifierC2Ev:
  746|  22.4k|		Asn1ObjectIdentifier() = default;
_ZN4pcpp19Asn1BitStringRecord6BitSetC2Ev:
  903|  5.09k|			BitSet() = default;
_ZN4pcpp17Asn1GenericRecordD2Ev:
  268|  1.26M|		~Asn1GenericRecord() override = default;
_ZN4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE4EEC2Ev:
  543|  13.9k|		Asn1StringRecord() : Asn1PrimitiveRecord(TagType)
  544|  13.9k|		{}

_ZN4pcpp8internal16CryptoDataReaderINS_15X509CertificateEE7fromDEREPhmb:
   33|  3.31k|			{
   34|  3.31k|				return std::unique_ptr<CryptoDecoder>(new CryptoDecoder(derData, derDataLen, ownDerData));
   35|  3.31k|			}

_ZNK4pcpp13X509Extension7getTypeEv:
  710|  8.56k|		{
  711|  8.56k|			return m_Type;
  712|  8.56k|		}
_ZNK4pcpp13X509Extension10isCriticalEv:
  717|  7.44k|		{
  718|  7.44k|			return m_IsCritical;
  719|  7.44k|		}
_ZNK4pcpp17X509ExtensionTypecvNS0_5ValueEEv:
  279|  4.07k|		{
  280|  4.07k|			return m_Value;
  281|  4.07k|		}
_ZN4pcpp13X509AlgorithmC2ENS0_5ValueE:
   91|  3.28k|		constexpr X509Algorithm(Value value) : m_Value(value)
   92|  3.28k|		{}
_ZN4pcpp21X520DistinguishedNameC2ENS0_5ValueE:
  172|  7.36k|		constexpr X520DistinguishedName(Value value) : m_Value(value)
  173|  7.36k|		{}
_ZN4pcpp17X509ExtensionTypeC2ENS0_5ValueE:
  263|  4.67k|		constexpr X509ExtensionType(Value value) : m_Value(value)
  264|  4.67k|		{}
_ZN4pcpp16X509SerialNumberC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  295|  1.99k|		explicit X509SerialNumber(const std::string& serialNumber) : m_SerialNumber(serialNumber)
  296|  1.99k|		{}
_ZN4pcpp13X509TimestampC2EPNS_14Asn1TimeRecordE:
  315|  3.44k|		explicit X509Timestamp(Asn1TimeRecord* timeRecord) : m_Record(timeRecord)
  316|  3.44k|		{}
_ZN4pcpp7X509KeyC2ERKNSt3__16vectorIhNS1_9allocatorIhEEEE:
  344|  3.16k|		explicit X509Key(const std::vector<uint8_t>& key) : m_Key(key)
  345|  3.16k|		{}
_ZN4pcpp12X509Internal15X509CertificateC2ENSt3__110unique_ptrINS_10Asn1RecordENS2_14default_deleteIS4_EEEE:
  639|  2.97k|			explicit X509Certificate(std::unique_ptr<Asn1Record> root) : m_Root(std::move(root))
  640|  2.97k|			{}
_ZN4pcpp12X509Internal8X509BaseINS_13Asn1SetRecordEEC2EPS2_:
  378|  7.68k|			explicit X509Base(Asn1RecordType* root) : m_Root(root)
  379|  7.68k|			{}
_ZN4pcpp12X509Internal8X509BaseINS_21Asn1ConstructedRecordEEC2EPS2_:
  378|  2.23k|			explicit X509Base(Asn1RecordType* root) : m_Root(root)
  379|  2.23k|			{}
_ZN4pcpp12X509Internal8X509BaseINS_18Asn1SequenceRecordEEC2EPS2_:
  378|  20.2k|			explicit X509Base(Asn1RecordType* root) : m_Root(root)
  379|  20.2k|			{}

_ZNK4pcpp29X509BasicConstraintsExtension4isCAEv:
  227|    201|		{
  228|    201|			return m_IsCA;
  229|    201|		}
_ZNK4pcpp29X509BasicConstraintsExtension20getPathLenConstraintEv:
  233|    201|		{
  234|    201|			return m_PathLenConstraint;
  235|    201|		}
_ZNK4pcpp29X509ExtendedKeyUsageExtension11getPurposesEv:
  321|    366|		{
  322|    366|			return m_Purposes;
  323|    366|		}
_ZNK4pcpp33X509SubjectKeyIdentifierExtension16getKeyIdentifierEv:
  252|    198|		{
  253|    198|			return m_KeyIdentifier;
  254|    198|		};
_ZN4pcpp17X509ExtensionData6castAsINS_29X509BasicConstraintsExtensionEEEPT_v:
  208|    201|		{
  209|    201|			auto castedExtension = dynamic_cast<X509ExtensionDataType*>(this);
  210|    201|			if (castedExtension == nullptr)
  ------------------
  |  Branch (210:8): [True: 0, False: 201]
  ------------------
  211|      0|			{
  212|      0|				throw std::runtime_error("Trying to cast X509 extension data to the wrong type");
  213|      0|			}
  214|    201|			return castedExtension;
  215|    201|		}
_ZN4pcpp17X509ExtensionData6castAsINS_21X509KeyUsageExtensionEEEPT_v:
  208|    359|		{
  209|    359|			auto castedExtension = dynamic_cast<X509ExtensionDataType*>(this);
  210|    359|			if (castedExtension == nullptr)
  ------------------
  |  Branch (210:8): [True: 0, False: 359]
  ------------------
  211|      0|			{
  212|      0|				throw std::runtime_error("Trying to cast X509 extension data to the wrong type");
  213|      0|			}
  214|    359|			return castedExtension;
  215|    359|		}
_ZN4pcpp17X509ExtensionData6castAsINS_29X509ExtendedKeyUsageExtensionEEEPT_v:
  208|    366|		{
  209|    366|			auto castedExtension = dynamic_cast<X509ExtensionDataType*>(this);
  210|    366|			if (castedExtension == nullptr)
  ------------------
  |  Branch (210:8): [True: 0, False: 366]
  ------------------
  211|      0|			{
  212|      0|				throw std::runtime_error("Trying to cast X509 extension data to the wrong type");
  213|      0|			}
  214|    366|			return castedExtension;
  215|    366|		}
_ZN4pcpp17X509ExtensionData6castAsINS_33X509SubjectKeyIdentifierExtensionEEEPT_v:
  208|    198|		{
  209|    198|			auto castedExtension = dynamic_cast<X509ExtensionDataType*>(this);
  210|    198|			if (castedExtension == nullptr)
  ------------------
  |  Branch (210:8): [True: 0, False: 198]
  ------------------
  211|      0|			{
  212|      0|				throw std::runtime_error("Trying to cast X509 extension data to the wrong type");
  213|      0|			}
  214|    198|			return castedExtension;
  215|    198|		}
_ZN4pcpp27X509ExtendedKeyUsagePurposeC2ENS0_5ValueE:
   49|    824|		constexpr X509ExtendedKeyUsagePurpose(Value value) : m_Value(value)
   50|    824|		{}
_ZNK4pcpp12X509Internal31X509BasicConstraintsDataDecoder4isCAEv:
  101|    201|			{
  102|    201|				return m_IsCA;
  103|    201|			}
_ZNK4pcpp12X509Internal31X509BasicConstraintsDataDecoder20getPathLenConstraintEv:
  107|    201|			{
  108|    201|				return m_PathLenConstraint;
  109|    201|			}
_ZN4pcpp12X509Internal31X509BasicConstraintsDataDecoderC2Ebi:
  113|    201|			    : m_IsCA(isCA), m_PathLenConstraint(pathLenConstraint)
  114|    201|			{}
_ZNK4pcpp12X509Internal35X509SubjectKeyIdentifierDataDecoder16getKeyIdentifierEv:
  134|    198|			{
  135|    198|				return m_KeyIdentifier;
  136|    198|			}
_ZN4pcpp12X509Internal35X509SubjectKeyIdentifierDataDecoderC2ERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  140|    198|			    : m_KeyIdentifier(keyIdentifier)
  141|    198|			{}
_ZNK4pcpp12X509Internal23X509KeyUsageDataDecoder11getKeyUsageEv:
  157|    359|			{
  158|    359|				return m_KeyUsage;
  159|    359|			}
_ZN4pcpp12X509Internal23X509KeyUsageDataDecoderC2ERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  162|    359|			explicit X509KeyUsageDataDecoder(const std::string& keyUsage) : m_KeyUsage(keyUsage)
  163|    359|			{}
_ZNK4pcpp12X509Internal31X509ExtendedKeyUsageDataDecoder27getExtendedKeyUsagePurposesEv:
  179|    366|			{
  180|    366|				return m_ExtendedKeyUsagePurposes;
  181|    366|			}
_ZN4pcpp12X509Internal31X509ExtendedKeyUsageDataDecoderC2Ev:
  185|    394|			{}
_ZN4pcpp17X509ExtensionDataD2Ev:
  200|  1.35k|		virtual ~X509ExtensionData() = default;

_ZN4pcpp10Asn1Record6decodeEPKhmb:
   93|  1.40M|	{
   94|  1.40M|		uint8_t tagLen;
   95|  1.40M|		auto decodedRecord = decodeTagAndCreateRecord(data, dataLen, tagLen);
   96|       |
   97|  1.40M|		uint8_t lengthLen;
   98|  1.40M|		lengthLen = decodedRecord->decodeLength(data + tagLen, dataLen - tagLen);
   99|       |
  100|  1.40M|		decodedRecord->m_TotalLength = tagLen + lengthLen + decodedRecord->m_ValueLength;
  101|  1.40M|		if (decodedRecord->m_TotalLength < decodedRecord->m_ValueLength ||  // check for overflow
  ------------------
  |  Branch (101:7): [True: 438, False: 1.39M]
  ------------------
  102|  1.39M|		    decodedRecord->m_TotalLength > dataLen)
  ------------------
  |  Branch (102:7): [True: 489, False: 1.39M]
  ------------------
  103|    494|		{
  104|    494|			throw std::invalid_argument("Cannot decode ASN.1 record, data doesn't contain the entire record");
  105|    494|		}
  106|       |
  107|  1.39M|		uint8_t const* startOfData = data + tagLen + lengthLen;
  108|  1.39M|		internal::Asn1LoadPolicy policy = lazy ? internal::Asn1LoadPolicy::Lazy : internal::Asn1LoadPolicy::Eager;
  ------------------
  |  Branch (108:37): [True: 4.24k, False: 1.39M]
  ------------------
  109|  1.39M|		decodedRecord->setEncodedValue(startOfData, policy);
  110|       |
  111|  1.39M|		return decodedRecord;
  112|  1.40M|	}
_ZNK4pcpp10Asn1Record19getUniversalTagTypeEv:
  196|  7.26k|	{
  197|  7.26k|		if (m_TagClass == Asn1TagClass::Universal)
  ------------------
  |  Branch (197:7): [True: 7.25k, False: 6]
  ------------------
  198|  7.25k|		{
  199|  7.25k|			return static_cast<Asn1UniversalTagType>(m_TagType);
  200|  7.25k|		}
  201|       |
  202|      6|		return Asn1UniversalTagType::NotApplicable;
  203|  7.26k|	}
_ZN4pcpp10Asn1Record24decodeTagAndCreateRecordEPKhmRh:
  207|  1.40M|	{
  208|  1.40M|		if (dataLen < 1)
  ------------------
  |  Branch (208:7): [True: 59, False: 1.40M]
  ------------------
  209|     59|		{
  210|     59|			throw std::invalid_argument("Cannot decode ASN.1 record tag");
  211|     59|		}
  212|       |
  213|  1.40M|		tagLen = 1;
  214|       |
  215|  1.40M|		Asn1TagClass tagClass = Asn1TagClass::Universal;
  216|       |
  217|       |		// Check first 2 bits
  218|  1.40M|		auto tagClassBits = data[0] & 0xc0;
  219|  1.40M|		if (tagClassBits == 0)
  ------------------
  |  Branch (219:7): [True: 1.38M, False: 11.1k]
  ------------------
  220|  1.38M|		{
  221|  1.38M|			tagClass = Asn1TagClass::Universal;
  222|  1.38M|		}
  223|  11.1k|		else if ((tagClassBits & 0xc0) == 0xc0)
  ------------------
  |  Branch (223:12): [True: 2.09k, False: 9.00k]
  ------------------
  224|  2.09k|		{
  225|  2.09k|			tagClass = Asn1TagClass::Private;
  226|  2.09k|		}
  227|  9.00k|		else if ((tagClassBits & 0x80) == 0x80)
  ------------------
  |  Branch (227:12): [True: 5.08k, False: 3.92k]
  ------------------
  228|  5.08k|		{
  229|  5.08k|			tagClass = Asn1TagClass::ContextSpecific;
  230|  5.08k|		}
  231|  3.92k|		else if ((tagClassBits & 0x40) == 0x40)
  ------------------
  |  Branch (231:12): [True: 3.92k, False: 0]
  ------------------
  232|  3.92k|		{
  233|  3.92k|			tagClass = Asn1TagClass::Application;
  234|  3.92k|		}
  235|       |
  236|       |		// Check bit 6
  237|  1.40M|		auto tagTypeBits = data[0] & 0x20;
  238|  1.40M|		bool isConstructed = (tagTypeBits != 0);
  239|       |
  240|       |		// Check last 5 bits
  241|  1.40M|		auto tagType = data[0] & 0x1f;
  242|  1.40M|		if (tagType == 0x1f)
  ------------------
  |  Branch (242:7): [True: 1.14k, False: 1.39M]
  ------------------
  243|  1.14k|		{
  244|  1.14k|			if (dataLen < 2)
  ------------------
  |  Branch (244:8): [True: 8, False: 1.14k]
  ------------------
  245|      8|			{
  246|      8|				throw std::invalid_argument("Cannot decode ASN.1 record tag");
  247|      8|			}
  248|       |
  249|  1.14k|			if ((data[1] & 0x80) != 0)
  ------------------
  |  Branch (249:8): [True: 40, False: 1.10k]
  ------------------
  250|     40|			{
  251|     40|				throw std::invalid_argument("ASN.1 tags with value larger than 127 are not supported");
  252|     40|			}
  253|       |
  254|  1.10k|			tagType = data[1] & 0x7f;
  255|  1.10k|			tagLen = 2;
  256|  1.10k|		}
  257|       |
  258|  1.40M|		std::unique_ptr<Asn1Record> newRecord;
  259|       |
  260|  1.40M|		if (isConstructed)
  ------------------
  |  Branch (260:7): [True: 52.1k, False: 1.34M]
  ------------------
  261|  52.1k|		{
  262|  52.1k|			if (tagClass == Asn1TagClass::Universal)
  ------------------
  |  Branch (262:8): [True: 45.7k, False: 6.37k]
  ------------------
  263|  45.7k|			{
  264|  45.7k|				switch (static_cast<Asn1UniversalTagType>(tagType))
  265|  45.7k|				{
  266|  32.9k|				case Asn1UniversalTagType::Sequence:
  ------------------
  |  Branch (266:5): [True: 32.9k, False: 12.8k]
  ------------------
  267|  32.9k|				{
  268|  32.9k|					newRecord.reset(new Asn1SequenceRecord());
  269|  32.9k|					break;
  270|      0|				}
  271|  8.06k|				case Asn1UniversalTagType::Set:
  ------------------
  |  Branch (271:5): [True: 8.06k, False: 37.7k]
  ------------------
  272|  8.06k|				{
  273|  8.06k|					newRecord.reset(new Asn1SetRecord());
  274|  8.06k|					break;
  275|      0|				}
  276|  4.76k|				default:
  ------------------
  |  Branch (276:5): [True: 4.76k, False: 41.0k]
  ------------------
  277|  4.76k|				{
  278|  4.76k|					newRecord.reset(new Asn1ConstructedRecord());
  279|  4.76k|				}
  280|  45.7k|				}
  281|  45.7k|			}
  282|  6.37k|			else
  283|  6.37k|			{
  284|  6.37k|				newRecord.reset(new Asn1ConstructedRecord());
  285|  6.37k|			}
  286|  52.1k|		}
  287|  1.34M|		else
  288|  1.34M|		{
  289|  1.34M|			if (tagClass == Asn1TagClass::Universal)
  ------------------
  |  Branch (289:8): [True: 1.34M, False: 4.68k]
  ------------------
  290|  1.34M|			{
  291|  1.34M|				auto asn1UniversalTagType = static_cast<Asn1UniversalTagType>(tagType);
  292|  1.34M|				switch (asn1UniversalTagType)
  293|  1.34M|				{
  294|  6.29k|				case Asn1UniversalTagType::Integer:
  ------------------
  |  Branch (294:5): [True: 6.29k, False: 1.33M]
  ------------------
  295|  6.29k|				{
  296|  6.29k|					newRecord.reset(new Asn1IntegerRecord());
  297|  6.29k|					break;
  298|      0|				}
  299|  2.12k|				case Asn1UniversalTagType::Enumerated:
  ------------------
  |  Branch (299:5): [True: 2.12k, False: 1.34M]
  ------------------
  300|  2.12k|				{
  301|  2.12k|					newRecord.reset(new Asn1EnumeratedRecord());
  302|  2.12k|					break;
  303|      0|				}
  304|  13.9k|				case Asn1UniversalTagType::OctetString:
  ------------------
  |  Branch (304:5): [True: 13.9k, False: 1.32M]
  ------------------
  305|  13.9k|				{
  306|  13.9k|					newRecord.reset(new Asn1OctetStringRecord());
  307|  13.9k|					break;
  308|      0|				}
  309|  7.09k|				case Asn1UniversalTagType::UTF8String:
  ------------------
  |  Branch (309:5): [True: 7.09k, False: 1.33M]
  ------------------
  310|  7.09k|				{
  311|  7.09k|					newRecord.reset(new Asn1UTF8StringRecord());
  312|  7.09k|					break;
  313|      0|				}
  314|  5.21k|				case Asn1UniversalTagType::PrintableString:
  ------------------
  |  Branch (314:5): [True: 5.21k, False: 1.33M]
  ------------------
  315|  5.21k|				{
  316|  5.21k|					newRecord.reset(new Asn1PrintableStringRecord());
  317|  5.21k|					break;
  318|      0|				}
  319|  5.28k|				case Asn1UniversalTagType::IA5String:
  ------------------
  |  Branch (319:5): [True: 5.28k, False: 1.33M]
  ------------------
  320|  5.28k|				{
  321|  5.28k|					newRecord.reset(new Asn1IA5StringRecord());
  322|  5.28k|					break;
  323|      0|				}
  324|  3.96k|				case Asn1UniversalTagType::Boolean:
  ------------------
  |  Branch (324:5): [True: 3.96k, False: 1.33M]
  ------------------
  325|  3.96k|				{
  326|  3.96k|					newRecord.reset(new Asn1BooleanRecord());
  327|  3.96k|					break;
  328|      0|				}
  329|  4.54k|				case Asn1UniversalTagType::BitString:
  ------------------
  |  Branch (329:5): [True: 4.54k, False: 1.33M]
  ------------------
  330|  4.54k|				{
  331|  4.54k|					newRecord.reset(new Asn1BitStringRecord());
  332|  4.54k|					break;
  333|      0|				}
  334|  1.03k|				case Asn1UniversalTagType::Null:
  ------------------
  |  Branch (334:5): [True: 1.03k, False: 1.34M]
  ------------------
  335|  1.03k|				{
  336|  1.03k|					newRecord.reset(new Asn1NullRecord());
  337|  1.03k|					break;
  338|      0|				}
  339|  22.4k|				case Asn1UniversalTagType::ObjectIdentifier:
  ------------------
  |  Branch (339:5): [True: 22.4k, False: 1.32M]
  ------------------
  340|  22.4k|				{
  341|  22.4k|					newRecord.reset(new Asn1ObjectIdentifierRecord());
  342|  22.4k|					break;
  343|      0|				}
  344|  6.45k|				case Asn1UniversalTagType::UTCTime:
  ------------------
  |  Branch (344:5): [True: 6.45k, False: 1.33M]
  ------------------
  345|  6.45k|				{
  346|  6.45k|					newRecord.reset(new Asn1UtcTimeRecord());
  347|  6.45k|					break;
  348|      0|				}
  349|  6.17k|				case Asn1UniversalTagType::GeneralizedTime:
  ------------------
  |  Branch (349:5): [True: 6.17k, False: 1.33M]
  ------------------
  350|  6.17k|				{
  351|  6.17k|					newRecord.reset(new Asn1GeneralizedTimeRecord());
  352|  6.17k|					break;
  353|      0|				}
  354|  1.25M|				default:
  ------------------
  |  Branch (354:5): [True: 1.25M, False: 84.5k]
  ------------------
  355|  1.25M|				{
  356|  1.25M|					newRecord.reset(new Asn1GenericRecord());
  357|  1.25M|				}
  358|  1.34M|				}
  359|  1.34M|			}
  360|  4.68k|			else
  361|  4.68k|			{
  362|  4.68k|				newRecord.reset(new Asn1GenericRecord());
  363|  4.68k|			}
  364|  1.34M|		}
  365|       |
  366|  1.40M|		newRecord->m_TagClass = tagClass;
  367|  1.40M|		newRecord->m_IsConstructed = isConstructed;
  368|  1.40M|		newRecord->m_TagType = tagType;
  369|       |
  370|  1.40M|		return newRecord;
  371|  1.40M|	}
_ZN4pcpp10Asn1Record12decodeLengthEPKhm:
  374|  1.40M|	{
  375|  1.40M|		if (dataLen < 1)
  ------------------
  |  Branch (375:7): [True: 188, False: 1.39M]
  ------------------
  376|    188|		{
  377|    188|			throw std::invalid_argument("Cannot decode ASN.1 record length");
  378|    188|		}
  379|       |
  380|       |		// Check 8th bit
  381|  1.39M|		auto lengthForm = data[0] & 0x80;
  382|       |
  383|       |		// Check if the tag is using more than one byte
  384|       |		// 8th bit at 0 means the length only uses one byte
  385|       |		// 8th bit at 1 means the length uses more than one byte. The number of bytes is encoded in the other 7 bits
  386|  1.39M|		if (lengthForm == 0)
  ------------------
  |  Branch (386:7): [True: 1.39M, False: 7.29k]
  ------------------
  387|  1.39M|		{
  388|  1.39M|			m_ValueLength = data[0];
  389|  1.39M|			return 1;
  390|  1.39M|		}
  391|       |
  392|  7.29k|		uint8_t actualLengthBytes = data[0] & 0x7F;
  393|  7.29k|		const uint8_t* actualLengthData = data + 1;
  394|       |
  395|  7.29k|		if (dataLen < static_cast<size_t>(actualLengthBytes) + 1)
  ------------------
  |  Branch (395:7): [True: 75, False: 7.21k]
  ------------------
  396|     75|		{
  397|     75|			throw std::invalid_argument("Cannot decode ASN.1 record length");
  398|     75|		}
  399|       |
  400|  27.3k|		for (int i = 0; i < actualLengthBytes; i++)
  ------------------
  |  Branch (400:19): [True: 20.2k, False: 7.15k]
  ------------------
  401|  20.2k|		{
  402|  20.2k|			size_t partialValueLength = m_ValueLength << 8;
  403|  20.2k|			if (partialValueLength < m_ValueLength)  // check for overflow
  ------------------
  |  Branch (403:8): [True: 63, False: 20.1k]
  ------------------
  404|     63|			{
  405|     63|				throw std::invalid_argument("Cannot decode ASN.1 record length");
  406|     63|			}
  407|       |
  408|  20.1k|			m_ValueLength = partialValueLength | actualLengthData[i];
  409|  20.1k|		}
  410|       |
  411|  7.15k|		return 1 + actualLengthBytes;
  412|  7.21k|	}
_ZNK4pcpp10Asn1Record19decodeValueIfNeededEv:
  415|  1.52M|	{
  416|       |		// TODO: This is not thread-safe and can cause issues in a multiple reader scenario.
  417|  1.52M|		if (m_EncodedValue != nullptr)
  ------------------
  |  Branch (417:7): [True: 1.39M, False: 121k]
  ------------------
  418|  1.39M|		{
  419|  1.39M|			decodeValue(m_EncodedValue);
  420|  1.39M|			m_EncodedValue = nullptr;  // Clear the encoded value after decoding
  421|  1.39M|		}
  422|  1.52M|	}
_ZN4pcpp10Asn1Record15setEncodedValueEPKhNS_8internal14Asn1LoadPolicyE:
  462|  1.39M|	{
  463|  1.39M|		m_EncodedValue = dataSource;
  464|       |
  465|  1.39M|		if (loadPolicy == internal::Asn1LoadPolicy::Eager)
  ------------------
  |  Branch (465:7): [True: 1.39M, False: 4.24k]
  ------------------
  466|  1.39M|		{
  467|  1.39M|			decodeValueIfNeeded();
  468|  1.39M|		}
  469|  1.39M|	}
_ZNK4pcpp17Asn1GenericRecord11decodeValueEPKh:
  484|  1.26M|	{
  485|  1.26M|		m_Value = std::make_unique<uint8_t[]>(m_ValueLength);
  486|  1.26M|		std::memcpy(m_Value.get(), data, m_ValueLength);
  487|  1.26M|	}
_ZNK4pcpp21Asn1ConstructedRecord11decodeValueEPKh:
  519|  51.7k|	{
  520|  51.7k|		if (!(data || m_ValueLength))
  ------------------
  |  Branch (520:9): [True: 51.7k, False: 0]
  |  Branch (520:17): [True: 0, False: 0]
  ------------------
  521|      0|		{
  522|      0|			return;
  523|      0|		}
  524|       |
  525|  51.7k|		auto value = data;
  526|  51.7k|		auto valueLen = m_ValueLength;
  527|       |
  528|  1.44M|		while (valueLen > 0)
  ------------------
  |  Branch (528:10): [True: 1.39M, False: 51.7k]
  ------------------
  529|  1.39M|		{
  530|  1.39M|			auto subRecord = Asn1Record::decode(value, valueLen, LazySubRecordDecoding);
  531|  1.39M|			value += subRecord->getTotalLength();
  532|  1.39M|			valueLen -= subRecord->getTotalLength();
  533|       |
  534|  1.39M|			m_SubRecords.pushBack(std::move(subRecord));
  535|  1.39M|		}
  536|  51.7k|	}
_ZN4pcpp19Asn1PrimitiveRecordC2ENS_20Asn1UniversalTagTypeE:
  583|  32.5k|	Asn1PrimitiveRecord::Asn1PrimitiveRecord(Asn1UniversalTagType tagType) : Asn1Record()
  584|  32.5k|	{
  585|  32.5k|		m_TagType = static_cast<uint8_t>(tagType);
  586|  32.5k|		m_TagClass = Asn1TagClass::Universal;
  587|  32.5k|		m_IsConstructed = false;
  588|  32.5k|	}
_ZN4pcpp17Asn1IntegerRecord6BigInt14initFromStringERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  601|  8.38k|	{
  602|  8.38k|		std::string valueStr = value;
  603|       |
  604|       |		// Optional 0x or 0X prefix
  605|  8.38k|		if (value.size() >= 2 && value[0] == '0' && (value[1] == 'x' || value[1] == 'X'))
  ------------------
  |  Branch (605:7): [True: 8.35k, False: 27]
  |  Branch (605:28): [True: 6.01k, False: 2.34k]
  |  Branch (605:48): [True: 0, False: 6.01k]
  |  Branch (605:67): [True: 0, False: 6.01k]
  ------------------
  606|      0|		{
  607|      0|			valueStr = value.substr(2);
  608|      0|		}
  609|       |
  610|  8.38k|		if (valueStr.empty())
  ------------------
  |  Branch (610:7): [True: 27, False: 8.35k]
  ------------------
  611|     27|		{
  612|     27|			throw std::invalid_argument("Value is not a valid hex stream");
  613|     27|		}
  614|       |
  615|  8.35k|		if (std::any_of(valueStr.begin(), valueStr.end(), [](char c) { return !std::isxdigit(c); }))
  ------------------
  |  Branch (615:7): [True: 0, False: 8.35k]
  ------------------
  616|      0|		{
  617|      0|			throw std::invalid_argument("Value is not a valid hex stream");
  618|      0|		}
  619|       |
  620|  8.35k|		return valueStr;
  621|  8.35k|	}
_ZN4pcpp17Asn1IntegerRecord6BigIntaSERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  624|  8.38k|	{
  625|  8.38k|		m_Value = initFromString(value);
  626|  8.38k|		return *this;
  627|  8.38k|	}
_ZNK4pcpp17Asn1IntegerRecord6BigInt8toStringEb:
  635|  1.99k|	{
  636|  1.99k|		if (!removeLeadingZeros)
  ------------------
  |  Branch (636:7): [True: 0, False: 1.99k]
  ------------------
  637|      0|		{
  638|      0|			return m_Value;
  639|      0|		}
  640|       |
  641|  1.99k|		auto firstNonZero = m_Value.find_first_not_of('0');
  642|  1.99k|		if (firstNonZero == std::string::npos)
  ------------------
  |  Branch (642:7): [True: 70, False: 1.92k]
  ------------------
  643|     70|		{
  644|     70|			return "0";
  645|     70|		}
  646|       |
  647|  1.92k|		return m_Value.substr(firstNonZero);
  648|  1.99k|	}
_ZNK4pcpp17Asn1IntegerRecord11decodeValueEPKh:
  692|  8.38k|	{
  693|  8.38k|		m_Value = pcpp::byteArrayToHexString(data, m_ValueLength);
  694|  8.38k|	}
_ZNK4pcpp21Asn1OctetStringRecord11decodeValueEPKh:
  721|  13.8k|	{
  722|  13.8k|		auto value = reinterpret_cast<char const*>(data);
  723|       |
  724|  13.8k|		m_IsPrintable = std::all_of(value, value + m_ValueLength, [](char c) { return isprint(0xff & c); });
  725|       |
  726|  13.8k|		if (m_IsPrintable)
  ------------------
  |  Branch (726:7): [True: 2.97k, False: 10.9k]
  ------------------
  727|  2.97k|		{
  728|  2.97k|			Asn1StringRecord::decodeValue(data);
  729|  2.97k|		}
  730|  10.9k|		else
  731|  10.9k|		{
  732|  10.9k|			m_Value = byteArrayToHexString(data, m_ValueLength);
  733|  10.9k|		}
  734|  13.8k|	}
_ZNK4pcpp17Asn1BooleanRecord11decodeValueEPKh:
  761|  3.93k|	{
  762|  3.93k|		if (m_ValueLength != 1)
  ------------------
  |  Branch (762:7): [True: 27, False: 3.90k]
  ------------------
  763|     27|		{
  764|     27|			throw std::invalid_argument("Cannot decode ASN.1 Boolean record, value length must be 1");
  765|     27|		}
  766|       |
  767|  3.90k|		m_Value = data[0] != 0;
  768|  3.90k|	}
_ZN4pcpp14Asn1NullRecordC2Ev:
  781|  1.03k|	Asn1NullRecord::Asn1NullRecord() : Asn1PrimitiveRecord(Asn1UniversalTagType::Null)
  782|  1.03k|	{
  783|  1.03k|		m_ValueLength = 0;
  784|  1.03k|		m_TotalLength = 2;
  785|  1.03k|	}
_ZN4pcpp20Asn1ObjectIdentifierC2EPKhm:
  788|  22.3k|	{
  789|       |		// A description of OID encoding can be found here:
  790|       |		// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-object-identifier?redirectedfrom=MSDN
  791|       |
  792|  22.3k|		if (!data || dataLen == 0)
  ------------------
  |  Branch (792:7): [True: 0, False: 22.3k]
  |  Branch (792:16): [True: 5, False: 22.3k]
  ------------------
  793|      5|		{
  794|      5|			throw std::invalid_argument("Malformed OID: Not enough bytes for the first component");
  795|      5|		}
  796|       |
  797|  22.3k|		size_t currentByteIndex = 0;
  798|  22.3k|		std::vector<uint32_t> components;
  799|       |
  800|  22.3k|		uint8_t firstByte = data[currentByteIndex++];
  801|       |		// Decode the first byte: first_component * 40 + second_component
  802|  22.3k|		components.push_back(static_cast<uint32_t>(firstByte / 40));
  803|  22.3k|		components.push_back(static_cast<uint32_t>(firstByte % 40));
  804|       |
  805|  22.3k|		uint32_t currentComponentValue = 0;
  806|  22.3k|		bool componentStarted = false;
  807|       |
  808|       |		// Process remaining bytes using base-128 encoding
  809|   530k|		while (currentByteIndex < dataLen)
  ------------------
  |  Branch (809:10): [True: 508k, False: 22.3k]
  ------------------
  810|   508k|		{
  811|   508k|			uint8_t byte = data[currentByteIndex++];
  812|       |
  813|       |			// Shift previous bits left by 7 and append lower 7 bits
  814|   508k|			currentComponentValue = (currentComponentValue << 7) | (byte & 0x7f);
  815|   508k|			componentStarted = true;
  816|       |
  817|       |			// If the MSB is 0, this is the final byte of the current value
  818|   508k|			if ((byte & 0x80) == 0)
  ------------------
  |  Branch (818:8): [True: 460k, False: 47.7k]
  ------------------
  819|   460k|			{
  820|   460k|				components.push_back(currentComponentValue);
  821|   460k|				currentComponentValue = 0;
  822|   460k|				componentStarted = false;
  823|   460k|			}
  824|   508k|		}
  825|       |
  826|  22.3k|		if (componentStarted)
  ------------------
  |  Branch (826:7): [True: 15, False: 22.3k]
  ------------------
  827|     15|		{
  828|     15|			throw std::invalid_argument("Malformed OID: Incomplete component at end of data");
  829|     15|		}
  830|       |
  831|  22.3k|		m_Components = components;
  832|  22.3k|	}
_ZNK4pcpp20Asn1ObjectIdentifier8toStringEv:
  885|  16.1k|	{
  886|  16.1k|		if (m_Components.empty())
  ------------------
  |  Branch (886:7): [True: 0, False: 16.1k]
  ------------------
  887|      0|		{
  888|      0|			return "";
  889|      0|		}
  890|       |
  891|  16.1k|		std::ostringstream stream;
  892|  16.1k|		stream << m_Components[0];
  893|       |
  894|  88.7k|		for (size_t i = 1; i < m_Components.size(); ++i)
  ------------------
  |  Branch (894:22): [True: 72.6k, False: 16.1k]
  ------------------
  895|  72.6k|		{
  896|  72.6k|			stream << "." << m_Components[i];
  897|  72.6k|		}
  898|  16.1k|		return stream.str();
  899|  16.1k|	}
_ZNK4pcpp26Asn1ObjectIdentifierRecord11decodeValueEPKh:
  955|  22.3k|	{
  956|  22.3k|		m_Value = Asn1ObjectIdentifier(data, m_ValueLength);
  957|  22.3k|	}
_ZNK4pcpp14Asn1TimeRecord16getValueAsStringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_b:
  979|  1.48k|	{
  980|  1.48k|		auto value = getValue(timezone);
  981|  1.48k|		auto timeValue = std::chrono::system_clock::to_time_t(value);
  982|  1.48k|		auto tmValue = *std::gmtime(&timeValue);
  983|       |
  984|  1.48k|		std::ostringstream osstream;
  985|  1.48k|		osstream << std::put_time(&tmValue, format.c_str());
  986|       |
  987|  1.48k|		if (includeMilliseconds)
  ------------------
  |  Branch (987:7): [True: 0, False: 1.48k]
  ------------------
  988|      0|		{
  989|      0|			auto milliseconds =
  990|      0|			    std::chrono::duration_cast<std::chrono::milliseconds>(value.time_since_epoch()).count() % 1000;
  991|      0|			if (milliseconds != 0)
  ------------------
  |  Branch (991:8): [True: 0, False: 0]
  ------------------
  992|      0|			{
  993|      0|				osstream << "." << std::setw(3) << std::setfill('0') << milliseconds;
  994|      0|			}
  995|      0|		}
  996|       |
  997|  1.48k|		if (timezone != "Z")
  ------------------
  |  Branch (997:7): [True: 0, False: 1.48k]
  ------------------
  998|      0|		{
  999|      0|			osstream << " UTC" << timezone;
 1000|      0|		}
 1001|       |
 1002|  1.48k|		return osstream.str();
 1003|  1.48k|	}
_ZN4pcpp14Asn1TimeRecord16validateTimezoneERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 1011|  14.7k|	{
 1012|  14.7k|		if (timezone == "Z")
  ------------------
  |  Branch (1012:7): [True: 12.5k, False: 2.17k]
  ------------------
 1013|  12.5k|		{
 1014|  12.5k|			return;
 1015|  12.5k|		}
 1016|       |
 1017|  2.17k|		if (timezone.length() != 5 || (timezone[0] != '+' && timezone[0] != '-') || !std::isdigit(timezone[1]) ||
  ------------------
  |  Branch (1017:7): [True: 75, False: 2.10k]
  |  Branch (1017:34): [True: 774, False: 1.32k]
  |  Branch (1017:56): [True: 0, False: 774]
  |  Branch (1017:79): [True: 13, False: 2.08k]
  ------------------
 1018|  2.08k|		    !std::isdigit(timezone[2]) || !std::isdigit(timezone[3]) || !std::isdigit(timezone[4]))
  ------------------
  |  Branch (1018:7): [True: 18, False: 2.07k]
  |  Branch (1018:37): [True: 12, False: 2.05k]
  |  Branch (1018:67): [True: 13, False: 2.04k]
  ------------------
 1019|    131|		{
 1020|    131|			throw std::invalid_argument("Invalid timezone format. Use 'Z' or '+/-HHMM'.");
 1021|    131|		}
 1022|  2.17k|	}
_ZN4pcpp14Asn1TimeRecord15adjustTimezonesERKNSt3__16chrono10time_pointINS2_12system_clockENS2_8durationIxNS1_5ratioILl1ELl1000000EEEEEEERKNS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEESJ_:
 1027|  7.41k|	{
 1028|  7.41k|		validateTimezone(fromTimezone);
 1029|  7.41k|		validateTimezone(toTimezone);
 1030|       |
 1031|  7.41k|		int fromOffsetSeconds = 0;
 1032|  7.41k|		if (fromTimezone != "Z")
  ------------------
  |  Branch (1032:7): [True: 2.04k, False: 5.37k]
  ------------------
 1033|  2.04k|		{
 1034|  2.04k|			int fromSign = (fromTimezone[0] == '+') ? 1 : -1;
  ------------------
  |  Branch (1034:19): [True: 1.29k, False: 753]
  ------------------
 1035|  2.04k|			auto fromHours = std::stoi(fromTimezone.substr(1, 2));
 1036|  2.04k|			auto fromMinutes = std::stoi(fromTimezone.substr(3, 2));
 1037|  2.04k|			fromOffsetSeconds = fromSign * (fromHours * 3600 + fromMinutes * 60);
 1038|  2.04k|		}
 1039|       |
 1040|  7.41k|		int toOffsetSeconds = 0;
 1041|  7.41k|		if (toTimezone != "Z")
  ------------------
  |  Branch (1041:7): [True: 0, False: 7.41k]
  ------------------
 1042|      0|		{
 1043|      0|			int toSign = (toTimezone[0] == '+') ? 1 : -1;
  ------------------
  |  Branch (1043:17): [True: 0, False: 0]
  ------------------
 1044|      0|			auto toHours = std::stoi(toTimezone.substr(1, 2));
 1045|      0|			auto toMinutes = std::stoi(toTimezone.substr(3, 2));
 1046|      0|			toOffsetSeconds = toSign * (toHours * 3600 + toMinutes * 60);
 1047|      0|		}
 1048|       |
 1049|  7.41k|		return value + std::chrono::seconds(toOffsetSeconds - fromOffsetSeconds);
 1050|  7.41k|	}
_ZNK4pcpp17Asn1UtcTimeRecord11decodeValueEPKh:
 1065|  6.43k|	{
 1066|  6.43k|		std::string timeString(reinterpret_cast<const char*>(data), m_ValueLength);
 1067|       |
 1068|  6.43k|		if (timeString.empty())
  ------------------
  |  Branch (1068:7): [True: 4, False: 6.43k]
  ------------------
 1069|      4|		{
 1070|      4|			throw std::runtime_error("Failed to parse ASN.1 UTC time");
 1071|      4|		}
 1072|       |
 1073|  6.43k|		if (timeString.back() == 'Z')
  ------------------
  |  Branch (1073:7): [True: 2.89k, False: 3.53k]
  ------------------
 1074|  2.89k|		{
 1075|  2.89k|			timeString.pop_back();
 1076|  2.89k|		}
 1077|       |
 1078|  6.43k|		m_WithSeconds = true;
 1079|  6.43k|		if (timeString.size() == 10)
  ------------------
  |  Branch (1079:7): [True: 229, False: 6.20k]
  ------------------
 1080|    229|		{
 1081|    229|			m_WithSeconds = false;
 1082|    229|			timeString.append("00");
 1083|    229|		}
 1084|       |
 1085|  6.43k|		auto year = std::stoi(timeString.substr(0, 2));
 1086|  6.43k|		if (year <= 50)
  ------------------
  |  Branch (1086:7): [True: 5.95k, False: 483]
  ------------------
 1087|  5.95k|		{
 1088|  5.95k|			timeString.insert(0, "20");
 1089|  5.95k|		}
 1090|    483|		else
 1091|    483|		{
 1092|    483|			timeString.insert(0, "19");
 1093|    483|		}
 1094|       |
 1095|  6.43k|		std::tm tm = {};
 1096|  6.43k|		std::istringstream sstream(timeString);
 1097|  6.43k|		sstream >> std::get_time(&tm, "%Y%m%d%H%M%S");
 1098|       |
 1099|  6.43k|		if (sstream.fail())
  ------------------
  |  Branch (1099:7): [True: 41, False: 6.39k]
  ------------------
 1100|     41|		{
 1101|     41|			throw std::runtime_error("Failed to parse ASN.1 UTC time");
 1102|     41|		}
 1103|       |
 1104|  6.39k|		std::time_t timeValue = mkUtcTime(tm);
 1105|  6.39k|		m_Value = std::chrono::system_clock::from_time_t(timeValue);
 1106|  6.39k|	}
_ZNK4pcpp25Asn1GeneralizedTimeRecord11decodeValueEPKh:
 1138|  6.15k|	{
 1139|  6.15k|		std::string timeString(reinterpret_cast<const char*>(data), m_ValueLength);
 1140|       |
 1141|  6.15k|		if (timeString.empty())
  ------------------
  |  Branch (1141:7): [True: 6, False: 6.14k]
  ------------------
 1142|      6|		{
 1143|      6|			throw std::runtime_error("Failed to parse ASN.1 generalized time");
 1144|      6|		}
 1145|       |
 1146|  6.14k|		std::string timezone = "Z";
 1147|  6.14k|		auto timezonePos = timeString.find_first_of("+-");
 1148|  6.14k|		if (timeString.back() == 'Z')
  ------------------
  |  Branch (1148:7): [True: 595, False: 5.54k]
  ------------------
 1149|    595|		{
 1150|    595|			timeString.pop_back();
 1151|    595|		}
 1152|  5.54k|		else if (timezonePos != std::string::npos)
  ------------------
  |  Branch (1152:12): [True: 2.29k, False: 3.25k]
  ------------------
 1153|  2.29k|		{
 1154|  2.29k|			timezone = timeString.substr(timezonePos);
 1155|  2.29k|			timeString.erase(timezonePos);
 1156|  2.29k|		}
 1157|       |
 1158|  6.14k|		std::tm tm = {};
 1159|  6.14k|		std::istringstream sstream(timeString);
 1160|  6.14k|		sstream >> std::get_time(&tm, "%Y%m%d%H%M%S");
 1161|       |
 1162|  6.14k|		if (sstream.fail())
  ------------------
  |  Branch (1162:7): [True: 152, False: 5.99k]
  ------------------
 1163|    152|		{
 1164|    152|			throw std::runtime_error("Failed to parse ASN.1 generalized time");
 1165|    152|		}
 1166|       |
 1167|  5.99k|		size_t dotPos = timeString.find('.');
 1168|  5.99k|		int milliseconds = 0;
 1169|  5.99k|		if (dotPos != std::string::npos)
  ------------------
  |  Branch (1169:7): [True: 2.37k, False: 3.62k]
  ------------------
 1170|  2.37k|		{
 1171|       |			// The digits after the dot are a decimal fraction of a second, so ".5" is 500 milliseconds.
 1172|       |			// Pad or truncate them to 3 digits to read them as milliseconds
 1173|  2.37k|			std::string millisecondsStr = timeString.substr(dotPos + 1);
 1174|  2.37k|			millisecondsStr.resize(3, '0');
 1175|  2.37k|			milliseconds = std::stoi(millisecondsStr);
 1176|  2.37k|		}
 1177|       |
 1178|  5.99k|		auto timeValue = mkUtcTime(tm);
 1179|       |
 1180|  5.99k|		m_Timezone = timezone;
 1181|  5.99k|		m_Value = adjustTimezones(
 1182|  5.99k|		    std::chrono::system_clock::from_time_t(timeValue) + std::chrono::milliseconds(milliseconds), timezone, "Z");
 1183|  5.99k|	}
_ZN4pcpp19Asn1BitStringRecord6BitSetC2EPKhm:
 1240|  3.93k|	Asn1BitStringRecord::BitSet::BitSet(const uint8_t* data, size_t numBits) : m_NumBits(numBits)
 1241|  3.93k|	{
 1242|  3.93k|		if (!data || !numBits)
  ------------------
  |  Branch (1242:7): [True: 0, False: 3.93k]
  |  Branch (1242:16): [True: 0, False: 3.93k]
  ------------------
 1243|      0|		{
 1244|      0|			throw std::invalid_argument("Provided data is null or num of bits is 0");
 1245|      0|		}
 1246|       |
 1247|  3.93k|		size_t requiredBytes = (m_NumBits + 7) / 8;
 1248|  3.93k|		m_Data.resize(requiredBytes);
 1249|  3.93k|		std::copy_n(data, requiredBytes, m_Data.begin());
 1250|  3.93k|	}
_ZNK4pcpp19Asn1BitStringRecord6BitSet8toStringEv:
 1259|    359|	{
 1260|    359|		std::string result;
 1261|    359|		result.reserve(m_Data.size() * 8);
 1262|    359|		for (const auto bs : m_Data)
  ------------------
  |  Branch (1262:22): [True: 4.05k, False: 359]
  ------------------
 1263|  4.05k|		{
 1264|  4.05k|			result += bs.to_string();
 1265|  4.05k|		}
 1266|    359|		result.resize(m_NumBits);
 1267|    359|		return result;
 1268|    359|	}
_ZNK4pcpp19Asn1BitStringRecord6BitSet7toBytesEv:
 1271|  3.16k|	{
 1272|  3.16k|		std::vector<uint8_t> result;
 1273|  3.16k|		result.reserve(m_Data.size());
 1274|  3.16k|		for (const auto& bs : m_Data)
  ------------------
  |  Branch (1274:23): [True: 329k, False: 3.16k]
  ------------------
 1275|   329k|		{
 1276|   329k|			result.push_back(static_cast<uint8_t>(bs.to_ulong()));
 1277|   329k|		}
 1278|       |
 1279|  3.16k|		return result;
 1280|  3.16k|	}
_ZNK4pcpp19Asn1BitStringRecord11decodeValueEPKh:
 1296|  4.51k|	{
 1297|       |		// A BitString value must contain at least the initial octet holding the number of unused bits
 1298|  4.51k|		if (m_ValueLength == 0)
  ------------------
  |  Branch (1298:7): [True: 6, False: 4.50k]
  ------------------
 1299|      6|		{
 1300|      6|			throw std::invalid_argument("Cannot decode ASN.1 BitString record, value is empty");
 1301|      6|		}
 1302|       |
 1303|  4.50k|		auto unusedBits = static_cast<size_t>(data[0]);
 1304|       |
 1305|       |		// The number of unused bits must be in the range 0-7, and must be 0 if the bit string is empty
 1306|  4.50k|		if (unusedBits > 7 || (m_ValueLength == 1 && unusedBits != 0))
  ------------------
  |  Branch (1306:7): [True: 19, False: 4.48k]
  |  Branch (1306:26): [True: 555, False: 3.93k]
  |  Branch (1306:48): [True: 5, False: 550]
  ------------------
 1307|     24|		{
 1308|     24|			throw std::invalid_argument("Cannot decode ASN.1 BitString record, invalid number of unused bits");
 1309|     24|		}
 1310|       |
 1311|  4.48k|		auto numBits = (m_ValueLength - 1) * 8 - unusedBits;
 1312|  4.48k|		if (numBits == 0)
  ------------------
  |  Branch (1312:7): [True: 550, False: 3.93k]
  ------------------
 1313|    550|		{
 1314|    550|			m_Value = BitSet();
 1315|    550|			return;
 1316|    550|		}
 1317|       |
 1318|  3.93k|		m_Value = BitSet(data + 1, numBits);
 1319|  3.93k|	}
Asn1Codec.cpp:_ZZN4pcpp17Asn1IntegerRecord6BigInt14initFromStringERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEENK3$_0clEc:
  615|  1.00M|		if (std::any_of(valueStr.begin(), valueStr.end(), [](char c) { return !std::isxdigit(c); }))
Asn1Codec.cpp:_ZZNK4pcpp21Asn1OctetStringRecord11decodeValueEPKhENK3$_0clEc:
  724|  55.3k|		m_IsPrintable = std::all_of(value, value + m_ValueLength, [](char c) { return isprint(0xff & c); });

_ZNK4pcpp13X509Algorithm8toStringEv:
   12|  1.48k|	{
   13|  1.48k|		switch (m_Value)
   14|  1.48k|		{
   15|      0|		case SHA1:
  ------------------
  |  Branch (15:3): [True: 0, False: 1.48k]
  ------------------
   16|      0|			return "SHA1";
   17|      1|		case SHA256:
  ------------------
  |  Branch (17:3): [True: 1, False: 1.48k]
  ------------------
   18|      1|			return "SHA256";
   19|      1|		case SHA384:
  ------------------
  |  Branch (19:3): [True: 1, False: 1.48k]
  ------------------
   20|      1|			return "SHA384";
   21|      1|		case SHA512:
  ------------------
  |  Branch (21:3): [True: 1, False: 1.48k]
  ------------------
   22|      1|			return "SHA512";
   23|      4|		case MD5:
  ------------------
  |  Branch (23:3): [True: 4, False: 1.47k]
  ------------------
   24|      4|			return "MD5";
   25|     16|		case RSA:
  ------------------
  |  Branch (25:3): [True: 16, False: 1.46k]
  ------------------
   26|     16|			return "RSA";
   27|      8|		case RSAWithSHA1:
  ------------------
  |  Branch (27:3): [True: 8, False: 1.47k]
  ------------------
   28|      8|			return "RSAWithSHA1";
   29|      4|		case RSAWithSHA256:
  ------------------
  |  Branch (29:3): [True: 4, False: 1.47k]
  ------------------
   30|      4|			return "RSAWithSHA256";
   31|      3|		case RSAWithSHA384:
  ------------------
  |  Branch (31:3): [True: 3, False: 1.47k]
  ------------------
   32|      3|			return "RSAWithSHA384";
   33|      9|		case RSAWithSHA512:
  ------------------
  |  Branch (33:3): [True: 9, False: 1.47k]
  ------------------
   34|      9|			return "RSAWithSHA512";
   35|      4|		case RSAPSS:
  ------------------
  |  Branch (35:3): [True: 4, False: 1.47k]
  ------------------
   36|      4|			return "RSAPSS";
   37|     67|		case ECDSA:
  ------------------
  |  Branch (37:3): [True: 67, False: 1.41k]
  ------------------
   38|     67|			return "ECDSA";
   39|      8|		case ECDSAWithSHA1:
  ------------------
  |  Branch (39:3): [True: 8, False: 1.47k]
  ------------------
   40|      8|			return "ECDSAWithSHA1";
   41|     51|		case ECDSAWithSHA256:
  ------------------
  |  Branch (41:3): [True: 51, False: 1.43k]
  ------------------
   42|     51|			return "ECDSAWithSHA256";
   43|      4|		case ECDSAWithSHA384:
  ------------------
  |  Branch (43:3): [True: 4, False: 1.47k]
  ------------------
   44|      4|			return "ECDSAWithSHA384";
   45|     11|		case ECDSAWithSHA512:
  ------------------
  |  Branch (45:3): [True: 11, False: 1.47k]
  ------------------
   46|     11|			return "ECDSAWithSHA512";
   47|      4|		case ED25519:
  ------------------
  |  Branch (47:3): [True: 4, False: 1.47k]
  ------------------
   48|      4|			return "ED25519";
   49|      4|		case ED448:
  ------------------
  |  Branch (49:3): [True: 4, False: 1.47k]
  ------------------
   50|      4|			return "ED448";
   51|      6|		case DSA:
  ------------------
  |  Branch (51:3): [True: 6, False: 1.47k]
  ------------------
   52|      6|			return "DSA";
   53|      3|		case DSAWithSHA1:
  ------------------
  |  Branch (53:3): [True: 3, False: 1.47k]
  ------------------
   54|      3|			return "DSAWithSHA1";
   55|      1|		case DSAWithSHA256:
  ------------------
  |  Branch (55:3): [True: 1, False: 1.48k]
  ------------------
   56|      1|			return "DSAWithSHA256";
   57|      3|		case DiffieHellman:
  ------------------
  |  Branch (57:3): [True: 3, False: 1.47k]
  ------------------
   58|      3|			return "DiffieHellman";
   59|  1.26k|		case Unknown:
  ------------------
  |  Branch (59:3): [True: 1.26k, False: 213]
  ------------------
   60|  1.26k|		default:
  ------------------
  |  Branch (60:3): [True: 0, False: 1.48k]
  ------------------
   61|  1.26k|			return "Unknown";
   62|  1.48k|		}
   63|  1.48k|	}
_ZN4pcpp13X509Algorithm12fromOidValueERKNS_20Asn1ObjectIdentifierE:
  151|  3.28k|	{
  152|  3.28k|		std::string oidStringValue = value.toString();
  153|       |
  154|  3.28k|		auto it = X509AlgorithmOidMap.find(oidStringValue);
  155|  3.28k|		if (it != X509AlgorithmOidMap.end())
  ------------------
  |  Branch (155:7): [True: 446, False: 2.84k]
  ------------------
  156|    446|		{
  157|    446|			return { it->second };
  158|    446|		}
  159|       |
  160|  2.84k|		return { Unknown };
  161|  3.28k|	}
_ZNK4pcpp21X520DistinguishedName12getShortNameEv:
  212|  3.34k|	{
  213|  3.34k|		switch (m_Value)
  214|  3.34k|		{
  215|    274|		case CommonName:
  ------------------
  |  Branch (215:3): [True: 274, False: 3.07k]
  ------------------
  216|    274|			return "CN";
  217|     47|		case Surname:
  ------------------
  |  Branch (217:3): [True: 47, False: 3.29k]
  ------------------
  218|     47|			return "SN";
  219|     48|		case SerialNumber:
  ------------------
  |  Branch (219:3): [True: 48, False: 3.29k]
  ------------------
  220|     48|			return "SERIALNUMBER";
  221|    174|		case Country:
  ------------------
  |  Branch (221:3): [True: 174, False: 3.17k]
  ------------------
  222|    174|			return "C";
  223|    155|		case Locality:
  ------------------
  |  Branch (223:3): [True: 155, False: 3.19k]
  ------------------
  224|    155|			return "L";
  225|     91|		case StateOrProvince:
  ------------------
  |  Branch (225:3): [True: 91, False: 3.25k]
  ------------------
  226|     91|			return "ST";
  227|    178|		case Organization:
  ------------------
  |  Branch (227:3): [True: 178, False: 3.16k]
  ------------------
  228|    178|			return "O";
  229|     73|		case OrganizationalUnit:
  ------------------
  |  Branch (229:3): [True: 73, False: 3.27k]
  ------------------
  230|     73|			return "OU";
  231|     37|		case Title:
  ------------------
  |  Branch (231:3): [True: 37, False: 3.30k]
  ------------------
  232|     37|			return "T";
  233|     43|		case GivenName:
  ------------------
  |  Branch (233:3): [True: 43, False: 3.30k]
  ------------------
  234|     43|			return "G";
  235|     41|		case Initials:
  ------------------
  |  Branch (235:3): [True: 41, False: 3.30k]
  ------------------
  236|     41|			return "Initials";
  237|     46|		case Pseudonym:
  ------------------
  |  Branch (237:3): [True: 46, False: 3.29k]
  ------------------
  238|     46|			return "Pseudonym";
  239|     40|		case GenerationQualifier:
  ------------------
  |  Branch (239:3): [True: 40, False: 3.30k]
  ------------------
  240|     40|			return "GENERATION";
  241|     59|		case DnQualifier:
  ------------------
  |  Branch (241:3): [True: 59, False: 3.28k]
  ------------------
  242|     59|			return "dnQualifier";
  243|     21|		case DomainComponent:
  ------------------
  |  Branch (243:3): [True: 21, False: 3.32k]
  ------------------
  244|     21|			return "DC";
  245|     51|		case EmailAddress:
  ------------------
  |  Branch (245:3): [True: 51, False: 3.29k]
  ------------------
  246|     51|			return "E";
  247|     47|		case PostalCode:
  ------------------
  |  Branch (247:3): [True: 47, False: 3.29k]
  ------------------
  248|     47|			return "postalCode";
  249|     56|		case StreetAddress:
  ------------------
  |  Branch (249:3): [True: 56, False: 3.28k]
  ------------------
  250|     56|			return "STREET";
  251|     46|		case BusinessCategory:
  ------------------
  |  Branch (251:3): [True: 46, False: 3.29k]
  ------------------
  252|     46|			return "businessCategory";
  253|  1.81k|		case Unknown:
  ------------------
  |  Branch (253:3): [True: 1.81k, False: 1.52k]
  ------------------
  254|  1.81k|		default:
  ------------------
  |  Branch (254:3): [True: 0, False: 3.34k]
  ------------------
  255|  1.81k|			return "Unknown";
  256|  3.34k|		}
  257|  3.34k|	}
_ZN4pcpp21X520DistinguishedName12fromOidValueERKNS_20Asn1ObjectIdentifierE:
  330|  7.36k|	{
  331|  7.36k|		std::string oidStringValue = value.toString();
  332|       |
  333|  7.36k|		auto it = X520DistinguishedNameOidMap.find(oidStringValue);
  334|  7.36k|		if (it != X520DistinguishedNameOidMap.end())
  ------------------
  |  Branch (334:7): [True: 3.25k, False: 4.10k]
  ------------------
  335|  3.25k|		{
  336|  3.25k|			return { it->second };
  337|  3.25k|		}
  338|       |
  339|  4.10k|		return { Unknown };
  340|  7.36k|	}
_ZNK4pcpp17X509ExtensionType8toStringEv:
  343|  4.49k|	{
  344|  4.49k|		switch (m_Value)
  345|  4.49k|		{
  346|    322|		case BasicConstraints:
  ------------------
  |  Branch (346:3): [True: 322, False: 4.17k]
  ------------------
  347|    322|			return "BasicConstraints";
  348|    499|		case KeyUsage:
  ------------------
  |  Branch (348:3): [True: 499, False: 3.99k]
  ------------------
  349|    499|			return "KeyUsage";
  350|    560|		case ExtendedKeyUsage:
  ------------------
  |  Branch (350:3): [True: 560, False: 3.93k]
  ------------------
  351|    560|			return "ExtendedKeyUsage";
  352|    341|		case SubjectKeyIdentifier:
  ------------------
  |  Branch (352:3): [True: 341, False: 4.15k]
  ------------------
  353|    341|			return "SubjectKeyIdentifier";
  354|     42|		case AuthorityKeyIdentifier:
  ------------------
  |  Branch (354:3): [True: 42, False: 4.45k]
  ------------------
  355|     42|			return "AuthorityKeyIdentifier";
  356|     38|		case SubjectAltName:
  ------------------
  |  Branch (356:3): [True: 38, False: 4.45k]
  ------------------
  357|     38|			return "SubjectAltName";
  358|     16|		case IssuerAltName:
  ------------------
  |  Branch (358:3): [True: 16, False: 4.47k]
  ------------------
  359|     16|			return "IssuerAltName";
  360|     25|		case CrlDistributionPoints:
  ------------------
  |  Branch (360:3): [True: 25, False: 4.46k]
  ------------------
  361|     25|			return "CRLDistributionPoints";
  362|     17|		case AuthorityInfoAccess:
  ------------------
  |  Branch (362:3): [True: 17, False: 4.47k]
  ------------------
  363|     17|			return "AuthorityInfoAccess";
  364|     46|		case CertificatePolicies:
  ------------------
  |  Branch (364:3): [True: 46, False: 4.44k]
  ------------------
  365|     46|			return "CertificatePolicies";
  366|     34|		case PolicyMappings:
  ------------------
  |  Branch (366:3): [True: 34, False: 4.45k]
  ------------------
  367|     34|			return "PolicyMappings";
  368|    324|		case PolicyConstraints:
  ------------------
  |  Branch (368:3): [True: 324, False: 4.16k]
  ------------------
  369|    324|			return "PolicyConstraints";
  370|    107|		case NameConstraints:
  ------------------
  |  Branch (370:3): [True: 107, False: 4.38k]
  ------------------
  371|    107|			return "NameConstraints";
  372|    218|		case InhibitAnyPolicy:
  ------------------
  |  Branch (372:3): [True: 218, False: 4.27k]
  ------------------
  373|    218|			return "InhibitAnyPolicy";
  374|     17|		case CTPrecertificateSCTs:
  ------------------
  |  Branch (374:3): [True: 17, False: 4.47k]
  ------------------
  375|     17|			return "CTPrecertificateSCTs";
  376|     15|		case SubjectInfoAccess:
  ------------------
  |  Branch (376:3): [True: 15, False: 4.47k]
  ------------------
  377|     15|			return "SubjectInfoAccess";
  378|     45|		case FreshestCRL:
  ------------------
  |  Branch (378:3): [True: 45, False: 4.44k]
  ------------------
  379|     45|			return "FreshestCRL";
  380|     11|		case TLSFeature:
  ------------------
  |  Branch (380:3): [True: 11, False: 4.48k]
  ------------------
  381|     11|			return "TLSFeature";
  382|     20|		case OcspNoCheck:
  ------------------
  |  Branch (382:3): [True: 20, False: 4.47k]
  ------------------
  383|     20|			return "OcspNoCheck";
  384|     35|		case SubjectDirectoryAttributes:
  ------------------
  |  Branch (384:3): [True: 35, False: 4.45k]
  ------------------
  385|     35|			return "SubjectDirectoryAttributes";
  386|  1.76k|		case Unknown:
  ------------------
  |  Branch (386:3): [True: 1.76k, False: 2.73k]
  ------------------
  387|  1.76k|		default:
  ------------------
  |  Branch (387:3): [True: 0, False: 4.49k]
  ------------------
  388|  1.76k|			return "Unknown";
  389|  4.49k|		}
  390|  4.49k|	}
_ZN4pcpp17X509ExtensionType12fromOidValueERKNS_20Asn1ObjectIdentifierE:
  466|  4.67k|	{
  467|  4.67k|		std::string oidStr = value.toString();
  468|       |
  469|  4.67k|		auto it = X509ExtensionTypeOidMap.find(oidStr);
  470|  4.67k|		if (it != X509ExtensionTypeOidMap.end())
  ------------------
  |  Branch (470:7): [True: 2.80k, False: 1.87k]
  ------------------
  471|  2.80k|			return { it->second };
  472|       |
  473|  1.87k|		return { Unknown };
  474|  4.67k|	}
_ZNK4pcpp16X509SerialNumber8toStringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  503|    741|	{
  504|    741|		if (delimiter.empty())
  ------------------
  |  Branch (504:7): [True: 0, False: 741]
  ------------------
  505|      0|		{
  506|      0|			return m_SerialNumber;
  507|      0|		}
  508|       |
  509|       |		// Add delimiter
  510|    741|		std::string result;
  511|    741|		result.reserve(m_SerialNumber.length() + delimiter.size() * (m_SerialNumber.length() / 2 - 1));
  512|       |
  513|  25.8k|		for (size_t i = 0; i < m_SerialNumber.length(); ++i)
  ------------------
  |  Branch (513:22): [True: 25.0k, False: 741]
  ------------------
  514|  25.0k|		{
  515|  25.0k|			result += m_SerialNumber[i];
  516|       |			// Add a delimiter after every two characters, except for the very last pair
  517|  25.0k|			if ((i + 1) % 2 == 0 && i + 1 < m_SerialNumber.length())
  ------------------
  |  Branch (517:8): [True: 12.3k, False: 12.7k]
  |  Branch (517:28): [True: 11.9k, False: 402]
  ------------------
  518|  11.9k|			{
  519|  11.9k|				result += delimiter;
  520|  11.9k|			}
  521|  25.0k|		}
  522|    741|		return result;
  523|    741|	}
_ZNK4pcpp13X509Timestamp8toStringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_b:
  527|  1.48k|	{
  528|  1.48k|		return m_Record->getValueAsString(format, timezone, includeMilliseconds);
  529|  1.48k|	}
_ZNK4pcpp7X509Key8toStringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  537|  1.48k|	{
  538|  1.48k|		std::ostringstream result;
  539|  1.48k|		bool first = true;
  540|       |
  541|  1.48k|		for (const auto& byte : m_Key)
  ------------------
  |  Branch (541:25): [True: 160k, False: 1.48k]
  ------------------
  542|   160k|		{
  543|   160k|			if (!first)
  ------------------
  |  Branch (543:8): [True: 159k, False: 1.30k]
  ------------------
  544|   159k|			{
  545|   159k|				result << delimiter;
  546|   159k|			}
  547|   160k|			result << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(byte);
  548|   160k|			first = false;
  549|   160k|		}
  550|       |
  551|  1.48k|		return result.str();
  552|  1.48k|	}
_ZNK4pcpp12X509Internal17X509VersionRecord10getVersionEv:
  562|  1.53k|		{
  563|  1.53k|			auto intValue = getSubRecordAndCast<Asn1IntegerRecord>(m_Root, 0, "Version")->getIntValue<uint8_t>();
  564|  1.53k|			if (intValue > 3)
  ------------------
  |  Branch (564:8): [True: 5, False: 1.53k]
  ------------------
  565|      5|			{
  566|      5|				throw std::runtime_error("Invalid X509 version value: " + std::to_string(intValue));
  567|      5|			}
  568|       |
  569|  1.53k|			return static_cast<X509Version>(intValue);
  570|  1.53k|		}
_ZN4pcpp12X509Internal17X509VersionRecord20isValidVersionRecordEPKNS_10Asn1RecordE:
  573|  1.33k|		{
  574|  1.33k|			return record->getTagClass() == Asn1TagClass::ContextSpecific && record->getTagType() == 0 &&
  ------------------
  |  Branch (574:11): [True: 888, False: 445]
  |  Branch (574:69): [True: 872, False: 16]
  ------------------
  575|    872|			       record->isConstructed();
  ------------------
  |  Branch (575:11): [True: 862, False: 10]
  ------------------
  576|  1.33k|		}
_ZNK4pcpp12X509Internal29X509RelativeDistinguishedName9getRecordEi:
  579|  14.7k|		{
  580|  14.7k|			auto attributeTypeAndValue = getSubRecordAndCast<Asn1SequenceRecord>(m_Root, 0, "RDN");
  581|  14.7k|			try
  582|  14.7k|			{
  583|  14.7k|				return attributeTypeAndValue->getSubRecords().at(index);
  584|  14.7k|			}
  585|  14.7k|			catch (const std::out_of_range&)
  586|  14.7k|			{
  587|    116|				throw std::runtime_error("Invalid X509 certificate data: RDN");
  588|    116|			}
  589|  14.7k|		}
_ZNK4pcpp12X509Internal29X509RelativeDistinguishedName7getTypeEv:
  592|  7.38k|		{
  593|  7.38k|			auto oidRecord = castRecordAs<Asn1ObjectIdentifierRecord>(getRecord(typeOffset), "RDN Type");
  594|  7.38k|			return X520DistinguishedName::fromOidValue(oidRecord->getValue());
  595|  7.38k|		}
_ZNK4pcpp12X509Internal29X509RelativeDistinguishedName8getValueEv:
  598|  7.36k|		{
  599|  7.36k|			auto valueRecord = getRecord(valueOffset);
  600|  7.36k|			switch (valueRecord->getUniversalTagType())
  601|  7.36k|			{
  602|  2.67k|			case Asn1UniversalTagType::PrintableString:
  ------------------
  |  Branch (602:4): [True: 2.67k, False: 4.69k]
  ------------------
  603|  2.67k|			{
  604|  2.67k|				return valueRecord->castAs<Asn1PrintableStringRecord>()->getValue();
  605|      0|			}
  606|    614|			case Asn1UniversalTagType::IA5String:
  ------------------
  |  Branch (606:4): [True: 614, False: 6.75k]
  ------------------
  607|    614|			{
  608|    614|				return valueRecord->castAs<Asn1IA5StringRecord>()->getValue();
  609|      0|			}
  610|  3.95k|			case Asn1UniversalTagType::UTF8String:
  ------------------
  |  Branch (610:4): [True: 3.95k, False: 3.41k]
  ------------------
  611|  3.95k|			{
  612|  3.95k|				return valueRecord->castAs<Asn1UTF8StringRecord>()->getValue();
  613|      0|			}
  614|     12|			default:
  ------------------
  |  Branch (614:4): [True: 12, False: 7.35k]
  ------------------
  615|     12|			{
  616|     12|				throw std::runtime_error("Invalid X509 certificate data: unsupported RDN value ASN.1 type: " +
  617|     12|				                         std::to_string(static_cast<int>(valueRecord->getUniversalTagType())));
  618|      0|			}
  619|  7.36k|			}
  620|  7.36k|		}
_ZNK4pcpp12X509Internal8X509Name7getRDNsEv:
  623|  3.65k|		{
  624|  3.65k|			std::vector<X509RelativeDistinguishedName> result;
  625|  3.65k|			for (auto const& subRecord : m_Root->getSubRecords())
  ------------------
  |  Branch (625:31): [True: 7.69k, False: 3.65k]
  ------------------
  626|  7.69k|			{
  627|  7.69k|				result.push_back(X509RelativeDistinguishedName(castRecordAs<Asn1SetRecord>(subRecord, "RDN")));
  628|  7.69k|			}
  629|       |
  630|  3.65k|			return result;
  631|  3.65k|		}
_ZNK4pcpp12X509Internal23X509AlgorithmIdentifier12getAlgorithmEv:
  634|  3.28k|		{
  635|  3.28k|			auto oidRecord = getSubRecordAndCast<Asn1ObjectIdentifierRecord>(m_Root, algorithmOffset, "Algorithm");
  636|  3.28k|			return X509Algorithm::fromOidValue(oidRecord->getValue());
  637|  3.28k|		}
_ZNK4pcpp12X509Internal12X509Validity12getNotBeforeEv:
  640|  1.73k|		{
  641|  1.73k|			return X509Timestamp(getSubRecordAndCast<Asn1TimeRecord>(m_Root, notBeforeOffset, "Not Before"));
  642|  1.73k|		}
_ZNK4pcpp12X509Internal12X509Validity11getNotAfterEv:
  645|  1.72k|		{
  646|  1.72k|			return X509Timestamp(getSubRecordAndCast<Asn1TimeRecord>(m_Root, notAfterOffset, "Not After"));
  647|  1.72k|		}
_ZNK4pcpp12X509Internal24X509SubjectPublicKeyInfo12getAlgorithmEv:
  650|  1.71k|		{
  651|  1.71k|			auto root =
  652|  1.71k|			    getSubRecordAndCast<Asn1SequenceRecord>(m_Root, algorithmOffset, "Subject Public Key Algorithm");
  653|  1.71k|			return X509AlgorithmIdentifier(root);
  654|  1.71k|		}
_ZNK4pcpp12X509Internal24X509SubjectPublicKeyInfo19getSubjectPublicKeyEv:
  657|  1.71k|		{
  658|  1.71k|			return X509Key(
  659|  1.71k|			    getSubRecordAndCast<Asn1BitStringRecord>(m_Root, subjectPublicKeyOffset, "Subject Public Key")
  660|  1.71k|			        ->getVecValue());
  661|  1.71k|		}
_ZN4pcpp12X509Internal13X509ExtensionC2EPNS_18Asn1SequenceRecordE:
  663|  5.04k|		X509Extension::X509Extension(Asn1SequenceRecord* root) : X509Base(root)
  664|  5.04k|		{
  665|  5.04k|			if (root->getSubRecords().size() > 2)
  ------------------
  |  Branch (665:8): [True: 1.27k, False: 3.76k]
  ------------------
  666|  1.27k|			{
  667|  1.27k|				m_CriticalOffset = 1;
  668|  1.27k|				m_ExtensionValueOffset = 2;
  669|  1.27k|			}
  670|  5.04k|		}
_ZNK4pcpp12X509Internal13X509Extension7getTypeEv:
  673|  4.67k|		{
  674|  4.67k|			auto extensionTypeRecord =
  675|  4.67k|			    getSubRecordAndCast<Asn1ObjectIdentifierRecord>(m_Root, extensionIdOffset, "Extension Type");
  676|  4.67k|			return X509ExtensionType::fromOidValue(extensionTypeRecord->getValue());
  677|  4.67k|		}
_ZNK4pcpp12X509Internal13X509Extension10isCriticalEv:
  680|  4.68k|		{
  681|  4.68k|			if (m_CriticalOffset == -1)
  ------------------
  |  Branch (681:8): [True: 3.47k, False: 1.21k]
  ------------------
  682|  3.47k|			{
  683|  3.47k|				return false;
  684|  3.47k|			}
  685|       |
  686|  1.21k|			return getSubRecordAndCast<Asn1BooleanRecord>(m_Root, m_CriticalOffset, "Extension Critical")->getValue();
  687|  4.68k|		}
_ZNK4pcpp12X509Internal13X509Extension8getValueEv:
  690|  4.67k|		{
  691|  4.67k|			return getSubRecordAndCast<Asn1OctetStringRecord>(m_Root, m_ExtensionValueOffset, "Extension Value")
  692|  4.67k|			    ->getValue();
  693|  4.67k|		}
_ZNK4pcpp12X509Internal14X509Extensions13getExtensionsEv:
  696|    697|		{
  697|    697|			std::vector<X509Extension> result;
  698|    697|			auto extensionsRecord = getSubRecordAndCast<Asn1SequenceRecord>(m_Root, 0, "Extensions");
  699|    697|			for (const auto& extension : extensionsRecord->getSubRecords())
  ------------------
  |  Branch (699:31): [True: 5.04k, False: 697]
  ------------------
  700|  5.04k|			{
  701|  5.04k|				result.push_back(X509Extension(castRecordAs<Asn1SequenceRecord>(extension, "Extension")));
  702|  5.04k|			}
  703|       |
  704|    697|			return result;
  705|    697|		}
_ZN4pcpp12X509Internal14X509Extensions23isValidExtensionsRecordEPKNS_10Asn1RecordE:
  708|    931|		{
  709|    931|			return (record->getTagClass() == Asn1TagClass::ContextSpecific && record->getTagType() == 3 &&
  ------------------
  |  Branch (709:12): [True: 752, False: 179]
  |  Branch (709:70): [True: 720, False: 32]
  ------------------
  710|    720|			        record->isConstructed());
  ------------------
  |  Branch (710:12): [True: 711, False: 9]
  ------------------
  711|    931|		}
_ZNK4pcpp12X509Internal18X509TBSCertificate15getSerialNumberEv:
  714|  2.04k|		{
  715|  2.04k|			auto serialNumber = getSubRecordAndCast<Asn1IntegerRecord>(m_Root, m_SerialNumberOffset, "Serial Number")
  716|  2.04k|			                        ->getValueAsString(true);
  717|  2.04k|			return X509SerialNumber(serialNumber);
  718|  2.04k|		}
_ZN4pcpp12X509Internal18X509TBSCertificateC2EPNS_18Asn1SequenceRecordE:
  726|  1.34k|		X509TBSCertificate::X509TBSCertificate(Asn1SequenceRecord* root) : X509Base(root)
  727|  1.34k|		{
  728|  1.34k|			try
  729|  1.34k|			{
  730|  1.34k|				int currIndex = 0;
  731|  1.34k|				auto record = root->getSubRecords().at(currIndex);
  732|  1.34k|				if (X509VersionRecord::isValidVersionRecord(record))
  ------------------
  |  Branch (732:9): [True: 862, False: 487]
  ------------------
  733|    862|				{
  734|    862|					m_VersionOffset = currIndex++;
  735|    862|				}
  736|       |
  737|  1.34k|				m_SerialNumberOffset = currIndex++;
  738|  1.34k|				m_SignatureOffset = currIndex++;
  739|  1.34k|				m_IssuerOffset = currIndex++;
  740|  1.34k|				m_ValidityOffset = currIndex++;
  741|  1.34k|				m_SubjectOffset = currIndex++;
  742|  1.34k|				m_SubjectPublicKeyInfoOffset = currIndex++;
  743|       |
  744|  1.34k|				if (root->getSubRecords().size() > static_cast<size_t>(currIndex))
  ------------------
  |  Branch (744:9): [True: 933, False: 416]
  ------------------
  745|    933|				{
  746|    933|					record = root->getSubRecords().at(currIndex);
  747|       |
  748|    933|					if (record->getTagClass() == Asn1TagClass::ContextSpecific && record->getTagType() == 1)
  ------------------
  |  Branch (748:10): [True: 772, False: 161]
  |  Branch (748:68): [True: 23, False: 749]
  ------------------
  749|     23|					{
  750|     23|						m_IssuerUniqueID = currIndex++;
  751|     23|						record = root->getSubRecords().at(currIndex);
  752|     23|					}
  753|       |
  754|    933|					if (record->getTagClass() == Asn1TagClass::ContextSpecific && record->getTagType() == 2)
  ------------------
  |  Branch (754:10): [True: 755, False: 178]
  |  Branch (754:68): [True: 6, False: 749]
  ------------------
  755|      6|					{
  756|      6|						m_SubjectUniqueID = currIndex++;
  757|      6|						record = root->getSubRecords().at(currIndex);
  758|      6|					}
  759|       |
  760|    933|					if (X509Extensions::isValidExtensionsRecord(record))
  ------------------
  |  Branch (760:10): [True: 711, False: 222]
  ------------------
  761|    711|					{
  762|    711|						m_ExtensionsOffset = currIndex++;
  763|    711|					}
  764|    933|				}
  765|  1.34k|			}
  766|  1.34k|			catch (const std::out_of_range&)
  767|  1.34k|			{
  768|     18|				throw std::runtime_error("Invalid X509 certificate data: TBS Certificate");
  769|     18|			}
  770|  1.34k|		}
_ZNK4pcpp12X509Internal18X509TBSCertificate10getVersionEv:
  773|  2.07k|		{
  774|  2.07k|			if (m_VersionOffset == -1)
  ------------------
  |  Branch (774:8): [True: 536, False: 1.53k]
  ------------------
  775|    536|			{
  776|    536|				return X509Version::V1;
  777|    536|			}
  778|       |
  779|  1.53k|			auto versionAsn1Record = getSubRecordAndCast<Asn1ConstructedRecord>(m_Root, m_VersionOffset, "Version");
  780|  1.53k|			auto versionRecord = X509VersionRecord(versionAsn1Record);
  781|  1.53k|			return versionRecord.getVersion();
  782|  2.07k|		}
_ZNK4pcpp12X509Internal18X509TBSCertificate9getIssuerEv:
  785|  1.99k|		{
  786|  1.99k|			auto root = getSubRecordAndCast<Asn1SequenceRecord>(m_Root, m_IssuerOffset, "Issuer");
  787|  1.99k|			return X509Name(root);
  788|  1.99k|		}
_ZNK4pcpp12X509Internal18X509TBSCertificate11getValidityEv:
  791|  3.46k|		{
  792|  3.46k|			auto root = getSubRecordAndCast<Asn1SequenceRecord>(m_Root, m_ValidityOffset, "Validity");
  793|  3.46k|			return X509Validity(root);
  794|  3.46k|		}
_ZNK4pcpp12X509Internal18X509TBSCertificate10getSubjectEv:
  797|  1.75k|		{
  798|  1.75k|			auto root = getSubRecordAndCast<Asn1SequenceRecord>(m_Root, m_SubjectOffset, "Subject");
  799|  1.75k|			return X509Name(root);
  800|  1.75k|		}
_ZNK4pcpp12X509Internal18X509TBSCertificate23getSubjectPublicKeyInfoEv:
  803|  3.42k|		{
  804|  3.42k|			auto root = getSubRecordAndCast<Asn1SequenceRecord>(m_Root, m_SubjectPublicKeyInfoOffset,
  805|  3.42k|			                                                    "Subject Public Key Info");
  806|  3.42k|			return X509SubjectPublicKeyInfo(root);
  807|  3.42k|		}
_ZNK4pcpp12X509Internal18X509TBSCertificate13getExtensionsEv:
  810|    826|		{
  811|    826|			if (m_ExtensionsOffset == -1)
  ------------------
  |  Branch (811:8): [True: 129, False: 697]
  ------------------
  812|    129|			{
  813|    129|				return nullptr;
  814|    129|			}
  815|       |
  816|    697|			auto root = getSubRecordAndCast<Asn1ConstructedRecord>(m_Root, m_ExtensionsOffset, "Extensions");
  817|    697|			return std::unique_ptr<X509Extensions>(new X509Extensions(root));
  818|    826|		}
_ZN4pcpp12X509Internal15X509Certificate6decodeEPKhm:
  821|  3.31k|		{
  822|  3.31k|			return std::unique_ptr<X509Certificate>(new X509Certificate(Asn1Record::decode(data, dataLen)));
  823|  3.31k|		}
_ZNK4pcpp12X509Internal15X509Certificate11getAsn1RootEv:
  826|  6.14k|		{
  827|  6.14k|			return castRecordAs<Asn1SequenceRecord>(m_Root.get(), "Root");
  828|  6.14k|		}
_ZNK4pcpp12X509Internal15X509Certificate17getTbsCertificateEv:
  831|  2.97k|		{
  832|  2.97k|			auto root = getSubRecordAndCast<Asn1SequenceRecord>(getAsn1Root(), tbsCertificateOffset, "TBS Certificate");
  833|  2.97k|			return X509TBSCertificate(root);
  834|  2.97k|		}
_ZNK4pcpp12X509Internal15X509Certificate21getSignatureAlgorithmEv:
  837|  1.59k|		{
  838|  1.59k|			auto root =
  839|  1.59k|			    getSubRecordAndCast<Asn1SequenceRecord>(getAsn1Root(), signatureAlgorithmOffset, "Signature Algorithm");
  840|  1.59k|			return X509AlgorithmIdentifier(root);
  841|  1.59k|		}
_ZNK4pcpp12X509Internal15X509Certificate12getSignatureEv:
  844|  1.57k|		{
  845|  1.57k|			return X509Key(
  846|  1.57k|			    getSubRecordAndCast<Asn1BitStringRecord>(getAsn1Root(), signatureOffset, "Signature")->getVecValue());
  847|  1.57k|		}
_ZN4pcpp8X509NameC2ERKNS_12X509Internal8X509NameE:
  856|  3.65k|	{
  857|  3.65k|		for (const auto& rdn : internalName.getRDNs())
  ------------------
  |  Branch (857:24): [True: 7.38k, False: 3.65k]
  ------------------
  858|  7.38k|		{
  859|  7.38k|			m_RDNs.emplace_back(RDN{ rdn.getType(), rdn.getValue() });
  860|  7.38k|		}
  861|  3.65k|	}
_ZNK4pcpp8X509Name8toStringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  864|  1.48k|	{
  865|  1.48k|		std::ostringstream result;
  866|  1.48k|		bool first = true;
  867|       |
  868|  1.48k|		for (const auto& rdn : m_RDNs)
  ------------------
  |  Branch (868:24): [True: 3.34k, False: 1.48k]
  ------------------
  869|  3.34k|		{
  870|  3.34k|			if (!first)
  ------------------
  |  Branch (870:8): [True: 1.92k, False: 1.42k]
  ------------------
  871|  1.92k|			{
  872|  1.92k|				result << delimiter;
  873|  1.92k|			}
  874|  3.34k|			result << rdn.type.getShortName() << "=" << rdn.value;
  875|  3.34k|			first = false;
  876|  3.34k|		}
  877|       |
  878|  1.48k|		return result.str();
  879|  1.48k|	}
_ZN4pcpp13X509ExtensionC2ERKNS_12X509Internal13X509ExtensionE:
  882|  4.68k|	    : m_IsCritical(internalExtension.isCritical()), m_Type(internalExtension.getType()),
  883|  4.68k|	      m_Data(internalExtension.getValue())
  884|  4.68k|	{}
_ZNK4pcpp13X509Extension7getDataEv:
  887|  2.95k|	{
  888|  2.95k|		switch (m_Type)
  889|  2.95k|		{
  890|    263|		case X509ExtensionType::BasicConstraints:
  ------------------
  |  Branch (890:3): [True: 263, False: 2.68k]
  ------------------
  891|    263|		{
  892|    263|			return std::unique_ptr<X509ExtensionData>(new X509BasicConstraintsExtension(m_Data));
  893|      0|		}
  894|    252|		case X509ExtensionType::SubjectKeyIdentifier:
  ------------------
  |  Branch (894:3): [True: 252, False: 2.69k]
  ------------------
  895|    252|		{
  896|    252|			return std::unique_ptr<X509ExtensionData>(new X509SubjectKeyIdentifierExtension(m_Data));
  897|      0|		}
  898|    404|		case X509ExtensionType::KeyUsage:
  ------------------
  |  Branch (898:3): [True: 404, False: 2.54k]
  ------------------
  899|    404|		{
  900|    404|			return std::unique_ptr<X509ExtensionData>(new X509KeyUsageExtension(m_Data));
  901|      0|		}
  902|    436|		case X509ExtensionType::ExtendedKeyUsage:
  ------------------
  |  Branch (902:3): [True: 436, False: 2.51k]
  ------------------
  903|    436|		{
  904|    436|			return std::unique_ptr<X509ExtensionData>(new X509ExtendedKeyUsageExtension(m_Data));
  905|      0|		}
  906|  1.59k|		default:
  ------------------
  |  Branch (906:3): [True: 1.59k, False: 1.35k]
  ------------------
  907|  1.59k|		{
  908|  1.59k|			return {};
  909|      0|		}
  910|  2.95k|		}
  911|  2.95k|	}
_ZN4pcpp15X509CertificateC2EPhmb:
  914|  3.31k|	    : m_X509Internal(X509Internal::X509Certificate::decode(derData, derDataLen)),
  915|  3.31k|	      m_TBSCertificate(m_X509Internal->getTbsCertificate())
  916|  3.31k|	{
  917|  3.31k|		if (ownDerData)
  ------------------
  |  Branch (917:7): [True: 0, False: 3.31k]
  ------------------
  918|      0|		{
  919|      0|			m_DerData.reset(derData);
  920|      0|		}
  921|  3.31k|	}
_ZNK4pcpp15X509Certificate10getVersionEv:
  931|  2.07k|	{
  932|  2.07k|		return m_TBSCertificate.getVersion();
  933|  2.07k|	}
_ZNK4pcpp15X509Certificate13getExtensionsEv:
  936|  1.39k|	{
  937|  1.39k|		if (!m_ExtensionsParsed)
  ------------------
  |  Branch (937:7): [True: 826, False: 565]
  ------------------
  938|    826|		{
  939|    826|			auto extensions = m_TBSCertificate.getExtensions();
  940|    826|			if (extensions != nullptr)
  ------------------
  |  Branch (940:8): [True: 697, False: 129]
  ------------------
  941|    697|			{
  942|    697|				for (const auto& extension : extensions->getExtensions())
  ------------------
  |  Branch (942:32): [True: 4.68k, False: 697]
  ------------------
  943|  4.68k|				{
  944|  4.68k|					m_Extensions.emplace_back(X509Extension(extension));
  945|  4.68k|				}
  946|    697|			}
  947|    826|			m_ExtensionsParsed = true;
  948|    826|		}
  949|       |
  950|  1.39k|		return m_Extensions;
  951|  1.39k|	}
_ZNK4pcpp15X509Certificate10getSubjectEv:
  977|  1.75k|	{
  978|  1.75k|		return X509Name(m_TBSCertificate.getSubject());
  979|  1.75k|	}
_ZNK4pcpp15X509Certificate9getIssuerEv:
  982|  1.99k|	{
  983|  1.99k|		return X509Name(m_TBSCertificate.getIssuer());
  984|  1.99k|	}
_ZNK4pcpp15X509Certificate15getSerialNumberEv:
  987|  2.04k|	{
  988|  2.04k|		return m_TBSCertificate.getSerialNumber();
  989|  2.04k|	}
_ZNK4pcpp15X509Certificate12getNotBeforeEv:
  992|  1.74k|	{
  993|  1.74k|		return m_TBSCertificate.getValidity().getNotBefore();
  994|  1.74k|	}
_ZNK4pcpp15X509Certificate11getNotAfterEv:
  997|  1.72k|	{
  998|  1.72k|		return m_TBSCertificate.getValidity().getNotAfter();
  999|  1.72k|	}
_ZNK4pcpp15X509Certificate21getPublicKeyAlgorithmEv:
 1002|  1.71k|	{
 1003|  1.71k|		return m_TBSCertificate.getSubjectPublicKeyInfo().getAlgorithm().getAlgorithm();
 1004|  1.71k|	}
_ZNK4pcpp15X509Certificate12getPublicKeyEv:
 1007|  1.71k|	{
 1008|  1.71k|		return m_TBSCertificate.getSubjectPublicKeyInfo().getSubjectPublicKey();
 1009|  1.71k|	}
_ZNK4pcpp15X509Certificate21getSignatureAlgorithmEv:
 1012|  1.59k|	{
 1013|  1.59k|		return m_X509Internal->getSignatureAlgorithm().getAlgorithm();
 1014|  1.59k|	}
_ZNK4pcpp15X509Certificate12getSignatureEv:
 1017|  1.57k|	{
 1018|  1.57k|		return m_X509Internal->getSignature();
 1019|  1.57k|	}
_ZNK4pcpp15X509Certificate6toJsonEi:
 1037|    826|	{
 1038|    826|		auto extensions = nlohmann::ordered_json::array();
 1039|    826|		for (const auto& extension : getExtensions())
  ------------------
  |  Branch (1039:30): [True: 4.49k, False: 826]
  ------------------
 1040|  4.49k|		{
 1041|  4.49k|			extensions.push_back({
 1042|  4.49k|			    { "type",       extension.getType().toString() },
 1043|  4.49k|			    { "isCritical", extension.isCritical()         },
 1044|  4.49k|			});
 1045|  4.49k|		}
 1046|       |
 1047|    826|		nlohmann::ordered_json certificateJson = {
 1048|    826|			{ "version",              static_cast<int>(getVersion()) + 1 },
 1049|    826|			{ "serialNumber",         getSerialNumber().toString()       },
 1050|    826|			{ "issuer",               getIssuer().toString()             },
 1051|    826|			{ "validity",
 1052|    826|             {
 1053|    826|			      { "notBefore", getNotBefore().toString() },
 1054|    826|			      { "notAfter", getNotAfter().toString() },
 1055|    826|			  }			                                              },
 1056|    826|			{ "subject",              getSubject().toString()            },
 1057|    826|			{ "subjectPublicKeyInfo",
 1058|    826|             { { "subjectPublicKeyAlgorithm", getPublicKeyAlgorithm().toString() },
 1059|    826|			    { "subjectPublicKey", getPublicKey().toString() } }      },
 1060|    826|			{ "extensions",           extensions                         },
 1061|    826|			{ "signatureAlgorithm",   getSignatureAlgorithm().toString() },
 1062|    826|			{ "signature",            getSignature().toString()          }
 1063|    826|		};
 1064|       |
 1065|    826|		return certificateJson.dump(indent);
 1066|    826|	}
X509Decoder.cpp:_ZN4pcppL19getSubRecordAndCastINS_17Asn1IntegerRecordEEEPT_PNS_21Asn1ConstructedRecordEiRKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  491|  3.58k|	{
  492|  3.58k|		try
  493|  3.58k|		{
  494|  3.58k|			return castRecordAs<Asn1RecordType>(record->getSubRecords().at(index), fieldName);
  495|  3.58k|		}
  496|  3.58k|		catch (const std::out_of_range&)
  497|  3.58k|		{
  498|     12|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  499|     12|		}
  500|  3.58k|	}
X509Decoder.cpp:_ZN4pcppL12castRecordAsINS_17Asn1IntegerRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  478|  3.57k|	{
  479|  3.57k|		try
  480|  3.57k|		{
  481|  3.57k|			return record->castAs<Asn1RecordType>();
  482|  3.57k|		}
  483|  3.57k|		catch (const std::bad_cast&)
  484|  3.57k|		{
  485|     54|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  486|     54|		}
  487|  3.57k|	}
X509Decoder.cpp:_ZN4pcppL19getSubRecordAndCastINS_18Asn1SequenceRecordEEEPT_PNS_21Asn1ConstructedRecordEiRKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  491|  32.3k|	{
  492|  32.3k|		try
  493|  32.3k|		{
  494|  32.3k|			return castRecordAs<Asn1RecordType>(record->getSubRecords().at(index), fieldName);
  495|  32.3k|		}
  496|  32.3k|		catch (const std::out_of_range&)
  497|  32.3k|		{
  498|     75|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  499|     75|		}
  500|  32.3k|	}
X509Decoder.cpp:_ZN4pcppL12castRecordAsINS_26Asn1ObjectIdentifierRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  478|  15.3k|	{
  479|  15.3k|		try
  480|  15.3k|		{
  481|  15.3k|			return record->castAs<Asn1RecordType>();
  482|  15.3k|		}
  483|  15.3k|		catch (const std::bad_cast&)
  484|  15.3k|		{
  485|     11|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  486|     11|		}
  487|  15.3k|	}
X509Decoder.cpp:_ZN4pcppL12castRecordAsINS_13Asn1SetRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  478|  7.69k|	{
  479|  7.69k|		try
  480|  7.69k|		{
  481|  7.69k|			return record->castAs<Asn1RecordType>();
  482|  7.69k|		}
  483|  7.69k|		catch (const std::bad_cast&)
  484|  7.69k|		{
  485|     12|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  486|     12|		}
  487|  7.69k|	}
X509Decoder.cpp:_ZN4pcppL19getSubRecordAndCastINS_26Asn1ObjectIdentifierRecordEEEPT_PNS_21Asn1ConstructedRecordEiRKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  491|  7.96k|	{
  492|  7.96k|		try
  493|  7.96k|		{
  494|  7.96k|			return castRecordAs<Asn1RecordType>(record->getSubRecords().at(index), fieldName);
  495|  7.96k|		}
  496|  7.96k|		catch (const std::out_of_range&)
  497|  7.96k|		{
  498|      2|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  499|      2|		}
  500|  7.96k|	}
X509Decoder.cpp:_ZN4pcppL19getSubRecordAndCastINS_14Asn1TimeRecordEEEPT_PNS_21Asn1ConstructedRecordEiRKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  491|  3.45k|	{
  492|  3.45k|		try
  493|  3.45k|		{
  494|  3.45k|			return castRecordAs<Asn1RecordType>(record->getSubRecords().at(index), fieldName);
  495|  3.45k|		}
  496|  3.45k|		catch (const std::out_of_range&)
  497|  3.45k|		{
  498|      1|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  499|      1|		}
  500|  3.45k|	}
X509Decoder.cpp:_ZN4pcppL12castRecordAsINS_14Asn1TimeRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  478|  3.45k|	{
  479|  3.45k|		try
  480|  3.45k|		{
  481|  3.45k|			return record->castAs<Asn1RecordType>();
  482|  3.45k|		}
  483|  3.45k|		catch (const std::bad_cast&)
  484|  3.45k|		{
  485|     15|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  486|     15|		}
  487|  3.45k|	}
X509Decoder.cpp:_ZN4pcppL19getSubRecordAndCastINS_19Asn1BitStringRecordEEEPT_PNS_21Asn1ConstructedRecordEiRKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  491|  3.28k|	{
  492|  3.28k|		try
  493|  3.28k|		{
  494|  3.28k|			return castRecordAs<Asn1RecordType>(record->getSubRecords().at(index), fieldName);
  495|  3.28k|		}
  496|  3.28k|		catch (const std::out_of_range&)
  497|  3.28k|		{
  498|    109|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  499|    109|		}
  500|  3.28k|	}
X509Decoder.cpp:_ZN4pcppL12castRecordAsINS_19Asn1BitStringRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  478|  3.17k|	{
  479|  3.17k|		try
  480|  3.17k|		{
  481|  3.17k|			return record->castAs<Asn1RecordType>();
  482|  3.17k|		}
  483|  3.17k|		catch (const std::bad_cast&)
  484|  3.17k|		{
  485|     13|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  486|     13|		}
  487|  3.17k|	}
X509Decoder.cpp:_ZN4pcppL19getSubRecordAndCastINS_17Asn1BooleanRecordEEEPT_PNS_21Asn1ConstructedRecordEiRKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  491|  1.21k|	{
  492|  1.21k|		try
  493|  1.21k|		{
  494|  1.21k|			return castRecordAs<Asn1RecordType>(record->getSubRecords().at(index), fieldName);
  495|  1.21k|		}
  496|  1.21k|		catch (const std::out_of_range&)
  497|  1.21k|		{
  498|      0|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  499|      0|		}
  500|  1.21k|	}
X509Decoder.cpp:_ZN4pcppL12castRecordAsINS_17Asn1BooleanRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  478|  1.21k|	{
  479|  1.21k|		try
  480|  1.21k|		{
  481|  1.21k|			return record->castAs<Asn1RecordType>();
  482|  1.21k|		}
  483|  1.21k|		catch (const std::bad_cast&)
  484|  1.21k|		{
  485|      8|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  486|      8|		}
  487|  1.21k|	}
X509Decoder.cpp:_ZN4pcppL19getSubRecordAndCastINS_21Asn1OctetStringRecordEEEPT_PNS_21Asn1ConstructedRecordEiRKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  491|  4.67k|	{
  492|  4.67k|		try
  493|  4.67k|		{
  494|  4.67k|			return castRecordAs<Asn1RecordType>(record->getSubRecords().at(index), fieldName);
  495|  4.67k|		}
  496|  4.67k|		catch (const std::out_of_range&)
  497|  4.67k|		{
  498|     48|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  499|     48|		}
  500|  4.67k|	}
X509Decoder.cpp:_ZN4pcppL12castRecordAsINS_21Asn1OctetStringRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  478|  4.62k|	{
  479|  4.62k|		try
  480|  4.62k|		{
  481|  4.62k|			return record->castAs<Asn1RecordType>();
  482|  4.62k|		}
  483|  4.62k|		catch (const std::bad_cast&)
  484|  4.62k|		{
  485|     12|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  486|     12|		}
  487|  4.62k|	}
X509Decoder.cpp:_ZN4pcppL12castRecordAsINS_18Asn1SequenceRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  478|  42.4k|	{
  479|  42.4k|		try
  480|  42.4k|		{
  481|  42.4k|			return record->castAs<Asn1RecordType>();
  482|  42.4k|		}
  483|  42.4k|		catch (const std::bad_cast&)
  484|  42.4k|		{
  485|    661|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  486|    661|		}
  487|  42.4k|	}
X509Decoder.cpp:_ZN4pcppL19getSubRecordAndCastINS_21Asn1ConstructedRecordEEEPT_PS1_iRKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEE:
  491|  2.23k|	{
  492|  2.23k|		try
  493|  2.23k|		{
  494|  2.23k|			return castRecordAs<Asn1RecordType>(record->getSubRecords().at(index), fieldName);
  495|  2.23k|		}
  496|  2.23k|		catch (const std::out_of_range&)
  497|  2.23k|		{
  498|      0|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  499|      0|		}
  500|  2.23k|	}
X509Decoder.cpp:_ZN4pcppL12castRecordAsINS_21Asn1ConstructedRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  478|  2.23k|	{
  479|  2.23k|		try
  480|  2.23k|		{
  481|  2.23k|			return record->castAs<Asn1RecordType>();
  482|  2.23k|		}
  483|  2.23k|		catch (const std::bad_cast&)
  484|  2.23k|		{
  485|      0|			throw std::runtime_error("Invalid X509 certificate data: " + fieldName);
  486|      0|		}
  487|  2.23k|	}

_ZN4pcpp27X509ExtendedKeyUsagePurpose12fromOidValueERKNS_20Asn1ObjectIdentifierE:
   96|    824|	{
   97|    824|		auto it = X509ExtendedKeyUsagePurposeOidMap.find(value.toString());
   98|    824|		if (it != X509ExtendedKeyUsagePurposeOidMap.end())
  ------------------
  |  Branch (98:7): [True: 75, False: 749]
  ------------------
   99|     75|		{
  100|     75|			return { it->second };
  101|     75|		}
  102|       |
  103|    749|		return { Unknown };
  104|    824|	}
_ZN4pcpp12X509Internal24X509ExtensionDataDecoder14decodeAsn1DataERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERNS2_6vectorIhNS6_IhEEEE:
  138|  1.35k|		{
  139|  1.35k|			rawDataBytes.resize(rawData.length() / 2);
  140|       |			// A malformed hex string may decode into fewer bytes than the buffer size
  141|  1.35k|			rawDataBytes.resize(hexStringToByteArray(rawData, rawDataBytes.data(), rawDataBytes.size()));
  142|  1.35k|			return Asn1Record::decode(rawDataBytes.data(), rawDataBytes.size());
  143|  1.35k|		}
_ZN4pcpp12X509Internal31X509BasicConstraintsDataDecoder6createERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  147|    263|		{
  148|    263|			std::vector<uint8_t> rawDataBytes;
  149|    263|			auto record = decodeAsn1Data(rawData, rawDataBytes);
  150|    263|			auto basicConstraintsRecord = castRecordAs<Asn1SequenceRecord>(record.get(), "Basic Constraints", "Value");
  151|    263|			bool isCA = false;
  152|    263|			uint8_t pathLenConstraint = 0;
  153|    263|			if (basicConstraintsRecord->getSubRecords().size() > isCAOffset)
  ------------------
  |  Branch (153:8): [True: 67, False: 196]
  ------------------
  154|     67|			{
  155|     67|				isCA = getSubRecordAndCast<Asn1BooleanRecord>(basicConstraintsRecord, isCAOffset, "Basic Constraints",
  156|     67|				                                              "Is CA")
  157|     67|				           ->getValue();
  158|     67|			}
  159|    263|			if (basicConstraintsRecord->getSubRecords().size() > pathLenConstraintOffset)
  ------------------
  |  Branch (159:8): [True: 61, False: 202]
  ------------------
  160|     61|			{
  161|     61|				pathLenConstraint =
  162|     61|				    getSubRecordAndCast<Asn1IntegerRecord>(basicConstraintsRecord, pathLenConstraintOffset,
  163|     61|				                                           "Basic Constraints", "Path Length Constraint")
  164|     61|				        ->getIntValue<uint8_t>();
  165|     61|			}
  166|       |
  167|    263|			return std::unique_ptr<X509BasicConstraintsDataDecoder>(
  168|    263|			    new X509BasicConstraintsDataDecoder(isCA, pathLenConstraint));
  169|    263|		}
_ZN4pcpp12X509Internal35X509SubjectKeyIdentifierDataDecoder6createERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  173|    252|		{
  174|    252|			std::vector<uint8_t> rawDataBytes;
  175|    252|			auto record = decodeAsn1Data(rawData, rawDataBytes);
  176|    252|			auto keyIdentifier =
  177|    252|			    castRecordAs<Asn1OctetStringRecord>(record.get(), "Subject Key Identifier", "Key Identifier")
  178|    252|			        ->getValue();
  179|    252|			return std::unique_ptr<X509SubjectKeyIdentifierDataDecoder>(
  180|    252|			    new X509SubjectKeyIdentifierDataDecoder(keyIdentifier));
  181|    252|		}
_ZN4pcpp12X509Internal23X509KeyUsageDataDecoder6createERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  184|    404|		{
  185|    404|			std::vector<uint8_t> rawDataBytes;
  186|    404|			auto record = decodeAsn1Data(rawData, rawDataBytes);
  187|    404|			auto keyUsage = castRecordAs<Asn1BitStringRecord>(record.get(), "Key Usage", "Key Usage")->getValue();
  188|    404|			return std::unique_ptr<X509KeyUsageDataDecoder>(new X509KeyUsageDataDecoder(keyUsage));
  189|    404|		}
_ZN4pcpp12X509Internal31X509ExtendedKeyUsageDataDecoder6createERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  193|    436|		{
  194|    436|			std::vector<uint8_t> rawDataBytes;
  195|    436|			auto record = decodeAsn1Data(rawData, rawDataBytes);
  196|    436|			auto extendedKeyUsageRecord =
  197|    436|			    castRecordAs<Asn1SequenceRecord>(record.get(), "Extended Key Usage", "Purposes List");
  198|    436|			auto result = std::unique_ptr<X509ExtendedKeyUsageDataDecoder>(new X509ExtendedKeyUsageDataDecoder());
  199|    436|			for (const auto& subRecord : extendedKeyUsageRecord->getSubRecords())
  ------------------
  |  Branch (199:31): [True: 862, False: 436]
  ------------------
  200|    862|			{
  201|    862|				result->m_ExtendedKeyUsagePurposes.push_back(
  202|    862|				    subRecord->castAs<Asn1ObjectIdentifierRecord>()->getValue());
  203|    862|			}
  204|       |
  205|    436|			return result;
  206|    436|		}
_ZN4pcpp29X509BasicConstraintsExtensionC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  210|    263|	{
  211|    263|		auto dataDecoder = X509Internal::X509BasicConstraintsDataDecoder::create(rawExtensionData);
  212|    263|		m_IsCA = dataDecoder->isCA();
  213|    263|		m_PathLenConstraint = dataDecoder->getPathLenConstraint();
  214|    263|	}
_ZN4pcpp33X509SubjectKeyIdentifierExtensionC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  217|    252|	{
  218|    252|		auto dataDecoder = X509Internal::X509SubjectKeyIdentifierDataDecoder::create(rawExtensionData);
  219|    252|		m_KeyIdentifier = dataDecoder->getKeyIdentifier();
  220|    252|	}
_ZN4pcpp21X509KeyUsageExtensionC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  223|    404|	{
  224|    404|		auto dataDecoder = X509Internal::X509KeyUsageDataDecoder::create(rawExtensionData);
  225|    404|		m_BitString = dataDecoder->getKeyUsage();
  226|    404|	}
_ZNK4pcpp21X509KeyUsageExtension8isBitSetEm:
  229|  3.23k|	{
  230|  3.23k|		if (m_BitString.size() < location + 1)
  ------------------
  |  Branch (230:7): [True: 884, False: 2.34k]
  ------------------
  231|    884|		{
  232|    884|			return false;
  233|    884|		}
  234|       |
  235|  2.34k|		return m_BitString[m_BitString.size() - 1 - location] == '1';
  236|  3.23k|	}
_ZNK4pcpp21X509KeyUsageExtension18isDigitalSignatureEv:
  239|    359|	{
  240|    359|		return isBitSet(digitalSignatureLocation);
  241|    359|	}
_ZNK4pcpp21X509KeyUsageExtension16isNonRepudiationEv:
  244|    359|	{
  245|    359|		return isBitSet(nonRepudiationLocation);
  246|    359|	}
_ZNK4pcpp21X509KeyUsageExtension17isKeyEnciphermentEv:
  249|    359|	{
  250|    359|		return isBitSet(keyEnciphermentLocation);
  251|    359|	}
_ZNK4pcpp21X509KeyUsageExtension18isDataEnciphermentEv:
  254|    359|	{
  255|    359|		return isBitSet(dataEnciphermentLocation);
  256|    359|	}
_ZNK4pcpp21X509KeyUsageExtension14isKeyAgreementEv:
  259|    359|	{
  260|    359|		return isBitSet(keyAgreementLocation);
  261|    359|	}
_ZNK4pcpp21X509KeyUsageExtension13isKeyCertSignEv:
  264|    359|	{
  265|    359|		return isBitSet(keyCertSignLocation);
  266|    359|	}
_ZNK4pcpp21X509KeyUsageExtension9isCRLSignEv:
  269|    359|	{
  270|    359|		return isBitSet(crlSignLocation);
  271|    359|	}
_ZNK4pcpp21X509KeyUsageExtension14isEncipherOnlyEv:
  274|    359|	{
  275|    359|		return isBitSet(encipherOnlyLocation);
  276|    359|	}
_ZNK4pcpp21X509KeyUsageExtension14isDecipherOnlyEv:
  279|    359|	{
  280|    359|		return isBitSet(decipherOnlyLocation);
  281|    359|	}
_ZN4pcpp29X509ExtendedKeyUsageExtensionC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  284|    436|	{
  285|    436|		auto dataDecoder = X509Internal::X509ExtendedKeyUsageDataDecoder::create(rawExtensionData);
  286|    436|		for (const auto& purpose : dataDecoder->getExtendedKeyUsagePurposes())
  ------------------
  |  Branch (286:28): [True: 824, False: 436]
  ------------------
  287|    824|		{
  288|    824|			m_Purposes.push_back(X509ExtendedKeyUsagePurpose::fromOidValue(purpose));
  289|    824|		}
  290|    436|	}
X509ExtensionDataDecoder.cpp:_ZN4pcppL12castRecordAsINS_18Asn1SequenceRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEESE_:
  109|    665|	{
  110|    665|		try
  111|    665|		{
  112|    665|			return record->castAs<Asn1RecordType>();
  113|    665|		}
  114|    665|		catch (const std::bad_cast&)
  115|    665|		{
  116|     56|			throw std::runtime_error("Invalid X509 certificate " + extensionName + " extension data: " + fieldName);
  117|     56|		}
  118|    665|	}
X509ExtensionDataDecoder.cpp:_ZN4pcppL19getSubRecordAndCastINS_17Asn1BooleanRecordEEEPT_PNS_21Asn1ConstructedRecordEiRKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEESE_:
  123|     67|	{
  124|     67|		try
  125|     67|		{
  126|     67|			return castRecordAs<Asn1RecordType>(record->getSubRecords().at(index), extensionName, fieldName);
  127|     67|		}
  128|     67|		catch (const std::out_of_range&)
  129|     67|		{
  130|      0|			throw std::runtime_error("Invalid X509 certificate " + extensionName + " extension data: " + fieldName);
  131|      0|		}
  132|     67|	}
X509ExtensionDataDecoder.cpp:_ZN4pcppL12castRecordAsINS_17Asn1BooleanRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEESE_:
  109|     67|	{
  110|     67|		try
  111|     67|		{
  112|     67|			return record->castAs<Asn1RecordType>();
  113|     67|		}
  114|     67|		catch (const std::bad_cast&)
  115|     67|		{
  116|      3|			throw std::runtime_error("Invalid X509 certificate " + extensionName + " extension data: " + fieldName);
  117|      3|		}
  118|     67|	}
X509ExtensionDataDecoder.cpp:_ZN4pcppL19getSubRecordAndCastINS_17Asn1IntegerRecordEEEPT_PNS_21Asn1ConstructedRecordEiRKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEESE_:
  123|     61|	{
  124|     61|		try
  125|     61|		{
  126|     61|			return castRecordAs<Asn1RecordType>(record->getSubRecords().at(index), extensionName, fieldName);
  127|     61|		}
  128|     61|		catch (const std::out_of_range&)
  129|     61|		{
  130|      0|			throw std::runtime_error("Invalid X509 certificate " + extensionName + " extension data: " + fieldName);
  131|      0|		}
  132|     61|	}
X509ExtensionDataDecoder.cpp:_ZN4pcppL12castRecordAsINS_17Asn1IntegerRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEESE_:
  109|     61|	{
  110|     61|		try
  111|     61|		{
  112|     61|			return record->castAs<Asn1RecordType>();
  113|     61|		}
  114|     61|		catch (const std::bad_cast&)
  115|     61|		{
  116|      3|			throw std::runtime_error("Invalid X509 certificate " + extensionName + " extension data: " + fieldName);
  117|      3|		}
  118|     61|	}
X509ExtensionDataDecoder.cpp:_ZN4pcppL12castRecordAsINS_21Asn1OctetStringRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEESE_:
  109|    223|	{
  110|    223|		try
  111|    223|		{
  112|    223|			return record->castAs<Asn1RecordType>();
  113|    223|		}
  114|    223|		catch (const std::bad_cast&)
  115|    223|		{
  116|     25|			throw std::runtime_error("Invalid X509 certificate " + extensionName + " extension data: " + fieldName);
  117|     25|		}
  118|    223|	}
X509ExtensionDataDecoder.cpp:_ZN4pcppL12castRecordAsINS_19Asn1BitStringRecordEEEPT_PNS_10Asn1RecordERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEESE_:
  109|    385|	{
  110|    385|		try
  111|    385|		{
  112|    385|			return record->castAs<Asn1RecordType>();
  113|    385|		}
  114|    385|		catch (const std::bad_cast&)
  115|    385|		{
  116|     21|			throw std::runtime_error("Invalid X509 certificate " + extensionName + " extension data: " + fieldName);
  117|     21|		}
  118|    385|	}

LLVMFuzzerTestOneInput:
   10|  3.31k|{
   11|  3.31k|	if (size == 0)
  ------------------
  |  Branch (11:6): [True: 0, False: 3.31k]
  ------------------
   12|      0|		return 0;
   13|       |
   14|  3.31k|	pcpp::Logger::getInstance().suppressLogs();
   15|       |
   16|       |	// fromDER needs a mutable buffer that outlives the parse
   17|  3.31k|	std::vector<uint8_t> buf(data, data + size);
   18|       |
   19|  3.31k|	try
   20|  3.31k|	{
   21|  3.31k|		auto cert = pcpp::X509Certificate::fromDER(buf.data(), buf.size());
   22|  3.31k|		if (!cert)
  ------------------
  |  Branch (22:7): [True: 0, False: 3.31k]
  ------------------
   23|      0|			return 0;
   24|       |
   25|  3.31k|		cert->getVersion();
   26|  3.31k|		cert->getSerialNumber();
   27|  3.31k|		cert->getIssuer();
   28|  3.31k|		cert->getSubject();
   29|  3.31k|		cert->getNotBefore();
   30|  3.31k|		cert->getNotAfter();
   31|  3.31k|		cert->getPublicKeyAlgorithm();
   32|  3.31k|		cert->getPublicKey();
   33|  3.31k|		cert->getSignatureAlgorithm();
   34|  3.31k|		cert->getSignature();
   35|  3.31k|		cert->toJson();
   36|       |
   37|  3.31k|		for (const auto& ext : cert->getExtensions())
  ------------------
  |  Branch (37:24): [True: 2.95k, False: 3.08k]
  ------------------
   38|  2.95k|		{
   39|  2.95k|			ext.getType();
   40|  2.95k|			ext.isCritical();
   41|       |
   42|  2.95k|			auto extData = ext.getData();
   43|  2.95k|			if (!extData)
  ------------------
  |  Branch (43:8): [True: 1.59k, False: 1.35k]
  ------------------
   44|  1.59k|				continue;
   45|       |
   46|  1.35k|			switch (ext.getType())
   47|  1.35k|			{
   48|    201|			case pcpp::X509ExtensionType::BasicConstraints:
  ------------------
  |  Branch (48:4): [True: 201, False: 1.15k]
  ------------------
   49|    201|			{
   50|    201|				auto* bc = extData->castAs<pcpp::X509BasicConstraintsExtension>();
   51|    201|				bc->isCA();
   52|    201|				bc->getPathLenConstraint();
   53|    201|				break;
   54|      0|			}
   55|    359|			case pcpp::X509ExtensionType::KeyUsage:
  ------------------
  |  Branch (55:4): [True: 359, False: 996]
  ------------------
   56|    359|			{
   57|    359|				auto* ku = extData->castAs<pcpp::X509KeyUsageExtension>();
   58|    359|				ku->isDigitalSignature();
   59|    359|				ku->isNonRepudiation();
   60|    359|				ku->isKeyEncipherment();
   61|    359|				ku->isDataEncipherment();
   62|    359|				ku->isKeyAgreement();
   63|    359|				ku->isKeyCertSign();
   64|    359|				ku->isCRLSign();
   65|    359|				ku->isEncipherOnly();
   66|    359|				ku->isDecipherOnly();
   67|    359|				break;
   68|      0|			}
   69|    366|			case pcpp::X509ExtensionType::ExtendedKeyUsage:
  ------------------
  |  Branch (69:4): [True: 366, False: 989]
  ------------------
   70|    366|				extData->castAs<pcpp::X509ExtendedKeyUsageExtension>()->getPurposes();
   71|    366|				break;
   72|    198|			case pcpp::X509ExtensionType::SubjectKeyIdentifier:
  ------------------
  |  Branch (72:4): [True: 198, False: 1.15k]
  ------------------
   73|    198|				extData->castAs<pcpp::X509SubjectKeyIdentifierExtension>()->getKeyIdentifier();
   74|    198|				break;
   75|      0|			default:
  ------------------
  |  Branch (75:4): [True: 0, False: 1.35k]
  ------------------
   76|      0|				break;
   77|  1.35k|			}
   78|  1.35k|		}
   79|  3.31k|	}
   80|  3.31k|	catch (...)
   81|  3.31k|	{}
   82|       |
   83|  3.31k|	return 0;
   84|  3.31k|}

