/* This implements the `svn_ra_neon__startelem_cb_t' prototype. */ static svn_error_t * gls_start_element(int *elem, void *userdata, int parent_state, const char *ns, const char *ln, const char **atts) { get_location_segments_baton_t *baton = userdata; const svn_ra_neon__xml_elm_t *elm; /* Just skip unknown elements. */ if (! ((elm = svn_ra_neon__lookup_xml_elem(gls_report_elements, ns, ln)))) { *elem = NE_XML_DECLINE; return SVN_NO_ERROR; } if (parent_state == ELEM_get_location_segments_report && elm->id == ELEM_location_segment) { const char *rev_str; svn_revnum_t range_start = SVN_INVALID_REVNUM; svn_revnum_t range_end = SVN_INVALID_REVNUM; const char *path = NULL; path = svn_xml_get_attr_value("path", atts); rev_str = svn_xml_get_attr_value("range-start", atts); if (rev_str) range_start = SVN_STR_TO_REV(rev_str); rev_str = svn_xml_get_attr_value("range-end", atts); if (rev_str) range_end = SVN_STR_TO_REV(rev_str); if (SVN_IS_VALID_REVNUM(range_start) && SVN_IS_VALID_REVNUM(range_end)) { svn_location_segment_t *segment = apr_pcalloc(baton->subpool, sizeof(*segment)); segment->path = path; segment->range_start = range_start; segment->range_end = range_end; SVN_ERR(baton->receiver(segment, baton->receiver_baton, baton->subpool)); svn_pool_clear(baton->subpool); } else { return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Expected valid revision range")); } } *elem = elm->id; return SVN_NO_ERROR; }
static svn_error_t * start_gls(svn_ra_serf__xml_parser_t *parser, void *userData, svn_ra_serf__dav_props_t name, const char **attrs) { gls_context_t *gls_ctx = userData; if ((! gls_ctx->inside_report) && strcmp(name.name, "get-location-segments-report") == 0) { gls_ctx->inside_report = TRUE; } else if (gls_ctx->inside_report && strcmp(name.name, "location-segment") == 0) { const char *rev_str; svn_revnum_t range_start = SVN_INVALID_REVNUM; svn_revnum_t range_end = SVN_INVALID_REVNUM; const char *path = NULL; path = svn_xml_get_attr_value("path", attrs); rev_str = svn_xml_get_attr_value("range-start", attrs); if (rev_str) range_start = SVN_STR_TO_REV(rev_str); rev_str = svn_xml_get_attr_value("range-end", attrs); if (rev_str) range_end = SVN_STR_TO_REV(rev_str); if (SVN_IS_VALID_REVNUM(range_start) && SVN_IS_VALID_REVNUM(range_end)) { svn_location_segment_t *segment = apr_pcalloc(gls_ctx->subpool, sizeof(*segment)); segment->path = path; segment->range_start = range_start; segment->range_end = range_end; SVN_ERR(gls_ctx->receiver(segment, gls_ctx->receiver_baton, gls_ctx->subpool)); svn_pool_clear(gls_ctx->subpool); } else { return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Expected valid revision range")); } } return SVN_NO_ERROR; }
/* This implements the `svn_ra_neon__startelem_cb_t' prototype. */ static svn_error_t * gloc_start_element(int *elem, void *userdata, int parent_state, const char *ns, const char *ln, const char **atts) { get_locations_baton_t *baton = userdata; const svn_ra_neon__xml_elm_t *elm; elm = svn_ra_neon__lookup_xml_elem(gloc_report_elements, ns, ln); /* Just skip unknown elements. */ if (!elm) { *elem = NE_XML_DECLINE; return SVN_NO_ERROR; } if (parent_state == ELEM_get_locations_report && elm->id == ELEM_location) { svn_revnum_t rev = SVN_INVALID_REVNUM; const char *path; const char *r; r = svn_xml_get_attr_value("rev", atts); if (r) rev = SVN_STR_TO_REV(r); path = svn_xml_get_attr_value("path", atts); if (SVN_IS_VALID_REVNUM(rev) && path) apr_hash_set(baton->hash, apr_pmemdup(baton->pool, &rev, sizeof(rev)), sizeof(rev), apr_pstrdup(baton->pool, path)); else return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Expected a valid revnum and path")); } *elem = elm->id; return SVN_NO_ERROR; }
static svn_error_t * start_element(svn_ra_serf__xml_parser_t *parser, svn_ra_serf__dav_props_t name, const char **attrs, apr_pool_t *scratch_pool) { iprops_context_t *iprops_ctx = parser->user_data; iprops_state_e state; state = parser->state->current_state; if (state == NONE && strcmp(name.name, SVN_DAV__INHERITED_PROPS_REPORT) == 0) { svn_ra_serf__xml_push_state(parser, IPROPS_REPORT); } else if (state == IPROPS_REPORT && strcmp(name.name, SVN_DAV__IPROP_ITEM) == 0) { svn_stringbuf_setempty(iprops_ctx->curr_path); svn_stringbuf_setempty(iprops_ctx->curr_propname); svn_stringbuf_setempty(iprops_ctx->curr_propval); iprops_ctx->curr_prop_val_encoding = NULL; iprops_ctx->curr_iprop = NULL; svn_ra_serf__xml_push_state(parser, IPROPS_ITEM); } else if (state == IPROPS_ITEM && strcmp(name.name, SVN_DAV__IPROP_PROPVAL) == 0) { const char *prop_val_encoding = svn_xml_get_attr_value("encoding", attrs); iprops_ctx->curr_prop_val_encoding = apr_pstrdup(iprops_ctx->pool, prop_val_encoding); svn_ra_serf__xml_push_state(parser, IPROPS_PROPVAL); } else if (state == IPROPS_ITEM && strcmp(name.name, SVN_DAV__IPROP_PATH) == 0) { svn_ra_serf__xml_push_state(parser, IPROPS_PATH); } else if (state == IPROPS_ITEM && strcmp(name.name, SVN_DAV__IPROP_PROPNAME) == 0) { svn_ra_serf__xml_push_state(parser, IPROPS_PROPNAME); } else if (state == IPROPS_ITEM && strcmp(name.name, SVN_DAV__IPROP_PROPVAL) == 0) { svn_ra_serf__xml_push_state(parser, IPROPS_PROPVAL); } return SVN_NO_ERROR; }
static svn_error_t * start_getloc(svn_ra_serf__xml_parser_t *parser, void *userData, svn_ra_serf__dav_props_t name, const char **attrs) { loc_context_t *loc_ctx = userData; if (!loc_ctx->state && strcmp(name.name, "get-locations-report") == 0) { push_state(loc_ctx, REPORT); } else if (loc_ctx->state && loc_ctx->state->state == REPORT && strcmp(name.name, "location") == 0) { svn_revnum_t rev = SVN_INVALID_REVNUM; const char *revstr, *path; revstr = svn_xml_get_attr_value("rev", attrs); if (revstr) { rev = SVN_STR_TO_REV(revstr); } path = svn_xml_get_attr_value("path", attrs); if (SVN_IS_VALID_REVNUM(rev) && path) { apr_hash_set(loc_ctx->paths, apr_pmemdup(loc_ctx->pool, &rev, sizeof(rev)), sizeof(rev), apr_pstrdup(loc_ctx->pool, path)); } } return SVN_NO_ERROR; }
/* This implements the `svn_ra_neon__startelm_cb_t' prototype. */ static svn_error_t * getlocks_start_element(int *elem, void *userdata, int parent_state, const char *ns, const char *ln, const char **atts) { get_locks_baton_t *baton = userdata; const svn_ra_neon__xml_elm_t *elm; elm = svn_ra_neon__lookup_xml_elem(getlocks_report_elements, ns, ln); /* Just skip unknown elements. */ if (!elm) { *elem = NE_XML_DECLINE; return SVN_NO_ERROR; } if (elm->id == ELEM_lock) { if (parent_state != ELEM_get_locks_report) return UNEXPECTED_ELEMENT(ns, ln); else /* allocate a new svn_lock_t in the permanent pool */ baton->current_lock = svn_lock_create(baton->pool); } else if (elm->id == ELEM_lock_path || elm->id == ELEM_lock_token || elm->id == ELEM_lock_owner || elm->id == ELEM_lock_comment || elm->id == ELEM_lock_creationdate || elm->id == ELEM_lock_expirationdate) { const char *encoding; if (parent_state != ELEM_lock) return UNEXPECTED_ELEMENT(ns, ln); /* look for any incoming encodings on these elements. */ encoding = svn_xml_get_attr_value("encoding", atts); if (encoding) baton->encoding = apr_pstrdup(baton->scratchpool, encoding); } *elem = elm->id; return SVN_NO_ERROR; }
/* * This implements the `svn_ra_neon__xml_startelm_cb' prototype. */ static svn_error_t * log_start_element(int *elem, void *baton, int parent, const char *nspace, const char *name, const char **atts) { const char *copyfrom_path, *copyfrom_revstr; svn_revnum_t copyfrom_rev; struct log_baton *lb = baton; static const svn_ra_neon__xml_elm_t log_report_elements[] = { { SVN_XML_NAMESPACE, "log-report", ELEM_log_report, 0 }, { SVN_XML_NAMESPACE, "log-item", ELEM_log_item, 0 }, { SVN_XML_NAMESPACE, "date", ELEM_log_date, SVN_RA_NEON__XML_CDATA }, { SVN_XML_NAMESPACE, "added-path", ELEM_added_path, SVN_RA_NEON__XML_CDATA }, { SVN_XML_NAMESPACE, "deleted-path", ELEM_deleted_path, SVN_RA_NEON__XML_CDATA }, { SVN_XML_NAMESPACE, "modified-path", ELEM_modified_path, SVN_RA_NEON__XML_CDATA }, { SVN_XML_NAMESPACE, "replaced-path", ELEM_replaced_path, SVN_RA_NEON__XML_CDATA }, { SVN_XML_NAMESPACE, "revprop", ELEM_revprop, SVN_RA_NEON__XML_CDATA }, { "DAV:", SVN_DAV__VERSION_NAME, ELEM_version_name, SVN_RA_NEON__XML_CDATA }, { "DAV:", "creator-displayname", ELEM_creator_displayname, SVN_RA_NEON__XML_CDATA }, { "DAV:", "comment", ELEM_comment, SVN_RA_NEON__XML_CDATA }, { SVN_XML_NAMESPACE, "has-children", ELEM_has_children, SVN_RA_NEON__XML_CDATA }, { NULL } }; const svn_ra_neon__xml_elm_t *elm = svn_ra_neon__lookup_xml_elem(log_report_elements, nspace, name); *elem = elm ? elm->id : SVN_RA_NEON__XML_DECLINE; if (!elm) return SVN_NO_ERROR; switch (elm->id) { case ELEM_creator_displayname: case ELEM_log_date: case ELEM_version_name: case ELEM_added_path: case ELEM_replaced_path: case ELEM_deleted_path: case ELEM_modified_path: case ELEM_revprop: case ELEM_comment: lb->want_cdata = lb->cdata; svn_stringbuf_setempty(lb->cdata); if (elm->id == ELEM_revprop) { lb->revprop_name = apr_pstrdup(lb->subpool, svn_xml_get_attr_value("name", atts)); if (lb->revprop_name == NULL) return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Missing name attr in revprop element")); } break; case ELEM_has_children: lb->log_entry->has_children = TRUE; break; default: lb->want_cdata = NULL; break; } switch (elm->id) { case ELEM_added_path: case ELEM_replaced_path: case ELEM_deleted_path: case ELEM_modified_path: lb->this_path_item = apr_pcalloc(lb->subpool, sizeof(*(lb->this_path_item))); lb->this_path_item->copyfrom_rev = SVN_INVALID_REVNUM; /* See documentation for `svn_repos_node_t' in svn_repos.h, and `svn_log_changed_path_t' in svn_types.h, for more about these action codes. */ if ((elm->id == ELEM_added_path) || (elm->id == ELEM_replaced_path)) { lb->this_path_item->action = (elm->id == ELEM_added_path) ? 'A' : 'R'; copyfrom_path = svn_xml_get_attr_value("copyfrom-path", atts); copyfrom_revstr = svn_xml_get_attr_value("copyfrom-rev", atts); if (copyfrom_path && copyfrom_revstr && (SVN_IS_VALID_REVNUM (copyfrom_rev = SVN_STR_TO_REV(copyfrom_revstr)))) { lb->this_path_item->copyfrom_path = apr_pstrdup(lb->subpool, copyfrom_path); lb->this_path_item->copyfrom_rev = copyfrom_rev; } } else if (elm->id == ELEM_deleted_path) { lb->this_path_item->action = 'D'; } else { lb->this_path_item->action = 'M'; } break; default: lb->this_path_item = NULL; break; } return SVN_NO_ERROR; }
static svn_error_t * start_element(int *elem, void *baton, int parent_state, const char *nspace, const char *elt_name, const char **atts) { replay_baton_t *rb = baton; const svn_ra_neon__xml_elm_t *elm = svn_ra_neon__lookup_xml_elem(editor_report_elements, nspace, elt_name); if (! elm) { *elem = NE_XML_DECLINE; return SVN_NO_ERROR; } if (parent_state == ELEM_root) { /* If we're at the root of the tree, the element has to be the editor * report itself. */ if (elm->id != ELEM_editor_report) return UNEXPECTED_ELEMENT(nspace, elt_name); } else if (parent_state != ELEM_editor_report) { /* If we're not at the root, our parent has to be the editor report, * since we don't actually nest any elements. */ return UNEXPECTED_ELEMENT(nspace, elt_name); } switch (elm->id) { case ELEM_target_revision: { const char *crev = svn_xml_get_attr_value("rev", atts); if (! crev) return MISSING_ATTR(nspace, elt_name, "rev"); else return rb->editor->set_target_revision(rb->edit_baton, SVN_STR_TO_REV(crev), rb->pool); } break; case ELEM_open_root: { const char *crev = svn_xml_get_attr_value("rev", atts); if (! crev) return MISSING_ATTR(nspace, elt_name, "rev"); else { apr_pool_t *subpool = svn_pool_create(rb->pool); void *dir_baton; SVN_ERR(rb->editor->open_root(rb->edit_baton, SVN_STR_TO_REV(crev), subpool, &dir_baton)); push_dir(rb, dir_baton, "", subpool); } } break; case ELEM_delete_entry: { const char *path = svn_xml_get_attr_value("name", atts); const char *crev = svn_xml_get_attr_value("rev", atts); if (! path) return MISSING_ATTR(nspace, elt_name, "name"); else if (! crev) return MISSING_ATTR(nspace, elt_name, "rev"); else { dir_item_t *di = &TOP_DIR(rb); SVN_ERR(rb->editor->delete_entry(path, SVN_STR_TO_REV(crev), di->baton, di->pool)); } } break; case ELEM_open_directory: case ELEM_add_directory: { const char *crev = svn_xml_get_attr_value("rev", atts); const char *name = svn_xml_get_attr_value("name", atts); if (! name) return MISSING_ATTR(nspace, elt_name, "name"); else { dir_item_t *parent = &TOP_DIR(rb); apr_pool_t *subpool = svn_pool_create(parent->pool); svn_revnum_t rev; void *dir_baton; if (crev) rev = SVN_STR_TO_REV(crev); else rev = SVN_INVALID_REVNUM; if (elm->id == ELEM_open_directory) SVN_ERR(rb->editor->open_directory(name, parent->baton, rev, subpool, &dir_baton)); else if (elm->id == ELEM_add_directory) { const char *cpath = svn_xml_get_attr_value("copyfrom-path", atts); crev = svn_xml_get_attr_value("copyfrom-rev", atts); if (crev) rev = SVN_STR_TO_REV(crev); else rev = SVN_INVALID_REVNUM; SVN_ERR(rb->editor->add_directory(name, parent->baton, cpath, rev, subpool, &dir_baton)); } else SVN_ERR_MALFUNCTION(); push_dir(rb, dir_baton, name, subpool); } } break; case ELEM_open_file: case ELEM_add_file: { const char *path = svn_xml_get_attr_value("name", atts); svn_revnum_t rev; dir_item_t *parent = &TOP_DIR(rb); if (! path) return MISSING_ATTR(nspace, elt_name, "name"); svn_pool_clear(parent->file_pool); if (elm->id == ELEM_add_file) { const char *cpath = svn_xml_get_attr_value("copyfrom-path", atts); const char *crev = svn_xml_get_attr_value("copyfrom-rev", atts); if (crev) rev = SVN_STR_TO_REV(crev); else rev = SVN_INVALID_REVNUM; SVN_ERR(rb->editor->add_file(path, parent->baton, cpath, rev, parent->file_pool, &rb->file_baton)); } else { const char *crev = svn_xml_get_attr_value("rev", atts); if (crev) rev = SVN_STR_TO_REV(crev); else rev = SVN_INVALID_REVNUM; SVN_ERR(rb->editor->open_file(path, parent->baton, rev, parent->file_pool, &rb->file_baton)); } } break; case ELEM_apply_textdelta: if (! rb->file_baton) return svn_error_create (SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Got apply-textdelta element without preceding " "add-file or open-file")); else { const char *checksum = svn_xml_get_attr_value("checksum", atts); SVN_ERR(rb->editor->apply_textdelta(rb->file_baton, checksum, TOP_DIR(rb).file_pool, &rb->whandler, &rb->whandler_baton)); rb->svndiff_decoder = svn_txdelta_parse_svndiff (rb->whandler, rb->whandler_baton, TRUE, TOP_DIR(rb).file_pool); rb->base64_decoder = svn_base64_decode(rb->svndiff_decoder, TOP_DIR(rb).file_pool); } break; case ELEM_close_file: if (! rb->file_baton) return svn_error_create (SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Got close-file element without preceding " "add-file or open-file")); else { const char *checksum = svn_xml_get_attr_value("checksum", atts); SVN_ERR(rb->editor->close_file(rb->file_baton, checksum, TOP_DIR(rb).file_pool)); rb->file_baton = NULL; } break; case ELEM_close_directory: if (rb->dirs->nelts == 0) return svn_error_create (SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Got close-directory element without ever opening " "a directory")); else { dir_item_t *di = &TOP_DIR(rb); SVN_ERR(rb->editor->close_directory(di->baton, di->pool)); svn_pool_destroy(di->pool); apr_array_pop(rb->dirs); } break; case ELEM_change_file_prop: case ELEM_change_dir_prop: { const char *name = svn_xml_get_attr_value("name", atts); if (! name) return MISSING_ATTR(nspace, elt_name, "name"); else { svn_pool_clear(rb->prop_pool); if (svn_xml_get_attr_value("del", atts)) rb->prop_accum = NULL; else rb->prop_accum = svn_stringbuf_create("", rb->prop_pool); rb->prop_name = apr_pstrdup(rb->prop_pool, name); } } break; } *elem = elm->id; return SVN_NO_ERROR; }
static int start_err_element(void *baton, int parent, const char *nspace, const char *name, const char **atts) { const svn_ra_neon__xml_elm_t *elm = svn_ra_neon__lookup_xml_elem(error_elements, nspace, name); int acc = elm ? validate_error_elements(parent, elm->id) : SVN_RA_NEON__XML_DECLINE; error_parser_baton_t *b = baton; svn_error_t **err = &(b->tmp_err); if (acc < 1) /* ! > 0 */ return acc; switch (elm->id) { case ELEM_svn_error: { /* allocate the svn_error_t. Hopefully the value will be overwritten by the <human-readable> tag, or even someday by a <D:failed-precondition/> tag. */ *err = svn_error_create(APR_EGENERAL, NULL, _("General svn error from server")); break; } case ELEM_human_readable: { /* get the errorcode attribute if present */ const char *errcode_str = svn_xml_get_attr_value("errcode", /* ### make constant in some mod_dav header? */ atts); if (errcode_str && *err) { apr_int64_t val; svn_error_t *err2; err2 = svn_cstring_atoi64(&val, errcode_str); if (err2) { svn_error_clear(err2); break; } (*err)->apr_err = (apr_status_t)val; } break; } default: break; } switch (elm->id) { case ELEM_human_readable: b->want_cdata = b->cdata; svn_stringbuf_setempty(b->want_cdata); break; default: b->want_cdata = NULL; break; } return elm->id; }