Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/libsvn_subr/quoprint.c view on Meta::CPAN
/* Close handler for svn_quoprint_encode(). */
static svn_error_t *
finish_encoding_data(void *baton)
{
struct encode_baton *eb = baton;
svn_error_t *err = SVN_NO_ERROR;
apr_size_t len;
/* Terminate the current output line if it's not empty. */
if (eb->linelen > 0)
{
len = 2;
err = svn_stream_write(eb->output, "=\n", &len);
}
/* Pass on the close request and clean up the baton. */
if (err == SVN_NO_ERROR)
err = svn_stream_close(eb->output);
svn_pool_destroy(eb->pool);
return err;
}
svn_stream_t *
svn_quoprint_encode(svn_stream_t *output, apr_pool_t *pool)
{
apr_pool_t *subpool = svn_pool_create(pool);
struct encode_baton *eb = apr_palloc(subpool, sizeof(*eb));
svn_stream_t *stream;
eb->output = output;
eb->linelen = 0;
eb->pool = subpool;
stream = svn_stream_create(eb, pool);
svn_stream_set_write(stream, encode_data);
svn_stream_set_close(stream, finish_encoding_data);
return stream;
}
svn_stringbuf_t *
svn_quoprint_encode_string(const svn_stringbuf_t *str, apr_pool_t *pool)
{
svn_stringbuf_t *encoded = svn_stringbuf_create_empty(pool);
int linelen = 0;
encode_bytes(encoded, str->data, str->len, &linelen);
if (linelen > 0)
svn_stringbuf_appendcstr(encoded, "=\n");
return encoded;
}
/* Quoted-printable-encoded input --> binary output */
struct decode_baton {
svn_stream_t *output;
char buf[3]; /* Bytes waiting to be decoded */
int buflen; /* Number of bytes waiting */
apr_pool_t *pool;
};
/* Decode a byte string which may or may not be the total amount of
data being decoded. INBUF and *INBUFLEN carry the leftover bytes
from call to call. Have room for four bytes in INBUF and
initialize *INBUFLEN to 0 and *DONE to FALSE. Output will be
appended to STR. */
static void
decode_bytes(svn_stringbuf_t *str, const char *data, apr_size_t len,
char *inbuf, int *inbuflen)
{
const char *p, *find1, *find2;
char c;
for (p = data; p <= data + len; p++)
{
/* Append this byte to the buffer and see what we have. */
inbuf[(*inbuflen)++] = *p;
if (*inbuf != '=')
{
/* Literal character; append it if it's valid as such. */
if (VALID_LITERAL(*inbuf))
svn_stringbuf_appendbyte(str, *inbuf);
*inbuflen = 0;
}
else if (*inbuf == '=' && *inbuflen == 2 && inbuf[1] == '\n')
{
/* Soft newline; ignore. */
*inbuflen = 0;
}
else if (*inbuf == '=' && *inbuflen == 3)
{
/* Encoded character; decode it and append. */
find1 = strchr(hextab, inbuf[1]);
find2 = strchr(hextab, inbuf[2]);
if (find1 != NULL && find2 != NULL)
{
c = (char)(((find1 - hextab) << 4) | (find2 - hextab));
svn_stringbuf_appendbyte(str, c);
}
*inbuflen = 0;
}
}
}
/* Write handler for svn_quoprint_decode. */
static svn_error_t *
decode_data(void *baton, const char *data, apr_size_t *len)
{
struct decode_baton *db = baton;
apr_pool_t *subpool;
svn_stringbuf_t *decoded;
apr_size_t declen;
svn_error_t *err = SVN_NO_ERROR;
/* Decode this block of data. */
subpool = svn_pool_create(db->pool);
decoded = svn_stringbuf_create_empty(subpool);
decode_bytes(decoded, data, *len, db->buf, &db->buflen);
/* Write the output, clean up, go home. */
declen = decoded->len;
if (declen != 0)
err = svn_stream_write(db->output, decoded->data, &declen);
svn_pool_destroy(subpool);
return err;
}
/* Close handler for svn_quoprint_decode(). */
static svn_error_t *
finish_decoding_data(void *baton)
{
struct decode_baton *db = baton;
svn_error_t *err;
/* Pass on the close request and clean up the baton. */
err = svn_stream_close(db->output);
svn_pool_destroy(db->pool);
return err;
}
svn_stream_t *
svn_quoprint_decode(svn_stream_t *output, apr_pool_t *pool)
{
apr_pool_t *subpool = svn_pool_create(pool);
struct decode_baton *db = apr_palloc(subpool, sizeof(*db));
svn_stream_t *stream;
db->output = output;
db->buflen = 0;
db->pool = subpool;
stream = svn_stream_create(db, pool);
svn_stream_set_write(stream, decode_data);
svn_stream_set_close(stream, finish_decoding_data);
return stream;
}
svn_stringbuf_t *
svn_quoprint_decode_string(const svn_stringbuf_t *str, apr_pool_t *pool)
{
svn_stringbuf_t *decoded = svn_stringbuf_create_empty(pool);
char ingroup[4];
int ingrouplen = 0;
decode_bytes(decoded, str->data, str->len, ingroup, &ingrouplen);
return decoded;
}
( run in 1.919 second using v1.01-cache-2.11-cpan-677af5a14d3 )