Alien-SVN

 view release on metacpan or  search on metacpan

src/subversion/subversion/libsvn_ra_serf/ra_serf.h  view on Meta::CPAN

svn_error_t *
svn_ra_serf__context_run_one(svn_ra_serf__handler_t *handler,
                             apr_pool_t *scratch_pool);


/*
 * Helper function to queue a request in the @a handler's connection.
 */
void svn_ra_serf__request_create(svn_ra_serf__handler_t *handler);

/* XML helper callbacks. */

typedef struct svn_ra_serf__xml_state_t {
  /* A numeric value that represents the current state in parsing.
   *
   * Value 0 is reserved for use as the default state.
   */
  int current_state;

  /* Private pointer set by the parsing code. */
  void *private;

  /* Allocations should be made in this pool to match the lifetime of the
   * state.
   */
  apr_pool_t *pool;

  /* The currently-declared namespace for this state. */
  svn_ra_serf__ns_t *ns_list;

  /* Our previous states. */
  struct svn_ra_serf__xml_state_t *prev;
} svn_ra_serf__xml_state_t;

/* Forward declaration of the XML parser structure. */
typedef struct svn_ra_serf__xml_parser_t svn_ra_serf__xml_parser_t;

/* Callback invoked with @a baton by our XML @a parser when an element with
 * the @a name containing @a attrs is opened.
 */
typedef svn_error_t *
(*svn_ra_serf__xml_start_element_t)(svn_ra_serf__xml_parser_t *parser,
                                    svn_ra_serf__dav_props_t name,
                                    const char **attrs,
                                    apr_pool_t *scratch_pool);

/* Callback invoked with @a baton by our XML @a parser when an element with
 * the @a name is closed.
 */
typedef svn_error_t *
(*svn_ra_serf__xml_end_element_t)(svn_ra_serf__xml_parser_t *parser,
                                  svn_ra_serf__dav_props_t name,
                                  apr_pool_t *scratch_pool);

/* Callback invoked with @a baton by our XML @a parser when a CDATA portion
 * of @a data with size @a len is encountered.
 *
 * This may be invoked multiple times for the same tag.
 */
typedef svn_error_t *
(*svn_ra_serf__xml_cdata_chunk_handler_t)(svn_ra_serf__xml_parser_t *parser,
                                          const char *data,
                                          apr_size_t len,
                                          apr_pool_t *scratch_pool);

/*
 * Helper structure associated with handle_xml_parser handler that will
 * specify how an XML response will be processed.
 */
struct svn_ra_serf__xml_parser_t {
  /* Temporary allocations should be made in this pool. */
  apr_pool_t *pool;

  /* What kind of response are we parsing? If set, this should typically
     define the report name.  */
  const char *response_type;

  /* Caller-specific data passed to the start, end, cdata callbacks.  */
  void *user_data;

  /* Callback invoked when a tag is opened. */
  svn_ra_serf__xml_start_element_t start;

  /* Callback invoked when a tag is closed. */
  svn_ra_serf__xml_end_element_t end;

  /* Callback invoked when a cdata chunk is received. */
  svn_ra_serf__xml_cdata_chunk_handler_t cdata;

  /* Our associated expat-based XML parser. */
  XML_Parser xmlp;

  /* Our current state. */
  svn_ra_serf__xml_state_t *state;

  /* Our previously used states (will be reused). */
  svn_ra_serf__xml_state_t *free_state;

  /* If non-NULL, this value will be set to TRUE when the response is
   * completed.
   */
  svn_boolean_t *done;

  /* If non-NULL, when this parser completes, it will add done_item to
   * the list.
   */
  svn_ra_serf__list_t **done_list;

  /* A pointer to the item that will be inserted into the list upon
   * completeion.
   */
  svn_ra_serf__list_t *done_item;

  /* If this flag is TRUE, errors during parsing will be ignored.
   *
   * This is mainly used when we are processing an error XML response to
   * avoid infinite loops.
   */
  svn_boolean_t ignore_errors;

  /* If an error occurred, this value will be non-NULL. */
  svn_error_t *error;

  /* Deciding whether to pause, or not, is performed within the parsing
     callbacks. If a callback decides to set this flag, then the loop
     driving the parse (generally, a series of calls to serf_context_run())
     is going to need to coordinate the un-pausing of the parser by
     processing pending content. Thus, deciding to pause the parser is a
     coordinate effort rather than merely setting this flag.

     When an XML parsing callback sets this flag, note that additional
     elements may be parsed (as the current buffer is consumed). At some
     point, the flag will be recognized and arriving network content will
     be stashed away in the PENDING structure (see below).

     At some point, the controlling loop should clear this value. The
     underlying network processing will note the change and begin passing
     content into the XML callbacks.

     Note that the controlling loop should also process pending content
     since the arriving network content will typically finish first.  */
  svn_boolean_t paused;

