⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 property.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * property.c : property routines for ra_serf * * ==================================================================== * Copyright (c) 2006 CollabNet.  All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution.  The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals.  For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== */#include <serf.h>#include "svn_path.h"#include "svn_base64.h"#include "ra_serf.h"/* Our current parsing state we're in for the PROPFIND response. */typedef enum {  NONE = 0,  RESPONSE,  PROP,  PROPVAL,} prop_state_e;typedef struct {  apr_pool_t *pool;  /* Current ns, attribute name, and value of the property we're parsing */  const char *ns;  const char *name;  const char *val;  apr_size_t val_len;  const char *encoding;} prop_info_t;/* * This structure represents a pending PROPFIND response. */struct svn_ra_serf__propfind_context_t {  /* pool to issue allocations from */  apr_pool_t *pool;  svn_ra_serf__handler_t *handler;  /* associated serf session */  svn_ra_serf__session_t *sess;  svn_ra_serf__connection_t *conn;  /* the requested path */  const char *path;  /* the requested version (number and string form) */  svn_revnum_t rev;  const char *label;  /* the request depth */  const char *depth;  /* the list of requested properties */  const svn_ra_serf__dav_props_t *find_props;  /* should we cache the values of this propfind in our session? */  svn_boolean_t cache_props;  /* hash table that will be updated with the properties   *   * This can be shared between multiple svn_ra_serf__propfind_context_t   * structures   */  apr_hash_t *ret_props;  /* If we're dealing with a Depth: 1 response,   * we may be dealing with multiple paths.   */  const char *current_path;  /* Returned status code. */  int status_code;  /* Are we done issuing the PROPFIND? */  svn_boolean_t done;  /* Context from XML stream */  svn_ra_serf__xml_parser_t *parser_ctx;  /* If not-NULL, add us to this list when we're done. */  svn_ra_serf__list_t **done_list;  svn_ra_serf__list_t done_item;};const svn_string_t *svn_ra_serf__get_ver_prop_string(apr_hash_t *props,                                 const char *path,                                 svn_revnum_t rev,                                 const char *ns,                                 const char *name){  apr_hash_t *ver_props, *path_props, *ns_props;  void *val = NULL;  ver_props = apr_hash_get(props, &rev, sizeof(rev));  if (ver_props)    {      path_props = apr_hash_get(ver_props, path, APR_HASH_KEY_STRING);      if (path_props)        {          ns_props = apr_hash_get(path_props, ns, APR_HASH_KEY_STRING);          if (ns_props)            {              val = apr_hash_get(ns_props, name, APR_HASH_KEY_STRING);            }        }    }  return val;}const char *svn_ra_serf__get_ver_prop(apr_hash_t *props,                          const char *path,                          svn_revnum_t rev,                          const char *ns,                          const char *name){  const svn_string_t *val;  val = svn_ra_serf__get_ver_prop_string(props, path, rev, ns, name);  if (val)    {      return val->data;    }  return NULL;}const char *svn_ra_serf__get_prop(apr_hash_t *props,                      const char *path,                      const char *ns,                      const char *name){  return svn_ra_serf__get_ver_prop(props, path, SVN_INVALID_REVNUM, ns, name);}voidsvn_ra_serf__set_ver_prop(apr_hash_t *props,                          const char *path, svn_revnum_t rev,                          const char *ns, const char *name,                          const svn_string_t *val, apr_pool_t *pool){  apr_hash_t *ver_props, *path_props, *ns_props;  ver_props = apr_hash_get(props, &rev, sizeof(rev));  if (!ver_props)    {      ver_props = apr_hash_make(pool);      apr_hash_set(props, apr_pmemdup(pool, &rev, sizeof(rev)), sizeof(rev),                   ver_props);    }  path_props = apr_hash_get(ver_props, path, APR_HASH_KEY_STRING);  if (!path_props)    {      path_props = apr_hash_make(pool);      path = apr_pstrdup(pool, path);      apr_hash_set(ver_props, path, APR_HASH_KEY_STRING, path_props);      /* todo: we know that we'll fail the next check, but fall through       * for now for simplicity's sake.       */    }  ns_props = apr_hash_get(path_props, ns, APR_HASH_KEY_STRING);  if (!ns_props)    {      ns_props = apr_hash_make(pool);      ns = apr_pstrdup(pool, ns);      apr_hash_set(path_props, ns, APR_HASH_KEY_STRING, ns_props);    }  apr_hash_set(ns_props, name, APR_HASH_KEY_STRING, val);}voidsvn_ra_serf__set_prop(apr_hash_t *props,                      const char *path,                      const char *ns, const char *name,                      const svn_string_t *val, apr_pool_t *pool){  svn_ra_serf__set_ver_prop(props, path, SVN_INVALID_REVNUM, ns, name,                            val, pool);}static prop_info_t *push_state(svn_ra_serf__xml_parser_t *parser,           svn_ra_serf__propfind_context_t *propfind,           prop_state_e state){  svn_ra_serf__xml_push_state(parser, state);  if (state == PROPVAL)    {      prop_info_t *info;      info = apr_pcalloc(parser->state->pool, sizeof(*info));      info->pool = parser->state->pool;      parser->state->private = info;    }  return parser->state->private;}/* * Expat callback invoked on a start element tag for a PROPFIND response. */static svn_error_t *start_propfind(svn_ra_serf__xml_parser_t *parser,               void *userData,               svn_ra_serf__dav_props_t name,               const char **attrs){  svn_ra_serf__propfind_context_t *ctx = userData;  prop_state_e state;  prop_info_t *info;  state = parser->state->current_state;  if (state == NONE && strcmp(name.name, "response") == 0)    {      svn_ra_serf__xml_push_state(parser, RESPONSE);    }  else if (state == RESPONSE && strcmp(name.name, "href") == 0)    {      info = push_state(parser, ctx, PROPVAL);      info->ns = name.namespace;      info->name = apr_pstrdup(info->pool, name.name);    }  else if (state == RESPONSE && strcmp(name.name, "prop") == 0)    {      push_state(parser, ctx, PROP);    }  else if (state == PROP)    {      info = push_state(parser, ctx, PROPVAL);      info->ns = name.namespace;      info->name = apr_pstrdup(info->pool, name.name);      info->encoding = apr_pstrdup(info->pool,                                   svn_ra_serf__find_attr(attrs, "V:encoding"));    }  return SVN_NO_ERROR;}/* * Expat callback invoked on an end element tag for a PROPFIND response. */static svn_error_t *end_propfind(svn_ra_serf__xml_parser_t *parser,             void *userData,             svn_ra_serf__dav_props_t name){  svn_ra_serf__propfind_context_t *ctx = userData;  prop_state_e state;  prop_info_t *info;  state = parser->state->current_state;  info = parser->state->private;  if (state == RESPONSE && strcmp(name.name, "response") == 0)    {      svn_ra_serf__xml_pop_state(parser);    }  else if (state == PROP && strcmp(name.name, "prop") == 0)    {      svn_ra_serf__xml_pop_state(parser);    }  else if (state == PROPVAL)    {      const char *ns, *pname, *val;      svn_string_t *val_str;      /* if we didn't see a CDATA element, we may want the tag name       * as long as it isn't equivalent to the property name.       */      if (!info->val)        {          if (strcmp(info->name, name.name) != 0)            {              info->val = name.name;              info->val_len = strlen(info->val);            }          else            {              info->val = "";              info->val_len = 0;            }        }         if (parser->state->prev->current_state == RESPONSE &&          strcmp(name.name, "href") == 0)        {          if (strcmp(ctx->depth, "1") == 0)            {              ctx->current_path = svn_path_canonicalize(info->val, ctx->pool);            }          else            {              ctx->current_path = ctx->path;            }        }      else if (info->encoding)        {          if (strcmp(info->encoding, "base64") == 0)            {              svn_string_t encoded;              const svn_string_t *decoded;              encoded.data = info->val;              encoded.len = info->val_len;              decoded = svn_base64_decode_string(&encoded, parser->state->pool);              info->val = decoded->data;              info->val_len = decoded->len;            }          else            {              abort();            }        }      ns = apr_pstrdup(ctx->pool, info->ns);      pname = apr_pstrdup(ctx->pool, info->name);      val = apr_pmemdup(ctx->pool, info->val, info->val_len);      val_str = svn_string_ncreate(val, info->val_len, ctx->pool);      /* set the return props and update our cache too. */      svn_ra_serf__set_ver_prop(ctx->ret_props,                                ctx->current_path, ctx->rev,                                ns, pname, val_str,                                ctx->pool);      if (ctx->cache_props)        {          ns = apr_pstrdup(ctx->sess->pool, info->ns);          pname = apr_pstrdup(ctx->sess->pool, info->name);          val = apr_pmemdup(ctx->sess->pool, info->val, info->val_len);          val_str = svn_string_ncreate(val, info->val_len, ctx->sess->pool);          svn_ra_serf__set_ver_prop(ctx->sess->cached_props,                                    ctx->current_path, ctx->rev,                                    ns, pname, val_str,                                    ctx->sess->pool);        }      svn_ra_serf__xml_pop_state(parser);    }  return SVN_NO_ERROR;}/* * Expat callback invoked on CDATA elements in a PROPFIND response. * * This callback can be called multiple times. */static svn_error_t *cdata_propfind(svn_ra_serf__xml_parser_t *parser,               void *userData,               const char *data,               apr_size_t len){  svn_ra_serf__propfind_context_t *ctx = userData;  prop_state_e state;  prop_info_t *info;  state = parser->state->current_state;  info = parser->state->private;  if (state == PROPVAL)    {      svn_ra_serf__expand_string(&info->val, &info->val_len, data, len,                                 info->pool);    }  return SVN_NO_ERROR;}static apr_status_tsetup_propfind(serf_request_t *request,               void *setup_baton,               serf_bucket_t **req_bkt,               serf_response_acceptor_t *acceptor,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -