static svn_error_t * end_element(void *baton, int state, const char *nspace, const char *elt_name) { struct mergeinfo_baton *mb = baton; const svn_ra_neon__xml_elm_t *elm = svn_ra_neon__lookup_xml_elem(mergeinfo_report_elements, nspace, elt_name); if (! elm) return UNEXPECTED_ELEMENT(nspace, elt_name); if (elm->id == ELEM_mergeinfo_item) { if (mb->curr_info && mb->curr_path) { svn_mergeinfo_t path_mergeinfo; const char *path; SVN_ERR_ASSERT(mb->curr_path->data); path = apr_pstrdup(mb->pool, mb->curr_path->data); SVN_ERR((mb->err = svn_mergeinfo_parse(&path_mergeinfo, mb->curr_info->data, mb->pool))); /* Correct for naughty servers that send "relative" paths with leading slashes! */ apr_hash_set(mb->catalog, path[0] == '/' ? path + 1 : path, APR_HASH_KEY_STRING, path_mergeinfo); } } 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) { struct mergeinfo_baton *mb = baton; const svn_ra_neon__xml_elm_t *elm = svn_ra_neon__lookup_xml_elem(mergeinfo_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_mergeinfo_report) return UNEXPECTED_ELEMENT(nspace, elt_name); } if (elm->id == ELEM_mergeinfo_item) { svn_stringbuf_setempty(mb->curr_info); svn_stringbuf_setempty(mb->curr_path); } SVN_ERR(mb->err); *elem = elm->id; return SVN_NO_ERROR; }
static svn_error_t * start_element(int *elem, void *baton, int parent, const char *nspace, const char *name, const char **atts) { propfind_ctx_t *pc = baton; const svn_ra_neon__xml_elm_t *elm = svn_ra_neon__lookup_xml_elem(propfind_elements, nspace, name); *elem = elm ? validate_element(parent, elm->id) : SVN_RA_NEON__XML_DECLINE; if (*elem < 1) /* not a valid element */ return SVN_NO_ERROR; svn_stringbuf_setempty(pc->cdata); *elem = elm ? elm->id : ELEM_unknown; switch (*elem) { case ELEM_response: if (pc->rsrc) return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL); /* Create a new resource. */ pc->rsrc = apr_pcalloc(pc->pool, sizeof(*(pc->rsrc))); pc->rsrc->pool = pc->pool; pc->rsrc->propset = apr_hash_make(pc->pool); pc->status = 0; break; case ELEM_propstat: pc->status = 0; break; case ELEM_href: /* Remember this <href>'s parent so that when we close this tag, we know to whom the URL assignment belongs. Could be the resource itself, or one of the properties: ELEM_baseline_coll, ELEM_checked_in, ELEM_vcc: */ pc->rsrc->href_parent = pc->last_open_id; break; case ELEM_collection: pc->rsrc->is_collection = 1; break; case ELEM_unknown: /* these are our user-visible properties, presumably. */ pc->encoding = ne_xml_get_attr(pc->parser, atts, SVN_DAV_PROP_NS_DAV, "encoding"); if (pc->encoding) pc->encoding = apr_pstrdup(pc->pool, pc->encoding); break; default: /* nothing to do for these */ break; } /* Remember the last tag we opened. */ pc->last_open_id = *elem; return SVN_NO_ERROR; }
/* 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; }
/* 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; }
/* Implements svn_ra_neon__startelm_cb_t. */ static svn_error_t * start_207_element(int *elem, void *baton, int parent, const char *nspace, const char *name, const char **atts) { multistatus_baton_t *b = baton; const svn_ra_neon__xml_elm_t *elm = svn_ra_neon__lookup_xml_elem(multistatus_elements, nspace, name); *elem = elm ? validate_element(parent, elm->id) : SVN_RA_NEON__XML_DECLINE; if (parent == ELEM_prop) { svn_stringbuf_setempty(b->propname); if (strcmp(nspace, SVN_DAV_PROP_NS_SVN) == 0) svn_stringbuf_set(b->propname, SVN_PROP_PREFIX); else if (strcmp(nspace, "DAV:") == 0) svn_stringbuf_set(b->propname, "DAV:"); svn_stringbuf_appendcstr(b->propname, name); } if (*elem < 1) /* ! > 0 */ return SVN_NO_ERROR; switch (*elem) { case ELEM_propstat: b->in_propstat = TRUE; b->propstat_has_error = FALSE; break; default: break; } /* We're guaranteed to have ELM now: SVN_RA_NEON__XML_DECLINE < 1 */ if (elm->flags & SVN_RA_NEON__XML_CDATA) { svn_stringbuf_setempty(b->cdata); b->want_cdata = b->cdata; } return SVN_NO_ERROR; }
static svn_error_t * start_element(int *elem, void *baton, int parent, const char *nspace, const char *name, const char **atts) { options_ctx_t *oc = baton; const svn_ra_neon__xml_elm_t *elm = svn_ra_neon__lookup_xml_elem(options_elements, nspace, name); *elem = elm ? validate_element(parent, elm->id) : SVN_RA_NEON__XML_DECLINE; if (*elem < 1) /* Not a valid element */ return SVN_NO_ERROR; if (elm->id == ELEM_href) oc->want_cdata = oc->cdata; else oc->want_cdata = NULL; 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; }
/* * 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 * end_element(void *baton, int state, const char *nspace, const char *elt_name) { 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) return SVN_NO_ERROR; switch (elm->id) { case ELEM_editor_report: if (rb->dirs->nelts) svn_pool_destroy(APR_ARRAY_IDX(rb->dirs, 0, dir_item_t).pool); return SVN_NO_ERROR; break; case ELEM_apply_textdelta: SVN_ERR(svn_stream_close(rb->base64_decoder)); rb->whandler = NULL; rb->whandler_baton = NULL; rb->svndiff_decoder = NULL; rb->base64_decoder = NULL; break; case ELEM_change_file_prop: case ELEM_change_dir_prop: { const svn_string_t *decoded_value; if (rb->prop_accum) { const svn_string_t *prop; prop = svn_stringbuf__morph_into_string(rb->prop_accum); decoded_value = svn_base64_decode_string(prop, rb->prop_pool); } else decoded_value = NULL; /* It's a delete */ if (elm->id == ELEM_change_dir_prop) SVN_ERR(rb->editor->change_dir_prop(TOP_DIR(rb).baton, rb->prop_name, decoded_value, TOP_DIR(rb).pool)); else SVN_ERR(rb->editor->change_file_prop(rb->file_baton, rb->prop_name, decoded_value, TOP_DIR(rb).file_pool)); } break; default: 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; }
/* This implements the `svn_ra_neon__endelm_cb_t' prototype. */ static svn_error_t * getlocks_end_element(void *userdata, int state, const char *ns, const char *ln) { 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 == NULL) return SVN_NO_ERROR; switch (elm->id) { case ELEM_lock: /* is the final svn_lock_t valid? all fields must be present except for 'comment' and 'expiration_date'. */ if ((! baton->current_lock->path) || (! baton->current_lock->token) || (! baton->current_lock->owner) || (! baton->current_lock->creation_date)) SVN_ERR(svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Incomplete lock data returned"))); /* Filter out unwanted paths. Since Subversion only allows locks on files, we can treat depth=immediates the same as depth=files for filtering purposes. Meaning, we'll keep this lock if: a) its path is the very path we queried, or b) we've asked for a fully recursive answer, or c) we've asked for depth=files or depth=immediates, and this lock is on an immediate child of our query path. */ if ((strcmp(baton->path, baton->current_lock->path) == 0) || (baton->requested_depth == svn_depth_infinity)) { apr_hash_set(baton->lock_hash, baton->current_lock->path, APR_HASH_KEY_STRING, baton->current_lock); } else if ((baton->requested_depth == svn_depth_files) || (baton->requested_depth == svn_depth_immediates)) { const char *rel_uri = svn_fspath__is_child(baton->path, baton->current_lock->path, baton->scratchpool); if (rel_uri && (svn_path_component_count(rel_uri) == 1)) apr_hash_set(baton->lock_hash, baton->current_lock->path, APR_HASH_KEY_STRING, baton->current_lock); svn_pool_clear(baton->scratchpool); } break; case ELEM_lock_path: /* neon has already xml-unescaped the cdata for us. */ baton->current_lock->path = svn_fspath__canonicalize(apr_pstrmemdup(baton->scratchpool, baton->cdata_accum->data, baton->cdata_accum->len), baton->pool); /* clean up the accumulator. */ svn_stringbuf_setempty(baton->cdata_accum); svn_pool_clear(baton->scratchpool); break; case ELEM_lock_token: /* neon has already xml-unescaped the cdata for us. */ baton->current_lock->token = apr_pstrmemdup(baton->pool, baton->cdata_accum->data, baton->cdata_accum->len); /* clean up the accumulator. */ svn_stringbuf_setempty(baton->cdata_accum); svn_pool_clear(baton->scratchpool); break; case ELEM_lock_creationdate: SVN_ERR(svn_time_from_cstring(&(baton->current_lock->creation_date), baton->cdata_accum->data, baton->scratchpool)); /* clean up the accumulator. */ svn_stringbuf_setempty(baton->cdata_accum); svn_pool_clear(baton->scratchpool); break; case ELEM_lock_expirationdate: SVN_ERR(svn_time_from_cstring(&(baton->current_lock->expiration_date), baton->cdata_accum->data, baton->scratchpool)); /* clean up the accumulator. */ svn_stringbuf_setempty(baton->cdata_accum); svn_pool_clear(baton->scratchpool); break; case ELEM_lock_owner: case ELEM_lock_comment: { const char *final_val; if (baton->encoding) { /* Possibly recognize other encodings someday. */ if (strcmp(baton->encoding, "base64") == 0) { svn_string_t *encoded_val; const svn_string_t *decoded_val; encoded_val = svn_string_create_from_buf(baton->cdata_accum, baton->scratchpool); decoded_val = svn_base64_decode_string(encoded_val, baton->scratchpool); final_val = decoded_val->data; } else return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, _("Got unrecognized encoding '%s'"), baton->encoding); baton->encoding = NULL; } else { /* neon has already xml-unescaped the cdata for us. */ final_val = baton->cdata_accum->data; } if (elm->id == ELEM_lock_owner) baton->current_lock->owner = apr_pstrdup(baton->pool, final_val); if (elm->id == ELEM_lock_comment) baton->current_lock->comment = apr_pstrdup(baton->pool, final_val); /* clean up the accumulator. */ svn_stringbuf_setempty(baton->cdata_accum); svn_pool_clear(baton->scratchpool); break; } default: break; } 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; }