_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:
  368|  3.47k|		{
  369|  3.47k|			static Logger instance;
  370|  3.47k|			return instance;
  371|  3.47k|		}
_ZN4pcpp6Logger12suppressLogsEv:
  320|  3.40k|		{
  321|  3.40k|			m_LogsEnabled = false;
  322|  3.40k|		}
_ZN4pcpp9LogSourceC2ENS_9LogModuleEPKcS3_i:
  138|     64|		    : file(file), function(function), line(line), logModule(logModule)
  139|     64|		{}
_ZN4pcpp8internal10LogContext4initENS_8LogLevelERKNS_9LogSourceE:
  188|     64|			{
  189|     64|				m_Source = source;
  190|     64|				m_Level = level;
  191|     64|				m_Stream.clear();
  192|     64|				m_Stream.str({});
  193|     64|			}
_ZNK4pcpp6Logger9shouldLogENS_8LogLevelENS_9LogModuleE:
  288|     64|		{
  289|     64|			return level != LogLevel::Off && m_LogModulesArray[module] >= level;
  ------------------
  |  Branch (289:11): [True: 64, False: 0]
  |  Branch (289:37): [True: 64, False: 0]
  ------------------
  290|     64|		}
_ZN4pcpp8internal10LogContextlsIA28_cEERS1_RKT_:
  199|      5|			{
  200|      5|				m_Stream << value;
  201|      5|				return *this;
  202|      5|			}
_ZN4pcpp8internal10LogContextlsIA38_cEERS1_RKT_:
  199|     59|			{
  200|     59|				m_Stream << value;
  201|     59|				return *this;
  202|     59|			}
_ZN4pcpp9LogSourceC2Ev:
  125|      2|		constexpr LogSource() = default;
_ZN4pcpp8internal10LogContextC2Ev:
  176|      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|     64|			{
   69|     64|				return std::unique_ptr<T>(acquireObjectRaw());
   70|     64|			}
_ZN4pcpp8internal17DynamicObjectPoolINS0_10LogContextELb1EE16acquireObjectRawEv:
   79|     64|			{
   80|     64|				std::unique_lock<std::mutex> lock(m_Mutex);
   81|       |
   82|     64|				if (m_Pool.empty())
  ------------------
  |  Branch (82:9): [True: 0, False: 64]
  ------------------
   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|     64|				T* obj = m_Pool.top();
   90|     64|				m_Pool.pop();
   91|     64|				return obj;
   92|     64|			}
_ZN4pcpp8internal17DynamicObjectPoolINS0_10LogContextELb1EE13releaseObjectENSt3__110unique_ptrIS2_NS4_14default_deleteIS2_EEEE:
  101|     64|			{
  102|     64|				releaseObjectRaw(obj.release());
  103|     64|			}
_ZN4pcpp8internal17DynamicObjectPoolINS0_10LogContextELb1EE16releaseObjectRawEPS2_:
  112|     64|			{
  113|     64|				std::unique_lock<std::mutex> lock(m_Mutex);
  114|       |
  115|     64|				if (m_MaxPoolSize == INFINITE_POOL_SIZE || m_Pool.size() < m_MaxPoolSize)
  ------------------
  |  Branch (115:9): [True: 0, False: 64]
  |  Branch (115:48): [True: 64, False: 0]
  ------------------
  116|     64|				{
  117|     64|					m_Pool.push(obj);
  118|     64|				}
  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|     64|			}

_ZNK4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEE2atEi:
  319|  84.5k|		{
  320|  84.5k|			return m_Vector.at(index);
  321|  84.5k|		}
_ZN4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEE5beginEv:
  188|  5.37k|		{
  189|  5.37k|			return m_Vector.begin();
  190|  5.37k|		}
_ZN4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEE3endEv:
  202|  5.37k|		{
  203|  5.37k|			return m_Vector.end();
  204|  5.37k|		}
_ZNK4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEE4sizeEv:
  216|  6.55k|		{
  217|  6.55k|			return m_Vector.size();
  218|  6.55k|		}
_ZN4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEEC2Ev:
   59|  51.1k|		PointerVector() = default;
_ZN4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEED2Ev:
   78|  51.1k|		{
   79|  51.1k|			freeVectorUnsafe(m_Vector);
   80|  51.1k|		}
_ZN4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEE16freeVectorUnsafeERKNS2_6vectorIPS1_NS2_9allocatorIS7_EEEE:
  362|  51.1k|		{
  363|  51.1k|			for (auto& obj : origin)
  ------------------
  |  Branch (363:19): [True: 370k, False: 51.1k]
  ------------------
  364|   370k|			{
  365|   370k|				Deleter{}(obj);
  366|   370k|			}
  367|  51.1k|		}
_ZN4pcpp13PointerVectorINS_10Asn1RecordENSt3__114default_deleteIS1_EEE8pushBackENS2_10unique_ptrIS1_S4_EE:
  172|   370k|		{
  173|   370k|			if (!element)
  ------------------
  |  Branch (173:8): [True: 0, False: 370k]
  ------------------
  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|   370k|			m_Vector.push_back(element.get());
  182|   370k|			element.release();
  183|   370k|		}

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

_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|     64|	{
   90|     64|		if (m_UseContextPooling)
  ------------------
  |  Branch (90:7): [True: 64, False: 0]
  ------------------
   91|     64|		{
   92|     64|			auto ctx = m_LogContextPool.acquireObject();
   93|     64|			ctx->init(level, source);
   94|     64|			return ctx;
   95|     64|		}
   96|      0|		return std::make_unique<internal::LogContext>(level, source);
   97|     64|	}
_ZN4pcpp6Logger4emitENSt3__110unique_ptrINS_8internal10LogContextENS1_14default_deleteIS4_EEEE:
  100|     64|	{
  101|     64|		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|     64|		if (m_UseContextPooling)
  ------------------
  |  Branch (103:7): [True: 64, False: 0]
  ------------------
  104|     64|		{
  105|     64|			m_LogContextPool.releaseObject(std::move(message));
  106|     64|		}
  107|     64|	}
