YiinY

for sa-mp com

Feb 7th, 2013
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.23 KB | None | 0 0
  1. stock CompressFormat(const data[])
  2. {
  3.     // This function encodes the data format in to a single cell.  The format is:
  4.     //  
  5.     //  1111111001
  6.     //  
  7.     // Leading 1s indicate no data.  The 0 immediately following the leading 1s
  8.     // indicates the start of the format section (but is not PART of the format
  9.     // section).  The remaining bits represent either strings (1) or non-strings
  10.     // (0).  For example "(a, string:b, c)" would be:
  11.     //  
  12.     //  1..10010
  13.     //  
  14.     // Where "1..1" indicates full-cell padding of 1s.  From this it is known that
  15.     // the function takes three parameters: non-string, string, non-string.  In
  16.     // addition, as strings in inline functions MUST use the "string:" tag, it is
  17.     // known that ALL strings will ALWAYS be 128 (or "YSI_MAX_STRING") cells big.
  18.     new
  19.         pos = 0,
  20.         total = 1;
  21.     for ( ; ; )
  22.     {
  23.         // Now matchs the compile-time code much closer.
  24.         switch (data[pos++])
  25.         {
  26.             case '\0':
  27.             {
  28.                 break;
  29.             }
  30.             case 's':
  31.             {
  32.                 total <<= 1;
  33.             }
  34.             default:
  35.             {
  36.                 total = (total << 1) | 1;
  37.             }
  38.         }
  39.     }
  40.     // Store the compressed format, also instantly end the string.
  41.     return ~total;
  42. }
  43.  
  44. forward @queryCallback(e_CALLBACK_FLAGS:cF, cP, cX, Alloc:cA, Alloc:a);
  45. public @queryCallback(e_CALLBACK_FLAGS:cF, cP, cX, Alloc:cA, Alloc:a)
  46. {
  47.     new
  48.         ret[E_CALLBACK_DATA];
  49.     ret[E_CALLBACK_DATA_FLAGS] = cF;
  50.     ret[E_CALLBACK_DATA_POINTER] = cP;
  51.     ret[E_CALLBACK_DATA_FORMAT] = cX;
  52.     ret[E_CALLBACK_DATA_ALLOC] = cA;
  53.     Callback_Block(ret, Malloc_GetData(a, 2), Malloc_GetSlotSize(a) - 2);
  54.     free(cA);
  55.     free(a);
  56. }
  57.  
  58. stock send_query(connectionHandle, query[], bool:cache, callback:callback, const type[], GLOBAL_TAG_TYPES:...)
  59. {
  60.     new
  61.         ret[E_CALLBACK_DATA],
  62.         mem = CompressFormat(type);
  63.     if (!Callback_Get(callback, ret))
  64.     {
  65.         return 0;
  66.     }
  67.     if (!(ret[E_CALLBACK_DATA_FLAGS] & e_CALLBACK_FLAGS_PUBLIC) && mem != ret[E_CALLBACK_DATA_FORMAT])
  68.     {
  69.         P:E("Format specifier didn't match on inline function %s: %04x%04x != %04x%04x", callback, mem >>> 16, mem & 0xFFFF, ret[E_CALLBACK_DATA_FORMAT] >>> 16, ret[E_CALLBACK_DATA_FORMAT] & 0xFFFF);
  70.         Callback_Release(ret);
  71.         return 0;
  72.     }
  73.     mem = 2;
  74.     // Allocate enough memory to store all the parameters.
  75.     for (new i = 0; ; ++i)
  76.     {
  77.         switch (type[i])
  78.         {
  79.             case '\0':
  80.             {
  81.                 break;
  82.             }
  83.             case 's':
  84.             {
  85.                 mem += YSI_MAX_STRING;
  86.             }
  87.             case 'a':
  88.             {
  89.                 P:E("y_inline doesn't support arrays.");
  90.                 return 0;
  91.             }
  92.             default:
  93.             {
  94.                 ++mem;
  95.             }
  96.         }
  97.     }
  98.     new
  99.         Alloc:a = malloc(mem);
  100.     if (a == NO_ALLOC)
  101.     {
  102.         Callback_Release(ret);
  103.         return 0;
  104.     }
  105.     // Copy all the data to an array.
  106.     //mem = 2;
  107.     for (new i = 0, j = 4; ; ++i, ++j)
  108.     {
  109.         switch (type[i])
  110.         {
  111.             case '\0':
  112.             {
  113.                 break;
  114.             }
  115.             case 's':
  116.             {
  117.                 // Set variable argument string.
  118.                 mem -= YSI_MAX_STRING;
  119.                 Malloc_SetVAS(a, mem, j);
  120.                 //Malloc_Set(a, mem - 1, '\0');
  121.             }
  122.             default:
  123.             {
  124.                 --mem;
  125.                 Malloc_Set(a, mem, getarg(j));
  126.             }
  127.         }
  128.     }
  129.     // Now call the handler.
  130.     Malloc_Set(a, 1, _:ret[E_CALLBACK_DATA_ALLOC]);
  131.     Malloc_Set(a, 0, mysql_function_query(connectionHandle, query, cache, "@queryCallback", "iiiii", _:ret[E_CALLBACK_DATA_FLAGS], ret[E_CALLBACK_DATA_POINTER], ret[E_CALLBACK_DATA_FORMAT], _:ret[E_CALLBACK_DATA_ALLOC], _:a));
  132.     return 1;
  133. }
Advertisement
Add Comment
Please, Sign In to add comment