hgext/fsmonitor/pywatchman/bser.c
author Martijn Pieters <mjpieters@fb.com>
Wed, 02 Mar 2016 16:25:12 +0000
changeset 28432 2377c4ac4eec
child 28528 a011080fdb7b
permissions -rw-r--r--
fsmonitor: dependencies for new experimental extension In preparation for the filesystem monitor extension, include the pywatchman library. The fbmonitor extension relies on this library to communicate with the Watchman service. The library is BSD licensed and is taken from https://github.com/facebook/watchman/tree/master/python. This package has not been updated to mercurial code standards.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     1
/*
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     2
Copyright (c) 2013-2015, Facebook, Inc.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     3
All rights reserved.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     4
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     5
Redistribution and use in source and binary forms, with or without
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     6
modification, are permitted provided that the following conditions are met:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     7
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     8
 * Redistributions of source code must retain the above copyright notice,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     9
   this list of conditions and the following disclaimer.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    10
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    11
 * Redistributions in binary form must reproduce the above copyright notice,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    12
   this list of conditions and the following disclaimer in the documentation
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    13
   and/or other materials provided with the distribution.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    14
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    15
 * Neither the name Facebook nor the names of its contributors may be used to
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    16
   endorse or promote products derived from this software without specific
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    17
   prior written permission.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    18
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    19
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    20
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    21
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    22
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    23
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    24
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    25
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    26
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    27
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    28
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    29
*/
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    30
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    31
#include <Python.h>
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    32
#ifdef _MSC_VER
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    33
#define inline __inline
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    34
#include <stdint.h>
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    35
#endif
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    36
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    37
/* Return the smallest size int that can store the value */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    38
#define INT_SIZE(x) (((x) == ((int8_t)x))  ? 1 :    \
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    39
                     ((x) == ((int16_t)x)) ? 2 :    \
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    40
                     ((x) == ((int32_t)x)) ? 4 : 8)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    41
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    42
#define BSER_ARRAY     0x00
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    43
#define BSER_OBJECT    0x01
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    44
#define BSER_STRING    0x02
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    45
#define BSER_INT8      0x03
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    46
#define BSER_INT16     0x04
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    47
#define BSER_INT32     0x05
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    48
#define BSER_INT64     0x06
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    49
#define BSER_REAL      0x07
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    50
#define BSER_TRUE      0x08
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    51
#define BSER_FALSE     0x09
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    52
#define BSER_NULL      0x0a
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    53
#define BSER_TEMPLATE  0x0b
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    54
#define BSER_SKIP      0x0c
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    55
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    56
// An immutable object representation of BSER_OBJECT.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    57
// Rather than build a hash table, key -> value are obtained
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    58
// by walking the list of keys to determine the offset into
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    59
// the values array.  The assumption is that the number of
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    60
// array elements will be typically small (~6 for the top
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    61
// level query result and typically 3-5 for the file entries)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    62
// so that the time overhead for this is small compared to
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    63
// using a proper hash table.  Even with this simplistic
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    64
// approach, this is still faster for the mercurial use case
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    65
// as it helps to eliminate creating N other objects to
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    66
// represent the stat information in the hgwatchman extension
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    67
typedef struct {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    68
  PyObject_HEAD
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    69
  PyObject *keys;   // tuple of field names
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    70
  PyObject *values; // tuple of values
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    71
} bserObject;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    72
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    73
static Py_ssize_t bserobj_tuple_length(PyObject *o) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    74
  bserObject *obj = (bserObject*)o;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    75
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    76
  return PySequence_Length(obj->keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    77
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    78
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    79
static PyObject *bserobj_tuple_item(PyObject *o, Py_ssize_t i) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    80
  bserObject *obj = (bserObject*)o;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    81
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    82
  return PySequence_GetItem(obj->values, i);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    83
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    84
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    85
static PySequenceMethods bserobj_sq = {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    86
  bserobj_tuple_length,      /* sq_length */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    87
  0,                         /* sq_concat */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    88
  0,                         /* sq_repeat */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    89
  bserobj_tuple_item,        /* sq_item */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    90
  0,                         /* sq_ass_item */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    91
  0,                         /* sq_contains */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    92
  0,                         /* sq_inplace_concat */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    93
  0                          /* sq_inplace_repeat */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    94
};
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    95
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    96
static void bserobj_dealloc(PyObject *o) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    97
  bserObject *obj = (bserObject*)o;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    98
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    99
  Py_CLEAR(obj->keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   100
  Py_CLEAR(obj->values);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   101
  PyObject_Del(o);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   102
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   103
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   104
static PyObject *bserobj_getattrro(PyObject *o, PyObject *name) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   105
  bserObject *obj = (bserObject*)o;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   106
  Py_ssize_t i, n;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   107
  const char *namestr;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   108
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   109
  if (PyIndex_Check(name)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   110
    i = PyNumber_AsSsize_t(name, PyExc_IndexError);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   111
    if (i == -1 && PyErr_Occurred()) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   112
      return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   113
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   114
    return PySequence_GetItem(obj->values, i);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   115
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   116
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   117
  // hack^Wfeature to allow mercurial to use "st_size" to reference "size"
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   118
  namestr = PyString_AsString(name);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   119
  if (!strncmp(namestr, "st_", 3)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   120
    namestr += 3;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   121
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   122
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   123
  n = PyTuple_GET_SIZE(obj->keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   124
  for (i = 0; i < n; i++) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   125
    const char *item_name = NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   126
    PyObject *key = PyTuple_GET_ITEM(obj->keys, i);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   127
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   128
    item_name = PyString_AsString(key);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   129
    if (!strcmp(item_name, namestr)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   130
      return PySequence_GetItem(obj->values, i);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   131
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   132
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   133
  PyErr_Format(PyExc_AttributeError,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   134
              "bserobject has no attribute '%.400s'", namestr);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   135
  return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   136
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   137
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   138
static PyMappingMethods bserobj_map = {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   139
  bserobj_tuple_length,     /* mp_length */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   140
  bserobj_getattrro,        /* mp_subscript */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   141
  0                         /* mp_ass_subscript */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   142
};
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   143
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   144
PyTypeObject bserObjectType = {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   145
  PyVarObject_HEAD_INIT(NULL, 0)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   146
  "bserobj_tuple",           /* tp_name */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   147
  sizeof(bserObject),        /* tp_basicsize */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   148
  0,                         /* tp_itemsize */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   149
  bserobj_dealloc,           /* tp_dealloc */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   150
  0,                         /* tp_print */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   151
  0,                         /* tp_getattr */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   152
  0,                         /* tp_setattr */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   153
  0,                         /* tp_compare */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   154
  0,                         /* tp_repr */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   155
  0,                         /* tp_as_number */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   156
  &bserobj_sq,               /* tp_as_sequence */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   157
  &bserobj_map,              /* tp_as_mapping */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   158
  0,                         /* tp_hash  */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   159
  0,                         /* tp_call */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   160
  0,                         /* tp_str */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   161
  bserobj_getattrro,         /* tp_getattro */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   162
  0,                         /* tp_setattro */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   163
  0,                         /* tp_as_buffer */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   164
  Py_TPFLAGS_DEFAULT,        /* tp_flags */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   165
  "bserobj tuple",           /* tp_doc */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   166
  0,                         /* tp_traverse */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   167
  0,                         /* tp_clear */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   168
  0,                         /* tp_richcompare */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   169
  0,                         /* tp_weaklistoffset */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   170
  0,                         /* tp_iter */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   171
  0,                         /* tp_iternext */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   172
  0,                         /* tp_methods */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   173
  0,                         /* tp_members */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   174
  0,                         /* tp_getset */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   175
  0,                         /* tp_base */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   176
  0,                         /* tp_dict */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   177
  0,                         /* tp_descr_get */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   178
  0,                         /* tp_descr_set */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   179
  0,                         /* tp_dictoffset */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   180
  0,                         /* tp_init */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   181
  0,                         /* tp_alloc */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   182
  0,                         /* tp_new */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   183
};
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   184
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   185
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   186
static PyObject *bser_loads_recursive(const char **ptr, const char *end,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   187
    int mutable);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   188
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   189
static const char bser_true = BSER_TRUE;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   190
static const char bser_false = BSER_FALSE;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   191
static const char bser_null = BSER_NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   192
static const char bser_string_hdr = BSER_STRING;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   193
static const char bser_array_hdr = BSER_ARRAY;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   194
static const char bser_object_hdr = BSER_OBJECT;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   195
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   196
static inline uint32_t next_power_2(uint32_t n)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   197
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   198
  n |= (n >> 16);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   199
  n |= (n >> 8);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   200
  n |= (n >> 4);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   201
  n |= (n >> 2);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   202
  n |= (n >> 1);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   203
  return n + 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   204
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   205
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   206
// A buffer we use for building up the serialized result
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   207
struct bser_buffer {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   208
  char *buf;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   209
  int wpos, allocd;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   210
};
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   211
typedef struct bser_buffer bser_t;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   212
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   213
static int bser_append(bser_t *bser, const char *data, uint32_t len)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   214
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   215
  int newlen = next_power_2(bser->wpos + len);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   216
  if (newlen > bser->allocd) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   217
    char *nbuf = realloc(bser->buf, newlen);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   218
    if (!nbuf) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   219
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   220
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   221
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   222
    bser->buf = nbuf;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   223
    bser->allocd = newlen;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   224
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   225
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   226
  memcpy(bser->buf + bser->wpos, data, len);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   227
  bser->wpos += len;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   228
  return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   229
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   230
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   231
static int bser_init(bser_t *bser)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   232
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   233
  bser->allocd = 8192;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   234
  bser->wpos = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   235
  bser->buf = malloc(bser->allocd);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   236
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   237
  if (!bser->buf) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   238
    return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   239
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   240
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   241
  // Leave room for the serialization header, which includes
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   242
  // our overall length.  To make things simpler, we'll use an
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   243
  // int32 for the header
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   244
#define EMPTY_HEADER "\x00\x01\x05\x00\x00\x00\x00"
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   245
  bser_append(bser, EMPTY_HEADER, sizeof(EMPTY_HEADER)-1);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   246
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   247
  return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   248
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   249
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   250
static void bser_dtor(bser_t *bser)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   251
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   252
  free(bser->buf);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   253
  bser->buf = NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   254
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   255
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   256
static int bser_long(bser_t *bser, int64_t val)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   257
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   258
  int8_t i8;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   259
  int16_t i16;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   260
  int32_t i32;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   261
  int64_t i64;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   262
  char sz;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   263
  int size = INT_SIZE(val);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   264
  char *iptr;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   265
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   266
  switch (size) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   267
    case 1:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   268
      sz = BSER_INT8;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   269
      i8 = (int8_t)val;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   270
      iptr = (char*)&i8;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   271
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   272
    case 2:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   273
      sz = BSER_INT16;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   274
      i16 = (int16_t)val;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   275
      iptr = (char*)&i16;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   276
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   277
    case 4:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   278
      sz = BSER_INT32;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   279
      i32 = (int32_t)val;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   280
      iptr = (char*)&i32;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   281
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   282
    case 8:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   283
      sz = BSER_INT64;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   284
      i64 = (int64_t)val;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   285
      iptr = (char*)&i64;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   286
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   287
    default:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   288
      PyErr_SetString(PyExc_RuntimeError,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   289
          "Cannot represent this long value!?");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   290
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   291
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   292
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   293
  if (!bser_append(bser, &sz, sizeof(sz))) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   294
    return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   295
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   296
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   297
  return bser_append(bser, iptr, size);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   298
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   299
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   300
static int bser_string(bser_t *bser, PyObject *sval)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   301
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   302
  char *buf = NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   303
  Py_ssize_t len;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   304
  int res;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   305
  PyObject *utf = NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   306
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   307
  if (PyUnicode_Check(sval)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   308
    utf = PyUnicode_AsEncodedString(sval, "utf-8", "ignore");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   309
    sval = utf;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   310
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   311
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   312
  res = PyString_AsStringAndSize(sval, &buf, &len);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   313
  if (res == -1) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   314
    res = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   315
    goto out;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   316
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   317
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   318
  if (!bser_append(bser, &bser_string_hdr, sizeof(bser_string_hdr))) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   319
    res = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   320
    goto out;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   321
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   322
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   323
  if (!bser_long(bser, len)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   324
    res = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   325
    goto out;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   326
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   327
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   328
  if (len > UINT32_MAX) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   329
    PyErr_Format(PyExc_ValueError, "string too big");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   330
    res = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   331
    goto out;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   332
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   333
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   334
  res = bser_append(bser, buf, (uint32_t)len);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   335
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   336
out:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   337
  if (utf) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   338
    Py_DECREF(utf);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   339
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   340
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   341
  return res;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   342
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   343
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   344
static int bser_recursive(bser_t *bser, PyObject *val)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   345
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   346
  if (PyBool_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   347
    if (val == Py_True) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   348
      return bser_append(bser, &bser_true, sizeof(bser_true));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   349
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   350
    return bser_append(bser, &bser_false, sizeof(bser_false));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   351
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   352
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   353
  if (val == Py_None) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   354
    return bser_append(bser, &bser_null, sizeof(bser_null));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   355
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   356
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   357
  if (PyInt_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   358
    return bser_long(bser, PyInt_AS_LONG(val));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   359
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   360
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   361
  if (PyLong_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   362
    return bser_long(bser, PyLong_AsLongLong(val));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   363
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   364
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   365
  if (PyString_Check(val) || PyUnicode_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   366
    return bser_string(bser, val);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   367
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   368
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   369
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   370
  if (PyFloat_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   371
    double dval = PyFloat_AS_DOUBLE(val);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   372
    char sz = BSER_REAL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   373
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   374
    if (!bser_append(bser, &sz, sizeof(sz))) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   375
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   376
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   377
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   378
    return bser_append(bser, (char*)&dval, sizeof(dval));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   379
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   380
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   381
  if (PyList_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   382
    Py_ssize_t i, len = PyList_GET_SIZE(val);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   383
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   384
    if (!bser_append(bser, &bser_array_hdr, sizeof(bser_array_hdr))) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   385
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   386
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   387
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   388
    if (!bser_long(bser, len)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   389
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   390
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   391
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   392
    for (i = 0; i < len; i++) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   393
      PyObject *ele = PyList_GET_ITEM(val, i);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   394
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   395
      if (!bser_recursive(bser, ele)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   396
        return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   397
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   398
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   399
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   400
    return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   401
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   402
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   403
  if (PyTuple_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   404
    Py_ssize_t i, len = PyTuple_GET_SIZE(val);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   405
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   406
    if (!bser_append(bser, &bser_array_hdr, sizeof(bser_array_hdr))) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   407
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   408
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   409
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   410
    if (!bser_long(bser, len)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   411
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   412
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   413
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   414
    for (i = 0; i < len; i++) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   415
      PyObject *ele = PyTuple_GET_ITEM(val, i);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   416
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   417
      if (!bser_recursive(bser, ele)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   418
        return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   419
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   420
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   421
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   422
    return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   423
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   424
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   425
  if (PyMapping_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   426
    Py_ssize_t len = PyMapping_Length(val);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   427
    Py_ssize_t pos = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   428
    PyObject *key, *ele;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   429
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   430
    if (!bser_append(bser, &bser_object_hdr, sizeof(bser_object_hdr))) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   431
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   432
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   433
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   434
    if (!bser_long(bser, len)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   435
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   436
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   437
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   438
    while (PyDict_Next(val, &pos, &key, &ele)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   439
      if (!bser_string(bser, key)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   440
        return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   441
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   442
      if (!bser_recursive(bser, ele)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   443
        return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   444
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   445
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   446
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   447
    return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   448
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   449
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   450
  PyErr_SetString(PyExc_ValueError, "Unsupported value type");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   451
  return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   452
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   453
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   454
static PyObject *bser_dumps(PyObject *self, PyObject *args)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   455
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   456
  PyObject *val = NULL, *res;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   457
  bser_t bser;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   458
  uint32_t len;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   459
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   460
  if (!PyArg_ParseTuple(args, "O", &val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   461
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   462
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   463
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   464
  if (!bser_init(&bser)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   465
    return PyErr_NoMemory();
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   466
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   467
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   468
  if (!bser_recursive(&bser, val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   469
    bser_dtor(&bser);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   470
    if (errno == ENOMEM) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   471
      return PyErr_NoMemory();
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   472
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   473
    // otherwise, we've already set the error to something reasonable
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   474
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   475
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   476
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   477
  // Now fill in the overall length
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   478
  len = bser.wpos - (sizeof(EMPTY_HEADER) - 1);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   479
  memcpy(bser.buf + 3, &len, sizeof(len));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   480
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   481
  res = PyString_FromStringAndSize(bser.buf, bser.wpos);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   482
  bser_dtor(&bser);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   483
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   484
  return res;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   485
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   486
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   487
int bunser_int(const char **ptr, const char *end, int64_t *val)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   488
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   489
  int needed;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   490
  const char *buf = *ptr;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   491
  int8_t i8;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   492
  int16_t i16;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   493
  int32_t i32;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   494
  int64_t i64;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   495
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   496
  switch (buf[0]) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   497
    case BSER_INT8:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   498
      needed = 2;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   499
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   500
    case BSER_INT16:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   501
      needed = 3;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   502
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   503
    case BSER_INT32:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   504
      needed = 5;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   505
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   506
    case BSER_INT64:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   507
      needed = 9;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   508
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   509
    default:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   510
      PyErr_Format(PyExc_ValueError,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   511
          "invalid bser int encoding 0x%02x", buf[0]);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   512
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   513
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   514
  if (end - buf < needed) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   515
    PyErr_SetString(PyExc_ValueError, "input buffer to small for int encoding");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   516
    return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   517
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   518
  *ptr = buf + needed;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   519
  switch (buf[0]) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   520
    case BSER_INT8:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   521
      memcpy(&i8, buf + 1, sizeof(i8));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   522
      *val = i8;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   523
      return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   524
    case BSER_INT16:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   525
      memcpy(&i16, buf + 1, sizeof(i16));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   526
      *val = i16;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   527
      return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   528
    case BSER_INT32:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   529
      memcpy(&i32, buf + 1, sizeof(i32));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   530
      *val = i32;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   531
      return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   532
    case BSER_INT64:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   533
      memcpy(&i64, buf + 1, sizeof(i64));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   534
      *val = i64;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   535
      return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   536
    default:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   537
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   538
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   539
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   540
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   541
static int bunser_string(const char **ptr, const char *end,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   542
    const char **start, int64_t *len)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   543
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   544
  const char *buf = *ptr;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   545
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   546
  // skip string marker
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   547
  buf++;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   548
  if (!bunser_int(&buf, end, len)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   549
    return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   550
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   551
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   552
  if (buf + *len > end) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   553
    PyErr_Format(PyExc_ValueError, "invalid string length in bser data");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   554
    return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   555
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   556
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   557
  *ptr = buf + *len;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   558
  *start = buf;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   559
  return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   560
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   561
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   562
static PyObject *bunser_array(const char **ptr, const char *end, int mutable)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   563
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   564
  const char *buf = *ptr;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   565
  int64_t nitems, i;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   566
  PyObject *res;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   567
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   568
  // skip array header
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   569
  buf++;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   570
  if (!bunser_int(&buf, end, &nitems)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   571
    return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   572
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   573
  *ptr = buf;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   574
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   575
  if (nitems > LONG_MAX) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   576
    PyErr_Format(PyExc_ValueError, "too many items for python array");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   577
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   578
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   579
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   580
  if (mutable) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   581
    res = PyList_New((Py_ssize_t)nitems);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   582
  } else {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   583
    res = PyTuple_New((Py_ssize_t)nitems);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   584
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   585
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   586
  for (i = 0; i < nitems; i++) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   587
    PyObject *ele = bser_loads_recursive(ptr, end, mutable);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   588
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   589
    if (!ele) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   590
      Py_DECREF(res);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   591
      return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   592
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   593
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   594
    if (mutable) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   595
      PyList_SET_ITEM(res, i, ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   596
    } else {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   597
      PyTuple_SET_ITEM(res, i, ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   598
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   599
    // DECREF(ele) not required as SET_ITEM steals the ref
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   600
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   601
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   602
  return res;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   603
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   604
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   605
static PyObject *bunser_object(const char **ptr, const char *end,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   606
    int mutable)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   607
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   608
  const char *buf = *ptr;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   609
  int64_t nitems, i;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   610
  PyObject *res;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   611
  bserObject *obj;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   612
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   613
  // skip array header
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   614
  buf++;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   615
  if (!bunser_int(&buf, end, &nitems)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   616
    return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   617
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   618
  *ptr = buf;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   619
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   620
  if (mutable) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   621
    res = PyDict_New();
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   622
  } else {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   623
    obj = PyObject_New(bserObject, &bserObjectType);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   624
    obj->keys = PyTuple_New((Py_ssize_t)nitems);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   625
    obj->values = PyTuple_New((Py_ssize_t)nitems);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   626
    res = (PyObject*)obj;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   627
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   628
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   629
  for (i = 0; i < nitems; i++) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   630
    const char *keystr;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   631
    int64_t keylen;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   632
    PyObject *key;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   633
    PyObject *ele;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   634
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   635
    if (!bunser_string(ptr, end, &keystr, &keylen)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   636
      Py_DECREF(res);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   637
      return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   638
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   639
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   640
    if (keylen > LONG_MAX) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   641
      PyErr_Format(PyExc_ValueError, "string too big for python");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   642
      Py_DECREF(res);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   643
      return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   644
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   645
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   646
    key = PyString_FromStringAndSize(keystr, (Py_ssize_t)keylen);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   647
    if (!key) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   648
      Py_DECREF(res);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   649
      return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   650
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   651
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   652
    ele = bser_loads_recursive(ptr, end, mutable);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   653
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   654
    if (!ele) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   655
      Py_DECREF(key);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   656
      Py_DECREF(res);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   657
      return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   658
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   659
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   660
    if (mutable) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   661
      PyDict_SetItem(res, key, ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   662
      Py_DECREF(key);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   663
      Py_DECREF(ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   664
    } else {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   665
      /* PyTuple_SET_ITEM steals ele, key */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   666
      PyTuple_SET_ITEM(obj->values, i, ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   667
      PyTuple_SET_ITEM(obj->keys, i, key);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   668
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   669
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   670
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   671
  return res;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   672
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   673
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   674
static PyObject *bunser_template(const char **ptr, const char *end,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   675
    int mutable)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   676
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   677
  const char *buf = *ptr;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   678
  int64_t nitems, i;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   679
  PyObject *arrval;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   680
  PyObject *keys;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   681
  Py_ssize_t numkeys, keyidx;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   682
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   683
  if (buf[1] != BSER_ARRAY) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   684
    PyErr_Format(PyExc_ValueError, "Expect ARRAY to follow TEMPLATE");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   685
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   686
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   687
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   688
  // skip header
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   689
  buf++;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   690
  *ptr = buf;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   691
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   692
  // Load template keys
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   693
  keys = bunser_array(ptr, end, mutable);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   694
  if (!keys) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   695
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   696
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   697
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   698
  numkeys = PySequence_Length(keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   699
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   700
  // Load number of array elements
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   701
  if (!bunser_int(ptr, end, &nitems)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   702
    Py_DECREF(keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   703
    return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   704
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   705
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   706
  if (nitems > LONG_MAX) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   707
    PyErr_Format(PyExc_ValueError, "Too many items for python");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   708
    Py_DECREF(keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   709
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   710
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   711
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   712
  arrval = PyList_New((Py_ssize_t)nitems);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   713
  if (!arrval) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   714
    Py_DECREF(keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   715
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   716
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   717
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   718
  for (i = 0; i < nitems; i++) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   719
    PyObject *dict = NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   720
    bserObject *obj = NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   721
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   722
    if (mutable) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   723
      dict = PyDict_New();
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   724
    } else {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   725
      obj = PyObject_New(bserObject, &bserObjectType);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   726
      if (obj) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   727
        obj->keys = keys;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   728
        Py_INCREF(obj->keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   729
        obj->values = PyTuple_New(numkeys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   730
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   731
      dict = (PyObject*)obj;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   732
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   733
    if (!dict) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   734
fail:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   735
      Py_DECREF(keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   736
      Py_DECREF(arrval);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   737
      return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   738
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   739
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   740
    for (keyidx = 0; keyidx < numkeys; keyidx++) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   741
      PyObject *key;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   742
      PyObject *ele;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   743
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   744
      if (**ptr == BSER_SKIP) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   745
        *ptr = *ptr + 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   746
        ele = Py_None;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   747
        Py_INCREF(ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   748
      } else {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   749
        ele = bser_loads_recursive(ptr, end, mutable);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   750
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   751
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   752
      if (!ele) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   753
        goto fail;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   754
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   755
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   756
      if (mutable) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   757
        key = PyList_GET_ITEM(keys, keyidx);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   758
        PyDict_SetItem(dict, key, ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   759
        Py_DECREF(ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   760
      } else {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   761
        PyTuple_SET_ITEM(obj->values, keyidx, ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   762
        // DECREF(ele) not required as SET_ITEM steals the ref
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   763
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   764
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   765
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   766
    PyList_SET_ITEM(arrval, i, dict);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   767
    // DECREF(obj) not required as SET_ITEM steals the ref
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   768
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   769
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   770
  Py_DECREF(keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   771
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   772
  return arrval;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   773
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   774
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   775
static PyObject *bser_loads_recursive(const char **ptr, const char *end,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   776
    int mutable)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   777
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   778
  const char *buf = *ptr;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   779
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   780
  switch (buf[0]) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   781
    case BSER_INT8:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   782
    case BSER_INT16:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   783
    case BSER_INT32:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   784
    case BSER_INT64:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   785
      {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   786
        int64_t ival;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   787
        if (!bunser_int(ptr, end, &ival)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   788
          return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   789
        }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   790
        if (ival < LONG_MIN || ival > LONG_MAX) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   791
          return PyLong_FromLongLong(ival);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   792
        }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   793
        return PyInt_FromSsize_t(Py_SAFE_DOWNCAST(ival, int64_t, Py_ssize_t));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   794
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   795
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   796
    case BSER_REAL:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   797
      {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   798
        double dval;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   799
        memcpy(&dval, buf + 1, sizeof(dval));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   800
        *ptr = buf + 1 + sizeof(double);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   801
        return PyFloat_FromDouble(dval);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   802
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   803
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   804
    case BSER_TRUE:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   805
      *ptr = buf + 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   806
      Py_INCREF(Py_True);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   807
      return Py_True;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   808
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   809
    case BSER_FALSE:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   810
      *ptr = buf + 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   811
      Py_INCREF(Py_False);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   812
      return Py_False;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   813
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   814
    case BSER_NULL:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   815
      *ptr = buf + 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   816
      Py_INCREF(Py_None);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   817
      return Py_None;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   818
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   819
    case BSER_STRING:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   820
      {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   821
        const char *start;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   822
        int64_t len;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   823
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   824
        if (!bunser_string(ptr, end, &start, &len)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   825
          return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   826
        }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   827
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   828
        if (len > LONG_MAX) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   829
          PyErr_Format(PyExc_ValueError, "string too long for python");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   830
          return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   831
        }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   832
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   833
        return PyString_FromStringAndSize(start, (long)len);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   834
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   835
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   836
    case BSER_ARRAY:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   837
      return bunser_array(ptr, end, mutable);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   838
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   839
    case BSER_OBJECT:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   840
      return bunser_object(ptr, end, mutable);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   841
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   842
    case BSER_TEMPLATE:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   843
      return bunser_template(ptr, end, mutable);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   844
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   845
    default:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   846
      PyErr_Format(PyExc_ValueError, "unhandled bser opcode 0x%02x", buf[0]);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   847
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   848
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   849
  return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   850
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   851
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   852
// Expected use case is to read a packet from the socket and
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   853
// then call bser.pdu_len on the packet.  It returns the total
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   854
// length of the entire response that the peer is sending,
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   855
// including the bytes already received.  This allows the client
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   856
// to compute the data size it needs to read before it can
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   857
// decode the data
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   858
static PyObject *bser_pdu_len(PyObject *self, PyObject *args)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   859
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   860
  const char *start = NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   861
  const char *data = NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   862
  int datalen = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   863
  const char *end;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   864
  int64_t expected_len, total_len;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   865
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   866
  if (!PyArg_ParseTuple(args, "s#", &start, &datalen)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   867
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   868
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   869
  data = start;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   870
  end = data + datalen;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   871
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   872
  // Validate the header and length
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   873
  if (memcmp(data, EMPTY_HEADER, 2) != 0) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   874
    PyErr_SetString(PyExc_ValueError, "invalid bser header");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   875
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   876
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   877
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   878
  data += 2;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   879
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   880
  // Expect an integer telling us how big the rest of the data
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   881
  // should be
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   882
  if (!bunser_int(&data, end, &expected_len)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   883
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   884
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   885
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   886
  total_len = expected_len + (data - start);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   887
  if (total_len > LONG_MAX) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   888
    return PyLong_FromLongLong(total_len);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   889
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   890
  return PyInt_FromLong((long)total_len);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   891
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   892
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   893
static PyObject *bser_loads(PyObject *self, PyObject *args)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   894
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   895
  const char *data = NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   896
  int datalen = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   897
  const char *end;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   898
  int64_t expected_len;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   899
  int mutable = 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   900
  PyObject *mutable_obj = NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   901
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   902
  if (!PyArg_ParseTuple(args, "s#|O:loads", &data, &datalen, &mutable_obj)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   903
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   904
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   905
  if (mutable_obj) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   906
    mutable = PyObject_IsTrue(mutable_obj) > 0 ? 1 : 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   907
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   908
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   909
  end = data + datalen;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   910
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   911
  // Validate the header and length
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   912
  if (memcmp(data, EMPTY_HEADER, 2) != 0) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   913
    PyErr_SetString(PyExc_ValueError, "invalid bser header");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   914
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   915
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   916
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   917
  data += 2;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   918
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   919
  // Expect an integer telling us how big the rest of the data
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   920
  // should be
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   921
  if (!bunser_int(&data, end, &expected_len)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   922
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   923
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   924
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   925
  // Verify
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   926
  if (expected_len + data != end) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   927
    PyErr_SetString(PyExc_ValueError, "bser data len != header len");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   928
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   929
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   930
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   931
  return bser_loads_recursive(&data, end, mutable);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   932
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   933
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   934
static PyMethodDef bser_methods[] = {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   935
  {"loads",  bser_loads, METH_VARARGS, "Deserialize string."},
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   936
  {"pdu_len", bser_pdu_len, METH_VARARGS, "Extract PDU length."},
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   937
  {"dumps",  bser_dumps, METH_VARARGS, "Serialize string."},
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   938
  {NULL, NULL, 0, NULL}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   939
};
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   940
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   941
PyMODINIT_FUNC initbser(void)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   942
{
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   943
  (void)Py_InitModule("bser", bser_methods);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   944
  PyType_Ready(&bserObjectType);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   945
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   946
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   947
/* vim:ts=2:sw=2:et:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   948
 */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   949
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   950
// no-check-code -- this is a 3rd party library