/* * Copyright 2016 Facebook, Inc. * * Licensed 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. */ #pragma once #include namespace folly { template class GroupVarint; namespace detail { template struct GroupVarintTraits; template <> struct GroupVarintTraits { enum { kGroupSize = 4, kHeaderSize = 1, }; }; template <> struct GroupVarintTraits { enum { kGroupSize = 5, kHeaderSize = 2, }; }; template class GroupVarintBase { protected: typedef GroupVarintTraits Traits; enum { kHeaderSize = Traits::kHeaderSize }; public: typedef T type; /** * Number of integers encoded / decoded in one pass. */ enum { kGroupSize = Traits::kGroupSize }; /** * Maximum encoded size. */ enum { kMaxSize = kHeaderSize + sizeof(type) * kGroupSize }; /** * Maximum size for n values. */ static size_t maxSize(size_t n) { // Full groups size_t total = (n / kGroupSize) * kFullGroupSize; // Incomplete last group, if any n %= kGroupSize; if (n) { total += kHeaderSize + n * sizeof(type); } return total; } /** * Size of n values starting at p. */ static size_t totalSize(const T* p, size_t n) { size_t size = 0; for (; n >= kGroupSize; n -= kGroupSize, p += kGroupSize) { size += Derived::size(p); } if (n) { size += Derived::partialSize(p, n); } return size; } private: typedef GroupVarint Derived; enum { kFullGroupSize = kHeaderSize + kGroupSize * sizeof(type) }; }; } // namespace detail } // namespace folly