_ZN4pcpp6Logger4emitERKNS_9LogSourceENS_8LogLevelERKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEE:
  110|     64|	{
  111|       |		// If the log level is an error, save the error to the last error message variable.
  112|     64|		if (logLevel == LogLevel::Error)
  ------------------
  |  Branch (112:7): [True: 64, False: 0]
  ------------------
  113|     64|		{
  114|     64|			static_assert(m_LastError.size() >= 1,
  115|     64|			              "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|     64|			auto const copied = message.copy(m_LastError.data(), m_LastError.size() - 1);
  119|     64|			m_LastError[copied] = '\0';
  120|     64|		}
  121|     64|		if (m_LogsEnabled)
  ------------------
  |  Branch (121:7): [True: 0, False: 64]
  ------------------
  122|      0|		{
  123|      0|			m_LogPrinter(logLevel, message, source.file, source.function, source.line);
  124|      0|		}
  125|     64|	}

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

_ZNK4pcpp10Asn1Record11getTagClassEv:
  148|  5.04k|		{
  149|  5.04k|			return m_TagClass;
  150|  5.04k|		}
_ZNK4pcpp10Asn1Record13isConstructedEv:
  154|  2.04k|		{
  155|  2.04k|			return m_IsConstructed;
  156|  2.04k|		}
_ZNK4pcpp10Asn1Record10getTagTypeEv:
  164|  4.08k|		{
  165|  4.08k|			return m_TagType;
  166|  4.08k|		}
_ZNK4pcpp10Asn1Record14getTotalLengthEv:
  176|   740k|		{
  177|   740k|			return m_TotalLength;
  178|   740k|		}
_ZN4pcpp21Asn1ConstructedRecord13getSubRecordsEv:
  313|  97.7k|		{
  314|  97.7k|			decodeValueIfNeeded();
  315|  97.7k|			return m_SubRecords;
  316|  97.7k|		};
_ZNK4pcpp17Asn1IntegerRecord16getValueAsStringEb:
  441|  2.19k|		{
  442|  2.19k|			decodeValueIfNeeded();
  443|  2.19k|			return m_Value.toString(removeLeadingZeros);
  444|  2.19k|		}
_ZNK4pcpp17Asn1BooleanRecord8getValueEv:
  659|    743|		{
  660|    743|			decodeValueIfNeeded();
  661|    743|			return m_Value;
  662|    743|		};
_ZNK4pcpp14Asn1NullRecord11decodeValueEPKh:
  688|  1.61k|		{}
_ZNK4pcpp26Asn1ObjectIdentifierRecord8getValueEv:
  765|  17.7k|		{
  766|  17.7k|			decodeValueIfNeeded();
  767|  17.7k|			return m_Value;
  768|  17.7k|		}
_ZNK4pcpp14Asn1TimeRecord8getValueERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  793|  1.79k|		{
  794|  1.79k|			decodeValueIfNeeded();
  795|  1.79k|			return adjustTimezones(m_Value, "Z", timezone);
  796|  1.79k|		};
_ZN4pcpp19Asn1BitStringRecord8getValueEv:
  881|    350|		{
  882|    350|			decodeValueIfNeeded();
  883|    350|			return m_Value.toString();
  884|    350|		};
_ZN4pcpp19Asn1BitStringRecord11getVecValueEv:
  888|  3.79k|		{
  889|  3.79k|			decodeValueIfNeeded();
  890|  3.79k|			return m_Value.toBytes();
  891|  3.79k|		}
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE4EE11decodeValueEPKh:
  553|  3.41k|		{
  554|  3.41k|			m_Value = std::string(reinterpret_cast<char const*>(data), m_ValueLength);
  555|  3.41k|		}
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE4EE8getValueEv:
  537|  4.21k|		{
  538|  4.21k|			decodeValueIfNeeded();
  539|  4.21k|			return m_Value;
  540|  4.21k|		};
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE12EE11decodeValueEPKh:
  553|  8.03k|		{
  554|  8.03k|			m_Value = std::string(reinterpret_cast<char const*>(data), m_ValueLength);
  555|  8.03k|		}
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE12EE8getValueEv:
  537|  5.72k|		{
  538|  5.72k|			decodeValueIfNeeded();
  539|  5.72k|			return m_Value;
  540|  5.72k|		};
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE19EE11decodeValueEPKh:
  553|  4.72k|		{
  554|  4.72k|			m_Value = std::string(reinterpret_cast<char const*>(data), m_ValueLength);
  555|  4.72k|		}
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE19EE8getValueEv:
  537|  2.38k|		{
  538|  2.38k|			decodeValueIfNeeded();
  539|  2.38k|			return m_Value;
  540|  2.38k|		};
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE22EE11decodeValueEPKh:
  553|  5.66k|		{
  554|  5.66k|			m_Value = std::string(reinterpret_cast<char const*>(data), m_ValueLength);
  555|  5.66k|		}
_ZNK4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE22EE8getValueEv:
  537|    738|		{
  538|    738|			decodeValueIfNeeded();
  539|    738|			return m_Value;
  540|    738|		};
_ZN4pcpp10Asn1Record6castAsINS_17Asn1IntegerRecordEEEPT_v:
  188|  4.25k|		{
  189|  4.25k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  4.25k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 60, False: 4.19k]
  ------------------
  191|     60|			{
  192|     60|				throw std::bad_cast();
  193|     60|			}
  194|  4.19k|			return result;
  195|  4.25k|		}
_ZNK4pcpp17Asn1IntegerRecord11getIntValueIhTnNSt3__19enable_ifIXaasr3std11is_integralIT_EE5valuesr3std11is_unsignedIS4_EE5valueEiE4typeELi0EEES4_v:
  425|  1.99k|		{
  426|  1.99k|			decodeValueIfNeeded();
  427|  1.99k|			return m_Value.getInt<T>();
  428|  1.99k|		}
_ZNK4pcpp17Asn1IntegerRecord6BigInt6getIntIhTnNSt3__19enable_ifIXaasr3std11is_integralIT_EE5valuesr3std11is_unsignedIS5_EE5valueEiE4typeELi0EEES5_v:
  476|  1.99k|			{
  477|  1.99k|				if (!canFit<T>())
  ------------------
  |  Branch (477:9): [True: 8, False: 1.98k]
  ------------------
  478|      8|				{
  479|      8|					throw std::overflow_error("Value cannot fit into requested int type");
  480|      8|				}
  481|       |
  482|  1.98k|				std::stringstream sstream;
  483|  1.98k|				sstream << std::hex << m_Value;
  484|       |
  485|  1.98k|				uint64_t result;
  486|  1.98k|				sstream >> result;
  487|  1.98k|				return static_cast<T>(result);
  488|  1.99k|			}
_ZNK4pcpp17Asn1IntegerRecord6BigInt6canFitIhTnNSt3__19enable_ifIXaasr3std11is_integralIT_EE5valuesr3std11is_unsignedIS5_EE5valueEiE4typeELi0EEEbv:
  491|  1.99k|			{
  492|  1.99k|				return sizeof(T) >= (m_Value.size() + 1) / 2;
  493|  1.99k|			}
_ZN4pcpp10Asn1Record6castAsINS_26Asn1ObjectIdentifierRecordEEEPT_v:
  188|  17.7k|		{
  189|  17.7k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  17.7k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 30, False: 17.7k]
  ------------------
  191|     30|			{
  192|     30|				throw std::bad_cast();
  193|     30|			}
  194|  17.7k|			return result;
  195|  17.7k|		}
_ZN4pcpp10Asn1Record6castAsINS_25Asn1PrintableStringRecordEEEPT_v:
  188|  2.39k|		{
  189|  2.39k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  2.39k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 8, False: 2.38k]
  ------------------
  191|      8|			{
  192|      8|				throw std::bad_cast();
  193|      8|			}
  194|  2.38k|			return result;
  195|  2.39k|		}
_ZN4pcpp10Asn1Record6castAsINS_19Asn1IA5StringRecordEEEPT_v:
  188|    742|		{
  189|    742|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|    742|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 4, False: 738]
  ------------------
  191|      4|			{
  192|      4|				throw std::bad_cast();
  193|      4|			}
  194|    738|			return result;
  195|    742|		}
_ZN4pcpp10Asn1Record6castAsINS_20Asn1UTF8StringRecordEEEPT_v:
  188|  5.73k|		{
  189|  5.73k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  5.73k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 8, False: 5.72k]
  ------------------
  191|      8|			{
  192|      8|				throw std::bad_cast();
  193|      8|			}
  194|  5.72k|			return result;
  195|  5.73k|		}
_ZN4pcpp10Asn1Record6castAsINS_13Asn1SetRecordEEEPT_v:
  188|  9.10k|		{
  189|  9.10k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  9.10k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 8, False: 9.09k]
  ------------------
  191|      8|			{
  192|      8|				throw std::bad_cast();
  193|      8|			}
  194|  9.09k|			return result;
  195|  9.10k|		}
_ZN4pcpp10Asn1Record6castAsINS_14Asn1TimeRecordEEEPT_v:
  188|  3.87k|		{
  189|  3.87k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  3.87k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 16, False: 3.86k]
  ------------------
  191|     16|			{
  192|     16|				throw std::bad_cast();
  193|     16|			}
  194|  3.86k|			return result;
  195|  3.87k|		}
_ZN4pcpp10Asn1Record6castAsINS_19Asn1BitStringRecordEEEPT_v:
  188|  4.19k|		{
  189|  4.19k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  4.19k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 55, False: 4.14k]
  ------------------
  191|     55|			{
  192|     55|				throw std::bad_cast();
  193|     55|			}
  194|  4.14k|			return result;
  195|  4.19k|		}
