/****************************************************************************** **函数名称: invtd_search_list_trav **功 能: 构建搜索应答项 **输入参数: ** doc: 搜索列表 ** xml: 应答结果树 **输出参数: NONE **返 回: 0:Succ !0:Fail **实现描述: **注意事项: **作 者: # Qifeng.zou # 2016.05.04 01:33:38 # ******************************************************************************/ static int invtd_search_list_trav(invt_word_doc_t *doc, xml_tree_t *xml) { xml_node_t *root, *item; char freq[SRCH_SEG_FREQ_LEN]; root = xml->root->child; snprintf(freq, sizeof(freq), "%d", doc->freq); item = xml_add_child(xml, root, "ITEM", NULL); if (NULL == item) { log_error(xml->log, "Add child failed! url:%s freq:%d", doc->url.str, doc->freq); return -1; } xml_add_attr(xml, item, "URL", doc->url.str); xml_add_attr(xml, item, "FREQ", freq); return 0; }
/****************************************************************************** **函数名称: invtd_search_no_data_hdl **功 能: 无数据的应答处理 **输入参数: ** xml: 应答结果树 **输出参数: NONE **返 回: 0:Succ !0:Fail **实现描述: **注意事项: **作 者: # Qifeng.zou # 2016.05.01 01:49:01 # ******************************************************************************/ static int invtd_search_no_data_hdl(xml_tree_t *xml) { xml_node_t *root, *item; char freq[SRCH_SEG_FREQ_LEN]; xml_add_attr(xml, xml->root, "CODE", SRCH_CODE_NO_DATA); /* 无数据 */ snprintf(freq, sizeof(freq), "%d", 0); root = xml->root->child; item = xml_add_child(xml, root, "ITEM", NULL); if (NULL == item) { xml_destroy(xml); return -1; } xml_add_attr(xml, item, "URL", "Sorry, Didn't search anything!"); xml_add_attr(xml, item, "FREQ", freq); return 0; }
/****************************************************************************** **函数名称: invtd_search_query **功 能: 从倒排表中搜索关键字 **输入参数: ** ctx: 上下文 ** req: 搜索请求信息 **输出参数: NONE **返 回: 搜索结果(以XML树组织) **实现描述: 从倒排表中查询结果,并将结果以XML树组织. **注意事项: 完成发送后, 必须记得释放XML树的所有内存 **作 者: # Qifeng.zou # 2016.01.04 17:35:35 # ******************************************************************************/ static xml_tree_t *invtd_search_query(invtd_cntx_t *ctx, mesg_search_req_t *req) { xml_opt_t opt; xml_tree_t *xml; xml_node_t *root; invt_dic_word_t *word; memset(&opt, 0, sizeof(opt)); /* > 构建XML树 */ opt.pool = NULL; opt.alloc = mem_alloc; opt.dealloc = mem_dealloc; opt.log = ctx->log; xml = xml_empty(&opt); if (NULL == xml) { log_error(ctx->log, "Create xml failed!"); return NULL; } root = xml_set_root(xml, "SEARCH-RSP"); do { pthread_rwlock_rdlock(&ctx->invtab_lock); /* > 搜索倒排表 */ word = (invt_dic_word_t *)invtab_query(ctx->invtab, req->words); if (NULL == word || NULL == word->doc_list) { pthread_rwlock_unlock(&ctx->invtab_lock); log_warn(ctx->log, "Didn't search anything! words:%s", req->words); if (invtd_search_no_data_hdl(xml)) { break; } return xml; } /* > 构建搜索结果 */ if (list_trav(word->doc_list, (trav_cb_t)invtd_search_list_trav, (void *)xml)) { pthread_rwlock_unlock(&ctx->invtab_lock); log_error(ctx->log, "Contribute respone list failed! words:%s", req->words); break; } pthread_rwlock_unlock(&ctx->invtab_lock); xml_add_attr(xml, root, "CODE", SRCH_CODE_OK); /* 设置返回码 */ return xml; } while(0); xml_destroy(xml); return NULL; }
/****************************************************************************** **函数名称: xml_add_node **功 能: 给节点添加属性或孩子节点 **输入参数: ** node: 父节点 ** name: 新节点名 ** value: 新节点值 ** type: 新节点类型. 其取值范围xml_node_type_t **输出参数: **返 回: 新增节点地址 **实现描述: **注意事项: **作 者: # Qifeng.zou # 2013.06.12 # ******************************************************************************/ xml_node_t *xml_add_node(xml_tree_t *xml, xml_node_t *node, const char *name, const char *value, int type) { switch(type) { case XML_NODE_ATTR: { return xml_add_attr(xml, node, name, value); } case XML_NODE_ROOT: case XML_NODE_CHILD: { return xml_add_child(xml, node, name, value); } } return NULL; }
/****************************************************************************** **函数名称: mon_srch_set_body **功 能: 设置搜索报体 **输入参数: ** word: 搜索信息 ** size: 搜索请求的最大报体 **输出参数: NONE ** body: 搜索请求的报体 **返 回: 报体实际长度 **实现描述: **注意事项: **作 者: # Qifeng.zou # 2015.12.27 03:01:48 # ******************************************************************************/ static int mon_srch_set_body(const char *words, char *body, int size) { int len; xml_opt_t opt; xml_tree_t *xml; xml_node_t *node; memset(&opt, 0, sizeof(opt)); /* > 创建XML树 */ opt.log = NULL; opt.pool = NULL; opt.alloc = mem_alloc; opt.dealloc = mem_dealloc; xml = xml_creat_empty(&opt); if (NULL == xml) { fprintf(stderr, "Create xml failed!"); return -1; } node = xml_add_child(xml, xml->root, "SEARCH", NULL); xml_add_attr(xml, node, "WORDS", words); /* > 计算XML长度 */ len = xml_pack_len(xml); if (len >= size) { xml_destroy(xml); return -1; } /* > 输出XML至缓存 */ len = xml_spack(xml, body); xml_destroy(xml); return len; }
/** Process tag */ static void proc_in_tag( PPOS* ppos /**< input stream position */ ) { XML_ATTR* attr; int c; int empty = FALSE; char* name; char* value; assert(ppos != NULL); assert(ppos->state == STATE_IN_TAG); c = skip_space(ppos); if ((c == '/') || (c == '>') || (c == EOF)) { if (c == '/') { empty = TRUE; c = getsymbol(ppos); } if (c == EOF) { xml_error(ppos, "Unexpected EOF while in a tag"); ppos->state = STATE_ERROR; } if (c == '>') { ppos->state = STATE_PCDATA; if (empty && ! pop_pstack(ppos)) ppos->state = STATE_ERROR; } else { xml_error(ppos, "Expected tag end marker '>'"); ppos->state = STATE_ERROR; } } else { ungetsymbol(ppos, c); if ((name = get_name(ppos)) == NULL) { xml_error(ppos, "No name for attribute"); ppos->state = STATE_ERROR; } else { c = skip_space(ppos); if ((c != '=') || ((value = get_attrval(ppos)) == NULL)) { xml_error(ppos, "Missing attribute value"); ppos->state = STATE_ERROR; BMSfreeMemoryArray(&name); } else { if (NULL == (attr = xml_new_attr(name, value))) { xml_error(ppos, "Can't create new attribute"); ppos->state = STATE_ERROR; } else { xml_add_attr(top_pstack(ppos), attr); } BMSfreeMemoryArray(&name); BMSfreeMemoryArray(&value); } } } }
/** Parse file */ XML_NODE* xml_process( const char* filename /**< XML file name */ ) { PPOS ppos; XML_NODE* node = NULL; XML_ATTR* attr; int result = FALSE; char* myfilename; ALLOC_FALSE( BMSduplicateMemoryArray(&myfilename, filename, strlen(filename) + 5) ); #ifdef WITH_ZLIB if (access(filename, R_OK) != 0) { strcat(myfilename, ".gz"); /* If .gz also does not work, revert to the old name * to get a better error message. */ if (access(myfilename, R_OK) != 0) strcpy(myfilename, filename); } #endif ppos.fp = FOPEN(myfilename, "r"); if ( ppos.fp == NULL ) perror(myfilename); else { ppos.filename = myfilename; ppos.buf[0] = '\0'; ppos.pos = 0; ppos.lineno = 1; ppos.nextsym = 0; ppos.lastsym = 0; ppos.state = STATE_BEFORE; ppos.top = NULL; node = xml_new_node("#ROOT", ppos.lineno); if ( node == NULL ) { xml_error(&ppos, "Can't create new node"); } else { attr = xml_new_attr("filename", myfilename); if ( attr == NULL ) xml_error(&ppos, "Can't create new attribute"); else { xml_add_attr(node, attr); /* push root node on stack and start to process */ if ( push_pstack(&ppos, node) ) { result = xml_parse(&ppos); clear_pstack(&ppos); } } } if ( ! result && (node != NULL) ) { xml_errmsg(&ppos, "Parsing error, processing stopped", TRUE, __FILE__, __LINE__); xml_free_node(node); node = NULL; } if (FCLOSE(ppos.fp)) perror(myfilename); } BMSfreeMemoryArray(&myfilename); return node; }
/****************************************************************************** **函数名称: invtd_search_word_query **功 能: 从倒排表中搜索关键字 **输入参数: ** ctx: 上下文 ** req: 搜索请求信息 **输出参数: NONE **返 回: 搜索结果(以XML树组织) **实现描述: 从倒排表中查询结果,并将结果以XML树组织. **注意事项: 完成发送后, 必须记得释放XML树的所有内存 **作 者: # Qifeng.zou # 2016.01.04 17:35:35 # ******************************************************************************/ static xml_tree_t *invtd_search_word_query(invtd_cntx_t *ctx, mesg_search_word_req_t *req) { int idx; xml_opt_t opt; xml_tree_t *xml; xml_node_t *root, *item; list_node_t *node; invt_word_doc_t *doc; invt_dic_word_t *word; char freq[SRCH_SEG_FREQ_LEN]; memset(&opt, 0, sizeof(opt)); /* > 构建XML树 */ opt.pool = NULL; opt.alloc = mem_alloc; opt.dealloc = mem_dealloc; opt.log = ctx->log; xml = xml_creat_empty(&opt); if (NULL == xml) { log_error(ctx->log, "Create xml failed!"); return NULL; } root = xml_set_root(xml, "SEARCH-RSP"); if (NULL == root) { log_error(ctx->log, "Set xml root failed!"); goto GOTO_SEARCH_ERR; } /* > 搜索倒排表 */ pthread_rwlock_rdlock(&ctx->invtab_lock); word = invtab_query(ctx->invtab, req->words); if (NULL == word || NULL == word->doc_list) { pthread_rwlock_unlock(&ctx->invtab_lock); log_warn(ctx->log, "Didn't search anything! words:%s", req->words); goto GOTO_SEARCH_NO_DATA; } /* > 构建搜索结果 */ idx = 0; node = word->doc_list->head; for (; NULL!=node; node=node->next, ++idx) { doc = (invt_word_doc_t *)node->data; snprintf(freq, sizeof(freq), "%d", doc->freq); item = xml_add_child(xml, root, "ITEM", NULL); if (NULL == item) { goto GOTO_SEARCH_ERR; } xml_add_attr(xml, item, "URL", doc->url.str); xml_add_attr(xml, item, "FREQ", freq); } pthread_rwlock_unlock(&ctx->invtab_lock); xml_add_attr(xml, root, "CODE", SRCH_CODE_OK); /* 设置返回码 */ return xml; GOTO_SEARCH_ERR: /* 异常错误处理 */ xml_destroy(xml); return NULL; GOTO_SEARCH_NO_DATA: /* 搜索结果为空的处理 */ xml_add_attr(xml, root, "CODE", SRCH_CODE_NO_DATA); /* 无数据 */ snprintf(freq, sizeof(freq), "%d", 0); item = xml_add_child(xml, root, "ITEM", NULL); if (NULL == item) { goto GOTO_SEARCH_ERR; } xml_add_attr(xml, item, "URL", "Sorry, Didn't search anything!"); xml_add_attr(xml, item, "FREQ", freq); return xml; }
/******************************************************************** * FUNCTION mgr_rpc_send_request * * Send an <rpc> request to the agent on the specified session * non-blocking send, reply function will be called when * one is received or a timeout occurs * * INPUTS: * scb == session control block * req == request to send * rpyfn == reply callback function * * RETURNS: * status *********************************************************************/ status_t mgr_rpc_send_request (ses_cb_t *scb, mgr_rpc_req_t *req, mgr_rpc_cbfn_t rpyfn) { xml_msg_hdr_t msg; xml_attr_t *attr; status_t res; boolean anyout; xmlns_id_t nc_id; #ifdef DEBUG if (!scb || !req || !rpyfn) { return SET_ERROR(ERR_INTERNAL_PTR); } #endif #ifdef MGR_HELLO_DEBUG log_debug2("\nmgr sending RPC request %s on session %d", req->msg_id, scb->sid); #endif anyout = FALSE; xml_msg_init_hdr(&msg); nc_id = xmlns_nc_id(); /* make sure the message-id attribute is not already present */ attr = xml_find_attr_q(&req->attrs, 0, NCX_EL_MESSAGE_ID); if (attr) { dlq_remove(attr); xml_free_attr(attr); } /* setup the prefix map with the NETCONF (and maybe NCX) namespace */ res = xml_msg_build_prefix_map(&msg, &req->attrs, FALSE, (req->data->nsid == xmlns_ncx_id())); /* add the message-id attribute */ if (res == NO_ERR) { res = xml_add_attr(&req->attrs, 0, NCX_EL_MESSAGE_ID, req->msg_id); } /* set perf timestamp in case response timing active */ gettimeofday(&req->perfstarttime, NULL); /* send the <?xml?> directive */ if (res == NO_ERR) { res = ses_start_msg(scb); } /* start the <rpc> element */ if (res == NO_ERR) { anyout = TRUE; xml_wr_begin_elem_ex(scb, &msg, 0, nc_id, NCX_EL_RPC, &req->attrs, ATTRQ, 0, START); } /* send the method and parameters */ if (res == NO_ERR) { xml_wr_full_val(scb, &msg, req->data, NCX_DEF_INDENT); } /* finish the <rpc> element */ if (res == NO_ERR) { xml_wr_end_elem(scb, &msg, nc_id, NCX_EL_RPC, 0); } /* finish the message */ if (anyout) { ses_finish_msg(scb); } if (res == NO_ERR) { req->replycb = rpyfn; add_request(scb, req); } xml_msg_clean_hdr(&msg); return res; } /* mgr_rpc_send_request */