github.com/dbernstein1/tyk@v2.9.0-beta9-dl-apic+incompatible/coprocess/sds/sds.h (about)

     1  /* SDSLib 2.0 -- A C dynamic strings library
     2   *
     3   * Copyright (c) 2006-2015, Salvatore Sanfilippo <antirez at gmail dot com>
     4   * Copyright (c) 2015, Oran Agra
     5   * Copyright (c) 2015, Redis Labs, Inc
     6   * All rights reserved.
     7   *
     8   * Redistribution and use in source and binary forms, with or without
     9   * modification, are permitted provided that the following conditions are met:
    10   *
    11   *   * Redistributions of source code must retain the above copyright notice,
    12   *     this list of conditions and the following disclaimer.
    13   *   * Redistributions in binary form must reproduce the above copyright
    14   *     notice, this list of conditions and the following disclaimer in the
    15   *     documentation and/or other materials provided with the distribution.
    16   *   * Neither the name of Redis nor the names of its contributors may be used
    17   *     to endorse or promote products derived from this software without
    18   *     specific prior written permission.
    19   *
    20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    30   * POSSIBILITY OF SUCH DAMAGE.
    31   */
    32  
    33  #ifndef __SDS_H
    34  #define __SDS_H
    35  
    36  #define SDS_MAX_PREALLOC (1024*1024)
    37  
    38  #include <sys/types.h>
    39  #include <stdarg.h>
    40  #include <stdint.h>
    41  
    42  typedef char *sds;
    43  
    44  /* Note: sdshdr5 is never used, we just access the flags byte directly.
    45   * However is here to document the layout of type 5 SDS strings. */
    46  struct __attribute__ ((__packed__)) sdshdr5 {
    47      unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    48      char buf[];
    49  };
    50  struct __attribute__ ((__packed__)) sdshdr8 {
    51      uint8_t len; /* used */
    52      uint8_t alloc; /* excluding the header and null terminator */
    53      unsigned char flags; /* 3 lsb of type, 5 unused bits */
    54      char buf[];
    55  };
    56  struct __attribute__ ((__packed__)) sdshdr16 {
    57      uint16_t len; /* used */
    58      uint16_t alloc; /* excluding the header and null terminator */
    59      unsigned char flags; /* 3 lsb of type, 5 unused bits */
    60      char buf[];
    61  };
    62  struct __attribute__ ((__packed__)) sdshdr32 {
    63      uint32_t len; /* used */
    64      uint32_t alloc; /* excluding the header and null terminator */
    65      unsigned char flags; /* 3 lsb of type, 5 unused bits */
    66      char buf[];
    67  };
    68  struct __attribute__ ((__packed__)) sdshdr64 {
    69      uint64_t len; /* used */
    70      uint64_t alloc; /* excluding the header and null terminator */
    71      unsigned char flags; /* 3 lsb of type, 5 unused bits */
    72      char buf[];
    73  };
    74  
    75  #define SDS_TYPE_5  0
    76  #define SDS_TYPE_8  1
    77  #define SDS_TYPE_16 2
    78  #define SDS_TYPE_32 3
    79  #define SDS_TYPE_64 4
    80  #define SDS_TYPE_MASK 7
    81  #define SDS_TYPE_BITS 3
    82  #define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (void*)((s)-(sizeof(struct sdshdr##T)));
    83  #define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))
    84  #define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS)
    85  
    86  static inline size_t sdslen(const sds s) {
    87      unsigned char flags = s[-1];
    88      switch(flags&SDS_TYPE_MASK) {
    89          case SDS_TYPE_5:
    90              return SDS_TYPE_5_LEN(flags);
    91          case SDS_TYPE_8:
    92              return SDS_HDR(8,s)->len;
    93          case SDS_TYPE_16:
    94              return SDS_HDR(16,s)->len;
    95          case SDS_TYPE_32:
    96              return SDS_HDR(32,s)->len;
    97          case SDS_TYPE_64:
    98              return SDS_HDR(64,s)->len;
    99      }
   100      return 0;
   101  }
   102  
   103  static inline size_t sdsavail(const sds s) {
   104      unsigned char flags = s[-1];
   105      switch(flags&SDS_TYPE_MASK) {
   106          case SDS_TYPE_5: {
   107              return 0;
   108          }
   109          case SDS_TYPE_8: {
   110              SDS_HDR_VAR(8,s);
   111              return sh->alloc - sh->len;
   112          }
   113          case SDS_TYPE_16: {
   114              SDS_HDR_VAR(16,s);
   115              return sh->alloc - sh->len;
   116          }
   117          case SDS_TYPE_32: {
   118              SDS_HDR_VAR(32,s);
   119              return sh->alloc - sh->len;
   120          }
   121          case SDS_TYPE_64: {
   122              SDS_HDR_VAR(64,s);
   123              return sh->alloc - sh->len;
   124          }
   125      }
   126      return 0;
   127  }
   128  
   129  static inline void sdssetlen(sds s, size_t newlen) {
   130      unsigned char flags = s[-1];
   131      switch(flags&SDS_TYPE_MASK) {
   132          case SDS_TYPE_5:
   133              {
   134                  unsigned char *fp = ((unsigned char*)s)-1;
   135                  *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS);
   136              }
   137              break;
   138          case SDS_TYPE_8:
   139              SDS_HDR(8,s)->len = newlen;
   140              break;
   141          case SDS_TYPE_16:
   142              SDS_HDR(16,s)->len = newlen;
   143              break;
   144          case SDS_TYPE_32:
   145              SDS_HDR(32,s)->len = newlen;
   146              break;
   147          case SDS_TYPE_64:
   148              SDS_HDR(64,s)->len = newlen;
   149              break;
   150      }
   151  }
   152  
   153  static inline void sdsinclen(sds s, size_t inc) {
   154      unsigned char flags = s[-1];
   155      switch(flags&SDS_TYPE_MASK) {
   156          case SDS_TYPE_5:
   157              {
   158                  unsigned char *fp = ((unsigned char*)s)-1;
   159                  unsigned char newlen = SDS_TYPE_5_LEN(flags)+inc;
   160                  *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS);
   161              }
   162              break;
   163          case SDS_TYPE_8:
   164              SDS_HDR(8,s)->len += inc;
   165              break;
   166          case SDS_TYPE_16:
   167              SDS_HDR(16,s)->len += inc;
   168              break;
   169          case SDS_TYPE_32:
   170              SDS_HDR(32,s)->len += inc;
   171              break;
   172          case SDS_TYPE_64:
   173              SDS_HDR(64,s)->len += inc;
   174              break;
   175      }
   176  }
   177  
   178  /* sdsalloc() = sdsavail() + sdslen() */
   179  static inline size_t sdsalloc(const sds s) {
   180      unsigned char flags = s[-1];
   181      switch(flags&SDS_TYPE_MASK) {
   182          case SDS_TYPE_5:
   183              return SDS_TYPE_5_LEN(flags);
   184          case SDS_TYPE_8:
   185              return SDS_HDR(8,s)->alloc;
   186          case SDS_TYPE_16:
   187              return SDS_HDR(16,s)->alloc;
   188          case SDS_TYPE_32:
   189              return SDS_HDR(32,s)->alloc;
   190          case SDS_TYPE_64:
   191              return SDS_HDR(64,s)->alloc;
   192      }
   193      return 0;
   194  }
   195  
   196  static inline void sdssetalloc(sds s, size_t newlen) {
   197      unsigned char flags = s[-1];
   198      switch(flags&SDS_TYPE_MASK) {
   199          case SDS_TYPE_5:
   200              /* Nothing to do, this type has no total allocation info. */
   201              break;
   202          case SDS_TYPE_8:
   203              SDS_HDR(8,s)->alloc = newlen;
   204              break;
   205          case SDS_TYPE_16:
   206              SDS_HDR(16,s)->alloc = newlen;
   207              break;
   208          case SDS_TYPE_32:
   209              SDS_HDR(32,s)->alloc = newlen;
   210              break;
   211          case SDS_TYPE_64:
   212              SDS_HDR(64,s)->alloc = newlen;
   213              break;
   214      }
   215  }
   216  
   217  sds sdsnewlen(const void *init, size_t initlen);
   218  sds sdsnew(const char *init);
   219  sds sdsempty(void);
   220  sds sdsdup(const sds s);
   221  void sdsfree(sds s);
   222  sds sdsgrowzero(sds s, size_t len);
   223  sds sdscatlen(sds s, const void *t, size_t len);
   224  sds sdscat(sds s, const char *t);
   225  sds sdscatsds(sds s, const sds t);
   226  sds sdscpylen(sds s, const char *t, size_t len);
   227  sds sdscpy(sds s, const char *t);
   228  
   229  sds sdscatvprintf(sds s, const char *fmt, va_list ap);
   230  #ifdef __GNUC__
   231  sds sdscatprintf(sds s, const char *fmt, ...)
   232      __attribute__((format(printf, 2, 3)));
   233  #else
   234  sds sdscatprintf(sds s, const char *fmt, ...);
   235  #endif
   236  
   237  sds sdscatfmt(sds s, char const *fmt, ...);
   238  sds sdstrim(sds s, const char *cset);
   239  void sdsrange(sds s, int start, int end);
   240  void sdsupdatelen(sds s);
   241  void sdsclear(sds s);
   242  int sdscmp(const sds s1, const sds s2);
   243  sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count);
   244  void sdsfreesplitres(sds *tokens, int count);
   245  void sdstolower(sds s);
   246  void sdstoupper(sds s);
   247  sds sdsfromlonglong(long long value);
   248  sds sdscatrepr(sds s, const char *p, size_t len);
   249  sds *sdssplitargs(const char *line, int *argc);
   250  sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
   251  sds sdsjoin(char **argv, int argc, char *sep);
   252  sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);
   253  
   254  /* Low level functions exposed to the user API */
   255  sds sdsMakeRoomFor(sds s, size_t addlen);
   256  void sdsIncrLen(sds s, int incr);
   257  sds sdsRemoveFreeSpace(sds s);
   258  size_t sdsAllocSize(sds s);
   259  void *sdsAllocPtr(sds s);
   260  
   261  /* Export the allocator used by SDS to the program using SDS.
   262   * Sometimes the program SDS is linked to, may use a different set of
   263   * allocators, but may want to allocate or free things that SDS will
   264   * respectively free or allocate. */
   265  void *sds_malloc(size_t size);
   266  void *sds_realloc(void *ptr, size_t size);
   267  void sds_free(void *ptr);
   268  
   269  #ifdef REDIS_TEST
   270  int sdsTest(int argc, char *argv[]);
   271  #endif
   272  
   273  #endif