/** * MR_BITMASK type saving handler. Look up type descriptor and save as * stringified bitmask value or as integer otherwise. * @param ptrdes descriptor of the saved field * @param bitmask_or_delimiter delimiter for OR statement * @return stringified enum value */ char * mr_stringify_bitmask (mr_ptrdes_t * ptrdes, char * bitmask_or_delimiter) { int i, count; uint64_t value = 0; char * str = NULL; mr_td_t * tdp = mr_get_td_by_name (ptrdes->fd.type); /* look up for type descriptor */ /* check whether type descriptor was found */ if (NULL == tdp) { MR_MESSAGE (MR_LL_WARN, MR_MESSAGE_NO_TYPE_DESCRIPTOR, ptrdes->fd.type); return (mr_stringify_uint (ptrdes)); } if (MR_TYPE_ENUM != tdp->mr_type) { MR_MESSAGE (MR_LL_WARN, MR_MESSAGE_TYPE_NOT_ENUM, ptrdes->fd.type); return (mr_stringify_uint (ptrdes)); } value = mr_get_enum_value (tdp, ptrdes->data); if (0 == value) { mr_fd_t * fdp = mr_get_enum_by_value (tdp, value); return (MR_STRDUP (fdp && fdp->name.str ? fdp->name.str : "0")); } /* decompose value on bitmask */ count = tdp->fields.size / sizeof (tdp->fields.data[0]); for (i = 0; i < count; ++i) { mr_fd_t * fdp = tdp->fields.data[i].fdp; if ((value & fdp->param.enum_value) && !(~value & fdp->param.enum_value)) { if (NULL == str) str = MR_STRDUP (fdp->name.str); else str = mr_decompose_bitmask_add (str, bitmask_or_delimiter, fdp->name.str); if (NULL == str) break; value &= ~fdp->param.enum_value; } if (0 == value) break; } if (value != 0) { /* save non-matched part as integer */ mr_ptrdes_t ptrdes = { .data = &value, }; char * number = mr_stringify_uint64_t (&ptrdes); if (number != NULL) { str = mr_decompose_bitmask_add (str, bitmask_or_delimiter, number); MR_FREE (number); } MR_MESSAGE (MR_LL_WARN, MR_MESSAGE_SAVE_BITMASK, value); }
int xml2_load (xmlNodePtr node, mr_ra_mr_ptrdes_t * ptrs) { int idx = mr_add_ptr_to_list (ptrs); xmlNodePtr node_; char * content = NULL; char * property = NULL; if (idx < 0) return (idx); /* handle REF_IDX property */ property = (char*)xmlGetProp (node, (unsigned char*)MR_REF_IDX); if (property) { if (1 != sscanf (property, "%" SCNd32, &ptrs->ra.data[idx].idx)) MR_MESSAGE (MR_LL_WARN, MR_MESSAGE_READ_REF, property); ptrs->ra.data[idx].flags.is_referenced = MR_TRUE; xmlFree (property); } /* handle REF property */ property = (char*)xmlGetProp (node, (unsigned char*)MR_REF); if (property) { if (1 != sscanf (property, "%" SCNd32, &ptrs->ra.data[idx].ref_idx)) MR_MESSAGE (MR_LL_WARN, MR_MESSAGE_READ_REF, property); xmlFree (property); } /* handle REF_CONTENT property */ property = (char*)xmlGetProp (node, (unsigned char*)MR_REF_CONTENT); if (property) { if (1 != sscanf (property, "%" SCNd32, &ptrs->ra.data[idx].ref_idx)) MR_MESSAGE (MR_LL_WARN, MR_MESSAGE_READ_REF, property); else ptrs->ra.data[idx].flags.is_content_reference = MR_TRUE; xmlFree (property); } property = (char*)xmlGetProp (node, (unsigned char*)MR_ISNULL); if (property) { ptrs->ra.data[idx].flags.is_null= MR_TRUE; xmlFree (property); } for (node_ = node->xmlChildrenNode; node_ && !content; node_ = node_->next) content = (char*)XML_GET_CONTENT (node_); ptrs->ra.data[idx].mr_value.value_type = MR_VT_UNKNOWN; ptrs->ra.data[idx].mr_value.vt_string = content ? MR_STRDUP (content) : MR_STRDUP (""); ptrs->ra.data[idx].fd.name.str = MR_STRDUP ((char*)node->name); /* loop on subnodes */ for (node_ = node->xmlChildrenNode; node_; node_ = node_->next) if (XML_ELEMENT_NODE == node_->type) mr_add_child (idx, xml2_load (node_, ptrs), ptrs); return (idx); }
/** * MR_TYPE_FUNC & MR_TYPE_FUNC_TYPE type saving handler. * @param idx an index of node in ptrs * @param ptrs resizeable array with pointers descriptors * @return stringified function name */ static char * scm_save_func (int idx, mr_ra_mr_ptrdes_t * ptrs) { if (MR_TRUE == ptrs->ra.data[idx].flags.is_null) return (MR_STRDUP (MR_SCM_FALSE)); else return (mr_stringify_func (&ptrs->ra.data[idx])); }
/** * MR_STRING type saving handler. Save string. * @param idx an index of node in ptrs * @param ptrs resizeable array with pointers descriptors * @return string value */ static char * scm_save_string (int idx, mr_ra_mr_ptrdes_t * ptrs) { char * str = *(char**)ptrs->ra.data[idx].data; if ((NULL == str) || (ptrs->ra.data[idx].ref_idx >= 0)) return (MR_STRDUP (MR_SCM_FALSE)); else return (scm_quote_string (str, '"')); }
/** * MR_STRING type saving handler. Save string as XML node. * @param idx an index of node in ptrs * @param ptrs resizeable array with pointers descriptors * @return XML escaped string content */ static char * xml1_save_string (int idx, mr_ra_mr_ptrdes_t * ptrs) { char * str = *(char**)ptrs->ra[idx].data; if ((NULL == str) || (ptrs->ra[idx].ref_idx >= 0)) return (MR_STRDUP ("")); else return (xml_quote_string (str)); }
/** * MR_CHAR type saving handler. Stringify char. * @param idx an index of node in ptrs * @param ptrs resizeable array with pointers descriptors * @return stringified character value */ static char * xml_save_char (int idx, mr_ra_mr_ptrdes_t * ptrs) { char str[MR_CHAR_TO_STRING_BUF_SIZE] = " "; str[0] = *(char*)ptrs->ra[idx].data; if (isprint (str[0])) return (xml_quote_string (str)); sprintf (str, CINIT_CHAR_QUOTE, (int)(unsigned char)str[0]); return (MR_STRDUP (str)); }
/** * Save as string pointer descriptor * @param ptrdes descriptor of the saved field * @return stringified pointer value */ char * mr_stringify_func (mr_ptrdes_t * ptrdes) { if (MR_TRUE == ptrdes->flags.is_null) return (MR_STRDUP ("")); else { void * func = *(void**)ptrdes->data; char str[MR_INT_TO_STRING_BUF_SIZE]; #ifdef HAVE_LIBDL Dl_info info; memset (&info, 0, sizeof (info)); if (0 != dladdr (func, &info)) { if (info.dli_sname && (func == info.dli_saddr)) /* found some non-null name and address matches */ return (MR_STRDUP (info.dli_sname)); } #endif /* HAVE_LIBDL */ sprintf (str, "%p", func); return (MR_STRDUP (str)); } }
/** * MR_CHAR type saving handler. Stringify char. * @param idx an index of node in ptrs * @param ptrs resizeable array with pointers descriptors * @return stringified char */ static char * scm_save_char (int idx, mr_ra_mr_ptrdes_t * ptrs) { char c = *(char*)ptrs->ra.data[idx].data; char str[] = "#\\x00"; if (isprint (c)) { str[2] = c; str[3] = 0; } else sprintf (str, "#\\x%02x", (int)(unsigned char)c); return (MR_STRDUP (str)); }
/** * Stringify integer value. * @param ptrdes descriptor of the saved field * @return stringified enum value */ static char * mr_stringify_uint (mr_ptrdes_t * ptrdes) { switch (ptrdes->fd.size) { case sizeof (uint8_t): return (mr_stringify_uint8_t (ptrdes)); case sizeof (uint16_t): return (mr_stringify_uint16_t (ptrdes)); case sizeof (uint32_t): return (mr_stringify_uint32_t (ptrdes)); case sizeof (uint64_t): return (mr_stringify_uint64_t (ptrdes)); default: MR_MESSAGE (MR_LL_WARN, MR_MESSAGE_INT_OF_UNKNOWN_SIZE, ptrdes->fd.size); return (MR_STRDUP ("0")); } }
/** * MR_ENUM type saving handler. Look up enum descriptor and save as * stringified enum value or as integer otherwise. * @param ptrdes descriptor of the saved field * @return stringified enum value */ char * mr_stringify_enum (mr_ptrdes_t * ptrdes) { mr_td_t * tdp = mr_get_td_by_name (ptrdes->fd.type); /* look up for type descriptor */ /* check whether type descriptor was found */ if (NULL == tdp) MR_MESSAGE (MR_LL_WARN, MR_MESSAGE_NO_TYPE_DESCRIPTOR, ptrdes->fd.type); else if (MR_TYPE_ENUM != tdp->mr_type) MR_MESSAGE (MR_LL_WARN, MR_MESSAGE_TYPE_NOT_ENUM, ptrdes->fd.type); else { int64_t value = mr_get_enum_value (tdp, ptrdes->data); mr_fd_t * fdp = mr_get_enum_by_value (tdp, value); if (fdp && fdp->name.str) return (MR_STRDUP (fdp->name.str)); MR_MESSAGE (MR_LL_WARN, MR_MESSAGE_SAVE_ENUM, value, tdp->type.str, ptrdes->fd.name.str); ptrdes->fd.size = tdp->size_effective; } /* save as integer otherwise */ return (mr_stringify_uint (ptrdes)); }
/** * MR_POINTER type saving handler. Save pointer as a string. * @param idx an index of node in ptrs * @param ptrs resizeable array with pointers descriptors * @return stringified pointer */ static char * scm_save_pointer (int idx, mr_ra_mr_ptrdes_t * ptrs) { return (MR_STRDUP (MR_SCM_FALSE)); }
static scm_save_handler_t ext_scm_save_handler[] = { [MR_TYPE_EXT_ARRAY] = scm_save_empty, [MR_TYPE_EXT_RARRAY_DATA] = scm_save_pointer, [MR_TYPE_EXT_POINTER] = scm_save_pointer, }; /** * Public function. Save scheduler. Save any object as a string. * @param ptrs resizeable array with pointers descriptors * @return stringified representation of object */ char * scm_save (mr_ra_mr_ptrdes_t * ptrs) { mr_rarray_t mr_ra_str = { .data = MR_STRDUP (""), .size = sizeof (""), .alloc_size = sizeof (""), .ext = { NULL }, }; int idx = 0; if (NULL == mr_ra_str.data) return (NULL); while (idx >= 0) { mr_fd_t * fdp = &ptrs->ra.data[idx].fd; int level = MR_LIMIT_LEVEL (ptrs->ra.data[idx].level); int named_node = MR_SCM_UNNAMED_FIELDS; int parent = ptrs->ra.data[idx].parent; char * content = NULL; int in_comment = 0; if (parent >= 0)
[MR_TYPE_FUNC] = xml_save_func, [MR_TYPE_FUNC_TYPE] = xml_save_func, [MR_TYPE_UNION] = xml_save_empty, [MR_TYPE_ANON_UNION] = xml_save_empty, [MR_TYPE_NAMED_ANON_UNION] = xml_save_empty, }; /** * Public function. Save scheduler. Save any object as a string. * @param ptrs resizeable array with pointers descriptors * @return stringified representation of object */ char * xml1_save (mr_ra_mr_ptrdes_t * ptrs) { mr_rarray_t mr_ra_str = { .data = MR_STRDUP (MR_XML1_DOCUMENT_HEADER), .size = sizeof (MR_XML1_DOCUMENT_HEADER), .alloc_size = sizeof (MR_XML1_DOCUMENT_HEADER), .ext = { NULL }, }; int idx = 0; if (NULL == mr_ra_str.data) return (NULL); while (idx >= 0) { int level = 0; int empty_tag = !0; char * content = NULL; mr_fd_t * fdp = &ptrs->ra.data[idx].fd; /* route saving handler */ if ((fdp->mr_type_ext < MR_TYPE_EXT_LAST) && ext_xml_save_handler[fdp->mr_type_ext]) content = ext_xml_save_handler[fdp->mr_type_ext] (idx, ptrs);
/** * dummy stub for compaund types * @param idx an index of node in ptrs * @param ptrs resizeable array with pointers descriptors * @return empty string */ static char * xml_save_empty (int idx, mr_ra_mr_ptrdes_t * ptrs) { return (MR_STRDUP ("")); }
[MR_TYPE_FUNC_TYPE] = xml_save_func, [MR_TYPE_UNION] = xml_save_empty, [MR_TYPE_ANON_UNION] = xml_save_empty, [MR_TYPE_NAMED_ANON_UNION] = xml_save_empty, }; /** * Public function. Save scheduler. Save any object as a string. * @param ptrs resizeable array with pointers descriptors * @return stringified representation of object */ char * xml1_save (mr_ra_mr_ptrdes_t * ptrs) { mr_rarray_t mr_ra_str = { .data = { MR_STRDUP (MR_XML1_DOCUMENT_HEADER) }, .MR_SIZE = sizeof (MR_XML1_DOCUMENT_HEADER), .type = "char", .alloc_size = sizeof (MR_XML1_DOCUMENT_HEADER), }; int idx = 0; if (NULL == mr_ra_str.data.ptr) return (NULL); while (idx >= 0) { int level = 0; int empty_tag = !0; char * content = NULL; mr_fd_t * fdp = &ptrs->ra[idx].fd;
/** * Dummy stub for compaund types. * @param idx an index of node in ptrs * @param ptrs resizeable array with pointers descriptors * @return empty string */ static char * scm_save_empty (int idx, mr_ra_mr_ptrdes_t * ptrs) { return (MR_STRDUP (MR_SCM_EMPTY)); }
static char * scm_save_bool (int idx, mr_ra_mr_ptrdes_t * ptrs) { return (*(bool*)ptrs->ra.data[idx].data ? MR_STRDUP (MR_SCM_TRUE) : MR_STRDUP (MR_SCM_FALSE)); }
char * mr_output_format_bool (mr_ptrdes_t * ptrdes) { return (*(bool*)ptrdes->data ? MR_STRDUP ("TRUE") : MR_STRDUP ("FALSE")); }