_ZN4pcpp10Asn1Record6castAsINS_17Asn1BooleanRecordEEEPT_v:
  188|    762|		{
  189|    762|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|    762|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 19, False: 743]
  ------------------
  191|     19|			{
  192|     19|				throw std::bad_cast();
  193|     19|			}
  194|    743|			return result;
  195|    762|		}
_ZN4pcpp10Asn1Record6castAsINS_21Asn1OctetStringRecordEEEPT_v:
  188|  4.27k|		{
  189|  4.27k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  4.27k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 57, False: 4.21k]
  ------------------
  191|     57|			{
  192|     57|				throw std::bad_cast();
  193|     57|			}
  194|  4.21k|			return result;
  195|  4.27k|		}
_ZN4pcpp10Asn1Record6castAsINS_18Asn1SequenceRecordEEEPT_v:
  188|  48.6k|		{
  189|  48.6k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  48.6k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 628, False: 47.9k]
  ------------------
  191|    628|			{
  192|    628|				throw std::bad_cast();
  193|    628|			}
  194|  47.9k|			return result;
  195|  48.6k|		}
_ZN4pcpp10Asn1Record6castAsINS_21Asn1ConstructedRecordEEEPT_v:
  188|  2.85k|		{
  189|  2.85k|			auto result = dynamic_cast<Asn1RecordType*>(this);
  190|  2.85k|			if (result == nullptr)
  ------------------
  |  Branch (190:8): [True: 0, False: 2.85k]
  ------------------
  191|      0|			{
  192|      0|				throw std::bad_cast();
  193|      0|			}
  194|  2.85k|			return result;
  195|  2.85k|		}
_ZN4pcpp18Asn1SequenceRecordC2Ev:
  368|  30.2k|		Asn1SequenceRecord() = default;
_ZN4pcpp21Asn1ConstructedRecordC2Ev:
  319|  51.1k|		Asn1ConstructedRecord() = default;
_ZN4pcpp13Asn1SetRecordC2Ev:
  387|  8.18k|		Asn1SetRecord() = default;
_ZN4pcpp17Asn1IntegerRecordC2Ev:
  447|  8.32k|		Asn1IntegerRecord() = default;
_ZN4pcpp19Asn1PrimitiveRecordC2Ev:
  398|  46.8k|		Asn1PrimitiveRecord() = default;
_ZN4pcpp20Asn1EnumeratedRecordC2Ev:
  526|  2.13k|		Asn1EnumeratedRecord() = default;
_ZN4pcpp21Asn1OctetStringRecordC2Ev:
  593|  11.3k|		Asn1OctetStringRecord() = default;
_ZN4pcpp20Asn1UTF8StringRecordC2Ev:
  611|  8.05k|		Asn1UTF8StringRecord() = default;
_ZN4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE12EEC2Ev:
  543|  8.05k|		Asn1StringRecord() : Asn1PrimitiveRecord(TagType)
  544|  8.05k|		{}
_ZN4pcpp25Asn1PrintableStringRecordC2Ev:
  627|  4.74k|		Asn1PrintableStringRecord() = default;
_ZN4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE19EEC2Ev:
  543|  4.74k|		Asn1StringRecord() : Asn1PrimitiveRecord(TagType)
  544|  4.74k|		{}
_ZN4pcpp19Asn1IA5StringRecordC2Ev:
  643|  5.68k|		Asn1IA5StringRecord() = default;
_ZN4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE22EEC2Ev:
  543|  5.68k|		Asn1StringRecord() : Asn1PrimitiveRecord(TagType)
  544|  5.68k|		{}
_ZN4pcpp17Asn1BooleanRecordC2Ev:
  671|  1.87k|		Asn1BooleanRecord() = default;
_ZN4pcpp19Asn1BitStringRecordC2Ev:
  924|  4.80k|		Asn1BitStringRecord() = default;
_ZN4pcpp26Asn1ObjectIdentifierRecordC2Ev:
  779|  20.2k|		Asn1ObjectIdentifierRecord() = default;
_ZN4pcpp17Asn1UtcTimeRecordC2Ev:
  839|  5.71k|		Asn1UtcTimeRecord() = default;
_ZN4pcpp14Asn1TimeRecordC2Ev:
  808|  11.6k|		Asn1TimeRecord() = default;
_ZN4pcpp25Asn1GeneralizedTimeRecordC2Ev:
  863|  5.95k|		Asn1GeneralizedTimeRecord() = default;
_ZN4pcpp17Asn1GenericRecordC2Ev:
  278|   246k|		Asn1GenericRecord() = default;
_ZN4pcpp10Asn1RecordC2Ev:
  207|   376k|		Asn1Record() = default;
_ZN4pcpp10Asn1RecordD2Ev:
  197|   376k|		virtual ~Asn1Record() = default;
_ZN4pcpp17Asn1IntegerRecord6BigIntC2Ev:
  458|  8.32k|			BigInt() = default;
_ZN4pcpp20Asn1ObjectIdentifierC2Ev:
  746|  20.2k|		Asn1ObjectIdentifier() = default;
_ZN4pcpp19Asn1BitStringRecord6BitSetC2Ev:
  903|  5.43k|			BitSet() = default;
_ZN4pcpp17Asn1GenericRecordD2Ev:
  268|   246k|		~Asn1GenericRecord() override = default;
_ZN4pcpp16Asn1StringRecordILNS_20Asn1UniversalTagTypeE4EEC2Ev:
  543|  11.3k|		Asn1StringRecord() : Asn1PrimitiveRecord(TagType)
  544|  11.3k|		{}

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

_ZNK4pcpp13X509Extension7getTypeEv:
  710|  7.86k|		{
  711|  7.86k|			return m_Type;
  712|  7.86k|		}
_ZNK4pcpp13X509Extension10isCriticalEv:
  717|  6.56k|		{
  718|  6.56k|			return m_IsCritical;
  719|  6.56k|		}
_ZNK4pcpp17X509ExtensionTypecvNS0_5ValueEEv:
  279|  4.00k|		{
  280|  4.00k|			return m_Value;
  281|  4.00k|		}
_ZN4pcpp13X509AlgorithmC2ENS0_5ValueE:
   91|  3.81k|		constexpr X509Algorithm(Value value) : m_Value(value)
   92|  3.81k|		{}
_ZN4pcpp21X520DistinguishedNameC2ENS0_5ValueE:
  172|  8.98k|		constexpr X520DistinguishedName(Value value) : m_Value(value)
  173|  8.98k|		{}
_ZN4pcpp17X509ExtensionTypeC2ENS0_5ValueE:
  263|  4.04k|		constexpr X509ExtensionType(Value value) : m_Value(value)
  264|  4.04k|		{}
_ZN4pcpp16X509SerialNumberC2ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  295|  2.19k|		explicit X509SerialNumber(const std::string& serialNumber) : m_SerialNumber(serialNumber)
  296|  2.19k|		{}
_ZN4pcpp13X509TimestampC2EPNS_14Asn1TimeRecordE:
  315|  3.86k|		explicit X509Timestamp(Asn1TimeRecord* timeRecord) : m_Record(timeRecord)
  316|  3.86k|		{}
_ZN4pcpp7X509KeyC2ERKNSt3__16vectorIhNS1_9allocatorIhEEEE:
  344|  3.79k|		explicit X509Key(const std::vector<uint8_t>& key) : m_Key(key)
  345|  3.79k|		{}
_ZN4pcpp12X509Internal15X509CertificateC2ENSt3__110unique_ptrINS_10Asn1RecordENS2_14default_deleteIS4_EEEE:
  639|  3.04k|			explicit X509Certificate(std::unique_ptr<Asn1Record> root) : m_Root(std::move(root))
  640|  3.04k|			{}
_ZN4pcpp12X509Internal8X509BaseINS_13Asn1SetRecordEEC2EPS2_:
  378|  9.09k|			explicit X509Base(Asn1RecordType* root) : m_Root(root)
  379|  9.09k|			{}
