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

📄 stream.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * stream.c:   svn_stream operations * * ==================================================================== * Copyright (c) 2000-2004, 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 "svn_private_config.h"#include <assert.h>#include <stdio.h>#include <apr.h>#include <apr_pools.h>#include <apr_strings.h>#include <apr_file_io.h>#include <apr_errno.h>#include <apr_md5.h>#ifdef SVN_HAVE_ZLIB#include <zlib.h>#endif#include "svn_pools.h"#include "svn_io.h"#include "svn_error.h"#include "svn_string.h"#include "svn_utf.h"struct svn_stream_t {  void *baton;  svn_read_fn_t read_fn;  svn_write_fn_t write_fn;  svn_close_fn_t close_fn;};/*** Generic streams. ***/svn_stream_t *svn_stream_create(void *baton, apr_pool_t *pool){  svn_stream_t *stream;  stream = apr_palloc(pool, sizeof(*stream));  stream->baton = baton;  stream->read_fn = NULL;  stream->write_fn = NULL;  stream->close_fn = NULL;  return stream;}voidsvn_stream_set_baton(svn_stream_t *stream, void *baton){  stream->baton = baton;}voidsvn_stream_set_read(svn_stream_t *stream, svn_read_fn_t read_fn){  stream->read_fn = read_fn;}voidsvn_stream_set_write(svn_stream_t *stream, svn_write_fn_t write_fn){  stream->write_fn = write_fn;}voidsvn_stream_set_close(svn_stream_t *stream, svn_close_fn_t close_fn){  stream->close_fn = close_fn;}svn_error_t *svn_stream_read(svn_stream_t *stream, char *buffer, apr_size_t *len){  assert(stream->read_fn != NULL);  return stream->read_fn(stream->baton, buffer, len);}svn_error_t *svn_stream_write(svn_stream_t *stream, const char *data, apr_size_t *len){  assert(stream->write_fn != NULL);  return stream->write_fn(stream->baton, data, len);}svn_error_t *svn_stream_close(svn_stream_t *stream){  if (stream->close_fn == NULL)    return SVN_NO_ERROR;  return stream->close_fn(stream->baton);}svn_error_t *svn_stream_printf(svn_stream_t *stream,                  apr_pool_t *pool,                  const char *fmt,                  ...){  const char *message;  va_list ap;  apr_size_t len;  va_start(ap, fmt);  message = apr_pvsprintf(pool, fmt, ap);  va_end(ap);    len = strlen(message);  return svn_stream_write(stream, message, &len);}svn_error_t *svn_stream_printf_from_utf8(svn_stream_t *stream,                            const char *encoding,                            apr_pool_t *pool,                            const char *fmt,                            ...){  const char *message, *translated;  va_list ap;  apr_size_t len;  va_start(ap, fmt);  message = apr_pvsprintf(pool, fmt, ap);  va_end(ap);  SVN_ERR(svn_utf_cstring_from_utf8_ex2(&translated, message, encoding,                                        pool));    len = strlen(translated);  return svn_stream_write(stream, translated, &len);}svn_error_t *svn_stream_readline(svn_stream_t *stream,                    svn_stringbuf_t **stringbuf,                    const char *eol,                    svn_boolean_t *eof,                    apr_pool_t *pool){  apr_size_t numbytes;  const char *match;  char c;  svn_stringbuf_t *str = svn_stringbuf_create("", pool);  /* Since we're reading one character at a time, let's at least     optimize for the 90% case.  90% of the time, we can avoid the     stringbuf ever having to realloc() itself if we start it out at     80 chars.  */  svn_stringbuf_ensure(str, 80);  match = eol;  while (*match)    {      numbytes = 1;      SVN_ERR(svn_stream_read(stream, &c, &numbytes));      if (numbytes != 1)        {          /* a 'short' read means the stream has run out. */          *eof = TRUE;          *stringbuf = str;          return SVN_NO_ERROR;        }      if (c == *match)        match++;      else        match = eol;      svn_stringbuf_appendbytes(str, &c, 1);    }  *eof = FALSE;  svn_stringbuf_chop(str, match - eol);  *stringbuf = str;  return SVN_NO_ERROR;}svn_error_t *svn_stream_copy(svn_stream_t *from, svn_stream_t *to,                             apr_pool_t *pool){  char *buf = apr_palloc(pool, SVN__STREAM_CHUNK_SIZE);  apr_size_t len;  /* Read and write chunks until we get a short read, indicating the     end of the stream.  (We can't get a short write without an     associated error.) */  while (1)    {      len = SVN__STREAM_CHUNK_SIZE;      SVN_ERR(svn_stream_read(from, buf, &len));      if (len > 0)        SVN_ERR(svn_stream_write(to, buf, &len));      if (len != SVN__STREAM_CHUNK_SIZE)        break;    }  return SVN_NO_ERROR;}svn_error_t *svn_stream_contents_same(svn_boolean_t *same,                         svn_stream_t *stream1,                         svn_stream_t *stream2,                         apr_pool_t *pool){  char *buf1 = apr_palloc(pool, SVN__STREAM_CHUNK_SIZE);  char *buf2 = apr_palloc(pool, SVN__STREAM_CHUNK_SIZE);  apr_size_t bytes_read1 = SVN__STREAM_CHUNK_SIZE;  apr_size_t bytes_read2 = SVN__STREAM_CHUNK_SIZE;    *same = TRUE;  /* assume TRUE, until disproved below */  while (bytes_read1 == SVN__STREAM_CHUNK_SIZE         && bytes_read2 == SVN__STREAM_CHUNK_SIZE)    {      SVN_ERR(svn_stream_read(stream1, buf1, &bytes_read1));      SVN_ERR(svn_stream_read(stream2, buf2, &bytes_read2));            if ((bytes_read1 != bytes_read2)          || (memcmp(buf1, buf2, bytes_read1)))        {          *same = FALSE;          break;        }    }  return SVN_NO_ERROR;}/*** Generic readable empty stream ***/static svn_error_t *read_handler_empty(void *baton, char *buffer, apr_size_t *len){  *len = 0;  return SVN_NO_ERROR;}static svn_error_t *write_handler_empty(void *baton, const char *data, apr_size_t *len){  return SVN_NO_ERROR;}svn_stream_t *svn_stream_empty(apr_pool_t *pool){  svn_stream_t *stream;  stream = svn_stream_create(NULL, pool);  svn_stream_set_read(stream, read_handler_empty);  svn_stream_set_write(stream, write_handler_empty);  return stream;}/*** Ownership detaching stream ***/static svn_error_t *read_handler_disown(void *baton, char *buffer, apr_size_t *len){  return svn_stream_read((svn_stream_t *)baton, buffer, len);}static svn_error_t *write_handler_disown(void *baton, const char *buffer, apr_size_t *len){  return svn_stream_write((svn_stream_t *)baton, buffer, len);}svn_stream_t *svn_stream_disown(svn_stream_t *stream, apr_pool_t *pool){  svn_stream_t *s = svn_stream_create(stream, pool);  svn_stream_set_read(s, read_handler_disown);  svn_stream_set_write(s, write_handler_disown);  return s;}/*** Generic stream for APR files ***/struct baton_apr {  apr_file_t *file;  apr_pool_t *pool;};static svn_error_t *read_handler_apr(void *baton, char *buffer, apr_size_t *len){  struct baton_apr *btn = baton;  svn_error_t *err;  err = svn_io_file_read_full(btn->file, buffer, *len, len, btn->pool);  if (err && APR_STATUS_IS_EOF(err->apr_err))    {      svn_error_clear(err);      err = SVN_NO_ERROR;    }  return err;}static svn_error_t *write_handler_apr(void *baton, const char *data, apr_size_t *len){  struct baton_apr *btn = baton;  return svn_io_file_write_full(btn->file, data, *len, len, btn->pool);}static svn_error_t *close_handler_apr(void *baton){  struct baton_apr *btn = baton;  return svn_io_file_close(btn->file, btn->pool);}svn_stream_t *svn_stream_from_aprfile2(apr_file_t *file,                         svn_boolean_t disown,                         apr_pool_t *pool){  struct baton_apr *baton;  svn_stream_t *stream;  if (file == NULL)    return svn_stream_empty(pool);  baton = apr_palloc(pool, sizeof(*baton));  baton->file = file;  baton->pool = pool;  stream = svn_stream_create(baton, pool);  svn_stream_set_read(stream, read_handler_apr);  svn_stream_set_write(stream, write_handler_apr);  if (! disown)    svn_stream_set_close(stream, close_handler_apr);  return stream;}svn_stream_t *svn_stream_from_aprfile(apr_file_t *file, apr_pool_t *pool){  return svn_stream_from_aprfile2(file, TRUE, pool);}/* Compressed stream support */#ifdef SVN_HAVE_ZLIB#define ZBUFFER_SIZE 4096       /* The size of the buffer the                                   compressed stream uses to read from                                   the substream. Basically an                                   arbitrary value, picked to be about                                   page-sized. */struct zbaton {  z_stream *in;                 /* compressed stream for reading */  z_stream *out;                /* compressed stream for writing */  svn_read_fn_t read;           /* substream's read function */  svn_write_fn_t write;         /* substream's write function */  svn_close_fn_t close;         /* substream's close function */  void *read_buffer;            /* buffer   used   for  reading   from                                   substream */  int read_flush;               /* what flush mode to use while                                   reading */  apr_pool_t *pool;             /* The pool this baton is allocated                                   on */  void *subbaton;               /* The substream's baton */};/* zlib alloc function. opaque is the pool we need. */static voidpfzalloc(voidpf opaque, uInt items, uInt size){  apr_pool_t *pool = opaque;    return apr_palloc(pool, items * size);}/* zlib free function */static voidzfree(voidpf opaque, voidpf address){  /* Empty, since we allocate on the pool */}/* Converts a zlib error to an svn_error_t. zerr is the error code,   function is the function name, and stream is the z_stream we are   using.  */static svn_error_t *zerr_to_svn_error(int zerr, const char *function, z_stream *stream){  apr_status_t status;  const char *message;  if (zerr == Z_OK)

⌨️ 快捷键说明

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