  /* While the XML parser is paused, content arriving from the server
     must be saved locally. We cannot stop reading, or the server may
     decide to drop the connection. The content will be stored in memory
     up to a certain limit, and will then be spilled over to disk.

     See libsvn_ra_serf/util.c  */
  struct svn_ra_serf__pending_t *pending;
};


/* v2 of the XML parsing functions  */

/* The XML parsing context.  */
typedef struct svn_ra_serf__xml_context_t svn_ra_serf__xml_context_t;


/* An opaque structure for the XML parse element/state.  */
typedef struct svn_ra_serf__xml_estate_t svn_ra_serf__xml_estate_t;

/* Called just after the parser moves into ENTERED_STATE. The tag causing
   the transition is passed in TAG.

   This callback is applied to a parsing context by using the
   svn_ra_serf__xml_context_customize() function.

   NOTE: this callback, when set, will be invoked on *every* transition.
   The callback must examine ENTERED_STATE to determine if any action
   must be taken. The original state is not provided, but must be derived
   from ENTERED_STATE and/or the TAG causing the transition (if needed).  */
typedef svn_error_t *
(*svn_ra_serf__xml_opened_t)(svn_ra_serf__xml_estate_t *xes,
                             void *baton,
                             int entered_state,
                             const svn_ra_serf__dav_props_t *tag,
                             apr_pool_t *scratch_pool);


/* Called just before the parser leaves LEAVING_STATE.

   If cdata collection was enabled for this state, then CDATA will be
   non-NULL and contain the collected cdata.

   If attribute collection was enabled for this state, then ATTRS will
   contain the attributes collected for this element only, along with
   any values stored via svn_ra_serf__xml_note().

   Use svn_ra_serf__xml_gather_since() to gather up data from outer states.

   ATTRS is char* -> char*.

   Temporary allocations may be made in SCRATCH_POOL.  */
typedef svn_error_t *
(*svn_ra_serf__xml_closed_t)(svn_ra_serf__xml_estate_t *xes,
                             void *baton,
                             int leaving_state,
                             const svn_string_t *cdata,
                             apr_hash_t *attrs,
                             apr_pool_t *scratch_pool);


/* Called for all states that are not using the builtin cdata collection.
   This callback is (only) appropriate for unbounded-size cdata content.

   CURRENT_STATE may be used to decide what to do with the data.

   Temporary allocations may be made in SCRATCH_POOL.  */
typedef svn_error_t *
(*svn_ra_serf__xml_cdata_t)(svn_ra_serf__xml_estate_t *xes,
                            void *baton,
                            int current_state,
                            const char *data,
                            apr_size_t len,
                            apr_pool_t *scratch_pool);


/* State transition table.

   When the XML Context is constructed, it is in state 0. User states are
   positive integers.

   In a list of transitions, use { 0 } to indicate the end. Specifically,
   the code looks for NS == NULL.

   ### more docco
*/
typedef struct svn_ra_serf__xml_transition_t {
  /* This transition applies when in this state  */
  int from_state;

  /* And when this tag is observed  */
  const char *ns;
  const char *name;

  /* Moving to this state  */
  int to_state;

  /* Should the cdata of NAME be collected? Note that CUSTOM_CLOSE should
     be TRUE in order to capture this cdata.  */
  svn_boolean_t collect_cdata;

  /* Which attributes of NAME should be collected? Terminate with NULL.
     Maximum of 10 attributes may be collected. Note that attribute
     namespaces are ignored at this time.

     Attribute names beginning with "?" are optional. Other names must
     exist on the element, or SVN_ERR_XML_ATTRIB_NOT_FOUND will be raised.  */
  const char *collect_attrs[11];

  /* When NAME is closed, should the callback be invoked?  */
  svn_boolean_t custom_close;

} svn_ra_serf__xml_transition_t;


/* Construct an XML parsing context, based on the TTABLE transition table.
   As content is parsed, the CLOSED_CB callback will be invoked according
   to the definition in the table.

   If OPENED_CB is not NULL, then it will be invoked for *every* tag-open
   event. The callback will need to use the ENTERED_STATE and TAG parameters
   to decide what it would like to do.

   If CDATA_CB is not NULL, then it will be called for all cdata that is
   not be automatically collected (based on the transition table record's
   COLLECT_CDATA flag). It will be called in every state, so the callback
   must examine the CURRENT_STATE parameter to decide what to do.

   The same BATON value will be passed to all three callbacks.

   The context will be created within RESULT_POOL.  */
svn_ra_serf__xml_context_t *
svn_ra_serf__xml_context_create(
  const svn_ra_serf__xml_transition_t *ttable,
  svn_ra_serf__xml_opened_t opened_cb,
  svn_ra_serf__xml_closed_t closed_cb,
  svn_ra_serf__xml_cdata_t cdata_cb,
  void *baton,
  apr_pool_t *result_pool);

