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

📄 marshal.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
      else if (*fmt == '?')        opt = TRUE;      else if (*fmt == '(' && !opt)        SVN_ERR(svn_ra_svn_start_list(conn, pool));      else if (*fmt == ')')        {          SVN_ERR(svn_ra_svn_end_list(conn, pool));          opt = FALSE;        }      else if (*fmt == '!' && !*(fmt + 1))        return SVN_NO_ERROR;      else        abort();    }  SVN_ERR(svn_ra_svn_end_list(conn, pool));  return SVN_NO_ERROR;}svn_error_t *svn_ra_svn_write_tuple(svn_ra_svn_conn_t *conn, apr_pool_t *pool,                                    const char *fmt, ...){  svn_error_t *err;  va_list ap;  va_start(ap, fmt);  err = vwrite_tuple(conn, pool, fmt, ap);  va_end(ap);  return err;}/* --- READING DATA ITEMS --- *//* Read LEN bytes from CONN into already-allocated structure ITEM. * Afterwards, *ITEM is of type 'SVN_RA_SVN_STRING', and its string * data is allocated in POOL. */static svn_error_t *read_string(svn_ra_svn_conn_t *conn, apr_pool_t *pool,                                svn_ra_svn_item_t *item, apr_uint64_t len){  char readbuf[4096];  apr_size_t readbuf_len;  svn_stringbuf_t *stringbuf = svn_stringbuf_create("", pool);  /* We can't store strings longer than the maximum size of apr_size_t,   * so check for wrapping */  if (((apr_size_t) len) < len)     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,                            _("String length larger than maximum"));  while (len)    {      readbuf_len = len > sizeof(readbuf) ? sizeof(readbuf) : len;      SVN_ERR(readbuf_read(conn, pool, readbuf, readbuf_len));      /* Read into a stringbuf_t to so we don't allow the sender to allocate       * an arbitrary amount of memory without actually sending us that much       * data */      svn_stringbuf_appendbytes(stringbuf, readbuf, readbuf_len);      len -= readbuf_len;    }    item->kind = SVN_RA_SVN_STRING;  item->u.string = apr_palloc(pool, sizeof(*item->u.string));  item->u.string->data = stringbuf->data;  item->u.string->len = stringbuf->len;  return SVN_NO_ERROR; }/* Given the first non-whitespace character FIRST_CHAR, read an item * into the already allocated structure ITEM.  LEVEL should be set * to 0 for the first call and is used to enforce a recurssion limit * on the parser. */static svn_error_t *read_item(svn_ra_svn_conn_t *conn, apr_pool_t *pool,                              svn_ra_svn_item_t *item, char first_char,                              int level){  char c = first_char;  apr_uint64_t val, prev_val=0;  svn_stringbuf_t *str;  svn_ra_svn_item_t *listitem;  if (++level >= 64)    return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,                            _("Too many nested items"));      /* Determine the item type and read it in.  Make sure that c is the   * first character at the end of the item so we can test to make   * sure it's whitespace. */  if (apr_isdigit(c))    {      /* It's a number or a string.  Read the number part, either way. */      val = c - '0';      while (1)        {          prev_val = val;          SVN_ERR(readbuf_getchar(conn, pool, &c));          if (!apr_isdigit(c))            break;          val = val * 10 + (c - '0');          if ((val / 10) != prev_val) /* val wrapped past maximum value */            return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,                                    _("Number is larger than maximum"));        }      if (c == ':')        {          /* It's a string. */          SVN_ERR(read_string(conn, pool, item, val));          SVN_ERR(readbuf_getchar(conn, pool, &c));        }      else        {          /* It's a number. */          item->kind = SVN_RA_SVN_NUMBER;          item->u.number = val;        }    }  else if (apr_isalpha(c))    {      /* It's a word. */      str = svn_stringbuf_ncreate(&c, 1, pool);      while (1)        {          SVN_ERR(readbuf_getchar(conn, pool, &c));          if (!apr_isalnum(c) && c != '-')            break;          svn_stringbuf_appendbytes(str, &c, 1);        }      item->kind = SVN_RA_SVN_WORD;      item->u.word = str->data;    }  else if (c == '(')    {      /* Read in the list items. */      item->kind = SVN_RA_SVN_LIST;      item->u.list = apr_array_make(pool, 0, sizeof(svn_ra_svn_item_t));      while (1)        {          SVN_ERR(readbuf_getchar_skip_whitespace(conn, pool, &c));          if (c == ')')            break;          listitem = apr_array_push(item->u.list);          SVN_ERR(read_item(conn, pool, listitem, c, level));        }      SVN_ERR(readbuf_getchar(conn, pool, &c));    }  if (!svn_iswhitespace(c))    return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,                            _("Malformed network data"));  return SVN_NO_ERROR;}svn_error_t *svn_ra_svn_read_item(svn_ra_svn_conn_t *conn, apr_pool_t *pool,                                  svn_ra_svn_item_t **item){  char c;  /* Allocate space, read the first character, and then do the rest of   * the work.  This makes sense because of the way lists are read. */  *item = apr_palloc(pool, sizeof(**item));  SVN_ERR(readbuf_getchar_skip_whitespace(conn, pool, &c));  return read_item(conn, pool, *item, c, 0);}svn_error_t *svn_ra_svn_skip_leading_garbage(svn_ra_svn_conn_t *conn,                                             apr_pool_t *pool){  return readbuf_skip_leading_garbage(conn);}/* --- READING AND PARSING TUPLES --- *//* Parse a tuple.  Advance *FMT to the end of the tuple specification * and advance AP by the corresponding arguments. */static svn_error_t *vparse_tuple(apr_array_header_t *list, apr_pool_t *pool,                                 const char **fmt, va_list *ap){  int count, list_level;  svn_ra_svn_item_t *elt;  for (count = 0; **fmt && count < list->nelts; (*fmt)++, count++)    {      /* '?' just means the tuple may stop; skip past it. */      if (**fmt == '?')        (*fmt)++;      elt = &((svn_ra_svn_item_t *) list->elts)[count];      if (**fmt == 'n' && elt->kind == SVN_RA_SVN_NUMBER)        *va_arg(*ap, apr_uint64_t *) = elt->u.number;      else if (**fmt == 'r' && elt->kind == SVN_RA_SVN_NUMBER)        *va_arg(*ap, svn_revnum_t *) = elt->u.number;      else if (**fmt == 's' && elt->kind == SVN_RA_SVN_STRING)        *va_arg(*ap, svn_string_t **) = elt->u.string;      else if (**fmt == 'c' && elt->kind == SVN_RA_SVN_STRING)        *va_arg(*ap, const char **) = elt->u.string->data;      else if (**fmt == 'w' && elt->kind == SVN_RA_SVN_WORD)        *va_arg(*ap, const char **) = elt->u.word;      else if (**fmt == 'b' && elt->kind == SVN_RA_SVN_WORD)        {          if (strcmp(elt->u.word, "true") == 0)            *va_arg(*ap, svn_boolean_t *) = TRUE;          else if (strcmp(elt->u.word, "false") == 0)            *va_arg(*ap, svn_boolean_t *) = FALSE;          else            break;        }      else if (**fmt == 'l' && elt->kind == SVN_RA_SVN_LIST)        *va_arg(*ap, apr_array_header_t **) = elt->u.list;      else if (**fmt == '(' && elt->kind == SVN_RA_SVN_LIST)        {          (*fmt)++;          SVN_ERR(vparse_tuple(elt->u.list, pool, fmt, ap));        }      else if (**fmt == ')')        return SVN_NO_ERROR;      else        break;    }  if (**fmt == '?')    {      list_level = 0;      for (; **fmt; (*fmt)++)        {          switch (**fmt)            {            case '?':              break;            case 'r':              *va_arg(*ap, svn_revnum_t *) = SVN_INVALID_REVNUM;              break;            case 's':              *va_arg(*ap, svn_string_t **) = NULL;              break;            case 'c':            case 'w':              *va_arg(*ap, const char **) = NULL;              break;            case 'l':              *va_arg(*ap, apr_array_header_t **) = NULL;              break;            case 'n':              *va_arg(*ap, apr_uint64_t *) = SVN_RA_SVN_UNSPECIFIED_NUMBER;              break;            case '(':              list_level++;              break;            case ')':              if (--list_level < 0)                return SVN_NO_ERROR;              break;            default:              abort();            }        }    }  if (**fmt && **fmt != ')')    return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,                            _("Malformed network data"));  return SVN_NO_ERROR;}svn_error_t *svn_ra_svn_parse_tuple(apr_array_header_t *list,                                    apr_pool_t *pool,                                    const char *fmt, ...){  svn_error_t *err;  va_list ap;  va_start(ap, fmt);  err = vparse_tuple(list, pool, &fmt, &ap);  va_end(ap);  return err;}svn_error_t *svn_ra_svn_read_tuple(svn_ra_svn_conn_t *conn, apr_pool_t *pool,                                   const char *fmt, ...){  va_list ap;  svn_ra_svn_item_t *item;  svn_error_t *err;  SVN_ERR(svn_ra_svn_read_item(conn, pool, &item));  if (item->kind != SVN_RA_SVN_LIST)    return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,                            _("Malformed network data"));  va_start(ap, fmt);  err = vparse_tuple(item->u.list, pool, &fmt, &ap);  va_end(ap);  return err;}/* --- READING AND WRITING COMMANDS AND RESPONSES --- */svn_error_t *svn_ra_svn__handle_failure_status(apr_array_header_t *params,                                               apr_pool_t *pool){  const char *message, *file;  svn_error_t *err = NULL;  svn_ra_svn_item_t *elt;  int i;  apr_uint64_t apr_err, line;  apr_pool_t *subpool = svn_pool_create(pool);  if (params->nelts == 0)    return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,                            _("Empty error list"));  /* Rebuild the error list from the end, to avoid reversing the order. */  for (i = params->nelts - 1; i >= 0; i--)    {      svn_pool_clear(subpool);      elt = &((svn_ra_svn_item_t *) params->elts)[i];      if (elt->kind != SVN_RA_SVN_LIST)        return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,                                _("Malformed error list"));      SVN_ERR(svn_ra_svn_parse_tuple(elt->u.list, subpool, "nccn", &apr_err,                                      &message, &file, &line));      /* The message field should have been optional, but we can't         easily change that, so "" means a nonexistent message. */      if (!*message)        message = NULL;      err = svn_error_create(apr_err, err, message);      err->file = apr_pstrdup(err->pool, file);      err->line = line;    }  svn_pool_destroy(subpool);  return err;}svn_error_t *svn_ra_svn_read_cmd_response(svn_ra_svn_conn_t *conn,                                          apr_pool_t *pool,                                          const char *fmt, ...){  va_list ap;  const char *status;  apr_array_header_t *params;  svn_error_t *err;  SVN_ERR(svn_ra_svn_read_tuple(conn, pool, "wl", &status, &params));  if (strcmp(status, "success") == 0)    {      va_start(ap, fmt);      err = vparse_tuple(params, pool, &fmt, &ap);      va_end(ap);      return err;    }  else if (strcmp(status, "failure") == 0)    {      return svn_ra_svn__handle_failure_status(params, pool);    }  return svn_error_createf(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,                           _("Unknown status '%s' in command response"),                           status);}svn_error_t *svn_ra_svn_handle_commands(svn_ra_svn_conn_t *conn,                                        apr_pool_t *pool,                                        const svn_ra_svn_cmd_entry_t *commands,                                        void *baton){  apr_pool_t *subpool = svn_pool_create(pool);  const char *cmdname;  int i;  svn_error_t *err, *write_err;  apr_array_header_t *params;  while (1)    {      apr_pool_clear(subpool);      SVN_ERR(svn_ra_svn_read_tuple(conn, subpool, "wl", &cmdname, &params));      for (i = 0; commands[i].cmdname; i++)        {          if (strcmp(cmdname, commands[i].cmdname) == 0)            break;        }      if (commands[i].cmdname)        err = (*commands[i].handler)(conn, subpool, params, baton);      else        {          err = svn_error_createf(SVN_ERR_RA_SVN_UNKNOWN_CMD, NULL,                                  _("Unknown command '%s'"), cmdname);          err = svn_error_create(SVN_ERR_RA_SVN_CMD_ERR, err, NULL);        }      if (err && err->apr_err == SVN_ERR_RA_SVN_CMD_ERR)        {          write_err = svn_ra_svn_write_cmd_failure(conn, subpool, err->child);          svn_error_clear(err);          if (write_err)            return write_err;        }      else if (err)        return err;      if (commands[i].terminate)        break;    }  apr_pool_destroy(subpool);  return SVN_NO_ERROR;}svn_error_t *svn_ra_svn_write_cmd(svn_ra_svn_conn_t *conn, apr_pool_t *pool,                                  const char *cmdname, const char *fmt, ...){  va_list ap;  svn_error_t *err;  SVN_ERR(svn_ra_svn_start_list(conn, pool));  SVN_ERR(svn_ra_svn_write_word(conn, pool, cmdname));  va_start(ap, fmt);  err = vwrite_tuple(conn, pool, fmt, ap);  va_end(ap);  if (err)    return err;  SVN_ERR(svn_ra_svn_end_list(conn, pool));  return SVN_NO_ERROR;}svn_error_t *svn_ra_svn_write_cmd_response(svn_ra_svn_conn_t *conn,                                           apr_pool_t *pool,                                           const char *fmt, ...){  va_list ap;  svn_error_t *err;  SVN_ERR(svn_ra_svn_start_list(conn, pool));  SVN_ERR(svn_ra_svn_write_word(conn, pool, "success"));  va_start(ap, fmt);  err = vwrite_tuple(conn, pool, fmt, ap);  va_end(ap);  if (err)    return err;  SVN_ERR(svn_ra_svn_end_list(conn, pool));  return SVN_NO_ERROR;}svn_error_t *svn_ra_svn_write_cmd_failure(svn_ra_svn_conn_t *conn,                                          apr_pool_t *pool, svn_error_t *err){  SVN_ERR(svn_ra_svn_start_list(conn, pool));  SVN_ERR(svn_ra_svn_write_word(conn, pool, "failure"));  SVN_ERR(svn_ra_svn_start_list(conn, pool));  for (; err; err = err->child)    {      /* The message string should have been optional, but we can't         easily change that, so marshal nonexistent messages as "". */      SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "nccn",                                     (apr_uint64_t) err->apr_err,                                     err->message ? err->message : "",                                     err->file, (apr_uint64_t) err->line));    }  SVN_ERR(svn_ra_svn_end_list(conn, pool));  SVN_ERR(svn_ra_svn_end_list(conn, pool));  return SVN_NO_ERROR;}

⌨️ 快捷键说明

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