go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/server/quota/internal/luatest/testdata/luamsgpack/MessagePack.lua (about)

     1  --
     2  -- lua-MessagePack : <https://fperrad.frama.io/lua-MessagePack/>
     3  --
     4  
     5  local r, jit = pcall(require, 'jit')
     6  if not r then
     7      jit = nil
     8  end
     9  
    10  local SIZEOF_NUMBER = string.pack and #string.pack('n', 0.0) or 8
    11  local maxinteger
    12  local mininteger
    13  
    14  local assert = assert
    15  local error = error
    16  local pairs = pairs
    17  local pcall = pcall
    18  local setmetatable = setmetatable
    19  local tostring = tostring
    20  local type = type
    21  local char = require'string'.char
    22  local format = require'string'.format
    23  local floor = require'math'.floor
    24  local tointeger = require'math'.tointeger or floor
    25  local frexp = require'math'.frexp or require'mathx'.frexp
    26  local ldexp = require'math'.ldexp or require'mathx'.ldexp
    27  local huge = require'math'.huge
    28  local tconcat = require'table'.concat
    29  
    30  local _ENV = nil
    31  local m = {}
    32  
    33  --[[ debug only
    34  local function hexadump (s)
    35      return (s:gsub('.', function (c) return format('%02X ', c:byte()) end))
    36  end
    37  m.hexadump = hexadump
    38  --]]
    39  
    40  local function argerror (caller, narg, extramsg)
    41      error("bad argument #" .. tostring(narg) .. " to "
    42            .. caller .. " (" .. extramsg .. ")")
    43  end
    44  
    45  local function typeerror (caller, narg, arg, tname)
    46      argerror(caller, narg, tname .. " expected, got " .. type(arg))
    47  end
    48  
    49  local function checktype (caller, narg, arg, tname)
    50      if type(arg) ~= tname then
    51          typeerror(caller, narg, arg, tname)
    52      end
    53  end
    54  
    55  local packers = setmetatable({}, {
    56      __index = function (t, k)
    57          if k == 1 then return end   -- allows ipairs
    58          error("pack '" .. k .. "' is unimplemented")
    59      end
    60  })
    61  m.packers = packers
    62  
    63  packers['nil'] = function (buffer)
    64      buffer[#buffer+1] = char(0xC0)              -- nil
    65  end
    66  
    67  packers['boolean'] = function (buffer, bool)
    68      if bool then
    69          buffer[#buffer+1] = char(0xC3)          -- true
    70      else
    71          buffer[#buffer+1] = char(0xC2)          -- false
    72      end
    73  end
    74  
    75  packers['string_compat'] = function (buffer, str)
    76      local n = #str
    77      if n <= 0x1F then
    78          buffer[#buffer+1] = char(0xA0 + n)      -- fixstr
    79      elseif n <= 0xFFFF then
    80          buffer[#buffer+1] = char(0xDA,          -- str16
    81                                   floor(n / 0x100),
    82                                   n % 0x100)
    83      elseif n <= 4294967295.0 then
    84          buffer[#buffer+1] = char(0xDB,          -- str32
    85                                   floor(n / 0x1000000),
    86                                   floor(n / 0x10000) % 0x100,
    87                                   floor(n / 0x100) % 0x100,
    88                                   n % 0x100)
    89      else
    90          error"overflow in pack 'string_compat'"
    91      end
    92      buffer[#buffer+1] = str
    93  end
    94  
    95  packers['_string'] = function (buffer, str)
    96      local n = #str
    97      if n <= 0x1F then
    98          buffer[#buffer+1] = char(0xA0 + n)      -- fixstr
    99      elseif n <= 0xFF then
   100          buffer[#buffer+1] = char(0xD9,          -- str8
   101                                   n)
   102      elseif n <= 0xFFFF then
   103          buffer[#buffer+1] = char(0xDA,          -- str16
   104                                   floor(n / 0x100),
   105                                   n % 0x100)
   106      elseif n <= 4294967295.0 then
   107          buffer[#buffer+1] = char(0xDB,          -- str32
   108                                   floor(n / 0x1000000),
   109                                   floor(n / 0x10000) % 0x100,
   110                                   floor(n / 0x100) % 0x100,
   111                                   n % 0x100)
   112      else
   113          error"overflow in pack 'string'"
   114      end
   115      buffer[#buffer+1] = str
   116  end
   117  
   118  packers['binary'] = function (buffer, str)
   119      local n = #str
   120      if n <= 0xFF then
   121          buffer[#buffer+1] = char(0xC4,          -- bin8
   122                                   n)
   123      elseif n <= 0xFFFF then
   124          buffer[#buffer+1] = char(0xC5,          -- bin16
   125                                   floor(n / 0x100),
   126                                   n % 0x100)
   127      elseif n <= 4294967295.0 then
   128          buffer[#buffer+1] = char(0xC6,          -- bin32
   129                                   floor(n / 0x1000000),
   130                                   floor(n / 0x10000) % 0x100,
   131                                   floor(n / 0x100) % 0x100,
   132                                   n % 0x100)
   133      else
   134          error"overflow in pack 'binary'"
   135      end
   136      buffer[#buffer+1] = str
   137  end
   138  
   139  local set_string = function (str)
   140      if str == 'string_compat' then
   141          packers['string'] = packers['string_compat']
   142      elseif str == 'string' then
   143          packers['string'] = packers['_string']
   144      elseif str == 'binary' then
   145          packers['string'] = packers['binary']
   146      else
   147          argerror('set_string', 1, "invalid option '" .. str .."'")
   148      end
   149  end
   150  m.set_string = set_string
   151  
   152  packers['map'] = function (buffer, tbl, n)
   153      if n <= 0x0F then
   154          buffer[#buffer+1] = char(0x80 + n)      -- fixmap
   155      elseif n <= 0xFFFF then
   156          buffer[#buffer+1] = char(0xDE,          -- map16
   157                                   floor(n / 0x100),
   158                                   n % 0x100)
   159      elseif n <= 4294967295.0 then
   160          buffer[#buffer+1] = char(0xDF,          -- map32
   161                                   floor(n / 0x1000000),
   162                                   floor(n / 0x10000) % 0x100,
   163                                   floor(n / 0x100) % 0x100,
   164                                   n % 0x100)
   165      else
   166          error"overflow in pack 'map'"
   167      end
   168      for k, v in pairs(tbl) do
   169          packers[type(k)](buffer, k)
   170          packers[type(v)](buffer, v)
   171      end
   172  end
   173  
   174  packers['array'] = function (buffer, tbl, n)
   175      if n <= 0x0F then
   176          buffer[#buffer+1] = char(0x90 + n)      -- fixarray
   177      elseif n <= 0xFFFF then
   178          buffer[#buffer+1] = char(0xDC,          -- array16
   179                                   floor(n / 0x100),
   180                                   n % 0x100)
   181      elseif n <= 4294967295.0 then
   182          buffer[#buffer+1] = char(0xDD,          -- array32
   183                                   floor(n / 0x1000000),
   184                                   floor(n / 0x10000) % 0x100,
   185                                   floor(n / 0x100) % 0x100,
   186                                   n % 0x100)
   187      else
   188          error"overflow in pack 'array'"
   189      end
   190      for i = 1, n do
   191          local v = tbl[i]
   192          packers[type(v)](buffer, v)
   193      end
   194  end
   195  
   196  local set_array = function (array)
   197      if array == 'without_hole' then
   198          packers['_table'] = function (buffer, tbl)
   199              local is_map, n, max = false, 0, 0
   200              for k in pairs(tbl) do
   201                  if type(k) == 'number' and k > 0 then
   202                      if k > max then
   203                          max = k
   204                      end
   205                  else
   206                      is_map = true
   207                  end
   208                  n = n + 1
   209              end
   210              if max ~= n then    -- there are holes
   211                  is_map = true
   212              end
   213              if is_map then
   214                  packers['map'](buffer, tbl, n)
   215              else
   216                  packers['array'](buffer, tbl, n)
   217              end
   218          end
   219      elseif array == 'with_hole' then
   220          packers['_table'] = function (buffer, tbl)
   221              local is_map, n, max = false, 0, 0
   222              for k in pairs(tbl) do
   223                  if type(k) == 'number' and k > 0 then
   224                      if k > max then
   225                          max = k
   226                      end
   227                  else
   228                      is_map = true
   229                  end
   230                  n = n + 1
   231              end
   232              if is_map then
   233                  packers['map'](buffer, tbl, n)
   234              else
   235                  packers['array'](buffer, tbl, max)
   236              end
   237          end
   238      elseif array == 'always_as_map' then
   239          packers['_table'] = function(buffer, tbl)
   240              local n = 0
   241              for k in pairs(tbl) do
   242                  n = n + 1
   243              end
   244              packers['map'](buffer, tbl, n)
   245          end
   246      else
   247          argerror('set_array', 1, "invalid option '" .. array .."'")
   248      end
   249  end
   250  m.set_array = set_array
   251  
   252  packers['table'] = function (buffer, tbl)
   253      packers['_table'](buffer, tbl)
   254  end
   255  
   256  packers['unsigned'] = function (buffer, n)
   257      if n >= 0 then
   258          if n <= 0x7F then
   259              buffer[#buffer+1] = char(n)         -- fixnum_pos
   260          elseif n <= 0xFF then
   261              buffer[#buffer+1] = char(0xCC,      -- uint8
   262                                       n)
   263          elseif n <= 0xFFFF then
   264              buffer[#buffer+1] = char(0xCD,      -- uint16
   265                                       floor(n / 0x100),
   266                                       n % 0x100)
   267          elseif n <= 4294967295.0 then
   268              buffer[#buffer+1] = char(0xCE,      -- uint32
   269                                       floor(n / 0x1000000),
   270                                       floor(n / 0x10000) % 0x100,
   271                                       floor(n / 0x100) % 0x100,
   272                                       n % 0x100)
   273          else
   274              buffer[#buffer+1] = char(0xCF,      -- uint64
   275                                       0,         -- only 53 bits from double
   276                                       floor(n / 0x1000000000000) % 0x100,
   277                                       floor(n / 0x10000000000) % 0x100,
   278                                       floor(n / 0x100000000) % 0x100,
   279                                       floor(n / 0x1000000) % 0x100,
   280                                       floor(n / 0x10000) % 0x100,
   281                                       floor(n / 0x100) % 0x100,
   282                                       n % 0x100)
   283          end
   284      else
   285          if n >= -0x20 then
   286              buffer[#buffer+1] = char(0x100 + n) -- fixnum_neg
   287          elseif n >= -0x80 then
   288              buffer[#buffer+1] = char(0xD0,      -- int8
   289                                       0x100 + n)
   290          elseif n >= -0x8000 then
   291              n = 0x10000 + n
   292              buffer[#buffer+1] = char(0xD1,      -- int16
   293                                       floor(n / 0x100),
   294                                       n % 0x100)
   295          elseif n >= -0x80000000 then
   296              n = 4294967296.0 + n
   297              buffer[#buffer+1] = char(0xD2,      -- int32
   298                                       floor(n / 0x1000000),
   299                                       floor(n / 0x10000) % 0x100,
   300                                       floor(n / 0x100) % 0x100,
   301                                       n % 0x100)
   302          else
   303              buffer[#buffer+1] = char(0xD3,      -- int64
   304                                       0xFF,      -- only 53 bits from double
   305                                       floor(n / 0x1000000000000) % 0x100,
   306                                       floor(n / 0x10000000000) % 0x100,
   307                                       floor(n / 0x100000000) % 0x100,
   308                                       floor(n / 0x1000000) % 0x100,
   309                                       floor(n / 0x10000) % 0x100,
   310                                       floor(n / 0x100) % 0x100,
   311                                       n % 0x100)
   312          end
   313      end
   314  end
   315  
   316  packers['signed'] = function (buffer, n)
   317      if n >= 0 then
   318          if n <= 0x7F then
   319              buffer[#buffer+1] = char(n)         -- fixnum_pos
   320          elseif n <= 0x7FFF then
   321              buffer[#buffer+1] = char(0xD1,      -- int16
   322                                       floor(n / 0x100),
   323                                       n % 0x100)
   324          elseif n <= 0x7FFFFFFF then
   325              buffer[#buffer+1] = char(0xD2,      -- int32
   326                                       floor(n / 0x1000000),
   327                                       floor(n / 0x10000) % 0x100,
   328                                       floor(n / 0x100) % 0x100,
   329                                       n % 0x100)
   330          else
   331              buffer[#buffer+1] = char(0xD3,      -- int64
   332                                       0,         -- only 53 bits from double
   333                                       floor(n / 0x1000000000000) % 0x100,
   334                                       floor(n / 0x10000000000) % 0x100,
   335                                       floor(n / 0x100000000) % 0x100,
   336                                       floor(n / 0x1000000) % 0x100,
   337                                       floor(n / 0x10000) % 0x100,
   338                                       floor(n / 0x100) % 0x100,
   339                                       n % 0x100)
   340          end
   341      else
   342          if n >= -0x20 then
   343              buffer[#buffer+1] = char(0xE0 + 0x20 + n)   -- fixnum_neg
   344          elseif n >= -0x80 then
   345              buffer[#buffer+1] = char(0xD0,      -- int8
   346                                       0x100 + n)
   347          elseif n >= -0x8000 then
   348              n = 0x10000 + n
   349              buffer[#buffer+1] = char(0xD1,      -- int16
   350                                       floor(n / 0x100),
   351                                       n % 0x100)
   352          elseif n >= -0x80000000 then
   353              n = 4294967296.0 + n
   354              buffer[#buffer+1] = char(0xD2,      -- int32
   355                                       floor(n / 0x1000000),
   356                                       floor(n / 0x10000) % 0x100,
   357                                       floor(n / 0x100) % 0x100,
   358                                       n % 0x100)
   359          else
   360              buffer[#buffer+1] = char(0xD3,      -- int64
   361                                       0xFF,      -- only 53 bits from double
   362                                       floor(n / 0x1000000000000) % 0x100,
   363                                       floor(n / 0x10000000000) % 0x100,
   364                                       floor(n / 0x100000000) % 0x100,
   365                                       floor(n / 0x1000000) % 0x100,
   366                                       floor(n / 0x10000) % 0x100,
   367                                       floor(n / 0x100) % 0x100,
   368                                       n % 0x100)
   369          end
   370      end
   371  end
   372  
   373  local set_integer = function (integer)
   374      if integer == 'unsigned' then
   375          packers['integer'] = packers['unsigned']
   376      elseif integer == 'signed' then
   377          packers['integer'] = packers['signed']
   378      else
   379          argerror('set_integer', 1, "invalid option '" .. integer .."'")
   380      end
   381  end
   382  m.set_integer = set_integer
   383  
   384  packers['float'] = function (buffer, n)
   385      local sign = 0
   386      if n < 0.0 then
   387          sign = 0x80
   388          n = -n
   389      end
   390      local mant, expo = frexp(n)
   391      if mant ~= mant then
   392          buffer[#buffer+1] = char(0xCA,  -- nan
   393                                   0xFF, 0x88, 0x00, 0x00)
   394      elseif mant == huge or expo > 0x80 then
   395          if sign == 0 then
   396              buffer[#buffer+1] = char(0xCA,      -- inf
   397                                       0x7F, 0x80, 0x00, 0x00)
   398          else
   399              buffer[#buffer+1] = char(0xCA,      -- -inf
   400                                       0xFF, 0x80, 0x00, 0x00)
   401          end
   402      elseif (mant == 0.0 and expo == 0) or expo < -0x7E then
   403          buffer[#buffer+1] = char(0xCA,  -- zero
   404                                   sign, 0x00, 0x00, 0x00)
   405      else
   406          expo = expo + 0x7E
   407          mant = floor((mant * 2.0 - 1.0) * ldexp(0.5, 24))
   408          buffer[#buffer+1] = char(0xCA,
   409                                   sign + floor(expo / 0x2),
   410                                   (expo % 0x2) * 0x80 + floor(mant / 0x10000),
   411                                   floor(mant / 0x100) % 0x100,
   412                                   mant % 0x100)
   413      end
   414  end
   415  
   416  packers['double'] = function (buffer, n)
   417      local sign = 0
   418      if n < 0.0 then
   419          sign = 0x80
   420          n = -n
   421      end
   422      local mant, expo = frexp(n)
   423      if mant ~= mant then
   424          buffer[#buffer+1] = char(0xCB,  -- nan
   425                                   0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
   426      elseif mant == huge or expo > 0x400 then
   427          if sign == 0 then
   428              buffer[#buffer+1] = char(0xCB,      -- inf
   429                                       0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
   430          else
   431              buffer[#buffer+1] = char(0xCB,      -- -inf
   432                                       0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
   433          end
   434      elseif (mant == 0.0 and expo == 0) or expo < -0x3FE then
   435          buffer[#buffer+1] = char(0xCB,  -- zero
   436                                   sign, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
   437      else
   438          expo = expo + 0x3FE
   439          mant = floor((mant * 2.0 - 1.0) * ldexp(0.5, 53))
   440          buffer[#buffer+1] = char(0xCB,
   441                                   sign + floor(expo / 0x10),
   442                                   (expo % 0x10) * 0x10 + floor(mant / 0x1000000000000),
   443                                   floor(mant / 0x10000000000) % 0x100,
   444                                   floor(mant / 0x100000000) % 0x100,
   445                                   floor(mant / 0x1000000) % 0x100,
   446                                   floor(mant / 0x10000) % 0x100,
   447                                   floor(mant / 0x100) % 0x100,
   448                                   mant % 0x100)
   449      end
   450  end
   451  
   452  local set_number = function (number)
   453      if number == 'float' then
   454          packers['number'] = function (buffer, n)
   455              if floor(n) == n and n < maxinteger and n > mininteger then
   456                  packers['integer'](buffer, n)
   457              else
   458                  packers['float'](buffer, n)
   459              end
   460          end
   461      elseif number == 'double' then
   462          packers['number'] = function (buffer, n)
   463              if floor(n) == n and n < maxinteger and n > mininteger then
   464                  packers['integer'](buffer, n)
   465              else
   466                  packers['double'](buffer, n)
   467              end
   468          end
   469      else
   470          argerror('set_number', 1, "invalid option '" .. number .."'")
   471      end
   472  end
   473  m.set_number = set_number
   474  
   475  for k = 0, 4 do
   476      local n = tointeger(2^k)
   477      local fixext = 0xD4 + k
   478      packers['fixext' .. tostring(n)] = function (buffer, tag, data)
   479          assert(#data == n, "bad length for fixext" .. tostring(n))
   480          buffer[#buffer+1] = char(fixext,
   481                                   tag < 0 and tag + 0x100 or tag)
   482          buffer[#buffer+1] = data
   483      end
   484  end
   485  
   486  packers['ext'] = function (buffer, tag, data)
   487      local n = #data
   488      if n <= 0xFF then
   489          buffer[#buffer+1] = char(0xC7,          -- ext8
   490                                   n,
   491                                   tag < 0 and tag + 0x100 or tag)
   492      elseif n <= 0xFFFF then
   493          buffer[#buffer+1] = char(0xC8,          -- ext16
   494                                   floor(n / 0x100),
   495                                   n % 0x100,
   496                                   tag < 0 and tag + 0x100 or tag)
   497      elseif n <= 4294967295.0 then
   498          buffer[#buffer+1] = char(0xC9,          -- ext&32
   499                                   floor(n / 0x1000000),
   500                                   floor(n / 0x10000) % 0x100,
   501                                   floor(n / 0x100) % 0x100,
   502                                   n % 0x100,
   503                                   tag < 0 and tag + 0x100 or tag)
   504      else
   505          error"overflow in pack 'ext'"
   506      end
   507      buffer[#buffer+1] = data
   508  end
   509  
   510  function m.pack (data)
   511      local buffer = {}
   512      packers[type(data)](buffer, data)
   513      return tconcat(buffer)
   514  end
   515  
   516  
   517  local unpackers         -- forward declaration
   518  
   519  local function unpack_cursor (c)
   520      local s, i, j = c.s, c.i, c.j
   521      if i > j then
   522          c:underflow(i)
   523          s, i, j = c.s, c.i, c.j
   524      end
   525      local val = s:byte(i)
   526      c.i = i+1
   527      return unpackers[val](c, val)
   528  end
   529  m.unpack_cursor = unpack_cursor
   530  
   531  local function unpack_str (c, n)
   532      local s, i, j = c.s, c.i, c.j
   533      local e = i+n-1
   534      if e > j or n < 0 then
   535          c:underflow(e)
   536          s, i, j = c.s, c.i, c.j
   537          e = i+n-1
   538      end
   539      c.i = i+n
   540      return s:sub(i, e)
   541  end
   542  
   543  local function unpack_array (c, n)
   544      local t = {}
   545      for i = 1, n do
   546          t[i] = unpack_cursor(c)
   547      end
   548      return t
   549  end
   550  
   551  local function unpack_map (c, n)
   552      local t = {}
   553      for i = 1, n do
   554          local k = unpack_cursor(c)
   555          local val = unpack_cursor(c)
   556          if k == nil or k ~= k then
   557              k = m.sentinel
   558          end
   559          if k ~= nil then
   560              t[k] = val
   561          end
   562      end
   563      return t
   564  end
   565  
   566  local function unpack_float (c)
   567      local s, i, j = c.s, c.i, c.j
   568      if i+3 > j then
   569          c:underflow(i+3)
   570          s, i, j = c.s, c.i, c.j
   571      end
   572      local b1, b2, b3, b4 = s:byte(i, i+3)
   573      local sign = b1 > 0x7F
   574      local expo = (b1 % 0x80) * 0x2 + floor(b2 / 0x80)
   575      local mant = ((b2 % 0x80) * 0x100 + b3) * 0x100 + b4
   576      if sign then
   577          sign = -1
   578      else
   579          sign = 1
   580      end
   581      local n
   582      if mant == 0 and expo == 0 then
   583          n = sign * 0.0
   584      elseif expo == 0xFF then
   585          if mant == 0 then
   586              n = sign * huge
   587          else
   588              n = 0.0/0.0
   589          end
   590      else
   591          n = sign * ldexp(1.0 + mant / 0x800000, expo - 0x7F)
   592      end
   593      c.i = i+4
   594      return n
   595  end
   596  
   597  local function unpack_double (c)
   598      local s, i, j = c.s, c.i, c.j
   599      if i+7 > j then
   600          c:underflow(i+7)
   601          s, i, j = c.s, c.i, c.j
   602      end
   603      local b1, b2, b3, b4, b5, b6, b7, b8 = s:byte(i, i+7)
   604      local sign = b1 > 0x7F
   605      local expo = (b1 % 0x80) * 0x10 + floor(b2 / 0x10)
   606      local mant = ((((((b2 % 0x10) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8
   607      if sign then
   608          sign = -1
   609      else
   610          sign = 1
   611      end
   612      local n
   613      if mant == 0 and expo == 0 then
   614          n = sign * 0.0
   615      elseif expo == 0x7FF then
   616          if mant == 0 then
   617              n = sign * huge
   618          else
   619              n = 0.0/0.0
   620          end
   621      else
   622          n = sign * ldexp(1.0 + mant / 4503599627370496.0, expo - 0x3FF)
   623      end
   624      c.i = i+8
   625      return n
   626  end
   627  
   628  local function unpack_uint8 (c)
   629      local s, i, j = c.s, c.i, c.j
   630      if i > j then
   631          c:underflow(i)
   632          s, i, j = c.s, c.i, c.j
   633      end
   634      local b1 = s:byte(i)
   635      c.i = i+1
   636      return b1
   637  end
   638  
   639  local function unpack_uint16 (c)
   640      local s, i, j = c.s, c.i, c.j
   641      if i+1 > j then
   642          c:underflow(i+1)
   643          s, i, j = c.s, c.i, c.j
   644      end
   645      local b1, b2 = s:byte(i, i+1)
   646      c.i = i+2
   647      return b1 * 0x100 + b2
   648  end
   649  
   650  local function unpack_uint32 (c)
   651      local s, i, j = c.s, c.i, c.j
   652      if i+3 > j then
   653          c:underflow(i+3)
   654          s, i, j = c.s, c.i, c.j
   655      end
   656      local b1, b2, b3, b4 = s:byte(i, i+3)
   657      c.i = i+4
   658      return ((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4
   659  end
   660  
   661  local function unpack_uint64 (c)
   662      local s, i, j = c.s, c.i, c.j
   663      if i+7 > j then
   664          c:underflow(i+7)
   665          s, i, j = c.s, c.i, c.j
   666      end
   667      local b1, b2, b3, b4, b5, b6, b7, b8 = s:byte(i, i+7)
   668      c.i = i+8
   669      return ((((((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8
   670  end
   671  
   672  local function unpack_int8 (c)
   673      local s, i, j = c.s, c.i, c.j
   674      if i > j then
   675          c:underflow(i)
   676          s, i, j = c.s, c.i, c.j
   677      end
   678      local b1 = s:byte(i)
   679      c.i = i+1
   680      if b1 < 0x80 then
   681          return b1
   682      else
   683          return b1 - 0x100
   684      end
   685  end
   686  
   687  local function unpack_int16 (c)
   688      local s, i, j = c.s, c.i, c.j
   689      if i+1 > j then
   690          c:underflow(i+1)
   691          s, i, j = c.s, c.i, c.j
   692      end
   693      local b1, b2 = s:byte(i, i+1)
   694      c.i = i+2
   695      if b1 < 0x80 then
   696          return b1 * 0x100 + b2
   697      else
   698          return ((b1 - 0xFF) * 0x100 + (b2 - 0xFF)) - 1
   699      end
   700  end
   701  
   702  local function unpack_int32 (c)
   703      local s, i, j = c.s, c.i, c.j
   704      if i+3 > j then
   705          c:underflow(i+3)
   706          s, i, j = c.s, c.i, c.j
   707      end
   708      local b1, b2, b3, b4 = s:byte(i, i+3)
   709      c.i = i+4
   710      if b1 < 0x80 then
   711          return ((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4
   712      else
   713          return ((((b1 - 0xFF) * 0x100 + (b2 - 0xFF)) * 0x100 + (b3 - 0xFF)) * 0x100 + (b4 - 0xFF)) - 1
   714      end
   715  end
   716  
   717  local function unpack_int64 (c)
   718      local s, i, j = c.s, c.i, c.j
   719      if i+7 > j then
   720          c:underflow(i+7)
   721          s, i, j = c.s, c.i, c.j
   722      end
   723      local b1, b2, b3, b4, b5, b6, b7, b8 = s:byte(i, i+7)
   724      c.i = i+8
   725      if b1 < 0x80 then
   726          return ((((((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8
   727      else
   728          return ((((((((b1 - 0xFF) * 0x100 + (b2 - 0xFF)) * 0x100 + (b3 - 0xFF)) * 0x100 + (b4 - 0xFF)) * 0x100 + (b5 - 0xFF)) * 0x100 + (b6 - 0xFF)) * 0x100 + (b7 - 0xFF)) * 0x100 + (b8 - 0xFF)) - 1
   729      end
   730  end
   731  
   732  function m.build_ext (tag, data)
   733      return nil
   734  end
   735  
   736  local function unpack_ext (c, n, tag)
   737      local s, i, j = c.s, c.i, c.j
   738      local e = i+n-1
   739      if e > j or n < 0 then
   740          c:underflow(e)
   741          s, i, j = c.s, c.i, c.j
   742          e = i+n-1
   743      end
   744      c.i = i+n
   745      return m.build_ext(tag, s:sub(i, e))
   746  end
   747  
   748  unpackers = setmetatable({
   749      [0xC0] = function () return nil end,
   750      [0xC2] = function () return false end,
   751      [0xC3] = function () return true end,
   752      [0xC4] = function (c) return unpack_str(c, unpack_uint8(c)) end,    -- bin8
   753      [0xC5] = function (c) return unpack_str(c, unpack_uint16(c)) end,   -- bin16
   754      [0xC6] = function (c) return unpack_str(c, unpack_uint32(c)) end,   -- bin32
   755      [0xC7] = function (c) return unpack_ext(c, unpack_uint8(c), unpack_int8(c)) end,
   756      [0xC8] = function (c) return unpack_ext(c, unpack_uint16(c), unpack_int8(c)) end,
   757      [0xC9] = function (c) return unpack_ext(c, unpack_uint32(c), unpack_int8(c)) end,
   758      [0xCA] = unpack_float,
   759      [0xCB] = unpack_double,
   760      [0xCC] = unpack_uint8,
   761      [0xCD] = unpack_uint16,
   762      [0xCE] = unpack_uint32,
   763      [0xCF] = unpack_uint64,
   764      [0xD0] = unpack_int8,
   765      [0xD1] = unpack_int16,
   766      [0xD2] = unpack_int32,
   767      [0xD3] = unpack_int64,
   768      [0xD4] = function (c) return unpack_ext(c, 1, unpack_int8(c)) end,
   769      [0xD5] = function (c) return unpack_ext(c, 2, unpack_int8(c)) end,
   770      [0xD6] = function (c) return unpack_ext(c, 4, unpack_int8(c)) end,
   771      [0xD7] = function (c) return unpack_ext(c, 8, unpack_int8(c)) end,
   772      [0xD8] = function (c) return unpack_ext(c, 16, unpack_int8(c)) end,
   773      [0xD9] = function (c) return unpack_str(c, unpack_uint8(c)) end,
   774      [0xDA] = function (c) return unpack_str(c, unpack_uint16(c)) end,
   775      [0xDB] = function (c) return unpack_str(c, unpack_uint32(c)) end,
   776      [0xDC] = function (c) return unpack_array(c, unpack_uint16(c)) end,
   777      [0xDD] = function (c) return unpack_array(c, unpack_uint32(c)) end,
   778      [0xDE] = function (c) return unpack_map(c, unpack_uint16(c)) end,
   779      [0xDF] = function (c) return unpack_map(c, unpack_uint32(c)) end,
   780  }, {
   781      __index = function (t, k)
   782          if k < 0xC0 then
   783              if k < 0x80 then
   784                  return function (c, val) return val end
   785              elseif k < 0x90 then
   786                  return function (c, val) return unpack_map(c, val % 0x10) end
   787              elseif k < 0xA0 then
   788                  return function (c, val) return unpack_array(c, val % 0x10) end
   789              else
   790                  return function (c, val) return unpack_str(c, val % 0x20) end
   791              end
   792          elseif k > 0xDF then
   793              return function (c, val) return val - 0x100 end
   794          else
   795              return function () error("unpack '" .. format('%#x', k) .. "' is unimplemented") end
   796          end
   797      end
   798  })
   799  
   800  local function cursor_string (str)
   801      return {
   802          s = str,
   803          i = 1,
   804          j = #str,
   805          underflow = function ()
   806                          error "missing bytes"
   807                      end,
   808      }
   809  end
   810  
   811  local function cursor_loader (ld)
   812      return {
   813          s = '',
   814          i = 1,
   815          j = 0,
   816          underflow = function (self, e)
   817                          self.s = self.s:sub(self.i)
   818                          e = e - self.i + 1
   819                          self.i = 1
   820                          self.j = 0
   821                          while e > self.j do
   822                              local chunk = ld()
   823                              if not chunk then
   824                                  error "missing bytes"
   825                              end
   826                              self.s = self.s .. chunk
   827                              self.j = #self.s
   828                          end
   829                      end,
   830      }
   831  end
   832  
   833  function m.unpack (s)
   834      checktype('unpack', 1, s, 'string')
   835      local cursor = cursor_string(s)
   836      local data = unpack_cursor(cursor)
   837      if cursor.i <= cursor.j then
   838          error "extra bytes"
   839      end
   840      return data
   841  end
   842  
   843  function m.unpacker (src)
   844      if type(src) == 'string' then
   845          local cursor = cursor_string(src)
   846          return function ()
   847              if cursor.i <= cursor.j then
   848                  return cursor.i, unpack_cursor(cursor)
   849              end
   850          end
   851      elseif type(src) == 'function' then
   852          local cursor = cursor_loader(src)
   853          return function ()
   854              if cursor.i > cursor.j then
   855                  pcall(cursor.underflow, cursor, cursor.i)
   856              end
   857              if cursor.i <= cursor.j then
   858                  return true, unpack_cursor(cursor)
   859              end
   860          end
   861      else
   862          argerror('unpacker', 1, "string or function expected, got " .. type(src))
   863      end
   864  end
   865  
   866  set_string'string_compat'
   867  set_integer'unsigned'
   868  if SIZEOF_NUMBER == 4 then
   869      maxinteger = 16777215
   870      mininteger = -maxinteger
   871      m.small_lua = true
   872      unpackers[0xCB] = nil       -- double
   873      unpackers[0xCF] = nil       -- uint64
   874      unpackers[0xD3] = nil       -- int64
   875      set_number'float'
   876  else
   877      maxinteger = 9007199254740991
   878      mininteger = -maxinteger
   879      set_number'double'
   880      if SIZEOF_NUMBER > 8 then
   881          m.long_double = true
   882      end
   883  end
   884  set_array'without_hole'
   885  
   886  m._VERSION = '0.5.2'
   887  m._DESCRIPTION = "lua-MessagePack : a pure Lua implementation"
   888  m._COPYRIGHT = "Copyright (c) 2012-2019 Francois Perrad"
   889  return m
   890  --
   891  -- This library is licensed under the terms of the MIT/X11 license,
   892  -- like Lua itself.
   893  --