/* Destroy all subpools for this structure. */
void
svn_ra_serf__xml_context_destroy(
  svn_ra_serf__xml_context_t *xmlctx);

/* Construct a handler with the response function/baton set up to parse
   a response body using the given XML context. The handler and its
   internal structures are allocated in RESULT_POOL.

   This also initializes HANDLER_POOL to the given RESULT_POOL.  */
svn_ra_serf__handler_t *
svn_ra_serf__create_expat_handler(svn_ra_serf__xml_context_t *xmlctx,
                                  apr_pool_t *result_pool);


/* Allocated within XES->STATE_POOL. Changes are not allowd (callers
   should make a deep copy if they need to make changes).

   The resulting hash maps char* names to char* values.  */
apr_hash_t *
svn_ra_serf__xml_gather_since(svn_ra_serf__xml_estate_t *xes,
                              int stop_state);


/* Attach the NAME/VALUE pair onto this/parent state identified by STATE.
   The name and value will be copied into the target state's pool.

   These values will be available to the CLOSED_CB for the target state,
   or part of the gathered state via xml_gather_since().

   Typically, this function is used by a child state's close callback,
   or within an opening callback to store additional data.

   Note: if the state is not found, then a programmer error has occurred,
   so the function will invoke SVN_ERR_MALFUNCTION().  */
void
svn_ra_serf__xml_note(svn_ra_serf__xml_estate_t *xes,
                      int state,
                      const char *name,
                      const char *value);


/* Returns XES->STATE_POOL for allocating structures that should live
   as long as the state identified by XES.

   Note: a state pool is created upon demand, so only use this function
   when memory is required for a given state.  */
apr_pool_t *
svn_ra_serf__xml_state_pool(svn_ra_serf__xml_estate_t *xes);


/* Any XML parser may be used. When an opening tag is seen, call this
   function to feed the information into XMLCTX.  */
svn_error_t *
svn_ra_serf__xml_cb_start(svn_ra_serf__xml_context_t *xmlctx,
                          const char *raw_name,
                          const char *const *attrs);


/* When a close tag is seen, call this function to feed the information
   into XMLCTX.  */
svn_error_t *
svn_ra_serf__xml_cb_end(svn_ra_serf__xml_context_t *xmlctx,
                        const char *raw_name);


/* When cdata is parsed by the wrapping XML parser, call this function to
   feed the cdata into the XMLCTX.  */
svn_error_t *
svn_ra_serf__xml_cb_cdata(svn_ra_serf__xml_context_t *xmlctx,
                          const char *data,
                          apr_size_t len);


/*
 * Parses a server-side error message into a local Subversion error.
 */
struct svn_ra_serf__server_error_t {
  /* Our local representation of the error. */
  svn_error_t *error;

  /* Are we done with the response? */
  svn_boolean_t done;

  /* Have we seen an error tag? */
  svn_boolean_t in_error;

  /* Have we seen a HTTP "412 Precondition Failed" error? */
  svn_boolean_t contains_precondition_error;

  /* Should we be collecting the XML cdata? */
  svn_boolean_t collect_cdata;

  /* Collected cdata. NULL if cdata not needed. */
  svn_stringbuf_t *cdata;

  /* XML parser and namespace used to parse the remote response */
  svn_ra_serf__xml_parser_t parser;
};


/*
 * Handler that discards the entire @a response body associated with a
 * @a request.  Implements svn_ra_serf__response_handler_t.
 *
 * If @a baton is a svn_ra_serf__server_error_t (i.e. non-NULL) and an
 * error is detected, it will be populated for later detection.
 *
 * All temporary allocations will be made in a @a pool.
 */
svn_error_t *
svn_ra_serf__handle_discard_body(serf_request_t *request,
                                 serf_bucket_t *response,
                                 void *baton,
                                 apr_pool_t *pool);


/*
 * Handler that retrieves the embedded XML multistatus response from the
 * the @a RESPONSE body associated with a @a REQUEST.
 *
 * Implements svn_ra_serf__response_handler_t.
 *
 * The @a BATON should be of type svn_ra_serf__handler_t. When the request
 * is complete, the handler's DONE flag will be set to TRUE.
 *
 * All temporary allocations will be made in a @a scratch_pool.
 */
svn_error_t *
svn_ra_serf__handle_multistatus_only(serf_request_t *request,
                                     serf_bucket_t *response,
                                     void *baton,
                                     apr_pool_t *scratch_pool);


/* Handler that expects an empty body.

   If a body IS present, and it is text/xml, then it will be parsed for
   a server-side error.

   BATON should be the svn_ra_serf__handler_t running REQUEST.

   Status line information will be in HANDLER->SLINE.

   Any parsed errors will be left in HANDLER->SERVER_ERROR. That member
   may be NULL if no body was present, or a problem occurred trying to
   parse the body.

   All temporary allocations will be made in SCRATCH_POOL.  */
