1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright 2008 Google Inc. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Author: Lincoln Smith 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Licensed under the Apache License, Version 2.0 (the "License"); 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// you may not use this file except in compliance with the License. 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// You may obtain a copy of the License at 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// http://www.apache.org/licenses/LICENSE-2.0 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Unless required by applicable law or agreed to in writing, software 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// distributed under the License is distributed on an "AS IS" BASIS, 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// See the License for the specific language governing permissions and 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// limitations under the License. 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <config.h> 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "varint_bigendian.h" 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <stdint.h> // int32_t, int64_t 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string.h> // memcpy 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "logging.h" 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "google/output_string.h" 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace open_vcdiff { 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<> const int32_t VarintBE<int32_t>::kMaxVal = 0x7FFFFFFF; 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate<> const int64_t VarintBE<int64_t>::kMaxVal = 0x7FFFFFFFFFFFFFFFULL; 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Reads a variable-length integer from **varint_ptr 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and returns it in a fixed-length representation. Increments 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// *varint_ptr by the number of bytes read. Will not read 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// past limit. Returns RESULT_ERROR if the value parsed 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// does not fit in a non-negative signed integer, or if limit is NULL. 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Returns RESULT_END_OF_DATA if address_stream_end is reached 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// before the whole integer can be decoded. 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename SignedIntegerType> 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSignedIntegerType VarintBE<SignedIntegerType>::Parse(const char* limit, 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char** varint_ptr) { 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!limit) { 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return RESULT_ERROR; 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SignedIntegerType result = 0; 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (const char* parse_ptr = *varint_ptr; parse_ptr < limit; ++parse_ptr) { 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott result += *parse_ptr & 0x7F; 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!(*parse_ptr & 0x80)) { 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *varint_ptr = parse_ptr + 1; 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return result; 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (result > (kMaxVal >> 7)) { 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Shifting result by 7 bits would produce a number too large 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // to be stored in a non-negative SignedIntegerType (an overflow.) 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return RESULT_ERROR; 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott result = result << 7; 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return RESULT_END_OF_DATA; 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename SignedIntegerType> 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint VarintBE<SignedIntegerType>::EncodeInternal(SignedIntegerType v, 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char* varint_buf) { 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (v < 0) { 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(DFATAL) << "Negative value " << v 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott << " passed to VarintBE::EncodeInternal," 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " which requires non-negative argument" << LOG_ENDL; 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int length = 1; 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char* buf_ptr = &varint_buf[kMaxBytes - 1]; 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *buf_ptr = static_cast<char>(v & 0x7F); 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott --buf_ptr; 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott v >>= 7; 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (v) { 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *buf_ptr = static_cast<char>((v & 0x7F) | 0x80); // add continuation bit 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott --buf_ptr; 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++length; 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott v >>= 7; 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return length; 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename SignedIntegerType> 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint VarintBE<SignedIntegerType>::Encode(SignedIntegerType v, char* ptr) { 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char varint_buf[kMaxBytes]; 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int length = EncodeInternal(v, varint_buf); 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(ptr, &varint_buf[kMaxBytes - length], length); 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return length; 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename SignedIntegerType> 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid VarintBE<SignedIntegerType>::AppendToString(SignedIntegerType value, 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott string* s) { 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char varint_buf[kMaxBytes]; 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int length = EncodeInternal(value, varint_buf); 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott s->append(&varint_buf[kMaxBytes - length], length); 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename SignedIntegerType> 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid VarintBE<SignedIntegerType>::AppendToOutputString( 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SignedIntegerType value, 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OutputStringInterface* output_string) { 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char varint_buf[kMaxBytes]; 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int length = EncodeInternal(value, varint_buf); 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output_string->append(&varint_buf[kMaxBytes - length], length); 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Returns the encoding length of the specified value. 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename SignedIntegerType> 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint VarintBE<SignedIntegerType>::Length(SignedIntegerType v) { 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (v < 0) { 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott LOG(DFATAL) << "Negative value " << v 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott << " passed to VarintBE::Length," 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " which requires non-negative argument" << LOG_ENDL; 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int length = 0; 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott do { 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott v >>= 7; 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++length; 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } while (v); 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return length; 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate class VarintBE<int32_t>; 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate class VarintBE<int64_t>; 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace open_vcdiff 129