📄 update.c
字号:
const svn_delta_editor_t *editor = info->dir->update_editor; return svn_ra_serf__set_baton_props(editor->change_file_prop, info->file_baton, ns, ns_len, name, name_len, NULL, pool);}static svn_error_t *remove_dir_props(void *baton, const char *ns, apr_ssize_t ns_len, const char *name, apr_ssize_t name_len, const svn_string_t *val, apr_pool_t *pool){ report_dir_t *dir = baton; return svn_ra_serf__set_baton_props(dir->update_editor->change_dir_prop, dir->dir_baton, ns, ns_len, name, name_len, NULL, pool);}/** Helpers to open and close directories */static svn_error_t*open_dir(report_dir_t *dir){ /* if we're already open, return now */ if (dir->dir_baton) { return SVN_NO_ERROR; } if (dir->base_name[0] == '\0') { apr_pool_create(&dir->dir_baton_pool, dir->pool); SVN_ERR(dir->update_editor->open_root(dir->update_baton, dir->base_rev, dir->dir_baton_pool, &dir->dir_baton)); } else { SVN_ERR(open_dir(dir->parent_dir)); apr_pool_create(&dir->dir_baton_pool, dir->parent_dir->dir_baton_pool); if (SVN_IS_VALID_REVNUM(dir->base_rev)) { SVN_ERR(dir->update_editor->open_directory(dir->name, dir->parent_dir->dir_baton, dir->base_rev, dir->dir_baton_pool, &dir->dir_baton)); } else { SVN_ERR(dir->update_editor->add_directory(dir->name, dir->parent_dir->dir_baton, NULL, SVN_INVALID_REVNUM, dir->dir_baton_pool, &dir->dir_baton)); } } return SVN_NO_ERROR;}static svn_error_t *close_dir(report_dir_t *dir){ report_dir_t *prev, *sibling; if (dir->ref_count) { abort(); } svn_ra_serf__walk_all_props(dir->props, dir->base_name, dir->base_rev, set_dir_props, dir, dir->dir_baton_pool); svn_ra_serf__walk_all_props(dir->removed_props, dir->base_name, dir->base_rev, remove_dir_props, dir, dir->dir_baton_pool); if (dir->fetch_props) { svn_ra_serf__walk_all_props(dir->props, dir->url, dir->target_rev, set_dir_props, dir, dir->dir_baton_pool); } SVN_ERR(dir->update_editor->close_directory(dir->dir_baton, dir->dir_baton_pool)); /* remove us from our parent's children list */ if (dir->parent_dir) { prev = NULL; sibling = dir->parent_dir->children; while (sibling != dir) { prev = sibling; sibling = sibling->sibling; if (!sibling) abort(); } if (!prev) { dir->parent_dir->children = dir->sibling; } else { prev->sibling = dir->sibling; } } apr_pool_destroy(dir->dir_baton_pool); apr_pool_destroy(dir->pool); return SVN_NO_ERROR;}static svn_error_t *close_all_dirs(report_dir_t *dir){ while (dir->children) { SVN_ERR(close_all_dirs(dir->children)); dir->ref_count--; } if (dir->ref_count) { abort(); } SVN_ERR(open_dir(dir)); return close_dir(dir);}/** Routines called when we are fetching a file *//* This function works around a bug in mod_dav_svn in that it will not * send remove-prop in the update report when a lock property disappears * when send-all is false. * * Therefore, we'll try to look at our properties and see if there's * an active lock. If not, then we'll assume there isn't a lock * anymore. */static voidcheck_lock(report_info_t *info){ const char *lock_val; lock_val = svn_ra_serf__get_ver_prop(info->props, info->url, info->target_rev, "DAV:", "lockdiscovery"); if (lock_val) { char *new_lock; new_lock = apr_pstrdup(info->editor_pool, lock_val); apr_collapse_spaces(new_lock, new_lock); lock_val = new_lock; } if (!lock_val || lock_val[0] == '\0') { svn_string_t *str; str = svn_string_ncreate("", 1, info->editor_pool); svn_ra_serf__set_ver_prop(info->dir->removed_props, info->base_name, info->base_rev, "DAV:", "lock-token", str, info->dir->pool); }}static apr_status_theaders_fetch(serf_bucket_t *headers, void *baton, apr_pool_t *pool){ report_fetch_t *fetch_ctx = baton; /* note that we have old VC URL */ if (SVN_IS_VALID_REVNUM(fetch_ctx->info->base_rev) && fetch_ctx->info->delta_base) { serf_bucket_headers_setn(headers, SVN_DAV_DELTA_BASE_HEADER, fetch_ctx->info->delta_base->data); serf_bucket_headers_setn(headers, "Accept-Encoding", "svndiff1;q=0.9,svndiff;q=0.8"); } else if (fetch_ctx->conn->using_compression == TRUE) { serf_bucket_headers_setn(headers, "Accept-Encoding", "gzip"); } return APR_SUCCESS;}static apr_status_tcancel_fetch(serf_request_t *request, serf_bucket_t *response, int status_code, void *baton){ report_fetch_t *fetch_ctx = baton; /* Uh-oh. Our connection died on us. * * The core ra_serf layer will requeue our request - we just need to note * that we got cut off in the middle of our song. */ if (!response) { /* If we already started the fetch and opened the file handle, we need * to hold subsequent read() ops until we get back to where we were * before the close and we can then resume the textdelta() calls. */ if (fetch_ctx->read_headers == TRUE) { if (fetch_ctx->aborted_read == FALSE && fetch_ctx->read_size) { fetch_ctx->aborted_read = TRUE; fetch_ctx->aborted_read_size = fetch_ctx->read_size; } fetch_ctx->read_size = 0; } return APR_SUCCESS; } /* We have no idea what went wrong. */ abort();}static apr_status_terror_fetch(serf_request_t *request, report_fetch_t *fetch_ctx, svn_error_t *err){ fetch_ctx->err = 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; serf_request_set_handler(request, svn_ra_serf__handle_discard_body, NULL); return APR_SUCCESS;}static apr_status_thandle_fetch(serf_request_t *request, serf_bucket_t *response, void *handler_baton, apr_pool_t *pool){ const char *data; apr_size_t len; apr_status_t status; report_fetch_t *fetch_ctx = handler_baton; svn_error_t *err; if (fetch_ctx->read_headers == FALSE) { serf_bucket_t *hdrs; const char *val; report_info_t *info; hdrs = serf_bucket_response_get_headers(response); val = serf_bucket_headers_get(hdrs, "Content-Type"); info = fetch_ctx->info; err = open_dir(info->dir); if (err) { return error_fetch(request, fetch_ctx, err); } 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)) { err = info->dir->update_editor->open_file(info->name, info->dir->dir_baton, info->base_rev, info->editor_pool, &info->file_baton); } else { err = info->dir->update_editor->add_file(info->name, info->dir->dir_baton, NULL, info->base_rev, info->editor_pool, &info->file_baton); } if (err) { return error_fetch(request, fetch_ctx, err); } err = info->dir->update_editor->apply_textdelta(info->file_baton, NULL, info->editor_pool, &info->textdelta, &info->textdelta_baton); if (err) { return error_fetch(request, fetch_ctx, err); } if (val && strcasecmp(val, "application/vnd.svn-svndiff") == 0) { fetch_ctx->delta_stream = svn_txdelta_parse_svndiff(info->textdelta, info->textdelta_baton, TRUE, info->editor_pool); } else { fetch_ctx->delta_stream = NULL; } fetch_ctx->read_headers = TRUE; } while (1) { svn_txdelta_window_t delta_window = { 0 }; svn_txdelta_op_t delta_op; svn_string_t window_data; 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 (fetch_ctx->delta_stream) { err = svn_stream_write(fetch_ctx->delta_stream, data, &len); if (err) { return error_fetch(request, fetch_ctx, err); } } /* otherwise, manually construct the text delta window. */ else if (len) { window_data.data = data; window_data.len = len; delta_op.action_code = svn_txdelta_new; delta_op.offset = 0; delta_op.length = len; delta_window.tview_len = len; delta_window.num_ops = 1; delta_window.ops = &delta_op; delta_window.new_data = &window_data; /* write to the file located in the info. */ err = fetch_ctx->info->textdelta(&delta_window, fetch_ctx->info->textdelta_baton); if (err) { return error_fetch(request, fetch_ctx, err); } } if (APR_STATUS_IS_EOF(status)) { report_info_t *info = fetch_ctx->info; err = info->textdelta(NULL, info->textdelta_baton); if (err) { return error_fetch(request, fetch_ctx, err); } 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -