📄 update.c
字号:
info->base_name, info->base_rev, remove_file_props, info, info->editor_pool); if (info->fetch_props) { svn_ra_serf__walk_all_props(info->props, info->url, info->target_rev, set_file_props, info, info->editor_pool); } err = info->dir->update_editor->close_file(info->file_baton, NULL, info->editor_pool); if (err) { return error_fetch(request, fetch_ctx, err); } fetch_ctx->done = TRUE; fetch_ctx->done_item.data = fetch_ctx; fetch_ctx->done_item.next = *fetch_ctx->done_list; *fetch_ctx->done_list = &fetch_ctx->done_item; /* We're done with our pools. */ apr_pool_destroy(info->editor_pool); apr_pool_destroy(info->pool); return status; } if (APR_STATUS_IS_EAGAIN(status)) { return status; } } /* not reached */}static apr_status_thandle_stream(serf_request_t *request, serf_bucket_t *response, void *handler_baton, apr_pool_t *pool){ report_fetch_t *fetch_ctx = handler_baton; serf_status_line sl; serf_bucket_response_status(response, &sl); /* Woo-hoo. Nothing here to see. */ if (sl.code == 404) { fetch_ctx->done = TRUE; fetch_ctx->err = svn_error_createf(SVN_ERR_RA_DAV_PATH_NOT_FOUND, NULL, "'%s' path not found", fetch_ctx->info->name); return svn_ra_serf__handle_discard_body(request, response, NULL, pool); } while (1) { const char *data; apr_size_t len; apr_status_t status; status = serf_bucket_read(response, 8000, &data, &len); if (SERF_BUCKET_READ_ERROR(status)) { return status; } fetch_ctx->read_size += len; if (fetch_ctx->aborted_read == TRUE) { /* We haven't caught up to where we were before. */ if (fetch_ctx->read_size < fetch_ctx->aborted_read_size) { /* Eek. What did the file shrink or something? */ if (APR_STATUS_IS_EOF(status)) { abort(); } /* Skip on to the next iteration of this loop. */ if (APR_STATUS_IS_EAGAIN(status)) { return status; } continue; } /* Woo-hoo. We're back. */ fetch_ctx->aborted_read = FALSE; /* Increment data and len by the difference. */ data += fetch_ctx->read_size - fetch_ctx->aborted_read_size; len += fetch_ctx->read_size - fetch_ctx->aborted_read_size; } if (len) { apr_size_t written_len; written_len = len; svn_stream_write(fetch_ctx->target_stream, data, &written_len); } if (APR_STATUS_IS_EOF(status)) { fetch_ctx->done = TRUE; } if (status) { return status; } } /* not reached */}static svn_error_t *handle_propchange_only(report_info_t *info){ /* Ensure our parent is open. */ SVN_ERR(open_dir(info->dir)); apr_pool_create(&info->editor_pool, info->dir->dir_baton_pool); /* Expand our full name now if we haven't done so yet. */ if (!info->name) { info->name_buf = svn_stringbuf_dup(info->dir->name_buf, info->editor_pool); svn_path_add_component(info->name_buf, info->base_name); info->name = info->name_buf->data; } if (SVN_IS_VALID_REVNUM(info->base_rev)) { SVN_ERR(info->dir->update_editor->open_file(info->name, info->dir->dir_baton, info->base_rev, info->editor_pool, &info->file_baton)); } else { SVN_ERR(info->dir->update_editor->add_file(info->name, info->dir->dir_baton, NULL, info->base_rev, info->editor_pool, &info->file_baton)); } if (info->fetch_file) { SVN_ERR(info->dir->update_editor->apply_textdelta(info->file_baton, NULL, info->editor_pool, &info->textdelta, &info->textdelta_baton)); } if (info->lock_token) check_lock(info); /* set all of the properties we received */ svn_ra_serf__walk_all_props(info->props, info->base_name, info->base_rev, set_file_props, info, info->editor_pool); svn_ra_serf__walk_all_props(info->dir->removed_props, info->base_name, info->base_rev, remove_file_props, info, info->editor_pool); if (info->fetch_props) { svn_ra_serf__walk_all_props(info->props, info->url, info->target_rev, set_file_props, info, info->editor_pool); } SVN_ERR(info->dir->update_editor->close_file(info->file_baton, NULL, info->editor_pool)); /* We're done with our pools. */ apr_pool_destroy(info->editor_pool); apr_pool_destroy(info->pool); info->dir->ref_count--; return SVN_NO_ERROR;}static void fetch_file(report_context_t *ctx, report_info_t *info){ svn_ra_serf__connection_t *conn; svn_ra_serf__handler_t *handler; /* What connection should we go on? */ conn = ctx->sess->conns[ctx->sess->cur_conn]; /* go fetch info->name from DAV:checked-in */ info->url = svn_ra_serf__get_ver_prop(info->props, info->base_name, info->base_rev, "DAV:", "checked-in"); if (!info->url) { abort(); } /* If needed, create the PROPFIND to retrieve the file's properties. */ info->propfind = NULL; if (info->fetch_props) { svn_ra_serf__deliver_props(&info->propfind, info->props, ctx->sess, conn, info->url, info->target_rev, "0", all_props, FALSE, &ctx->done_propfinds, info->dir->pool); if (!info->propfind) { abort(); } ctx->active_propfinds++; } /* If we've been asked to fetch the file or its an add, do so. * Otherwise, handle the case where only the properties changed. */ if (info->fetch_file && ctx->text_deltas == TRUE) { report_fetch_t *fetch_ctx; fetch_ctx = apr_pcalloc(info->dir->pool, sizeof(*fetch_ctx)); fetch_ctx->pool = info->pool; fetch_ctx->info = info; fetch_ctx->done_list = &ctx->done_fetches; fetch_ctx->sess = ctx->sess; fetch_ctx->conn = conn; handler = apr_pcalloc(info->pool, sizeof(*handler)); handler->method = "GET"; handler->path = fetch_ctx->info->url; handler->conn = conn; handler->session = ctx->sess; handler->header_delegate = headers_fetch; handler->header_delegate_baton = fetch_ctx; handler->response_handler = handle_fetch; handler->response_baton = fetch_ctx; handler->response_error = cancel_fetch; handler->response_error_baton = fetch_ctx; svn_ra_serf__request_create(handler); ctx->active_fetches++; } else if (info->propfind) { svn_ra_serf__list_t *list_item; list_item = apr_pcalloc(info->dir->pool, sizeof(*list_item)); list_item->data = info; list_item->next = ctx->file_propchanges_only; ctx->file_propchanges_only = list_item; } else { svn_error_t *err; /* No propfind or GET request. Just handle the prop changes now. */ err = handle_propchange_only(info); if (err) { abort(); } }}/** XML callbacks for our update-report response parsing */static svn_error_t *start_report(svn_ra_serf__xml_parser_t *parser, void *userData, svn_ra_serf__dav_props_t name, const char **attrs){ report_context_t *ctx = userData; report_state_e state; state = parser->state->current_state; if (state == NONE && strcmp(name.name, "target-revision") == 0) { const char *rev; rev = svn_ra_serf__find_attr(attrs, "rev"); if (!rev) { abort(); } ctx->update_editor->set_target_revision(ctx->update_baton, SVN_STR_TO_REV(rev), ctx->sess->pool); } else if (state == NONE && strcmp(name.name, "open-directory") == 0) { const char *rev; report_info_t *info; rev = svn_ra_serf__find_attr(attrs, "rev"); if (!rev) { abort(); } info = push_state(parser, ctx, OPEN_DIR); info->base_rev = apr_atoi64(rev); info->dir->base_rev = info->base_rev; info->dir->target_rev = ctx->target_rev; info->fetch_props = TRUE; info->dir->base_name = ""; info->dir->name_buf = svn_stringbuf_create("", info->pool); info->dir->name = info->dir->name_buf->data; info->base_name = info->dir->base_name; info->name = info->dir->name; info->name_buf = info->dir->name_buf; } else if (state == NONE) { /* do nothing as we haven't seen our valid start tag yet. */ } else if ((state == OPEN_DIR || state == ADD_DIR) && strcmp(name.name, "open-directory") == 0) { const char *rev, *dirname; report_dir_t *dir; report_info_t *info; rev = svn_ra_serf__find_attr(attrs, "rev"); if (!rev) { abort(); } dirname = svn_ra_serf__find_attr(attrs, "name"); if (!dirname) { abort(); } info = push_state(parser, ctx, OPEN_DIR); dir = info->dir; info->base_rev = apr_atoi64(rev); dir->base_rev = info->base_rev; dir->target_rev = ctx->target_rev; info->fetch_props = FALSE; dir->base_name = apr_pstrdup(dir->pool, dirname); info->base_name = dir->base_name; /* Expand our name. */ dir->name_buf = svn_stringbuf_dup(dir->parent_dir->name_buf, dir->pool); svn_path_add_component(dir->name_buf, dir->base_name); dir->name = dir->name_buf->data; info->name = dir->name; } else if ((state == OPEN_DIR || state == ADD_DIR) && strcmp(name.name, "add-directory") == 0) { const char *dir_name; report_dir_t *dir; report_info_t *info; dir_name = svn_ra_serf__find_attr(attrs, "name"); info = push_state(parser, ctx, ADD_DIR); dir = info->dir; dir->base_name = apr_pstrdup(dir->pool, dir_name); info->base_name = dir->base_name; /* Expand our name. */ dir->name_buf = svn_stringbuf_dup(dir->parent_dir->name_buf, dir->pool); svn_path_add_component(dir->name_buf, dir->base_name); dir->name = dir->name_buf->data; info->name = dir->name; /* Mark that we don't have a base. */ info->base_rev = SVN_INVALID_REVNUM; dir->base_rev = info->base_rev; dir->target_rev = ctx->target_rev; dir->fetch_props = TRUE; } else if ((state == OPEN_DIR || state == ADD_DIR) && strcmp(name.name, "open-file") == 0) { const char *file_name, *rev; report_info_t *info; file_name = svn_ra_serf__find_attr(attrs, "name"); if (!file_name) { abort(); } rev = svn_ra_serf__find_attr(attrs, "rev"); if (!rev) { abort(); } info = push_state(parser, ctx, OPEN_FILE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -