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

📄 reps-strings.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
  if (len != str->len)    return svn_error_createf      (SVN_ERR_FS_CORRUPT, NULL,       _("Failure reading rep '%s'"), rep_key);  /* Just the standard paranoia. */  {    representation_t *rep;    apr_md5_ctx_t md5_context;    unsigned char checksum[APR_MD5_DIGESTSIZE];    apr_md5_init(&md5_context);    apr_md5_update(&md5_context, str->data, str->len);    apr_md5_final(checksum, &md5_context);    SVN_ERR(svn_fs_bdb__read_rep(&rep, fs, rep_key, trail, pool));    if (! svn_md5_digests_match(checksum, rep->checksum))      return svn_error_createf        (SVN_ERR_FS_CORRUPT, NULL,         _("Checksum mismatch on rep '%s':\n"           "   expected:  %s\n"           "     actual:  %s\n"), rep_key,         svn_md5_digest_to_cstring_display(rep->checksum, pool),         svn_md5_digest_to_cstring_display(checksum, pool));  }  return SVN_NO_ERROR;}struct read_rep_args{  struct rep_read_baton *rb;   /* The data source.             */  char *buf;                   /* Where to put what we read.   */  apr_size_t *len;             /* How much to read / was read. */};/* BATON is of type `read_rep_args':   Read into BATON->rb->buf the *(BATON->len) bytes starting at   BATON->rb->offset from the data represented at BATON->rb->rep_key   in BATON->rb->fs, as part of TRAIL.   Afterwards, *(BATON->len) is the number of bytes actually read, and   BATON->rb->offset is incremented by that amount.   If BATON->rb->rep_key is null, this is assumed to mean the file's   contents have no representation, i.e., the file has no contents.   In that case, if BATON->rb->offset > 0, return the error   SVN_ERR_FS_FILE_CONTENTS_CHANGED, else just set *(BATON->len) to   zero and return.  */static svn_error_t *txn_body_read_rep(void *baton, trail_t *trail){  struct read_rep_args *args = baton;  if (args->rb->rep_key)    {      SVN_ERR(rep_read_range(args->rb->fs,                             args->rb->rep_key,                             args->rb->offset,                             args->buf,                             args->len,                             trail,                              trail->pool));      args->rb->offset += *(args->len);      /* We calculate the checksum just once, the moment we see the       * last byte of data.  But we can't assume there was a short       * read.  The caller may have known the length of the data and       * requested exactly that amount, so there would never be a       * short read.  (That's why the read baton has to know the       * length of the data in advance.)       *       * On the other hand, some callers invoke the stream reader in a       * loop whose termination condition is that the read returned       * zero bytes of data -- which usually results in the read       * function being called one more time *after* the call that got       * a short read (indicating end-of-stream).       *       * The conditions below ensure that we compare checksums even       * when there is no short read associated with the last byte of       * data, while also ensuring that it's harmless to repeatedly       * read 0 bytes from the stream.       */      if (! args->rb->checksum_finalized)        {          apr_md5_update(&(args->rb->md5_context), args->buf, *(args->len));          if (args->rb->offset == args->rb->size)            {              representation_t *rep;              unsigned char checksum[APR_MD5_DIGESTSIZE];              apr_md5_final(checksum, &(args->rb->md5_context));              args->rb->checksum_finalized = TRUE;              SVN_ERR(svn_fs_bdb__read_rep(&rep, args->rb->fs,                                           args->rb->rep_key,                                            trail, trail->pool));              if (! svn_md5_digests_match(checksum, rep->checksum))                return svn_error_createf                  (SVN_ERR_FS_CORRUPT, NULL,                   _("Checksum mismatch on rep '%s':\n"                     "   expected:  %s\n"                     "     actual:  %s\n"), args->rb->rep_key,                   svn_md5_digest_to_cstring_display(rep->checksum,                                                     trail->pool),                   svn_md5_digest_to_cstring_display(checksum, trail->pool));            }        }    }  else if (args->rb->offset > 0)    {      return        svn_error_create        (SVN_ERR_FS_REP_CHANGED, NULL,         _("Null rep, but offset past zero already"));    }  else    *(args->len) = 0;  return SVN_NO_ERROR;}static svn_error_t *rep_read_contents(void *baton, char *buf, apr_size_t *len){  struct rep_read_baton *rb = baton;  struct read_rep_args args;  args.rb = rb;  args.buf = buf;  args.len = len;  /* If we got a trail, use it; else make one. */  if (rb->trail)    SVN_ERR(txn_body_read_rep(&args, rb->trail));  else    {      /* Hey, guess what?  trails don't clear their own subpools.  In         the case of reading from the db, any returned data should         live in our pre-allocated buffer, so the whole operation can         happen within a single malloc/free cycle.  This prevents us         from creating millions of unnecessary trail subpools when         reading a big file. */      apr_pool_t *subpool = svn_pool_create(rb->pool);      SVN_ERR(svn_fs_base__retry_txn(rb->fs,                                     txn_body_read_rep,                                     &args,                                     subpool));      svn_pool_destroy(subpool);    }  return SVN_NO_ERROR;}/** Writing. **/struct rep_write_baton{  /* The FS in which we're writing. */  svn_fs_t *fs;  /* The representation skel whose contents we want to write. */  const char *rep_key;  /* The transaction id under which this write action will take     place. */  const char *txn_id;  /* If present, do the write as part of this trail, and use trail's     pool.  Otherwise, see `pool' below.  */  trail_t *trail;  /* MD5 checksum.  Initialized when the baton is created, updated as     we write data, and finalized and stored when the stream is     closed. */  struct apr_md5_ctx_t md5_context;  unsigned char md5_digest[APR_MD5_DIGESTSIZE];  svn_boolean_t finalized;  /* Used for temporary allocations, iff `trail' (above) is null.  */  apr_pool_t *pool;};static struct rep_write_baton *rep_write_get_baton(svn_fs_t *fs,                    const char *rep_key,                    const char *txn_id,                    trail_t *trail,                    apr_pool_t *pool){  struct rep_write_baton *b;  b = apr_pcalloc(pool, sizeof(*b));  apr_md5_init(&(b->md5_context));  b->fs = fs;  b->trail = trail;  b->pool = pool;  b->rep_key = rep_key;  b->txn_id = txn_id;  return b;}/* Write LEN bytes from BUF into the end of the string represented via   REP_KEY in FS, as part of TRAIL.  If the representation is not   mutable, return the error SVN_FS_REP_NOT_MUTABLE. */static svn_error_t *rep_write(svn_fs_t *fs,          const char *rep_key,          const char *buf,          apr_size_t len,          const char *txn_id,          trail_t *trail,          apr_pool_t *pool){  representation_t *rep;  SVN_ERR(svn_fs_bdb__read_rep(&rep, fs, rep_key, trail, pool));  if (! rep_is_mutable(rep, txn_id))    return svn_error_createf      (SVN_ERR_FS_REP_NOT_MUTABLE, NULL,       _("Rep '%s' is not mutable"), rep_key);  if (rep->kind == rep_kind_fulltext)    {      SVN_ERR(svn_fs_bdb__string_append              (fs, &(rep->contents.fulltext.string_key), len, buf,                trail, pool));    }  else if (rep->kind == rep_kind_delta)    {      /* There should never be a case when we have a mutable         non-fulltext rep.  The only code that creates mutable reps is         in this file, and it creates them fulltext. */      return svn_error_createf        (SVN_ERR_FS_CORRUPT, NULL,         _("Rep '%s' both mutable and non-fulltext"), rep_key);    }  else /* unknown kind */    return UNKNOWN_NODE_KIND(rep_key);  return SVN_NO_ERROR;}struct write_rep_args{  struct rep_write_baton *wb;   /* Destination.       */  const char *buf;              /* Data.              */  apr_size_t len;               /* How much to write. */};/* BATON is of type `write_rep_args':   Append onto BATON->wb->rep_key's contents BATON->len bytes of   data from BATON->wb->buf, in BATON->rb->fs, as part of TRAIL.   If the representation is not mutable, return the error   SVN_FS_REP_NOT_MUTABLE.  */static svn_error_t *txn_body_write_rep(void *baton, trail_t *trail){  struct write_rep_args *args = baton;  SVN_ERR(rep_write(args->wb->fs,                    args->wb->rep_key,                    args->buf,                    args->len,                    args->wb->txn_id,                    trail,                     trail->pool));  apr_md5_update(&(args->wb->md5_context), args->buf, args->len);  return SVN_NO_ERROR;}static svn_error_t *rep_write_contents(void *baton,                   const char *buf,                   apr_size_t *len){  struct rep_write_baton *wb = baton;  struct write_rep_args args;  /* We toss LEN's indirectness because if not all the bytes are     written, it's an error, so we wouldn't be reporting anything back     through *LEN anyway. */  args.wb = wb;  args.buf = buf;  args.len = *len;  /* If we got a trail, use it; else make one. */  if (wb->trail)    SVN_ERR(txn_body_write_rep(&args, wb->trail));  else    {      /* Hey, guess what?  trails don't clear their own subpools.  In         the case of simply writing the rep to the db, we're *certain*         that there's no data coming back to us that needs to be         preserved... so the whole operation can happen within a         single malloc/free cycle.  This prevents us from creating         millions of unnecessary trail subpools when writing a big         file. */      apr_pool_t *subpool = svn_pool_create(wb->pool);      SVN_ERR(svn_fs_base__retry_txn(wb->fs,                                     txn_body_write_rep,                                     &args,                                     subpool));      svn_pool_destroy(subpool);    }  return SVN_NO_ERROR;}/* Helper for rep_write_close_contents(); see that doc string for   more.  BATON is of type `struct rep_write_baton'. */static svn_error_t *txn_body_write_close_rep(void *baton, trail_t *trail){  struct rep_write_baton *wb = baton;  representation_t *rep;  SVN_ERR(svn_fs_bdb__read_rep(&rep, wb->fs, wb->rep_key,                                trail, trail->pool));  memcpy(rep->checksum, wb->md5_digest, APR_MD5_DIGESTSIZE);  SVN_ERR(svn_fs_bdb__write_rep(wb->fs, wb->rep_key, rep,                                 trail, trail->pool));  return SVN_NO_ERROR;}/* BATON is of type `struct rep_write_baton'. * * Finalize BATON->md5_context and store the resulting digest under * BATON->rep_key. */static svn_error_t *rep_write_close_contents(void *baton){  struct rep_write_baton *wb = baton;  /* ### Thought: if we fixed apr-util MD5 contexts to allow repeated     digestification, then we wouldn't need a stream close function at     all -- instead, we could update the stored checksum each time a     write occurred, which would have the added advantage of making     interleaving reads and writes work.  Currently, they'd fail with     a checksum mismatch, it just happens that our code never tries to     do that anyway. */  if (! wb->finalized)    {      apr_md5_final(wb->md5_digest, &wb->md5_context);      wb->finalized = TRUE;    }  /* If we got a trail, use it; else make one. */  if (wb->trail)    {      SVN_ERR(txn_body_write_close_rep(wb, wb->trail));    }  else    {      SVN_ERR(svn_fs_base__retry_txn(wb->fs,                                     txn_body_write_close_rep,                                     wb,                                     wb->pool));    }  return SVN_NO_ERROR;}/** Public read and write stream constructors. **/svn_error_t *svn_fs_base__rep_contents_read_stream(svn_stream_t **rs_p,                                      svn_fs_t *fs,                                      const char *rep_key,                                      svn_boolean_t use_trail_for_reads,                                      trail_t *trail,                                      apr_pool_t *pool)

⌨️ 快捷键说明

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