_ZN4pcpp12X509Internal8X509BaseINS_21Asn1ConstructedRecordEEC2EPS2_:
  378|  2.85k|			explicit X509Base(Asn1RecordType* root) : m_Root(root)
  379|  2.85k|			{}
_ZN4pcpp12X509Internal8X509BaseINS_18Asn1SequenceRecordEEC2EPS2_:
  378|  21.5k|			explicit X509Base(Asn1RecordType* root) : m_Root(root)
  379|  21.5k|			{}

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

_ZN4pcpp10Asn1Record6decodeEPKhmb:
   93|   376k|	{
   94|   376k|		uint8_t tagLen;
   95|   376k|		auto decodedRecord = decodeTagAndCreateRecord(data, dataLen, tagLen);
   96|       |
   97|   376k|		uint8_t lengthLen;
   98|   376k|		lengthLen = decodedRecord->decodeLength(data + tagLen, dataLen - tagLen);
   99|       |
  100|   376k|		decodedRecord->m_TotalLength = tagLen + lengthLen + decodedRecord->m_ValueLength;
  101|   376k|		if (decodedRecord->m_TotalLength < decodedRecord->m_ValueLength ||  // check for overflow
  ------------------
  |  Branch (101:7): [True: 497, False: 376k]
  ------------------
  102|   376k|		    decodedRecord->m_TotalLength > dataLen)
  ------------------
  |  Branch (102:7): [True: 580, False: 375k]
  ------------------
  103|    586|		{
  104|    586|			throw std::invalid_argument("Cannot decode ASN.1 record, data doesn't contain the entire record");
  105|    586|		}
  106|       |
  107|   376k|		uint8_t const* startOfData = data + tagLen + lengthLen;
  108|   376k|		internal::Asn1LoadPolicy policy = lazy ? internal::Asn1LoadPolicy::Lazy : internal::Asn1LoadPolicy::Eager;
  ------------------
  |  Branch (108:37): [True: 4.53k, False: 371k]
  ------------------
  109|   376k|		decodedRecord->setEncodedValue(startOfData, policy);
  110|       |
  111|   376k|		return decodedRecord;
  112|   376k|	}
_ZNK4pcpp10Asn1Record19getUniversalTagTypeEv:
  196|  9.07k|	{
  197|  9.07k|		if (m_TagClass == Asn1TagClass::Universal)
  ------------------
  |  Branch (197:7): [True: 9.04k, False: 30]
  ------------------
  198|  9.04k|		{
  199|  9.04k|			return static_cast<Asn1UniversalTagType>(m_TagType);
  200|  9.04k|		}
  201|       |
  202|     30|		return Asn1UniversalTagType::NotApplicable;
  203|  9.07k|	}
_ZN4pcpp10Asn1Record24decodeTagAndCreateRecordEPKhmRh:
  207|   376k|	{
  208|   376k|		if (dataLen < 1)
  ------------------
  |  Branch (208:7): [True: 68, False: 376k]
  ------------------
  209|     68|		{
  210|     68|			throw std::invalid_argument("Cannot decode ASN.1 record tag");
  211|     68|		}
  212|       |
  213|   376k|		tagLen = 1;
  214|       |
  215|   376k|		Asn1TagClass tagClass = Asn1TagClass::Universal;
  216|       |
  217|       |		// Check first 2 bits
  218|   376k|		auto tagClassBits = data[0] & 0xc0;
  219|   376k|		if (tagClassBits == 0)
  ------------------
  |  Branch (219:7): [True: 362k, False: 14.5k]
  ------------------
  220|   362k|		{
  221|   362k|			tagClass = Asn1TagClass::Universal;
  222|   362k|		}
  223|  14.5k|		else if ((tagClassBits & 0xc0) == 0xc0)
  ------------------
  |  Branch (223:12): [True: 3.15k, False: 11.3k]
  ------------------
  224|  3.15k|		{
  225|  3.15k|			tagClass = Asn1TagClass::Private;
  226|  3.15k|		}
  227|  11.3k|		else if ((tagClassBits & 0x80) == 0x80)
  ------------------
  |  Branch (227:12): [True: 6.37k, False: 4.97k]
  ------------------
  228|  6.37k|		{
  229|  6.37k|			tagClass = Asn1TagClass::ContextSpecific;
  230|  6.37k|		}
  231|  4.97k|		else if ((tagClassBits & 0x40) == 0x40)
  ------------------
  |  Branch (231:12): [True: 4.97k, False: 0]
  ------------------
  232|  4.97k|		{
  233|  4.97k|			tagClass = Asn1TagClass::Application;
  234|  4.97k|		}
  235|       |
  236|       |		// Check bit 6
  237|   376k|		auto tagTypeBits = data[0] & 0x20;
  238|   376k|		bool isConstructed = (tagTypeBits != 0);
  239|       |
  240|       |		// Check last 5 bits
  241|   376k|		auto tagType = data[0] & 0x1f;
  242|   376k|		if (tagType == 0x1f)
  ------------------
  |  Branch (242:7): [True: 1.55k, False: 374k]
  ------------------
  243|  1.55k|		{
  244|  1.55k|			if (dataLen < 2)
  ------------------
  |  Branch (244:8): [True: 9, False: 1.54k]
  ------------------
  245|      9|			{
  246|      9|				throw std::invalid_argument("Cannot decode ASN.1 record tag");
  247|      9|			}
  248|       |
  249|  1.54k|			if ((data[1] & 0x80) != 0)
  ------------------
  |  Branch (249:8): [True: 63, False: 1.48k]
  ------------------
  250|     63|			{
  251|     63|				throw std::invalid_argument("ASN.1 tags with value larger than 127 are not supported");
  252|     63|			}
  253|       |
  254|  1.48k|			tagType = data[1] & 0x7f;
  255|  1.48k|			tagLen = 2;
  256|  1.48k|		}
  257|       |
  258|   376k|		std::unique_ptr<Asn1Record> newRecord;
  259|       |
  260|   376k|		if (isConstructed)
  ------------------
  |  Branch (260:7): [True: 51.1k, False: 325k]
  ------------------
  261|  51.1k|		{
  262|  51.1k|			if (tagClass == Asn1TagClass::Universal)
  ------------------
  |  Branch (262:8): [True: 42.9k, False: 8.25k]
  ------------------
  263|  42.9k|			{
  264|  42.9k|				switch (static_cast<Asn1UniversalTagType>(tagType))
  265|  42.9k|				{
  266|  30.2k|				case Asn1UniversalTagType::Sequence:
  ------------------
  |  Branch (266:5): [True: 30.2k, False: 12.6k]
  ------------------
  267|  30.2k|				{
  268|  30.2k|					newRecord.reset(new Asn1SequenceRecord());
  269|  30.2k|					break;
  270|      0|				}
  271|  8.18k|				case Asn1UniversalTagType::Set:
  ------------------
  |  Branch (271:5): [True: 8.18k, False: 34.7k]
  ------------------
  272|  8.18k|				{
  273|  8.18k|					newRecord.reset(new Asn1SetRecord());
  274|  8.18k|					break;
  275|      0|				}
  276|  4.47k|				default:
  ------------------
  |  Branch (276:5): [True: 4.47k, False: 38.4k]
  ------------------
  277|  4.47k|				{
  278|  4.47k|					newRecord.reset(new Asn1ConstructedRecord());
  279|  4.47k|				}
  280|  42.9k|				}
  281|  42.9k|			}
  282|  8.25k|			else
  283|  8.25k|			{
  284|  8.25k|				newRecord.reset(new Asn1ConstructedRecord());
  285|  8.25k|			}
  286|  51.1k|		}
  287|   325k|		else
  288|   325k|		{
  289|   325k|			if (tagClass == Asn1TagClass::Universal)
  ------------------
  |  Branch (289:8): [True: 319k, False: 6.18k]
  ------------------
  290|   319k|			{
  291|   319k|				auto asn1UniversalTagType = static_cast<Asn1UniversalTagType>(tagType);
  292|   319k|				switch (asn1UniversalTagType)
  293|   319k|				{
  294|  6.18k|				case Asn1UniversalTagType::Integer:
  ------------------
  |  Branch (294:5): [True: 6.18k, False: 312k]
  ------------------
  295|  6.18k|				{
  296|  6.18k|					newRecord.reset(new Asn1IntegerRecord());
  297|  6.18k|					break;
  298|      0|				}
  299|  2.13k|				case Asn1UniversalTagType::Enumerated:
  ------------------
  |  Branch (299:5): [True: 2.13k, False: 316k]
  ------------------
  300|  2.13k|				{
  301|  2.13k|					newRecord.reset(new Asn1EnumeratedRecord());
  302|  2.13k|					break;
  303|      0|				}
  304|  11.3k|				case Asn1UniversalTagType::OctetString:
  ------------------
  |  Branch (304:5): [True: 11.3k, False: 307k]
  ------------------
  305|  11.3k|				{
  306|  11.3k|					newRecord.reset(new Asn1OctetStringRecord());
  307|  11.3k|					break;
  308|      0|				}
  309|  8.05k|				case Asn1UniversalTagType::UTF8String:
  ------------------
  |  Branch (309:5): [True: 8.05k, False: 311k]
  ------------------
  310|  8.05k|				{
  311|  8.05k|					newRecord.reset(new Asn1UTF8StringRecord());
  312|  8.05k|					break;
  313|      0|				}
  314|  4.74k|				case Asn1UniversalTagType::PrintableString:
  ------------------
  |  Branch (314:5): [True: 4.74k, False: 314k]
  ------------------
  315|  4.74k|				{
  316|  4.74k|					newRecord.reset(new Asn1PrintableStringRecord());
  317|  4.74k|					break;
  318|      0|				}
  319|  5.68k|				case Asn1UniversalTagType::IA5String:
  ------------------
  |  Branch (319:5): [True: 5.68k, False: 313k]
  ------------------
  320|  5.68k|				{
  321|  5.68k|					newRecord.reset(new Asn1IA5StringRecord());
  322|  5.68k|					break;
  323|      0|				}
  324|  1.87k|				case Asn1UniversalTagType::Boolean:
  ------------------
  |  Branch (324:5): [True: 1.87k, False: 317k]
  ------------------
  325|  1.87k|				{
  326|  1.87k|					newRecord.reset(new Asn1BooleanRecord());
  327|  1.87k|					break;
  328|      0|				}
  329|  4.80k|				case Asn1UniversalTagType::BitString:
  ------------------
  |  Branch (329:5): [True: 4.80k, False: 314k]
  ------------------
  330|  4.80k|				{
  331|  4.80k|					newRecord.reset(new Asn1BitStringRecord());
  332|  4.80k|					break;
  333|      0|				}
  334|  1.62k|				case Asn1UniversalTagType::Null:
  ------------------
  |  Branch (334:5): [True: 1.62k, False: 317k]
  ------------------
  335|  1.62k|				{
  336|  1.62k|					newRecord.reset(new Asn1NullRecord());
  337|  1.62k|					break;
  338|      0|				}
  339|  20.2k|				case Asn1UniversalTagType::ObjectIdentifier:
  ------------------
  |  Branch (339:5): [True: 20.2k, False: 298k]
  ------------------
  340|  20.2k|				{
  341|  20.2k|					newRecord.reset(new Asn1ObjectIdentifierRecord());
  342|  20.2k|					break;
  343|      0|				}
  344|  5.71k|				case Asn1UniversalTagType::UTCTime:
  ------------------
  |  Branch (344:5): [True: 5.71k, False: 313k]
  ------------------
  345|  5.71k|				{
  346|  5.71k|					newRecord.reset(new Asn1UtcTimeRecord());
  347|  5.71k|					break;
  348|      0|				}
  349|  5.95k|				case Asn1UniversalTagType::GeneralizedTime:
  ------------------
  |  Branch (349:5): [True: 5.95k, False: 313k]
  ------------------
  350|  5.95k|				{
  351|  5.95k|					newRecord.reset(new Asn1GeneralizedTimeRecord());
  352|  5.95k|					break;
  353|      0|				}
  354|   240k|				default:
  ------------------
  |  Branch (354:5): [True: 240k, False: 78.3k]
  ------------------
  355|   240k|				{
  356|   240k|					newRecord.reset(new Asn1GenericRecord());
  357|   240k|				}
  358|   319k|				}
  359|   319k|			}
  360|  6.18k|			else
  361|  6.18k|			{
  362|  6.18k|				newRecord.reset(new Asn1GenericRecord());
  363|  6.18k|			}
  364|   325k|		}
  365|       |
  366|   376k|		newRecord->m_TagClass = tagClass;
  367|   376k|		newRecord->m_IsConstructed = isConstructed;
  368|   376k|		newRecord->m_TagType = tagType;
  369|       |
  370|   376k|		return newRecord;
  371|   376k|	}
