diff options
Diffstat (limited to 'subversion/libsvn_subr/encode.c')
| -rw-r--r-- | subversion/libsvn_subr/encode.c | 107 | 
1 files changed, 107 insertions, 0 deletions
diff --git a/subversion/libsvn_subr/encode.c b/subversion/libsvn_subr/encode.c new file mode 100644 index 000000000000..503277cd9e2f --- /dev/null +++ b/subversion/libsvn_subr/encode.c @@ -0,0 +1,107 @@ +/* + * encode.c:  various data encoding routines + * + * ==================================================================== + *    Licensed to the Apache Software Foundation (ASF) under one + *    or more contributor license agreements.  See the NOTICE file + *    distributed with this work for additional information + *    regarding copyright ownership.  The ASF licenses this file + *    to you under the Apache License, Version 2.0 (the + *    "License"); you may not use this file except in compliance + *    with the License.  You may obtain a copy of the License at + * + *      http://www.apache.org/licenses/LICENSE-2.0 + * + *    Unless required by applicable law or agreed to in writing, + *    software distributed under the License is distributed on an + *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + *    KIND, either express or implied.  See the License for the + *    specific language governing permissions and limitations + *    under the License. + * ==================================================================== + */ + +#include "private/svn_subr_private.h" + +#include "svn_private_config.h" + +unsigned char * +svn__encode_uint(unsigned char *p, apr_uint64_t val) +{ +  int n; +  apr_uint64_t v; + +  /* Figure out how many bytes we'll need.  */ +  v = val >> 7; +  n = 1; +  while (v > 0) +    { +      v = v >> 7; +      n++; +    } + +  /* Encode the remaining bytes; n is always the number of bytes +     coming after the one we're encoding.  */ +  while (--n >= 1) +    *p++ = (unsigned char)(((val >> (n * 7)) | 0x80) & 0xff); + +  *p++ = (unsigned char)(val & 0x7f); + +  return p; +} + +unsigned char * +svn__encode_int(unsigned char *p, apr_int64_t val) +{ +  apr_uint64_t value = val; +  value = value & APR_UINT64_C(0x8000000000000000) +        ? APR_UINT64_MAX - (2 * value) +        : 2 * value; + +  return svn__encode_uint(p, value); +} + +const unsigned char * +svn__decode_uint(apr_uint64_t *val, +                 const unsigned char *p, +                 const unsigned char *end) +{ +  apr_uint64_t temp = 0; + +  if (end - p > SVN__MAX_ENCODED_UINT_LEN) +    end = p + SVN__MAX_ENCODED_UINT_LEN; + +  /* Decode bytes until we're done. */ +  while (SVN__PREDICT_TRUE(p < end)) +    { +      unsigned int c = *p++; + +      if (c < 0x80) +        { +          *val = (temp << 7) | c; +          return p; +        } +      else +        { +          temp = (temp << 7) | (c & 0x7f); +        } +    } + +  return NULL; +} + +const unsigned char * +svn__decode_int(apr_int64_t *val, +                const unsigned char *p, +                const unsigned char *end) +{ +  apr_uint64_t value; +  const unsigned char *result = svn__decode_uint(&value, p, end); + +  value = value & 1 +        ? (APR_UINT64_MAX - value / 2) +        : value / 2; +  *val = (apr_int64_t)value; + +  return result; +}  | 
