@@ -124,9 +124,9 @@ ly_ctx_ht_pattern_free_cb(void *val_p)
124124{
125125 struct ly_pattern_ht_rec * val = val_p ;
126126
127- if (val -> serialized_pattern ) {
127+ if (val -> pcode ) {
128128 /* free the pcode */
129- pcre2_serialize_free (val -> serialized_pattern );
129+ pcre2_code_free (val -> pcode );
130130 }
131131}
132132
@@ -488,160 +488,54 @@ ly_ctx_data_del(const struct ly_ctx *ctx)
488488 pthread_rwlock_unlock (& ly_ctx_data_rwlock );
489489}
490490
491- /**
492- * @brief Serialize a PCRE2 compiled code.
493- *
494- * @param[in] pcode PCRE2 compiled code to serialize.
495- * @param[out] serialized_code Pointer to the serialized code, must be freed by the caller.
496- * @return LY_SUCCESS on success, LY_EINT on serialization error.
497- */
498- static LY_ERR
499- ly_pcode_serialize (const pcre2_code * pcode , uint8_t * * serialized_code )
500- {
501- int r ;
502- uint8_t * ser_code = NULL ;
503- PCRE2_SIZE ser_code_size = 0 ;
504-
505- * serialized_code = NULL ;
506-
507- r = pcre2_serialize_encode (& pcode , 1 , & ser_code , & ser_code_size , NULL );
508- if (r < 0 ) {
509- PCRE2_UCHAR err_msg [LY_PCRE2_MSG_LIMIT ] = {0 };
510-
511- pcre2_get_error_message (r , err_msg , LY_PCRE2_MSG_LIMIT );
512- LOGERR (NULL , LY_EINT , "PCRE2 compiled code serialization failed (%s)." , err_msg );
513- return LY_EINT ;
514- }
515-
516- * serialized_code = ser_code ;
517- return LY_SUCCESS ;
518- }
519-
520- /**
521- * @brief Deserialize a PCRE2 compiled code from its serialized form.
522- *
523- * This code does not have to be recompiled, it can be used directly.
524- *
525- * @param[in] serialized_code Serialized PCRE2 compiled code.
526- * @param[out] pcode Pointer to the deserialized PCRE2 code, must be freed by the caller.
527- * @return LY_SUCCESS on success, LY_EINT on deserialization error.
528- */
529- static LY_ERR
530- ly_pcode_deserialize (const uint8_t * serialized_code , pcre2_code * * pcode )
531- {
532- int r ;
533- pcre2_code * pcode_tmp = NULL ;
534-
535- * pcode = NULL ;
536-
537- /* deserialize the pcode */
538- r = pcre2_serialize_decode (& pcode_tmp , 1 , serialized_code , NULL );
539- if (r < 0 ) {
540- PCRE2_UCHAR err_msg [LY_PCRE2_MSG_LIMIT ] = {0 };
541-
542- pcre2_get_error_message (r , err_msg , LY_PCRE2_MSG_LIMIT );
543- LOGERR (NULL , LY_EINT , "PCRE2 compiled code deserialization failed (%s)." , err_msg );
544- return LY_EINT ;
545- }
546-
547- * pcode = pcode_tmp ;
548- return LY_SUCCESS ;
549- }
550-
551- /**
552- * @brief Get a compiled PCRE2 pattern code from the context's pattern hash table.
553- *
554- * @param[in] ctx Context to get the pattern code from.
555- * @param[in] pattern Pattern string to search for.
556- * @param[in] pattern_ht Pattern hash table to search in.
557- * @param[out] pcode Optional compiled pattern code, must be freed by the caller.
558- * If NULL, the function only checks if the pattern exists in the hash table.
559- * @return LY_SUCCESS on success, LY_ENOTFOUND if the pattern was not found,
560- * other LY_ERR values on error.
561- */
562- static LY_ERR
563- _ly_ctx_get_pattern_code (const struct ly_ctx * ctx , const char * pattern ,
564- struct ly_ht * pattern_ht , pcre2_code * * pcode )
565- {
566- LY_ERR rc = LY_SUCCESS ;
567- uint32_t hash ;
568- struct ly_pattern_ht_rec rec = {0 }, * found_rec = NULL ;
569-
570- assert (ctx && pattern && pattern_ht );
571-
572- /* use the pattern as a key */
573- rec .pattern = pattern ;
574- rec .serialized_pattern = NULL ;
575- hash = lyht_hash (pattern , strlen (pattern ));
576-
577- /* try to find the record */
578- LY_CHECK_GOTO (rc = lyht_find (pattern_ht , & rec , hash , (void * * )& found_rec ), cleanup );
579-
580- if (pcode ) {
581- /* found it, deserialize the pcode */
582- LY_CHECK_GOTO (rc = ly_pcode_deserialize (found_rec -> serialized_pattern , pcode ), cleanup );
583- }
584-
585- cleanup :
586- return rc ;
587- }
588-
589491LY_ERR
590- ly_ctx_get_pattern_code (const struct ly_ctx * ctx , const char * pattern , pcre2_code * * pcode )
492+ ly_ctx_get_or_compile_pattern_code (const struct ly_ctx * ctx , const char * pattern , const pcre2_code * * pcode )
591493{
592494 LY_ERR rc = LY_SUCCESS ;
593495 struct ly_ctx_shared_data * ctx_data ;
496+ struct ly_pattern_ht_rec rec = {0 }, * found_rec = NULL ;
497+ uint32_t hash ;
498+ pcre2_code * pcode_tmp = NULL ;
594499
595- ctx_data = ly_ctx_shared_data_get (ctx );
596- LY_CHECK_RET (!ctx_data , LY_EINT );
500+ assert (ctx && pattern );
597501
598- rc = _ly_ctx_get_pattern_code (ctx , pattern , ctx_data -> pattern_ht , pcode );
599- if (rc ) {
600- LOGERR (ctx , rc , "Failed to get pattern code for \"%s\"." , pattern );
502+ if (pcode ) {
503+ * pcode = NULL ;
601504 }
602505
603- return rc ;
604- }
605-
606- LY_ERR
607- ly_ctx_compile_and_cache_pattern_code (const struct ly_ctx * ctx , const char * pattern )
608- {
609- LY_ERR rc = LY_SUCCESS ;
610- struct ly_ctx_shared_data * ctx_data ;
611- uint8_t * serialized_pcode = NULL ;
612- pcre2_code * pcode_tmp = NULL ;
613- struct ly_pattern_ht_rec rec = {0 };
614- uint32_t hash ;
615-
616506 ctx_data = ly_ctx_shared_data_get (ctx );
617507 LY_CHECK_RET (!ctx_data , LY_EINT );
618508
619- /* check for existing pattern code */
620- rc = _ly_ctx_get_pattern_code (ctx , pattern , ctx_data -> pattern_ht , NULL );
621- LY_CHECK_GOTO (rc && (rc != LY_ENOTFOUND ), cleanup );
622- if (!rc ) {
623- /* pattern is already compiled and stored, nothing to do */
509+ /* try to find the pattern code in the pattern ht */
510+ hash = lyht_hash (pattern , strlen (pattern ));
511+ rec .pattern = pattern ;
512+ if (!lyht_find (ctx_data -> pattern_ht , & rec , hash , (void * * )& found_rec )) {
513+ /* found it, return it */
514+ if (pcode ) {
515+ * pcode = found_rec -> pcode ;
516+ }
624517 goto cleanup ;
625518 }
626519
627- /* record not found, we need to compile the pattern and insert it */
520+ /* didnt find it, need to compile it */
628521 LY_CHECK_GOTO (rc = lys_compile_type_pattern_check (ctx , pattern , & pcode_tmp ), cleanup );
629522
630- /* serialize the pcode */
631- LY_CHECK_GOTO (rc = ly_pcode_serialize (pcode_tmp , & serialized_pcode ), cleanup );
632-
633- /* insert the record */
523+ /* store the compiled pattern code in the hash table */
634524 hash = lyht_hash (pattern , strlen (pattern ));
635525 rec .pattern = pattern ;
636- rec .serialized_pattern = serialized_pcode ;
526+ rec .pcode = pcode_tmp ;
637527 LY_CHECK_GOTO (rc = lyht_insert_no_check (ctx_data -> pattern_ht , & rec , hash , NULL ), cleanup );
638528
639- /* dont free the serialized pcode, it is now owned by the record in the hash table */
640- serialized_pcode = NULL ;
529+ if (pcode ) {
530+ * pcode = pcode_tmp ;
531+ pcode_tmp = NULL ;
532+ }
641533
642534cleanup :
643- pcre2_code_free (pcode_tmp );
644- pcre2_serialize_free (serialized_pcode );
535+ if (rc ) {
536+ /* only free the pcode if we failed, because it belongs to the hash table */
537+ pcre2_code_free (pcode_tmp );
538+ }
645539 return rc ;
646540}
647541
0 commit comments