_ZN4pcpp10Asn1Record12decodeLengthEPKhm:
  374|   376k|	{
  375|   376k|		if (dataLen < 1)
  ------------------
  |  Branch (375:7): [True: 200, False: 376k]
  ------------------
  376|    200|		{
  377|    200|			throw std::invalid_argument("Cannot decode ASN.1 record length");
  378|    200|		}
  379|       |
  380|       |		// Check 8th bit
  381|   376k|		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|   376k|		if (lengthForm == 0)
  ------------------
  |  Branch (386:7): [True: 368k, False: 8.06k]
  ------------------
  387|   368k|		{
  388|   368k|			m_ValueLength = data[0];
  389|   368k|			return 1;
  390|   368k|		}
  391|       |
  392|  8.06k|		uint8_t actualLengthBytes = data[0] & 0x7F;
  393|  8.06k|		const uint8_t* actualLengthData = data + 1;
  394|       |
  395|  8.06k|		if (dataLen < static_cast<size_t>(actualLengthBytes) + 1)
  ------------------
  |  Branch (395:7): [True: 96, False: 7.96k]
  ------------------
  396|     96|		{
  397|     96|			throw std::invalid_argument("Cannot decode ASN.1 record length");
  398|     96|		}
  399|       |
  400|  24.4k|		for (int i = 0; i < actualLengthBytes; i++)
  ------------------
  |  Branch (400:19): [True: 16.5k, False: 7.91k]
  ------------------
  401|  16.5k|		{
  402|  16.5k|			size_t partialValueLength = m_ValueLength << 8;
  403|  16.5k|			if (partialValueLength < m_ValueLength)  // check for overflow
  ------------------
  |  Branch (403:8): [True: 55, False: 16.4k]
  ------------------
  404|     55|			{
  405|     55|				throw std::invalid_argument("Cannot decode ASN.1 record length");
  406|     55|			}
  407|       |
  408|  16.4k|			m_ValueLength = partialValueLength | actualLengthData[i];
  409|  16.4k|		}
  410|       |
  411|  7.91k|		return 1 + actualLengthBytes;
  412|  7.96k|	}
_ZNK4pcpp10Asn1Record19decodeValueIfNeededEv:
  415|   510k|	{
  416|       |		// TODO: This is not thread-safe and can cause issues in a multiple reader scenario.
  417|   510k|		if (m_EncodedValue != nullptr)
  ------------------
  |  Branch (417:7): [True: 375k, False: 135k]
  ------------------
  418|   375k|		{
  419|   375k|			decodeValue(m_EncodedValue);
  420|   375k|			m_EncodedValue = nullptr;  // Clear the encoded value after decoding
  421|   375k|		}
  422|   510k|	}
_ZN4pcpp10Asn1Record15setEncodedValueEPKhNS_8internal14Asn1LoadPolicyE:
  462|   375k|	{
  463|   375k|		m_EncodedValue = dataSource;
  464|       |
  465|   375k|		if (loadPolicy == internal::Asn1LoadPolicy::Eager)
  ------------------
  |  Branch (465:7): [True: 370k, False: 4.53k]
  ------------------
  466|   370k|		{
  467|   370k|			decodeValueIfNeeded();
  468|   370k|		}
  469|   375k|	}
_ZNK4pcpp17Asn1GenericRecord11decodeValueEPKh:
  484|   246k|	{
  485|   246k|		m_Value = std::make_unique<uint8_t[]>(m_ValueLength);
  486|   246k|		std::memcpy(m_Value.get(), data, m_ValueLength);
  487|   246k|	}
_ZNK4pcpp21Asn1ConstructedRecord11decodeValueEPKh:
  519|  50.6k|	{
  520|  50.6k|		if (!(data || m_ValueLength))
  ------------------
  |  Branch (520:9): [True: 50.6k, False: 0]
  |  Branch (520:17): [True: 0, False: 0]
  ------------------
  521|      0|		{
  522|      0|			return;
  523|      0|		}
  524|       |
  525|  50.6k|		auto value = data;
  526|  50.6k|		auto valueLen = m_ValueLength;
  527|       |
  528|   422k|		while (valueLen > 0)
  ------------------
  |  Branch (528:10): [True: 371k, False: 50.6k]
  ------------------
  529|   371k|		{
  530|   371k|			auto subRecord = Asn1Record::decode(value, valueLen, LazySubRecordDecoding);
  531|   371k|			value += subRecord->getTotalLength();
  532|   371k|			valueLen -= subRecord->getTotalLength();
  533|       |
  534|   371k|			m_SubRecords.pushBack(std::move(subRecord));
  535|   371k|		}
  536|  50.6k|	}
_ZN4pcpp19Asn1PrimitiveRecordC2ENS_20Asn1UniversalTagTypeE:
  583|  31.4k|	Asn1PrimitiveRecord::Asn1PrimitiveRecord(Asn1UniversalTagType tagType) : Asn1Record()
  584|  31.4k|	{
  585|  31.4k|		m_TagType = static_cast<uint8_t>(tagType);
  586|  31.4k|		m_TagClass = Asn1TagClass::Universal;
  587|  31.4k|		m_IsConstructed = false;
  588|  31.4k|	}
_ZN4pcpp17Asn1IntegerRecord6BigInt14initFromStringERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  601|  8.26k|	{
  602|  8.26k|		std::string valueStr = value;
  603|       |
  604|       |		// Optional 0x or 0X prefix
  605|  8.26k|		if (value.size() >= 2 && value[0] == '0' && (value[1] == 'x' || value[1] == 'X'))
  ------------------
  |  Branch (605:7): [True: 8.25k, False: 12]
  |  Branch (605:28): [True: 6.27k, False: 1.98k]
  |  Branch (605:48): [True: 0, False: 6.27k]
  |  Branch (605:67): [True: 0, False: 6.27k]
  ------------------
  606|      0|		{
  607|      0|			valueStr = value.substr(2);
  608|      0|		}
  609|       |
  610|  8.26k|		if (valueStr.empty())
  ------------------
  |  Branch (610:7): [True: 12, False: 8.25k]
  ------------------
  611|     12|		{
  612|     12|			throw std::invalid_argument("Value is not a valid hex stream");
  613|     12|		}
  614|       |
  615|  8.25k|		if (std::any_of(valueStr.begin(), valueStr.end(), [](char c) { return !std::isxdigit(c); }))
  ------------------
  |  Branch (615:7): [True: 0, False: 8.25k]
  ------------------
  616|      0|		{
  617|      0|			throw std::invalid_argument("Value is not a valid hex stream");
  618|      0|		}
  619|       |
  620|  8.25k|		return valueStr;
  621|  8.25k|	}
_ZN4pcpp17Asn1IntegerRecord6BigIntaSERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  624|  8.26k|	{
  625|  8.26k|		m_Value = initFromString(value);
  626|  8.26k|		return *this;
  627|  8.26k|	}
_ZNK4pcpp17Asn1IntegerRecord6BigInt8toStringEb:
  635|  2.19k|	{
  636|  2.19k|		if (!removeLeadingZeros)
  ------------------
  |  Branch (636:7): [True: 0, False: 2.19k]
  ------------------
  637|      0|		{
  638|      0|			return m_Value;
  639|      0|		}
  640|       |
  641|  2.19k|		auto firstNonZero = m_Value.find_first_not_of('0');
  642|  2.19k|		if (firstNonZero == std::string::npos)
  ------------------
  |  Branch (642:7): [True: 33, False: 2.16k]
  ------------------
  643|     33|		{
  644|     33|			return "0";
  645|     33|		}
  646|       |
  647|  2.16k|		return m_Value.substr(firstNonZero);
  648|  2.19k|	}
_ZNK4pcpp17Asn1IntegerRecord11decodeValueEPKh:
  692|  8.26k|	{
  693|  8.26k|		m_Value = pcpp::byteArrayToHexString(data, m_ValueLength);
  694|  8.26k|	}
_ZNK4pcpp21Asn1OctetStringRecord11decodeValueEPKh:
  721|  11.3k|	{
  722|  11.3k|		auto value = reinterpret_cast<char const*>(data);
  723|       |
  724|  11.3k|		m_IsPrintable = std::all_of(value, value + m_ValueLength, [](char c) { return isprint(0xff & c); });
  725|       |
  726|  11.3k|		if (m_IsPrintable)
  ------------------
  |  Branch (726:7): [True: 3.41k, False: 7.93k]
  ------------------
  727|  3.41k|		{
  728|  3.41k|			Asn1StringRecord::decodeValue(data);
  729|  3.41k|		}
  730|  7.93k|		else
  731|  7.93k|		{
  732|  7.93k|			m_Value = byteArrayToHexString(data, m_ValueLength);
  733|  7.93k|		}
  734|  11.3k|	}
_ZNK4pcpp17Asn1BooleanRecord11decodeValueEPKh:
  761|  1.84k|	{
  762|  1.84k|		if (m_ValueLength != 1)
  ------------------
  |  Branch (762:7): [True: 21, False: 1.82k]
  ------------------
  763|     21|		{
  764|     21|			throw std::invalid_argument("Cannot decode ASN.1 Boolean record, value length must be 1");
  765|     21|		}
  766|       |
  767|  1.82k|		m_Value = data[0] != 0;
  768|  1.82k|	}
_ZN4pcpp14Asn1NullRecordC2Ev:
  781|  1.62k|	Asn1NullRecord::Asn1NullRecord() : Asn1PrimitiveRecord(Asn1UniversalTagType::Null)
  782|  1.62k|	{
  783|  1.62k|		m_ValueLength = 0;
  784|  1.62k|		m_TotalLength = 2;
  785|  1.62k|	}
_ZN4pcpp20Asn1ObjectIdentifierC2EPKhm:
  788|  20.1k|	{
  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|  20.1k|		if (!data || dataLen == 0)
  ------------------
  |  Branch (792:7): [True: 0, False: 20.1k]
  |  Branch (792:16): [True: 5, False: 20.1k]
  ------------------
  793|      5|		{
  794|      5|			throw std::invalid_argument("Malformed OID: Not enough bytes for the first component");
  795|      5|		}
  796|       |
  797|  20.1k|		size_t currentByteIndex = 0;
  798|  20.1k|		std::vector<uint32_t> components;
  799|       |
  800|  20.1k|		uint8_t firstByte = data[currentByteIndex++];
  801|       |		// Decode the first byte: first_component * 40 + second_component
  802|  20.1k|		components.push_back(static_cast<uint32_t>(firstByte / 40));
  803|  20.1k|		components.push_back(static_cast<uint32_t>(firstByte % 40));
  804|       |
  805|  20.1k|		uint32_t currentComponentValue = 0;
  806|  20.1k|		bool componentStarted = false;
  807|       |
  808|       |		// Process remaining bytes using base-128 encoding
  809|   365k|		while (currentByteIndex < dataLen)
  ------------------
  |  Branch (809:10): [True: 345k, False: 20.1k]
  ------------------
  810|   345k|		{
  811|   345k|			uint8_t byte = data[currentByteIndex++];
  812|       |
  813|       |			// Shift previous bits left by 7 and append lower 7 bits
  814|   345k|			currentComponentValue = (currentComponentValue << 7) | (byte & 0x7f);
  815|   345k|			componentStarted = true;
  816|       |
  817|       |			// If the MSB is 0, this is the final byte of the current value
  818|   345k|			if ((byte & 0x80) == 0)
  ------------------
  |  Branch (818:8): [True: 303k, False: 42.2k]
  ------------------
  819|   303k|			{
  820|   303k|				components.push_back(currentComponentValue);
  821|   303k|				currentComponentValue = 0;
  822|   303k|				componentStarted = false;
  823|   303k|			}
  824|   345k|		}
  825|       |
  826|  20.1k|		if (componentStarted)
  ------------------
  |  Branch (826:7): [True: 23, False: 20.1k]
  ------------------
  827|     23|		{
  828|     23|			throw std::invalid_argument("Malformed OID: Incomplete component at end of data");
  829|     23|		}
  830|       |
  831|  20.1k|		m_Components = components;
  832|  20.1k|	}
