LCOV - app.info - other-licenses/snappy/src/snappy-stubs-internal.h

LCOV - code coverage report
| Current view: | directory - other-licenses/snappy/src - snappy-stubs-internal.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 86 | 46 | 53.5 %
| Date: | 2012-04-21 | Functions: | 18 | 9 | 50.0 %

           1                 : // Copyright 2011 Google Inc. All Rights Reserved.
           2                 : //
           3                 : // Redistribution and use in source and binary forms, with or without
           4                 : // modification, are permitted provided that the following conditions are
           5                 : // met:
           6                 : //
           7                 : //     * Redistributions of source code must retain the above copyright
           8                 : // notice, this list of conditions and the following disclaimer.
           9                 : //     * Redistributions in binary form must reproduce the above
          10                 : // copyright notice, this list of conditions and the following disclaimer
          11                 : // in the documentation and/or other materials provided with the
          12                 : // distribution.
          13                 : //     * Neither the name of Google Inc. nor the names of its
          14                 : // contributors may be used to endorse or promote products derived from
          15                 : // this software without specific prior written permission.
          16                 : //
          17                 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
          18                 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
          19                 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
          20                 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
          21                 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
          22                 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
          23                 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
          24                 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
          25                 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
          26                 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
          27                 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
          28                 : //
          29                 : // Various stubs for the open-source version of Snappy.
          30                 :
          31                 : #ifndef UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
          32                 : #define UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_
          33                 :
          34                 : #ifdef HAVE_CONFIG_H
          35                 : #include "config.h"
          36                 : #endif
          37                 :
          38                 : #include <iostream>
          39                 : #include <string>
          40                 :
          41                 : #include <assert.h>
          42                 : #include <stdlib.h>
          43                 : #include <string.h>
          44                 :
          45                 : #ifdef HAVE_SYS_MMAN_H
          46                 : #include <sys/mman.h>
          47                 : #endif
          48                 :
          49                 : #include "snappy-stubs-public.h"
          50                 :
          51                 : #if defined(__x86_64__)
          52                 :
          53                 : // Enable 64-bit optimized versions of some routines.
          54                 : #define ARCH_K8 1
          55                 :
          56                 : #endif
          57                 :
          58                 : // Needed by OS X, among others.
          59                 : #ifndef MAP_ANONYMOUS
          60                 : #define MAP_ANONYMOUS MAP_ANON
          61                 : #endif
          62                 :
          63                 : // Pull in std::min, std::ostream, and the likes. This is safe because this
          64                 : // header file is never used from any public header files.
          65                 : using namespace std;
          66                 :
          67                 : // The size of an array, if known at compile-time.
          68                 : // Will give unexpected results if used on a pointer.
          69                 : // We undefine it first, since some compilers already have a definition.
          70                 : #ifdef ARRAYSIZE
          71                 : #undef ARRAYSIZE
          72                 : #endif
          73                 : #define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))
          74                 :
          75                 : // Static prediction hints.
          76                 : #ifdef HAVE_BUILTIN_EXPECT
          77                 : #define PREDICT_FALSE(x) (__builtin_expect(x, 0))
          78                 : #define PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
          79                 : #else
          80                 : #define PREDICT_FALSE(x) x
          81                 : #define PREDICT_TRUE(x) x
          82                 : #endif
          83                 :
          84                 : // This is only used for recomputing the tag byte table used during
          85                 : // decompression; for simplicity we just remove it from the open-source
          86                 : // version (anyone who wants to regenerate it can just do the call
          87                 : // themselves within main()).
          88                 : #define DEFINE_bool(flag_name, default_value, description) \
          89                 :   bool FLAGS_ ## flag_name = default_value
          90                 : #define DECLARE_bool(flag_name) \
          91                 :   extern bool FLAGS_ ## flag_name
          92                 :
          93                 : namespace snappy {
          94                 :
          95                 : static const uint32 kuint32max = static_cast<uint32>(0xFFFFFFFF);
          96                 : static const int64 kint64max = static_cast<int64>(0x7FFFFFFFFFFFFFFFLL);
          97                 :
          98                 : // Logging.
          99                 :
         100                 : #define LOG(level) LogMessage()
         101                 : #define VLOG(level) true ? (void)0 : \
         102                 :     snappy::LogMessageVoidify() & snappy::LogMessage()
         103                 :
         104                 : class LogMessage {
         105                 :  public:
         106               0 :   LogMessage() { }
         107                 :   ~LogMessage() {
         108                 :     cerr << endl;
         109                 :   }
         110                 :
         111               0 :   LogMessage& operator<<(const std::string& msg) {
         112               0 :     cerr << msg;
         113               0 :     return *this;
         114                 :   }
         115               0 :   LogMessage& operator<<(int x) {
         116               0 :     cerr << x;
         117               0 :     return *this;
         118                 :   }
         119                 : };
         120                 :
         121                 : // Asserts, both versions activated in debug mode only,
         122                 : // and ones that are always active.
         123                 :
         124                 : #define CRASH_UNLESS(condition) \
         125                 :     PREDICT_TRUE(condition) ? (void)0 : \
         126                 :     snappy::LogMessageVoidify() & snappy::LogMessageCrash()
         127                 :
         128                 : class LogMessageCrash : public LogMessage {
         129                 :  public:
         130               0 :   LogMessageCrash() { }
         131               0 :   ~LogMessageCrash() {
         132               0 :     cerr << endl;
         133               0 :     abort();
         134                 :   }
         135                 : };
         136                 :
         137                 : // This class is used to explicitly ignore values in the conditional
         138                 : // logging macros.  This avoids compiler warnings like "value computed
         139                 : // is not used" and "statement has no effect".
         140                 :
         141                 : class LogMessageVoidify {
         142                 :  public:
         143               0 :   LogMessageVoidify() { }
         144                 :   // This has to be an operator with a precedence lower than << but
         145                 :   // higher than ?:
         146               0 :   void operator&(const LogMessage&) { }
         147                 : };
         148                 :
         149                 : #define CHECK(cond) CRASH_UNLESS(cond)
         150                 : #define CHECK_LE(a, b) CRASH_UNLESS((a) <= (b))
         151                 : #define CHECK_GE(a, b) CRASH_UNLESS((a) >= (b))
         152                 : #define CHECK_EQ(a, b) CRASH_UNLESS((a) == (b))
         153                 : #define CHECK_NE(a, b) CRASH_UNLESS((a) != (b))
         154                 : #define CHECK_LT(a, b) CRASH_UNLESS((a) < (b))
         155                 : #define CHECK_GT(a, b) CRASH_UNLESS((a) > (b))
         156                 :
         157                 : #ifdef NDEBUG
         158                 :
         159                 : #define DCHECK(cond) CRASH_UNLESS(true)
         160                 : #define DCHECK_LE(a, b) CRASH_UNLESS(true)
         161                 : #define DCHECK_GE(a, b) CRASH_UNLESS(true)
         162                 : #define DCHECK_EQ(a, b) CRASH_UNLESS(true)
         163                 : #define DCHECK_NE(a, b) CRASH_UNLESS(true)
         164                 : #define DCHECK_LT(a, b) CRASH_UNLESS(true)
         165                 : #define DCHECK_GT(a, b) CRASH_UNLESS(true)
         166                 :
         167                 : #else
         168                 :
         169                 : #define DCHECK(cond) CHECK(cond)
         170                 : #define DCHECK_LE(a, b) CHECK_LE(a, b)
         171                 : #define DCHECK_GE(a, b) CHECK_GE(a, b)
         172                 : #define DCHECK_EQ(a, b) CHECK_EQ(a, b)
         173                 : #define DCHECK_NE(a, b) CHECK_NE(a, b)
         174                 : #define DCHECK_LT(a, b) CHECK_LT(a, b)
         175                 : #define DCHECK_GT(a, b) CHECK_GT(a, b)
         176                 :
         177                 : #endif
         178                 :
         179                 : // Potentially unaligned loads and stores.
         180                 :
         181                 : #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__)
         182                 :
         183                 : #define UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16 *>(_p))
         184                 : #define UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p))
         185                 : #define UNALIGNED_LOAD64(_p) (*reinterpret_cast<const uint64 *>(_p))
         186                 :
         187                 : #define UNALIGNED_STORE16(_p, _val) (*reinterpret_cast<uint16 *>(_p) = (_val))
         188                 : #define UNALIGNED_STORE32(_p, _val) (*reinterpret_cast<uint32 *>(_p) = (_val))
         189                 : #define UNALIGNED_STORE64(_p, _val) (*reinterpret_cast<uint64 *>(_p) = (_val))
         190                 :
         191                 : #else
         192                 :
         193                 : // These functions are provided for architectures that don't support
         194                 : // unaligned loads and stores.
         195                 :
         196                 : inline uint16 UNALIGNED_LOAD16(const void *p) {
         197                 :   uint16 t;
         198                 :   memcpy(&t, p, sizeof t);
         199                 :   return t;
         200                 : }
         201                 :
         202                 : inline uint32 UNALIGNED_LOAD32(const void *p) {
         203                 :   uint32 t;
         204                 :   memcpy(&t, p, sizeof t);
         205                 :   return t;
         206                 : }
         207                 :
         208                 : inline uint64 UNALIGNED_LOAD64(const void *p) {
         209                 :   uint64 t;
         210                 :   memcpy(&t, p, sizeof t);
         211                 :   return t;
         212                 : }
         213                 :
         214                 : inline void UNALIGNED_STORE16(void *p, uint16 v) {
         215                 :   memcpy(p, &v, sizeof v);
         216                 : }
         217                 :
         218                 : inline void UNALIGNED_STORE32(void *p, uint32 v) {
         219                 :   memcpy(p, &v, sizeof v);
         220                 : }
         221                 :
         222                 : inline void UNALIGNED_STORE64(void *p, uint64 v) {
         223                 :   memcpy(p, &v, sizeof v);
         224                 : }
         225                 :
         226                 : #endif
         227                 :
         228                 : // The following guarantees declaration of the byte swap functions.
         229                 : #ifdef WORDS_BIGENDIAN
         230                 :
         231                 : #ifdef HAVE_SYS_BYTEORDER_H
         232                 : #include <sys/byteorder.h>
         233                 : #endif
         234                 :
         235                 : #ifdef HAVE_SYS_ENDIAN_H
         236                 : #include <sys/endian.h>
         237                 : #endif
         238                 :
         239                 : #ifdef _MSC_VER
         240                 : #include <stdlib.h>
         241                 : #define bswap_16(x) _byteswap_ushort(x)
         242                 : #define bswap_32(x) _byteswap_ulong(x)
         243                 : #define bswap_64(x) _byteswap_uint64(x)
         244                 :
         245                 : #elif defined(__APPLE__)
         246                 : // Mac OS X / Darwin features
         247                 : #include <libkern/OSByteOrder.h>
         248                 : #define bswap_16(x) OSSwapInt16(x)
         249                 : #define bswap_32(x) OSSwapInt32(x)
         250                 : #define bswap_64(x) OSSwapInt64(x)
         251                 :
         252                 : #elif defined(HAVE_BYTESWAP_H)
         253                 : #include <byteswap.h>
         254                 :
         255                 : #elif defined(bswap32)
         256                 : // FreeBSD defines bswap{16,32,64} in <sys/endian.h> (already #included).
         257                 : #define bswap_16(x) bswap16(x)
         258                 : #define bswap_32(x) bswap32(x)
         259                 : #define bswap_64(x) bswap64(x)
         260                 :
         261                 : #elif defined(BSWAP_64)
         262                 : // Solaris 10 defines BSWAP_{16,32,64} in <sys/byteorder.h> (already #included).
         263                 : #define bswap_16(x) BSWAP_16(x)
         264                 : #define bswap_32(x) BSWAP_32(x)
         265                 : #define bswap_64(x) BSWAP_64(x)
         266                 :
         267                 : #else
         268                 :
         269                 : inline uint16 bswap_16(uint16 x) {
         270                 :   return (x << 8) | (x >> 8);
         271                 : }
         272                 :
         273                 : inline uint32 bswap_32(uint32 x) {
         274                 :   x = ((x & 0xff00ff00UL) >> 8) | ((x & 0x00ff00ffUL) << 8);
         275                 :   return (x >> 16) | (x << 16);
         276                 : }
         277                 :
         278                 : inline uint64 bswap_64(uint64 x) {
         279                 :   x = ((x & 0xff00ff00ff00ff00ULL) >> 8) | ((x & 0x00ff00ff00ff00ffULL) << 8);
         280                 :   x = ((x & 0xffff0000ffff0000ULL) >> 16) | ((x & 0x0000ffff0000ffffULL) << 16);
         281                 :   return (x >> 32) | (x << 32);
         282                 : }
         283                 :
         284                 : #endif
         285                 :
         286                 : #endif  // WORDS_BIGENDIAN
         287                 :
         288                 : // Convert to little-endian storage, opposite of network format.
         289                 : // Convert x from host to little endian: x = LittleEndian.FromHost(x);
         290                 : // convert x from little endian to host: x = LittleEndian.ToHost(x);
         291                 : //
         292                 : //  Store values into unaligned memory converting to little endian order:
         293                 : //    LittleEndian.Store16(p, x);
         294                 : //
         295                 : //  Load unaligned values stored in little endian converting to host order:
         296                 : //    x = LittleEndian.Load16(p);
         297                 : class LittleEndian {
         298                 :  public:
         299                 :   // Conversion functions.
         300                 : #ifdef WORDS_BIGENDIAN
         301                 :
         302                 :   static uint16 FromHost16(uint16 x) { return bswap_16(x); }
         303                 :   static uint16 ToHost16(uint16 x) { return bswap_16(x); }
         304                 :
         305                 :   static uint32 FromHost32(uint32 x) { return bswap_32(x); }
         306                 :   static uint32 ToHost32(uint32 x) { return bswap_32(x); }
         307                 :
         308                 :   static bool IsLittleEndian() { return false; }
         309                 :
         310                 : #else  // !defined(WORDS_BIGENDIAN)
         311                 :
         312              57 :   static uint16 FromHost16(uint16 x) { return x; }
         313                 :   static uint16 ToHost16(uint16 x) { return x; }
         314                 :
         315                 :   static uint32 FromHost32(uint32 x) { return x; }
         316            4250 :   static uint32 ToHost32(uint32 x) { return x; }
         317                 :
         318            6477 :   static bool IsLittleEndian() { return true; }
         319                 :
         320                 : #endif  // !defined(WORDS_BIGENDIAN)
         321                 :
         322                 :   // Functions to do unaligned loads and stores in little-endian order.
         323                 :   static uint16 Load16(const void *p) {
         324                 :     return ToHost16(UNALIGNED_LOAD16(p));
         325                 :   }
         326                 :
         327              57 :   static void Store16(void *p, uint16 v) {
         328              57 :     UNALIGNED_STORE16(p, FromHost16(v));
         329              57 :   }
         330                 :
         331            4250 :   static uint32 Load32(const void *p) {
         332            4250 :     return ToHost32(UNALIGNED_LOAD32(p));
         333                 :   }
         334                 :
         335                 :   static void Store32(void *p, uint32 v) {
         336                 :     UNALIGNED_STORE32(p, FromHost32(v));
         337                 :   }
         338                 : };
         339                 :
         340                 : // Some bit-manipulation functions.
         341                 : class Bits {
         342                 :  public:
         343                 :   // Return floor(log2(n)) for positive integer n.  Returns -1 iff n == 0.
         344                 :   static int Log2Floor(uint32 n);
         345                 :
         346                 :   // Return the first set least / most significant bit, 0-indexed.  Returns an
         347                 :   // undefined value if n == 0.  FindLSBSetNonZero() is similar to ffs() except
         348                 :   // that it's 0-indexed.
         349                 :   static int FindLSBSetNonZero(uint32 n);
         350                 :   static int FindLSBSetNonZero64(uint64 n);
         351                 :
         352                 :  private:
         353                 :   DISALLOW_COPY_AND_ASSIGN(Bits);
         354                 : };
         355                 :
         356                 : #ifdef HAVE_BUILTIN_CTZ
         357                 :
         358                 : inline int Bits::Log2Floor(uint32 n) {
         359                 :   return n == 0 ? -1 : 31 ^ __builtin_clz(n);
         360                 : }
         361                 :
         362                 : inline int Bits::FindLSBSetNonZero(uint32 n) {
         363                 :   return __builtin_ctz(n);
         364                 : }
         365                 :
         366                 : inline int Bits::FindLSBSetNonZero64(uint64 n) {
         367                 :   return __builtin_ctzll(n);
         368                 : }
         369                 :
         370                 : #else  // Portable versions.
         371                 :
         372            1837 : inline int Bits::Log2Floor(uint32 n) {
         373            1837 :   if (n == 0)
         374               0 :     return -1;
         375            1837 :   int log = 0;
         376            1837 :   uint32 value = n;
         377           11022 :   for (int i = 4; i >= 0; --i) {
         378            9185 :     int shift = (1 << i);
         379            9185 :     uint32 x = value >> shift;
         380            9185 :     if (x != 0) {
         381            1837 :       value = x;
         382            1837 :       log += shift;
         383                 :     }
         384                 :   }
         385            1837 :   assert(value == 1);
         386            1837 :   return log;
         387                 : }
         388                 :
         389            1657 : inline int Bits::FindLSBSetNonZero(uint32 n) {
         390            1657 :   int rc = 31;
         391            9942 :   for (int i = 4, shift = 1 << 4; i >= 0; --i) {
         392            8285 :     const uint32 x = n << shift;
         393            8285 :     if (x != 0) {
         394            4986 :       n = x;
         395            4986 :       rc -= shift;
         396                 :     }
         397            8285 :     shift >>= 1;
         398                 :   }
         399            1657 :   return rc;
         400                 : }
         401                 :
         402                 : // FindLSBSetNonZero64() is defined in terms of FindLSBSetNonZero().
         403                 : inline int Bits::FindLSBSetNonZero64(uint64 n) {
         404                 :   const uint32 bottombits = static_cast<uint32>(n);
         405                 :   if (bottombits == 0) {
         406                 :     // Bottom bits are zero, so scan in top bits
         407                 :     return 32 + FindLSBSetNonZero(static_cast<uint32>(n >> 32));
         408                 :   } else {
         409                 :     return FindLSBSetNonZero(bottombits);
         410                 :   }
         411                 : }
         412                 :
         413                 : #endif  // End portable versions.
         414                 :
         415                 : // Variable-length integer encoding.
         416                 : class Varint {
         417                 :  public:
         418                 :   // Maximum lengths of varint encoding of uint32.
         419                 :   static const int kMax32 = 5;
         420                 :
         421                 :   // Attempts to parse a varint32 from a prefix of the bytes in [ptr,limit-1].
         422                 :   // Never reads a character at or beyond limit.  If a valid/terminated varint32
         423                 :   // was found in the range, stores it in *OUTPUT and returns a pointer just
         424                 :   // past the last byte of the varint32. Else returns NULL.  On success,
         425                 :   // "result <= limit".
         426                 :   static const char* Parse32WithLimit(const char* ptr, const char* limit,
         427                 :                                       uint32* OUTPUT);
         428                 :
         429                 :   // REQUIRES   "ptr" points to a buffer of length sufficient to hold "v".
         430                 :   // EFFECTS    Encodes "v" into "ptr" and returns a pointer to the
         431                 :   //            byte just past the last encoded byte.
         432                 :   static char* Encode32(char* ptr, uint32 v);
         433                 :
         434                 :   // EFFECTS    Appends the varint representation of "value" to "*s".
         435                 :   static void Append32(string* s, uint32 value);
         436                 : };
         437                 :
         438            2149 : inline const char* Varint::Parse32WithLimit(const char* p,
         439                 :                                             const char* l,
         440                 :                                             uint32* OUTPUT) {
         441            2149 :   const unsigned char* ptr = reinterpret_cast<const unsigned char*>(p);
         442            2149 :   const unsigned char* limit = reinterpret_cast<const unsigned char*>(l);
         443                 :   uint32 b, result;
         444            2149 :   if (ptr >= limit) return NULL;
         445            2149 :   b = *(ptr++); result = b & 127;          if (b < 128) goto done;
         446             224 :   if (ptr >= limit) return NULL;
         447             224 :   b = *(ptr++); result |= (b & 127) <<  7; if (b < 128) goto done;
         448               0 :   if (ptr >= limit) return NULL;
         449               0 :   b = *(ptr++); result |= (b & 127) << 14; if (b < 128) goto done;
         450               0 :   if (ptr >= limit) return NULL;
         451               0 :   b = *(ptr++); result |= (b & 127) << 21; if (b < 128) goto done;
         452               0 :   if (ptr >= limit) return NULL;
         453               0 :   b = *(ptr++); result |= (b & 127) << 28; if (b < 16) goto done;
         454               0 :   return NULL;       // Value is too long to be a varint32
         455                 :  done:
         456            2149 :   *OUTPUT = result;
         457            2149 :   return reinterpret_cast<const char*>(ptr);
         458                 : }
         459                 :
         460            1837 : inline char* Varint::Encode32(char* sptr, uint32 v) {
         461                 :   // Operate on characters as unsigneds
         462            1837 :   unsigned char* ptr = reinterpret_cast<unsigned char*>(sptr);
         463                 :   static const int B = 128;
         464            1837 :   if (v < (1<<7)) {
         465            1792 :     *(ptr++) = v;
         466              45 :   } else if (v < (1<<14)) {
         467              45 :     *(ptr++) = v | B;
         468              45 :     *(ptr++) = v>>7;
         469               0 :   } else if (v < (1<<21)) {
         470               0 :     *(ptr++) = v | B;
         471               0 :     *(ptr++) = (v>>7) | B;
         472               0 :     *(ptr++) = v>>14;
         473               0 :   } else if (v < (1<<28)) {
         474               0 :     *(ptr++) = v | B;
         475               0 :     *(ptr++) = (v>>7) | B;
         476               0 :     *(ptr++) = (v>>14) | B;
         477               0 :     *(ptr++) = v>>21;
         478                 :   } else {
         479               0 :     *(ptr++) = v | B;
         480               0 :     *(ptr++) = (v>>7) | B;
         481               0 :     *(ptr++) = (v>>14) | B;
         482               0 :     *(ptr++) = (v>>21) | B;
         483               0 :     *(ptr++) = v>>28;
         484                 :   }
         485            1837 :   return reinterpret_cast<char*>(ptr);
         486                 : }
         487                 :
         488                 : // If you know the internal layout of the std::string in use, you can
         489                 : // replace this function with one that resizes the string without
         490                 : // filling the new space with zeros (if applicable) --
         491                 : // it will be non-portable but faster.
         492               0 : inline void STLStringResizeUninitialized(string* s, size_t new_size) {
         493               0 :   s->resize(new_size);
         494               0 : }
         495                 :
         496                 : // Return a mutable char* pointing to a string's internal buffer,
         497                 : // which may not be null-terminated. Writing through this pointer will
         498                 : // modify the string.
         499                 : //
         500                 : // string_as_array(&str)[i] is valid for 0 <= i < str.size() until the
         501                 : // next call to a string method that invalidates iterators.
         502                 : //
         503                 : // As of 2006-04, there is no standard-blessed way of getting a
         504                 : // mutable reference to a string's internal buffer. However, issue 530
         505                 : // (http://www.open-std.org/JTC1/SC22/WG21/docs/lwg-defects.html#530)
         506                 : // proposes this as the method. It will officially be part of the standard
         507                 : // for C++0x. This should already work on all current implementations.
         508               0 : inline char* string_as_array(string* str) {
         509               0 :   return str->empty() ? NULL : &*str->begin();
         510                 : }
         511                 :
         512                 : }  // namespace snappy
         513                 :
         514                 : #endif  // UTIL_SNAPPY_OPENSOURCE_SNAPPY_STUBS_INTERNAL_H_

Generated by: LCOV version 1.7