@@ -14,6 +14,7 @@ MRB_END_DECL
1414#include <mruby/variable.h>
1515#include <mruby/error.h>
1616#include <mruby/ned.h>
17+ #include <mruby/str_constantize.h>
1718
1819#include <stdlib.h>
1920#include <stdint.h>
@@ -33,6 +34,8 @@ MRB_END_DECL
3334 #endif
3435#endif
3536
37+ #define CBOR_TAG_CLASS UINT32_C(49999)
38+
3639typedef struct {
3740 const uint8_t * base ;
3841 const uint8_t * p ;
@@ -627,6 +630,16 @@ decode_symbol(mrb_state *mrb, Reader* r, mrb_value src, mrb_value sharedrefs)
627630 return mrb_nil_value ();
628631}
629632
633+ static mrb_value
634+ decode_class (mrb_state * mrb , Reader * r , mrb_value src , mrb_value sharedrefs )
635+ {
636+ mrb_value v = decode_value (mrb , r , src , sharedrefs );
637+ if (likely (mrb_string_p (v )))
638+ return mrb_str_constantize (mrb , v );
639+ mrb_raise (mrb , E_TYPE_ERROR , "invalid payload for tag 49999 (expected text string)" );
640+ return mrb_undef_value ();
641+ }
642+
630643// ============================================================================
631644// Master decode with depth protection
632645// ============================================================================
@@ -673,6 +686,10 @@ decode_value(mrb_state* mrb, Reader* r, mrb_value src, mrb_value sharedrefs)
673686 result = decode_symbol (mrb , r , src , sharedrefs );
674687 goto done ;
675688 }
689+ if (mrb_integer_p (tag ) && (uint64_t )mrb_integer (tag ) == CBOR_TAG_CLASS ) {
690+ result = decode_class (mrb , r , src , sharedrefs );
691+ goto done ;
692+ }
676693
677694 {
678695 mrb_value reg = cbor_tag_registry (mrb );
@@ -999,6 +1016,20 @@ encode_string(CborWriter* w, mrb_value str)
9991016 cbor_writer_write (w , (const uint8_t * )p , (size_t )blen );
10001017}
10011018
1019+ static void
1020+ encode_class (CborWriter * w , mrb_value obj )
1021+ {
1022+ mrb_state * mrb = w -> mrb ;
1023+ mrb_value name = mrb_class_path (mrb , mrb_class_ptr (obj ));
1024+
1025+ if (likely (mrb_string_p (name ))) {
1026+ encode_len (w , 6 , CBOR_TAG_CLASS );
1027+ encode_string (w , name );
1028+ } else {
1029+ mrb_raise (mrb , E_ARGUMENT_ERROR , "cannot encode anonymous class/module" );
1030+ }
1031+ }
1032+
10021033static void
10031034encode_simple (CborWriter * w , mrb_value obj )
10041035{
@@ -1088,6 +1119,8 @@ encode_value(CborWriter* w, mrb_value obj)
10881119#ifdef MRB_USE_BIGINT
10891120 case MRB_TT_BIGINT : encode_bignum (w , obj ); break ;
10901121#endif
1122+ case MRB_TT_CLASS :
1123+ case MRB_TT_MODULE : encode_class (w , obj ); break ;
10911124 default : {
10921125 mrb_value rev = cbor_tag_rev_registry (mrb );
10931126 mrb_value klass = mrb_obj_value (mrb_class (mrb , obj ));
@@ -1822,6 +1855,8 @@ cbor_register_tag_impl(mrb_state *mrb, mrb_value tag_v, mrb_value klass)
18221855 mrb_raisef (mrb , E_ARGUMENT_ERROR ,
18231856 "tag %v is reserved for internal CBOR use" , tag_v );
18241857 }
1858+ if (unlikely (mrb_integer_p (tag_v ) && (uint64_t )mrb_integer (tag_v ) == CBOR_TAG_CLASS ))
1859+ mrb_raise (mrb , E_ARGUMENT_ERROR , "tag 49999 is reserved for internal CBOR use" );
18251860
18261861 {
18271862 struct RClass * kp = mrb_class_ptr (klass );
0 commit comments