daily pastebin goal
44%
SHARE
TWEET

Untitled

a guest Dec 30th, 2012 33 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. template<typename T> struct alignment_trick { char c; T member; };
  3. #define ALIGNOF(type) offsetof (alignment_trick<type>, member)
  4. #define PADDING(x, y) ((ALIGNOF(y) - ((uintptr_t)(x) & (ALIGNOF(y) - 1))) & (ALIGNOF(y) - 1))
  5.  
  6.         void *getStruct(std::string &name, std::string format, size_t len)
  7.         {
  8.                 std::vector<std::string *> strs_alloced;
  9.                 std::string *str;
  10.                 char *s = &(get(name))[0];
  11.                 char *buf = new char[len];
  12.                 char *bufpos = buf;
  13.                 char *f, *snext;
  14.                 size_t pos;
  15.  
  16.                 char *fmt = &format[0];
  17.                 while ((f = strsep(&fmt, ",")) && s) {
  18.                         bool is_unsigned = false;
  19.                         int width = 0;
  20.                         char valtype = *f;
  21.  
  22.                         width = (int)strtol(f + 1, &f, 10);
  23.                         if (width && valtype == 's')
  24.                                 valtype = 'i';
  25.  
  26.                         switch (*f) {
  27.                                 case 'u':
  28.                                         is_unsigned = true;
  29.                                         /* FALLTHROUGH */
  30.                                 case 'i':
  31.                                         if (width == 16) {
  32.                                                 bufpos += PADDING(bufpos, u16);
  33.                                                 if ((bufpos - buf) + sizeof(u16) <= len) {
  34.                                                         if (is_unsigned)
  35.                                                                 *(u16 *)bufpos = (u16)strtoul(s, &s, 10);
  36.                                                         else
  37.                                                                 *(s16 *)bufpos = (s16)strtol(s, &s, 10);
  38.                                                 }
  39.                                                 bufpos += sizeof(u16);
  40.                                         } else if (width == 32) {
  41.                                                 bufpos += PADDING(bufpos, u32);
  42.                                                 if ((bufpos - buf) + sizeof(u32) <= len) {
  43.                                                         if (is_unsigned)
  44.                                                                 *(u32 *)bufpos = (u32)strtoul(s, &s, 10);
  45.                                                         else
  46.                                                                 *(s32 *)bufpos = (s32)strtol(s, &s, 10);
  47.                                                 }
  48.                                                 bufpos += sizeof(u32);
  49.                                         } else if (width == 64) {
  50.                                                 bufpos += PADDING(bufpos, u64);
  51.                                                 if ((bufpos - buf) + sizeof(u64) <= len) {
  52.                                                         if (is_unsigned)
  53.                                                                 *(u64 *)bufpos = (u64)strtoull(s, &s, 10);
  54.                                                         else
  55.                                                                 *(s64 *)bufpos = (s64)strtoll(s, &s, 10);
  56.                                                 }
  57.                                                 bufpos += sizeof(u64);
  58.                                         }
  59.                                         s = strchr(s, ',');
  60.                                         break;
  61.                                 case 'b':
  62.                                         snext = strchr(s, ',');
  63.                                         if (snext)
  64.                                                 *snext++ = 0;
  65.  
  66.                                         bufpos += PADDING(bufpos, bool);
  67.                                         if ((bufpos - buf) + sizeof(bool) <= len)
  68.                                                 *(bool *)bufpos = is_yes(std::string(s));
  69.                                         bufpos += sizeof(bool);
  70.  
  71.                                         s = snext;
  72.                                         break;
  73.                                 case 'f':
  74.                                         bufpos += PADDING(bufpos, float);
  75.                                         if ((bufpos - buf) + sizeof(float) <= len)
  76.                                                 *(float *)bufpos = strtof(s, &s);
  77.                                         bufpos += sizeof(float);
  78.  
  79.                                         s = strchr(s, ',');
  80.                                         break;
  81.                                 case 's':
  82.                                         while (*s == ' ' || *s == '\t')
  83.                                                 s++;
  84.                                         if (*s++ != '"') //error, expected string
  85.                                                 goto fail;
  86.                                         snext = s;
  87.  
  88.                                         while (snext[0] && !(snext[-1] != '\\' && snext[0] == '"'))
  89.                                                 snext++;
  90.                                         *snext++ = 0;
  91.  
  92.                                         bufpos += PADDING(bufpos, std::string *);
  93.  
  94.                                         str = new std::string(s);
  95.                                         pos = 0;
  96.                                         while ((pos = str->find("\\\"", pos)) != std::string::npos)
  97.                                                 str->erase(pos, 1);
  98.  
  99.                                         if ((bufpos - buf) + sizeof(std::string *) <= len)
  100.                                                 *(std::string **)bufpos = str;
  101.                                         bufpos += sizeof(std::string *);
  102.                                         strs_alloced.push_back(str);
  103.  
  104.                                         s = *snext ? snext + 1 : NULL;
  105.                                         break;
  106.                                 case 'v':
  107.                                         while (*s == ' ' || *s == '\t')
  108.                                                 s++;
  109.                                         if (*s++ != '(') //error, expected vector
  110.                                                 goto fail;
  111.  
  112.                                         if (width == 2) {
  113.                                                 bufpos += PADDING(bufpos, v2f);
  114.  
  115.                                                 if ((bufpos - buf) + sizeof(v2f) <= len) {
  116.                                                 v2f *v = (v2f *)bufpos;
  117.                                                         v->X = strtof(s, &s);
  118.                                                         s++;
  119.                                                         v->Y = strtof(s, &s);
  120.                                                 }
  121.  
  122.                                                 bufpos += sizeof(v2f);
  123.                                         } else if (width == 3) {
  124.                                                 bufpos += PADDING(bufpos, v3f);
  125.                                                 if ((bufpos - buf) + sizeof(v3f) <= len) {
  126.                                                         v3f *v = (v3f *)bufpos;
  127.                                                         v->X = strtof(s, &s);
  128.                                                         s++;
  129.                                                         v->Y = strtof(s, &s);
  130.                                                         s++;
  131.                                                         v->Z = strtof(s, &s);
  132.                                                 }
  133.  
  134.                                                 bufpos += sizeof(v3f);
  135.                                         }
  136.                                         s = strchr(s, ',');
  137.                         }
  138.  
  139.                         if (s && *s == ',')
  140.                                 s++;
  141.  
  142.                         if ((bufpos - buf) > len) //error, buffer too small
  143.                                 goto fail;
  144.                 }
  145.  
  146.                 if (f && *f) { //error, mismatched number of fields and values
  147. fail:
  148.                         for (int i = 0; i != strs_alloced.size(); i++)
  149.                                 delete strs_alloced[i];
  150.                         delete[] buf;
  151.                         buf = NULL;
  152.                 }
  153.  
  154.                 return buf;
  155.         }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top