encode.c revision 362181
1/* 2 * encode.c: various data encoding routines 3 * 4 * ==================================================================== 5 * Licensed to the Apache Software Foundation (ASF) under one 6 * or more contributor license agreements. See the NOTICE file 7 * distributed with this work for additional information 8 * regarding copyright ownership. The ASF licenses this file 9 * to you under the Apache License, Version 2.0 (the 10 * "License"); you may not use this file except in compliance 11 * with the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, 16 * software distributed under the License is distributed on an 17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18 * KIND, either express or implied. See the License for the 19 * specific language governing permissions and limitations 20 * under the License. 21 * ==================================================================== 22 */ 23 24#include "private/svn_subr_private.h" 25 26#include "svn_private_config.h" 27 28unsigned char * 29svn__encode_uint(unsigned char *p, apr_uint64_t val) 30{ 31 int n; 32 apr_uint64_t v; 33 34 /* Figure out how many bytes we'll need. */ 35 v = val >> 7; 36 n = 1; 37 while (v > 0) 38 { 39 v = v >> 7; 40 n++; 41 } 42 43 /* Encode the remaining bytes; n is always the number of bytes 44 coming after the one we're encoding. */ 45 while (--n >= 1) 46 *p++ = (unsigned char)(((val >> (n * 7)) | 0x80) & 0xff); 47 48 *p++ = (unsigned char)(val & 0x7f); 49 50 return p; 51} 52 53unsigned char * 54svn__encode_int(unsigned char *p, apr_int64_t val) 55{ 56 apr_uint64_t value = val; 57 value = value & APR_UINT64_C(0x8000000000000000) 58 ? APR_UINT64_MAX - (2 * value) 59 : 2 * value; 60 61 return svn__encode_uint(p, value); 62} 63 64const unsigned char * 65svn__decode_uint(apr_uint64_t *val, 66 const unsigned char *p, 67 const unsigned char *end) 68{ 69 apr_uint64_t temp = 0; 70 71 if (end - p > SVN__MAX_ENCODED_UINT_LEN) 72 end = p + SVN__MAX_ENCODED_UINT_LEN; 73 74 /* Decode bytes until we're done. */ 75 while (SVN__PREDICT_TRUE(p < end)) 76 { 77 unsigned int c = *p++; 78 79 if (c < 0x80) 80 { 81 *val = (temp << 7) | c; 82 return p; 83 } 84 else 85 { 86 temp = (temp << 7) | (c & 0x7f); 87 } 88 } 89 90 return NULL; 91} 92 93const unsigned char * 94svn__decode_int(apr_int64_t *val, 95 const unsigned char *p, 96 const unsigned char *end) 97{ 98 apr_uint64_t value; 99 const unsigned char *result = svn__decode_uint(&value, p, end); 100 101 value = value & 1 102 ? (APR_UINT64_MAX - value / 2) 103 : value / 2; 104 *val = (apr_int64_t)value; 105 106 return result; 107} 108