_ZNK4pcpp20Asn1ObjectIdentifier8toStringEv:
  885|  17.7k|	{
  886|  17.7k|		if (m_Components.empty())
  ------------------
  |  Branch (886:7): [True: 0, False: 17.7k]
  ------------------
  887|      0|		{
  888|      0|			return "";
  889|      0|		}
  890|       |
  891|  17.7k|		std::ostringstream stream;
  892|  17.7k|		stream << m_Components[0];
  893|       |
  894|  95.9k|		for (size_t i = 1; i < m_Components.size(); ++i)
  ------------------
  |  Branch (894:22): [True: 78.1k, False: 17.7k]
  ------------------
  895|  78.1k|		{
  896|  78.1k|			stream << "." << m_Components[i];
  897|  78.1k|		}
  898|  17.7k|		return stream.str();
  899|  17.7k|	}
_ZNK4pcpp26Asn1ObjectIdentifierRecord11decodeValueEPKh:
  955|  20.1k|	{
  956|  20.1k|		m_Value = Asn1ObjectIdentifier(data, m_ValueLength);
  957|  20.1k|	}
_ZNK4pcpp14Asn1TimeRecord16getValueAsStringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_b:
  979|  1.79k|	{
  980|  1.79k|		auto value = getValue(timezone);
  981|  1.79k|		auto timeValue = std::chrono::system_clock::to_time_t(value);
  982|  1.79k|		auto tmValue = *std::gmtime(&timeValue);
  983|       |
  984|  1.79k|		std::ostringstream osstream;
  985|  1.79k|		osstream << std::put_time(&tmValue, format.c_str());
  986|       |
  987|  1.79k|		if (includeMilliseconds)
  ------------------
  |  Branch (987:7): [True: 0, False: 1.79k]
  ------------------
  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.79k|		if (timezone != "Z")
  ------------------
  |  Branch (997:7): [True: 0, False: 1.79k]
  ------------------
  998|      0|		{
  999|      0|			osstream << " UTC" << timezone;
 1000|      0|		}
 1001|       |
 1002|  1.79k|		return osstream.str();
 1003|  1.79k|	}
_ZN4pcpp14Asn1TimeRecord16validateTimezoneERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 1011|  14.8k|	{
 1012|  14.8k|		if (timezone == "Z")
  ------------------
  |  Branch (1012:7): [True: 13.9k, False: 865]
  ------------------
 1013|  13.9k|		{
 1014|  13.9k|			return;
 1015|  13.9k|		}
 1016|       |
 1017|    865|		if (timezone.length() != 5 || (timezone[0] != '+' && timezone[0] != '-') || !std::isdigit(timezone[1]) ||
  ------------------
  |  Branch (1017:7): [True: 61, False: 804]
  |  Branch (1017:34): [True: 524, False: 280]
  |  Branch (1017:56): [True: 0, False: 524]
  |  Branch (1017:79): [True: 16, False: 788]
  ------------------
 1018|    788|		    !std::isdigit(timezone[2]) || !std::isdigit(timezone[3]) || !std::isdigit(timezone[4]))
  ------------------
  |  Branch (1018:7): [True: 20, False: 768]
  |  Branch (1018:37): [True: 17, False: 751]
  |  Branch (1018:67): [True: 13, False: 738]
  ------------------
 1019|    127|		{
 1020|    127|			throw std::invalid_argument("Invalid timezone format. Use 'Z' or '+/-HHMM'.");
 1021|    127|		}
 1022|    865|	}
_ZN4pcpp14Asn1TimeRecord15adjustTimezonesERKNSt3__16chrono10time_pointINS2_12system_clockENS2_8durationIxNS1_5ratioILl1ELl1000000EEEEEEERKNS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEESJ_:
 1027|  7.47k|	{
 1028|  7.47k|		validateTimezone(fromTimezone);
 1029|  7.47k|		validateTimezone(toTimezone);
 1030|       |
 1031|  7.47k|		int fromOffsetSeconds = 0;
 1032|  7.47k|		if (fromTimezone != "Z")
  ------------------
  |  Branch (1032:7): [True: 738, False: 6.73k]
  ------------------
 1033|    738|		{
 1034|    738|			int fromSign = (fromTimezone[0] == '+') ? 1 : -1;
  ------------------
  |  Branch (1034:19): [True: 242, False: 496]
  ------------------
 1035|    738|			auto fromHours = std::stoi(fromTimezone.substr(1, 2));
 1036|    738|			auto fromMinutes = std::stoi(fromTimezone.substr(3, 2));
 1037|    738|			fromOffsetSeconds = fromSign * (fromHours * 3600 + fromMinutes * 60);
 1038|    738|		}
 1039|       |
 1040|  7.47k|		int toOffsetSeconds = 0;
 1041|  7.47k|		if (toTimezone != "Z")
  ------------------
  |  Branch (1041:7): [True: 0, False: 7.47k]
  ------------------
 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.47k|		return value + std::chrono::seconds(toOffsetSeconds - fromOffsetSeconds);
 1050|  7.47k|	}
_ZNK4pcpp17Asn1UtcTimeRecord11decodeValueEPKh:
 1065|  5.70k|	{
 1066|  5.70k|		std::string timeString(reinterpret_cast<const char*>(data), m_ValueLength);
 1067|       |
 1068|  5.70k|		if (timeString.empty())
  ------------------
  |  Branch (1068:7): [True: 3, False: 5.70k]
  ------------------
 1069|      3|		{
 1070|      3|			throw std::runtime_error("Failed to parse ASN.1 UTC time");
 1071|      3|		}
 1072|       |
 1073|  5.70k|		if (timeString.back() == 'Z')
  ------------------
  |  Branch (1073:7): [True: 2.50k, False: 3.20k]
  ------------------
 1074|  2.50k|		{
 1075|  2.50k|			timeString.pop_back();
 1076|  2.50k|		}
 1077|       |
 1078|  5.70k|		m_WithSeconds = true;
 1079|  5.70k|		if (timeString.size() == 10)
  ------------------
  |  Branch (1079:7): [True: 200, False: 5.50k]
  ------------------
 1080|    200|		{
 1081|    200|			m_WithSeconds = false;
 1082|    200|			timeString.append("00");
 1083|    200|		}
 1084|       |
 1085|  5.70k|		auto year = std::stoi(timeString.substr(0, 2));
 1086|  5.70k|		if (year <= 50)
  ------------------
  |  Branch (1086:7): [True: 5.23k, False: 463]
  ------------------
 1087|  5.23k|		{
 1088|  5.23k|			timeString.insert(0, "20");
 1089|  5.23k|		}
 1090|    463|		else
 1091|    463|		{
 1092|    463|			timeString.insert(0, "19");
 1093|    463|		}
 1094|       |
 1095|  5.70k|		std::tm tm = {};
 1096|  5.70k|		std::istringstream sstream(timeString);
 1097|  5.70k|		sstream >> std::get_time(&tm, "%Y%m%d%H%M%S");
 1098|       |
 1099|  5.70k|		if (sstream.fail())
  ------------------
  |  Branch (1099:7): [True: 38, False: 5.66k]
  ------------------
 1100|     38|		{
 1101|     38|			throw std::runtime_error("Failed to parse ASN.1 UTC time");
 1102|     38|		}
 1103|       |
 1104|  5.66k|		std::time_t timeValue = mkUtcTime(tm);
 1105|  5.66k|		m_Value = std::chrono::system_clock::from_time_t(timeValue);
 1106|  5.66k|	}
_ZNK4pcpp25Asn1GeneralizedTimeRecord11decodeValueEPKh:
 1138|  5.93k|	{
 1139|  5.93k|		std::string timeString(reinterpret_cast<const char*>(data), m_ValueLength);
 1140|       |
 1141|  5.93k|		if (timeString.empty())
  ------------------
  |  Branch (1141:7): [True: 6, False: 5.92k]
  ------------------
 1142|      6|		{
 1143|      6|			throw std::runtime_error("Failed to parse ASN.1 generalized time");
 1144|      6|		}
 1145|       |
 1146|  5.92k|		std::string timezone = "Z";
 1147|  5.92k|		auto timezonePos = timeString.find_first_of("+-");
 1148|  5.92k|		if (timeString.back() == 'Z')
  ------------------
  |  Branch (1148:7): [True: 515, False: 5.41k]
  ------------------
 1149|    515|		{
 1150|    515|			timeString.pop_back();
 1151|    515|		}
 1152|  5.41k|		else if (timezonePos != std::string::npos)
  ------------------
  |  Branch (1152:12): [True: 1.01k, False: 4.39k]
  ------------------
 1153|  1.01k|		{
 1154|  1.01k|			timezone = timeString.substr(timezonePos);
 1155|  1.01k|			timeString.erase(timezonePos);
 1156|  1.01k|		}
 1157|       |
 1158|  5.92k|		std::tm tm = {};
 1159|  5.92k|		std::istringstream sstream(timeString);
 1160|  5.92k|		sstream >> std::get_time(&tm, "%Y%m%d%H%M%S");
 1161|       |
 1162|  5.92k|		if (sstream.fail())
  ------------------
  |  Branch (1162:7): [True: 198, False: 5.73k]
  ------------------
 1163|    198|		{
 1164|    198|			throw std::runtime_error("Failed to parse ASN.1 generalized time");
 1165|    198|		}
 1166|       |
 1167|  5.73k|		size_t dotPos = timeString.find('.');
 1168|  5.73k|		int milliseconds = 0;
 1169|  5.73k|		if (dotPos != std::string::npos)
  ------------------
  |  Branch (1169:7): [True: 2.78k, False: 2.95k]
  ------------------
 1170|  2.78k|		{
 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.78k|			std::string millisecondsStr = timeString.substr(dotPos + 1);
 1174|  2.78k|			millisecondsStr.resize(3, '0');
 1175|  2.78k|			milliseconds = std::stoi(millisecondsStr);
 1176|  2.78k|		}
 1177|       |
 1178|  5.73k|		auto timeValue = mkUtcTime(tm);
 1179|       |
 1180|  5.73k|		m_Timezone = timezone;
 1181|  5.73k|		m_Value = adjustTimezones(
 1182|  5.73k|		    std::chrono::system_clock::from_time_t(timeValue) + std::chrono::milliseconds(milliseconds), timezone, "Z");
 1183|  5.73k|	}
_ZN4pcpp19Asn1BitStringRecord6BitSetC2EPKhm:
 1240|  4.13k|	Asn1BitStringRecord::BitSet::BitSet(const uint8_t* data, size_t numBits) : m_NumBits(numBits)
 1241|  4.13k|	{
 1242|  4.13k|		if (!data || !numBits)
  ------------------
  |  Branch (1242:7): [True: 0, False: 4.13k]
  |  Branch (1242:16): [True: 0, False: 4.13k]
  ------------------
 1243|      0|		{
 1244|      0|			throw std::invalid_argument("Provided data is null or num of bits is 0");
 1245|      0|		}
 1246|       |
 1247|  4.13k|		size_t requiredBytes = (m_NumBits + 7) / 8;
 1248|  4.13k|		m_Data.resize(requiredBytes);
 1249|  4.13k|		std::copy_n(data, requiredBytes, m_Data.begin());
 1250|  4.13k|	}
_ZNK4pcpp19Asn1BitStringRecord6BitSet8toStringEv:
 1259|    347|	{
 1260|    347|		std::string result;
 1261|    347|		result.reserve(m_Data.size() * 8);
 1262|    347|		for (const auto bs : m_Data)
  ------------------
  |  Branch (1262:22): [True: 2.94k, False: 347]
  ------------------
 1263|  2.94k|		{
 1264|  2.94k|			result += bs.to_string();
 1265|  2.94k|		}
 1266|    347|		result.resize(m_NumBits);
 1267|    347|		return result;
 1268|    347|	}
_ZNK4pcpp19Asn1BitStringRecord6BitSet7toBytesEv:
 1271|  3.79k|	{
 1272|  3.79k|		std::vector<uint8_t> result;
 1273|  3.79k|		result.reserve(m_Data.size());
 1274|  3.79k|		for (const auto& bs : m_Data)
  ------------------
  |  Branch (1274:23): [True: 244k, False: 3.79k]
  ------------------
 1275|   244k|		{
 1276|   244k|			result.push_back(static_cast<uint8_t>(bs.to_ulong()));
 1277|   244k|		}
 1278|       |
 1279|  3.79k|		return result;
 1280|  3.79k|	}
_ZNK4pcpp19Asn1BitStringRecord11decodeValueEPKh:
 1296|  4.78k|	{
 1297|       |		// A BitString value must contain at least the initial octet holding the number of unused bits
 1298|  4.78k|		if (m_ValueLength == 0)
  ------------------
  |  Branch (1298:7): [True: 5, False: 4.78k]
  ------------------
 1299|      5|		{
 1300|      5|			throw std::invalid_argument("Cannot decode ASN.1 BitString record, value is empty");
 1301|      5|		}
 1302|       |
 1303|  4.78k|		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.78k|		if (unusedBits > 7 || (m_ValueLength == 1 && unusedBits != 0))
  ------------------
  |  Branch (1306:7): [True: 15, False: 4.76k]
  |  Branch (1306:26): [True: 635, False: 4.13k]
  |  Branch (1306:48): [True: 6, False: 629]
  ------------------
 1307|     21|		{
 1308|     21|			throw std::invalid_argument("Cannot decode ASN.1 BitString record, invalid number of unused bits");
 1309|     21|		}
 1310|       |
 1311|  4.76k|		auto numBits = (m_ValueLength - 1) * 8 - unusedBits;
 1312|  4.76k|		if (numBits == 0)
  ------------------
  |  Branch (1312:7): [True: 629, False: 4.13k]
  ------------------
 1313|    629|		{
 1314|    629|			m_Value = BitSet();
 1315|    629|			return;
 1316|    629|		}
 1317|       |
 1318|  4.13k|		m_Value = BitSet(data + 1, numBits);
 1319|  4.13k|	}
Asn1Codec.cpp:_ZZN4pcpp17Asn1IntegerRecord6BigInt14initFromStringERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEENK3$_0clEc:
  615|   575k|		if (std::any_of(valueStr.begin(), valueStr.end(), [](char c) { return !std::isxdigit(c); }))
Asn1Codec.cpp:_ZZNK4pcpp21Asn1OctetStringRecord11decodeValueEPKhENK3$_0clEc:
  724|  30.6k|		m_IsPrintable = std::all_of(value, value + m_ValueLength, [](char c) { return isprint(0xff & c); });

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

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

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