svn_error_t *
svn_ra_serf__expect_empty_body(serf_request_t *request,
                               serf_bucket_t *response,
                               void *baton,
                               apr_pool_t *scratch_pool);

src/subversion/subversion/libsvn_ra_serf/ra_serf.h  view on Meta::CPAN


/*
 * Add the appropriate serf buckets to @a agg_bucket represented by
 * the XML * @a tag and @a value.
 *
 * The bucket will be allocated from @a bkt_alloc.
 */
void
svn_ra_serf__add_tag_buckets(serf_bucket_t *agg_bucket,
                             const char *tag,
                             const char *value,
                             serf_bucket_alloc_t *bkt_alloc);

/*
 * Add the appropriate serf buckets to AGG_BUCKET with standard XML header:
 *  <?xml version="1.0" encoding="utf-8"?>
 *
 * The bucket will be allocated from BKT_ALLOC.
 */
void
svn_ra_serf__add_xml_header_buckets(serf_bucket_t *agg_bucket,
                                    serf_bucket_alloc_t *bkt_alloc);

/*
 * Add the appropriate serf buckets to AGG_BUCKET representing the XML
 * open tag with name TAG.
 *
 * Take the tag's attributes from varargs, a NULL-terminated list of
 * alternating <tt>char *</tt> key and <tt>char *</tt> val.  Attribute
 * will be ignored if it's value is NULL.
 *
 * NOTE: Callers are responsible for XML-escaping attribute values as
 * necessary.
 *
 * The bucket will be allocated from BKT_ALLOC.
 */
void
svn_ra_serf__add_open_tag_buckets(serf_bucket_t *agg_bucket,
                                  serf_bucket_alloc_t *bkt_alloc,
                                  const char *tag,
                                  ...);

/*
 * Add the appropriate serf buckets to AGG_BUCKET representing xml tag close
 * with name TAG.
 *
 * The bucket will be allocated from BKT_ALLOC.
 */
void
svn_ra_serf__add_close_tag_buckets(serf_bucket_t *agg_bucket,
                                   serf_bucket_alloc_t *bkt_alloc,
                                   const char *tag);

/*
 * Add the appropriate serf buckets to AGG_BUCKET with xml-escaped
 * version of DATA.
 *
 * The bucket will be allocated from BKT_ALLOC.
 */
void
svn_ra_serf__add_cdata_len_buckets(serf_bucket_t *agg_bucket,
                                   serf_bucket_alloc_t *bkt_alloc,
                                   const char *data, apr_size_t len);
/*
 * Look up the @a attrs array for namespace definitions and add each one
 * to the @a ns_list of namespaces.
 *
 * New namespaces will be allocated in RESULT_POOL.
 */
void
svn_ra_serf__define_ns(svn_ra_serf__ns_t **ns_list,
                       const char *const *attrs,
                       apr_pool_t *result_pool);

/*
 * Look up @a name in the @a ns_list list for previously declared namespace
 * definitions.
 *
 * Return (in @a *returned_prop_name) a #svn_ra_serf__dav_props_t tuple
 * representing the expanded name.
 */
void
svn_ra_serf__expand_ns(svn_ra_serf__dav_props_t *returned_prop_name,
                       const svn_ra_serf__ns_t *ns_list,
                       const char *name);


/** PROPFIND-related functions **/

/*
 * This function will deliver a PROP_CTX PROPFIND request in the SESS
 * serf context for the properties listed in LOOKUP_PROPS at URL for
 * DEPTH ("0","1","infinity").
 *
 * This function will not block waiting for the response. Callers are
 * expected to call svn_ra_serf__wait_for_props().
 */
svn_error_t *
svn_ra_serf__deliver_props(svn_ra_serf__handler_t **propfind_handler,
                           apr_hash_t *prop_vals,
                           svn_ra_serf__session_t *sess,
                           svn_ra_serf__connection_t *conn,
                           const char *url,
                           svn_revnum_t rev,
                           const char *depth,
                           const svn_ra_serf__dav_props_t *lookup_props,
                           svn_ra_serf__list_t **done_list,
                           apr_pool_t *pool);

/*
 * This helper function will block until PROPFIND_HANDLER indicates that is
 * done or another error is returned.
 */
svn_error_t *
svn_ra_serf__wait_for_props(svn_ra_serf__handler_t *handler,
                            apr_pool_t *scratch_pool);

/* This is a blocking version of deliver_props.

   The properties are fetched and placed into RESULTS, allocated in
   RESULT_POOL.



( run in 0.871 second using v1.01-cache-2.11-cpan-f889d44b568 )