source: valtobtest/subversion-1.6.2/subversion/libsvn_ra_serf/getdate.c @ 3

Last change on this file since 3 was 3, checked in by valtob, 15 years ago

subversion source 1.6.2 as test

File size: 6.0 KB
Line 
1/*
2 * getdate.c :  entry point for get_dated_revision for ra_serf
3 *
4 * ====================================================================
5 * Copyright (c) 2006-2007 CollabNet.  All rights reserved.
6 *
7 * This software is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution.  The terms
9 * are also available at http://subversion.tigris.org/license-1.html.
10 * If newer versions of this license are posted there, you may use a
11 * newer version instead, at your option.
12 *
13 * This software consists of voluntary contributions made by many
14 * individuals.  For exact contribution history, see the revision
15 * history and logs, available at http://subversion.tigris.org/.
16 * ====================================================================
17 */
18
19
20
21#include <apr_uri.h>
22
23#include <expat.h>
24
25#include <serf.h>
26
27#include "svn_pools.h"
28#include "svn_ra.h"
29#include "svn_dav.h"
30#include "svn_xml.h"
31#include "../libsvn_ra/ra_loader.h"
32#include "svn_config.h"
33#include "svn_delta.h"
34#include "svn_version.h"
35#include "svn_path.h"
36#include "svn_time.h"
37
38#include "private/svn_dav_protocol.h"
39#include "svn_private_config.h"
40
41#include "ra_serf.h"
42
43
44/*
45 * This enum represents the current state of our XML parsing for a REPORT.
46 */
47typedef enum {
48  NONE = 0,
49  VERSION_NAME,
50} date_state_e;
51
52typedef struct {
53  /* The currently collected value as we build it up */
54  const char *tmp;
55  apr_size_t tmp_len;
56} date_info_t;
57
58typedef struct {
59  apr_pool_t *pool;
60
61  /* The time asked about. */
62  apr_time_t time;
63
64  /* What was the youngest revision at that time? */
65  svn_revnum_t *revision;
66
67  /* are we done? */
68  svn_boolean_t done;
69
70} date_context_t;
71
72
73static date_info_t *
74push_state(svn_ra_serf__xml_parser_t *parser,
75           date_context_t *date_ctx,
76           date_state_e state)
77{
78  svn_ra_serf__xml_push_state(parser, state);
79
80  if (state == VERSION_NAME)
81    {
82      date_info_t *info;
83
84      info = apr_pcalloc(parser->state->pool, sizeof(*info));
85
86      parser->state->private = info;
87    }
88
89  return parser->state->private;
90}
91
92static svn_error_t *
93start_getdate(svn_ra_serf__xml_parser_t *parser,
94              void *userData,
95              svn_ra_serf__dav_props_t name,
96              const char **attrs)
97{
98  date_context_t *date_ctx = userData;
99  date_state_e state;
100
101  state = parser->state->current_state;
102
103  if (state == NONE &&
104      strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
105    {
106      push_state(parser, date_ctx, VERSION_NAME);
107    }
108
109  return SVN_NO_ERROR;
110}
111
112static svn_error_t *
113end_getdate(svn_ra_serf__xml_parser_t *parser,
114            void *userData,
115            svn_ra_serf__dav_props_t name)
116{
117  date_context_t *date_ctx = userData;
118  date_state_e state;
119  date_info_t *info;
120
121  state = parser->state->current_state;
122  info = parser->state->private;
123
124  if (state == VERSION_NAME &&
125      strcmp(name.name, SVN_DAV__VERSION_NAME) == 0)
126    {
127      *date_ctx->revision = SVN_STR_TO_REV(info->tmp);
128      svn_ra_serf__xml_pop_state(parser);
129    }
130
131  return SVN_NO_ERROR;
132}
133
134static svn_error_t *
135cdata_getdate(svn_ra_serf__xml_parser_t *parser,
136              void *userData,
137              const char *data,
138              apr_size_t len)
139{
140  date_context_t *date_ctx = userData;
141  date_state_e state;
142  date_info_t *info;
143
144  UNUSED_CTX(date_ctx);
145
146  state = parser->state->current_state;
147  info = parser->state->private;
148
149  switch (state)
150    {
151    case VERSION_NAME:
152        svn_ra_serf__expand_string(&info->tmp, &info->tmp_len,
153                                   data, len, parser->state->pool);
154        break;
155    default:
156        break;
157    }
158
159  return SVN_NO_ERROR;
160}
161
162static serf_bucket_t*
163create_getdate_body(void *baton,
164                    serf_bucket_alloc_t *alloc,
165                    apr_pool_t *pool)
166{
167  serf_bucket_t *buckets;
168  date_context_t *date_ctx = baton;
169
170  buckets = serf_bucket_aggregate_create(alloc);
171
172  svn_ra_serf__add_open_tag_buckets(buckets, alloc, "S:dated-rev-report",
173                                    "xmlns:S", SVN_XML_NAMESPACE,
174                                    "xmlns:D", "DAV:",
175                                    NULL);
176
177  svn_ra_serf__add_tag_buckets(buckets,
178                               "D:" SVN_DAV__CREATIONDATE,
179                               svn_time_to_cstring(date_ctx->time, pool),
180                               alloc);
181
182  svn_ra_serf__add_close_tag_buckets(buckets, alloc, "S:dated-rev-report");
183
184  return buckets;
185}
186
187svn_error_t *
188svn_ra_serf__get_dated_revision(svn_ra_session_t *ra_session,
189                                svn_revnum_t *revision,
190                                apr_time_t tm,
191                                apr_pool_t *pool)
192{
193  date_context_t *date_ctx;
194  svn_ra_serf__session_t *session = ra_session->priv;
195  svn_ra_serf__handler_t *handler;
196  svn_ra_serf__xml_parser_t *parser_ctx;
197  const char *vcc_url;
198  int status_code;
199
200  date_ctx = apr_pcalloc(pool, sizeof(*date_ctx));
201  date_ctx->pool = pool;
202  date_ctx->time = tm;
203  date_ctx->revision = revision;
204  date_ctx->done = FALSE;
205
206  SVN_ERR(svn_ra_serf__discover_root(&vcc_url, NULL,
207                                     session, session->conns[0],
208                                     session->repos_url.path, pool));
209
210  handler = apr_pcalloc(pool, sizeof(*handler));
211
212  handler->method = "REPORT";
213  handler->path = vcc_url;
214  handler->body_type = "text/xml";
215  handler->conn = session->conns[0];
216  handler->session = session;
217
218  parser_ctx = apr_pcalloc(pool, sizeof(*parser_ctx));
219
220  parser_ctx->pool = pool;
221  parser_ctx->user_data = date_ctx;
222  parser_ctx->start = start_getdate;
223  parser_ctx->end = end_getdate;
224  parser_ctx->cdata = cdata_getdate;
225  parser_ctx->done = &date_ctx->done;
226  parser_ctx->status_code = &status_code;
227
228  handler->body_delegate = create_getdate_body;
229  handler->body_delegate_baton = date_ctx;
230
231  handler->response_handler = svn_ra_serf__handle_xml_parser;
232  handler->response_baton = parser_ctx;
233
234  svn_ra_serf__request_create(handler);
235
236  *date_ctx->revision = SVN_INVALID_REVNUM;
237
238  return svn_ra_serf__context_run_wait(&date_ctx->done, session, pool);
239}
Note: See TracBrowser for help on using the repository browser.