/* * msg.h - prototypes of msg-hv converting functions */ #ifndef _MSG_H #define _MSG_H #include #include #include #include #include typedef char* charp; /* * store an uint16_t into AV */ inline static int av_store_uint16_t(AV* av, int index, uint16_t val) { SV* sv = NULL; /* Perl has a hard time figuring out the an unsigned int is equal to INFINITE or NO_VAL since they are treated as signed ints so we will handle this here. */ if(val == INFINITE16) sv = newSViv(INFINITE); else if(val == NO_VAL16) sv = newSViv(NO_VAL); else sv = newSViv(val); if (av_store(av, (I32)index, sv) == NULL) { SvREFCNT_dec(sv); return -1; } return 0; } /* * store an uint32_t into AV */ inline static int av_store_uint32_t(AV* av, int index, uint32_t val) { SV* sv = NULL; /* Perl has a hard time figuring out the an unsigned int is equal to INFINITE or NO_VAL since they are treated as signed ints so we will handle this here. */ if(val == INFINITE) sv = newSViv(INFINITE); else if(val == NO_VAL) sv = newSViv(NO_VAL); else sv = newSViv(val); if (av_store(av, (I32)index, sv) == NULL) { SvREFCNT_dec(sv); return -1; } return 0; } /* * store an int into AV */ inline static int av_store_int(AV* av, int index, int val) { SV* sv = newSViv(val); if (av_store(av, (I32)index, sv) == NULL) { SvREFCNT_dec(sv); return -1; } return 0; } /* * store an uint32_t into AV */ inline static int av_store_int32_t(AV* av, int index, int32_t val) { return av_store_int(av, index, val); } /* * store a string into HV */ inline static int hv_store_charp(HV* hv, const char *key, charp val) { SV* sv = NULL; if (val) { sv = newSVpv(val, 0); if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) { SvREFCNT_dec(sv); return -1; } } return 0; } /* * store an unsigned 64b int into HV */ inline static int hv_store_uint64_t(HV* hv, const char *key, uint64_t val) { SV* sv = NULL; /* Perl has a hard time figuring out the an unsigned int is equal to INFINITE or NO_VAL since they are treated as signed ints so we will handle this here. */ if(val == (uint64_t)INFINITE) sv = newSViv(INFINITE); else if(val == (uint64_t)NO_VAL) sv = newSViv(NO_VAL); else sv = newSVuv(val); if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) { SvREFCNT_dec(sv); return -1; } return 0; } /* * store an unsigned 32b int into HV */ inline static int hv_store_uint32_t(HV* hv, const char *key, uint32_t val) { SV* sv = NULL; /* Perl has a hard time figuring out the an unsigned int is equal to INFINITE or NO_VAL since they are treated as signed ints so we will handle this here. */ if(val == INFINITE) sv = newSViv(INFINITE); else if(val == NO_VAL) sv = newSViv(NO_VAL); else sv = newSVuv(val); if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) { SvREFCNT_dec(sv); return -1; } return 0; } /* * store an unsigned 16b int into HV */ inline static int hv_store_uint16_t(HV* hv, const char *key, uint16_t val) { SV* sv = NULL; /* Perl has a hard time figuring out the an unsigned int is equal to INFINITE or NO_VAL since they are treated as signed ints so we will handle this here. */ if(val == INFINITE16) sv = newSViv(INFINITE); else if(val == NO_VAL16) sv = newSViv(NO_VAL); else sv = newSVuv(val); if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) { SvREFCNT_dec(sv); return -1; } return 0; } /* * store an unsigned 8b int into HV */ inline static int hv_store_uint8_t(HV* hv, const char *key, uint8_t val) { SV* sv = NULL; /* Perl has a hard time figuring out the an unsigned int is equal to INFINITE or NO_VAL since they are treated as signed ints so we will handle this here. */ if(val == INFINITE8) sv = newSViv(INFINITE); else if(val == NO_VAL8) sv = newSViv(NO_VAL); else sv = newSVuv(val); if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) { SvREFCNT_dec(sv); return -1; } return 0; } /* * store a uid_t into HV */ inline static int hv_store_uid_t(HV* hv, const char *key, uid_t val) { SV* sv = newSVuv(val); if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) { SvREFCNT_dec(sv); return -1; } return 0; } /* * store a signed int into HV */ inline static int hv_store_int(HV* hv, const char *key, int val) { SV* sv = newSViv(val); if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) { SvREFCNT_dec(sv); return -1; } return 0; } /* * store a double */ inline static int hv_store_double(HV* hv, const char *key, double val) { SV* sv = newSVnv(val); if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) { SvREFCNT_dec(sv); return -1; } return 0; } /* * store a signed 32b int into HV */ inline static int hv_store_int32_t(HV* hv, const char *key, int32_t val) { return hv_store_int(hv, key, val); } /* * store a bool into HV */ inline static int hv_store_bool(HV* hv, const char *key, bool val) { if (!key || hv_store(hv, key, (I32)strlen(key), (val ? &PL_sv_yes : &PL_sv_no), 0) == NULL) { return -1; } return 0; } /* * store a time_t into HV */ inline static int hv_store_time_t(HV* hv, const char *key, time_t val) { SV* sv = newSVuv(val); if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) { SvREFCNT_dec(sv); return -1; } return 0; } /* * store a SV into HV */ inline static int hv_store_sv(HV* hv, const char *key, SV* sv) { if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) { return -1; } return 0; } /* * store a PTR into HV * set classname to Nullch to avoid blessing the created SV. */ inline static int hv_store_ptr(HV* hv, const char *key, void* ptr, const char *classname) { SV* sv = NULL; /* * if ptr == NULL and we call sv_setref_pv() and store the sv in hv, * sv_isobject() will fail later when FETCH_PTR_FIELD. */ if(ptr) { sv = newSV(0); sv_setref_pv(sv, classname, ptr); if (!key || hv_store(hv, key, (I32)strlen(key), sv, 0) == NULL) { SvREFCNT_dec(sv); return -1; } } return 0; } #define SV2int(sv) SvIV(sv) #define SV2int32_t(sv) SvIV(sv) #define SV2uint64_t(sv) SvUV(sv) #define SV2uint32_t(sv) SvUV(sv) #define SV2uint16_t(sv) SvUV(sv) #define SV2uint8_t(sv) SvUV(sv) #define SV2time_t(sv) SvUV(sv) #define SV2charp(sv) SvPV_nolen(sv) #define SV2bool(sv) SvTRUE(sv) #if 0 /* Error on some 32-bit systems */ #define SV2ptr(sv) SvIV(SvRV(sv)) #else static inline void * SV2ptr(SV *sv) { void * ptr = (void *) ((intptr_t) SvIV(SvRV(sv))); return ptr; } #endif #define FETCH_FIELD(hv, ptr, field, type, required) \ do { \ SV** svp; \ if ( (svp = hv_fetch (hv, #field, strlen(#field), FALSE)) ) { \ ptr->field = (type) (SV2##type (*svp)); \ } else if (required) { \ Perl_warn (aTHX_ "Required field \"" #field "\" missing in HV"); \ return -1; \ } \ } while (0) #define FETCH_PTR_FIELD(hv, ptr, field, classname, required) \ do { \ SV** svp; \ if ( (svp = hv_fetch (hv, #field, strlen(#field), FALSE)) ) { \ if (classname) { \ if (! ( sv_isobject(*svp) && \ SvTYPE(SvRV(*svp)) == SVt_PVMG && \ sv_derived_from(*svp, classname)) ) { \ Perl_croak(aTHX_ "field %s is not an object of %s", #field, classname); \ } \ } \ ptr->field = (typeof(ptr->field)) (SV2ptr (*svp)); \ } else if (required) { \ Perl_warn (aTHX_ "Required field \"" #field "\" missing in HV"); \ return -1; \ } \ } while (0) #define STORE_FIELD(hv, ptr, field, type) \ do { \ if (hv_store_##type(hv, #field, ptr->field)) { \ Perl_warn (aTHX_ "Failed to store field \"" #field "\""); \ return -1; \ } \ } while (0) #define STORE_PTR_FIELD(hv, ptr, field, classname) \ do { \ if (hv_store_ptr(hv, #field, ptr->field, classname)) { \ Perl_warn (aTHX_ "Failed to store field \"" #field "\""); \ return -1; \ } \ } while (0) #endif /* _MSG_H */