summaryrefslogtreecommitdiff
path: root/subversion/libsvn_ra_neon/file_revs.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_ra_neon/file_revs.c')
-rw-r--r--subversion/libsvn_ra_neon/file_revs.c388
1 files changed, 0 insertions, 388 deletions
diff --git a/subversion/libsvn_ra_neon/file_revs.c b/subversion/libsvn_ra_neon/file_revs.c
deleted file mode 100644
index 461a9f0..0000000
--- a/subversion/libsvn_ra_neon/file_revs.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * file_revs.c : routines for requesting and parsing file-revs reports
- *
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- * ====================================================================
- */
-
-
-
-#define APR_WANT_STRFUNC
-#include <apr_want.h> /* for strcmp() */
-
-#include <apr_tables.h>
-#include <apr_strings.h>
-#include <apr_xml.h>
-
-#include "svn_error.h"
-#include "svn_pools.h"
-#include "svn_delta.h"
-#include "svn_io.h"
-#include "svn_path.h"
-#include "svn_xml.h"
-#include "svn_base64.h"
-#include "svn_props.h"
-#include "../libsvn_ra/ra_loader.h"
-#include "svn_private_config.h"
-
-#include "ra_neon.h"
-
-
-
-/*** Code ***/
-
-struct report_baton {
- /* From the caller. */
- svn_file_rev_handler_t handler;
- void *handler_baton;
-
- /* Arguments for the callback. */
- const char *path;
- svn_revnum_t revnum;
- apr_hash_t *rev_props;
- apr_array_header_t *prop_diffs;
-
- /* The current property name. */
- const char *prop_name;
-
- /* Is the current property encoded in base64? */
- svn_boolean_t base64_prop;
-
- /* Buffer for accumulating CDATA for prop values. */
- svn_stringbuf_t *cdata_accum;
-
- /* Stream for writing text delta to. */
- svn_stream_t *stream;
-
- /* Merged revision flag. */
- svn_boolean_t merged_rev;
-
- svn_boolean_t had_txdelta; /* Did we have a txdelta in this file-rev elem? */
-
- apr_pool_t *subpool;
-};
-
-/* Prepare RB for a new revision. */
-static void
-reset_file_rev(struct report_baton *rb)
-{
- svn_pool_clear(rb->subpool);
- rb->path = NULL;
- rb->revnum = SVN_INVALID_REVNUM;
- rb->rev_props = apr_hash_make(rb->subpool);
- rb->prop_diffs = apr_array_make(rb->subpool, 0, sizeof(svn_prop_t));
- rb->merged_rev = FALSE;
- rb->had_txdelta = FALSE;
- /* Just in case... */
- rb->stream = NULL;
-}
-
-
-/* Our beloved elements. */
-static const svn_ra_neon__xml_elm_t report_elements[] =
- {
- { SVN_XML_NAMESPACE, "file-revs-report", ELEM_file_revs_report, 0 },
- { SVN_XML_NAMESPACE, "file-rev", ELEM_file_rev, 0 },
- { SVN_XML_NAMESPACE, "rev-prop", ELEM_rev_prop, 0 },
- { SVN_XML_NAMESPACE, "set-prop", ELEM_set_prop, 0 },
- { SVN_XML_NAMESPACE, "remove-prop", ELEM_remove_prop, 0 },
- { SVN_XML_NAMESPACE, "merged-revision", ELEM_merged_revision, 0 },
- { SVN_XML_NAMESPACE, "txdelta", ELEM_txdelta, 0 },
- { NULL }
- };
-
-
-/* This implements the `svn_ra_neon__startelm_cb_t' prototype. */
-static svn_error_t *
-start_element(int *elem, void *userdata, int parent_state, const char *ns,
- const char *ln, const char **atts)
-{
- struct report_baton *rb = userdata;
- const svn_ra_neon__xml_elm_t *elm;
- const char *att;
-
- elm = svn_ra_neon__lookup_xml_elem(report_elements, ns, ln);
-
- /* Skip unknown elements. */
- if (!elm)
- {
- *elem = NE_XML_DECLINE;
- return SVN_NO_ERROR;
- }
-
- switch (parent_state)
- {
- case ELEM_root:
- if (elm->id != ELEM_file_revs_report)
- return UNEXPECTED_ELEMENT(ns, ln);
- break;
-
- case ELEM_file_revs_report:
- if (elm->id == ELEM_file_rev)
- {
- reset_file_rev(rb);
- att = svn_xml_get_attr_value("rev", atts);
- if (!att)
- return MISSING_ATTR(ns, ln, "rev");
- rb->revnum = SVN_STR_TO_REV(att);
- att = svn_xml_get_attr_value("path", atts);
- if (!att)
- return MISSING_ATTR(ns, ln, "path");
- rb->path = apr_pstrdup(rb->subpool, att);
- }
- else
- return UNEXPECTED_ELEMENT(ns, ln);
- break;
-
- case ELEM_file_rev:
- /* txdelta must be the last elem in file-rev. */
- if (rb->had_txdelta)
- return UNEXPECTED_ELEMENT(ns, ln);
- switch (elm->id)
- {
- case ELEM_rev_prop:
- case ELEM_set_prop:
- att = svn_xml_get_attr_value("name", atts);
- if (!att)
- return MISSING_ATTR(ns, ln, "name");
- rb->prop_name = apr_pstrdup(rb->subpool, att);
- att = svn_xml_get_attr_value("encoding", atts);
- if (att && strcmp(att, "base64") == 0)
- rb->base64_prop = TRUE;
- else
- rb->base64_prop = FALSE;
- break;
- case ELEM_remove_prop:
- {
- svn_prop_t *prop = apr_array_push(rb->prop_diffs);
- att = svn_xml_get_attr_value("name", atts);
- if (!att || *att == '\0')
- return MISSING_ATTR(ns, ln, "name");
- prop->name = apr_pstrdup(rb->subpool, att);
- prop->value = NULL;
- }
- break;
- case ELEM_txdelta:
- {
- svn_txdelta_window_handler_t whandler = NULL;
- void *wbaton;
- /* It's time to call our hanlder. */
- SVN_ERR(rb->handler(rb->handler_baton, rb->path, rb->revnum,
- rb->rev_props, rb->merged_rev, &whandler,
- &wbaton, rb->prop_diffs, rb->subpool));
- if (whandler)
- rb->stream = svn_base64_decode
- (svn_txdelta_parse_svndiff(whandler, wbaton, TRUE,
- rb->subpool), rb->subpool);
- }
- break;
- case ELEM_merged_revision:
- {
- rb->merged_rev = TRUE;
- }
- break;
- default:
- return UNEXPECTED_ELEMENT(ns, ln);
- }
- break;
- default:
- return UNEXPECTED_ELEMENT(ns, ln);
- }
-
- *elem = elm->id;
-
- return SVN_NO_ERROR;
-}
-
-/* Extract the property value from RB, possibly base64-decoding it.
- Resets RB->cdata_accum. */
-static const svn_string_t *
-extract_propval(struct report_baton *rb)
-{
- const svn_string_t *v = svn_string_create_from_buf(rb->cdata_accum,
- rb->subpool);
- svn_stringbuf_setempty(rb->cdata_accum);
- if (rb->base64_prop)
- return svn_base64_decode_string(v, rb->subpool);
- else
- return v;
-}
-
-/* This implements the `svn_ra_neon__endelm_cb_t' prototype. */
-static svn_error_t *
-end_element(void *userdata, int state,
- const char *nspace, const char *elt_name)
-{
- struct report_baton *rb = userdata;
-
- switch (state)
- {
- case ELEM_file_rev:
- /* If we had no txdelta, we call the handler here, informing it that
- there were no content changes. */
- if (!rb->had_txdelta)
- SVN_ERR(rb->handler(rb->handler_baton, rb->path, rb->revnum,
- rb->rev_props, rb->merged_rev, NULL, NULL,
- rb->prop_diffs, rb->subpool));
- break;
-
- case ELEM_rev_prop:
- apr_hash_set(rb->rev_props, rb->prop_name, APR_HASH_KEY_STRING,
- extract_propval(rb));
- break;
-
- case ELEM_set_prop:
- {
- svn_prop_t *prop = apr_array_push(rb->prop_diffs);
- prop->name = rb->prop_name;
- prop->value = extract_propval(rb);
- break;
- }
-
- case ELEM_txdelta:
- if (rb->stream)
- {
- SVN_ERR(svn_stream_close(rb->stream));
- rb->stream = NULL;
- }
- rb->had_txdelta = TRUE;
- break;
- }
- return SVN_NO_ERROR;
-}
-
-/* This implements the `svn_ra_neon__cdata_cb' prototype. */
-static svn_error_t *
-cdata_handler(void *userdata, int state,
- const char *cdata, size_t len)
-{
- struct report_baton *rb = userdata;
-
- switch (state)
- {
- case ELEM_rev_prop:
- case ELEM_set_prop:
- svn_stringbuf_appendbytes(rb->cdata_accum, cdata, len);
- break;
- case ELEM_txdelta:
- if (rb->stream)
- {
- apr_size_t l = len;
- SVN_ERR(svn_stream_write(rb->stream, cdata, &l));
- if (l != len)
- return svn_error_create(SVN_ERR_INCOMPLETE_DATA, NULL,
- _("Failed to write full amount to stream"));
- }
-
- /* In other cases, we just ingore the CDATA. */
- }
-
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
-svn_ra_neon__get_file_revs(svn_ra_session_t *session,
- const char *path,
- svn_revnum_t start,
- svn_revnum_t end,
- svn_boolean_t include_merged_revisions,
- svn_file_rev_handler_t handler,
- void *handler_baton,
- apr_pool_t *pool)
-{
- svn_ra_neon__session_t *ras = session->priv;
- svn_stringbuf_t *request_body = svn_stringbuf_create("", pool);
- const char *bc_url;
- const char *bc_relative;
- const char *final_bc_url;
- int http_status = 0;
- struct report_baton rb;
- svn_error_t *err;
- apr_hash_t *request_headers = apr_hash_make(pool);
- static const char request_head[]
- = "<S:file-revs-report xmlns:S=\"" SVN_XML_NAMESPACE "\">" DEBUG_CR;
- static const char request_tail[]
- = "</S:file-revs-report>";
-
- apr_hash_set(request_headers, "Accept-Encoding", APR_HASH_KEY_STRING,
- "svndiff1;q=0.9,svndiff;q=0.8");
-
- /* Construct request body. */
- svn_stringbuf_appendcstr(request_body, request_head);
- svn_stringbuf_appendcstr(request_body,
- apr_psprintf(pool,
- "<S:start-revision>%ld"
- "</S:start-revision>", start));
- svn_stringbuf_appendcstr(request_body,
- apr_psprintf(pool,
- "<S:end-revision>%ld"
- "</S:end-revision>", end));
- if (include_merged_revisions)
- {
- svn_stringbuf_appendcstr(request_body,
- apr_psprintf(pool,
- "<S:include-merged-revisions/>"));
- }
-
- svn_stringbuf_appendcstr(request_body, "<S:path>");
- svn_stringbuf_appendcstr(request_body,
- apr_xml_quote_string(pool, path, 0));
- svn_stringbuf_appendcstr(request_body, "</S:path>");
- svn_stringbuf_appendcstr(request_body, request_tail);
-
- /* Initialize the baton. */
- rb.handler = handler;
- rb.handler_baton = handler_baton;
- rb.cdata_accum = svn_stringbuf_create("", pool);
- rb.subpool = svn_pool_create(pool);
- reset_file_rev(&rb);
-
- /* ras's URL may not exist in HEAD, and thus it's not safe to send
- it as the main argument to the REPORT request; it might cause
- dav_get_resource() to choke on the server. So instead, we pass a
- baseline-collection URL, which we get from END. */
- SVN_ERR(svn_ra_neon__get_baseline_info(&bc_url, &bc_relative, NULL, ras,
- ras->url->data, end, pool));
- final_bc_url = svn_path_url_add_component2(bc_url, bc_relative, pool);
-
- /* Dispatch the request. */
- err = svn_ra_neon__parsed_request(ras, "REPORT", final_bc_url,
- request_body->data, NULL, NULL,
- start_element, cdata_handler, end_element,
- &rb, request_headers, &http_status, FALSE,
- pool);
-
- /* Map status 501: Method Not Implemented to our not implemented error.
- 1.0.x servers and older don't support this report. */
- if (http_status == 501)
- return svn_error_createf(SVN_ERR_RA_NOT_IMPLEMENTED, err,
- _("'%s' REPORT not implemented"), "get-file-revs");
-
- SVN_ERR(err);
-
- /* Caller expects at least one revision. Signal error otherwise. */
- if (!SVN_IS_VALID_REVNUM(rb.revnum))
- return svn_error_create(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
- _("The file-revs report didn't contain any "
- "revisions"));
-
- svn_pool_destroy(rb.subpool);
-
- return SVN_NO_ERROR;
-}