hgext/fsmonitor/pywatchman/bser.c
author Pulkit Goyal <7895pulkit@gmail.com>
Thu, 05 Apr 2018 17:00:15 +0530
changeset 37367 87c4253bebdb
parent 30656 16f4b341288d
child 37594 b1f62cd39b5c
permissions -rw-r--r--
py3: suppress the output of open() using `and None` This patch suppresses the output of open() on Python 3 as it does not return any output on Python 2. This makes test-diffstat.t pass on Python 3.5 Differential Revision: https://phab.mercurial-scm.org/D3128
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>
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    32
#include <bytesobject.h>
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    33
#ifdef _MSC_VER
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    34
#define inline __inline
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    35
#if _MSC_VER >= 1800
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    36
#include <stdint.h>
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    37
#else
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    38
// The compiler associated with Python 2.7 on Windows doesn't ship
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    39
// with stdint.h, so define the small subset that we use here.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    40
typedef __int8 int8_t;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    41
typedef __int16 int16_t;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    42
typedef __int32 int32_t;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    43
typedef __int64 int64_t;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    44
typedef unsigned __int8 uint8_t;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    45
typedef unsigned __int16 uint16_t;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    46
typedef unsigned __int32 uint32_t;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    47
typedef unsigned __int64 uint64_t;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    48
#define UINT32_MAX 4294967295U
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    49
#endif
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    50
#endif
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    51
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    52
// clang-format off
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    53
/* 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
    54
#define INT_SIZE(x) (((x) == ((int8_t)x))  ? 1 :    \
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    55
                     ((x) == ((int16_t)x)) ? 2 :    \
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    56
                     ((x) == ((int32_t)x)) ? 4 : 8)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    57
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    58
#define BSER_ARRAY     0x00
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    59
#define BSER_OBJECT    0x01
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    60
#define BSER_BYTESTRING 0x02
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    61
#define BSER_INT8      0x03
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    62
#define BSER_INT16     0x04
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    63
#define BSER_INT32     0x05
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    64
#define BSER_INT64     0x06
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    65
#define BSER_REAL      0x07
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    66
#define BSER_TRUE      0x08
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    67
#define BSER_FALSE     0x09
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    68
#define BSER_NULL      0x0a
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    69
#define BSER_TEMPLATE  0x0b
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    70
#define BSER_SKIP      0x0c
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    71
#define BSER_UTF8STRING 0x0d
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    72
// clang-format on
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    73
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    74
// An immutable object representation of BSER_OBJECT.
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    75
// 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
    76
// 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
    77
// 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
    78
// 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
    79
// 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
    80
// 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
    81
// using a proper hash table.  Even with this simplistic
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    82
// 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
    83
// 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
    84
// represent the stat information in the hgwatchman extension
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    85
// clang-format off
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    86
typedef struct {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    87
  PyObject_HEAD
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    88
  PyObject *keys;   // tuple of field names
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    89
  PyObject *values; // tuple of values
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    90
} bserObject;
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    91
// clang-format on
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    92
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    93
static Py_ssize_t bserobj_tuple_length(PyObject* o) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    94
  bserObject* obj = (bserObject*)o;
28432
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
  return PySequence_Length(obj->keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    97
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    98
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
    99
static PyObject* bserobj_tuple_item(PyObject* o, Py_ssize_t i) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   100
  bserObject* obj = (bserObject*)o;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   101
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   102
  return PySequence_GetItem(obj->values, i);
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
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   105
// clang-format off
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   106
static PySequenceMethods bserobj_sq = {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   107
  bserobj_tuple_length,      /* sq_length */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   108
  0,                         /* sq_concat */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   109
  0,                         /* sq_repeat */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   110
  bserobj_tuple_item,        /* sq_item */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   111
  0,                         /* sq_ass_item */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   112
  0,                         /* sq_contains */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   113
  0,                         /* sq_inplace_concat */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   114
  0                          /* sq_inplace_repeat */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   115
};
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   116
// clang-format on
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   117
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   118
static void bserobj_dealloc(PyObject* o) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   119
  bserObject* obj = (bserObject*)o;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   120
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   121
  Py_CLEAR(obj->keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   122
  Py_CLEAR(obj->values);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   123
  PyObject_Del(o);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   124
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   125
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   126
static PyObject* bserobj_getattrro(PyObject* o, PyObject* name) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   127
  bserObject* obj = (bserObject*)o;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   128
  Py_ssize_t i, n;
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   129
  PyObject* name_bytes = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   130
  PyObject* ret = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   131
  const char* namestr;
28432
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
  if (PyIndex_Check(name)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   134
    i = PyNumber_AsSsize_t(name, PyExc_IndexError);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   135
    if (i == -1 && PyErr_Occurred()) {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   136
      goto bail;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   137
    }
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   138
    ret = PySequence_GetItem(obj->values, i);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   139
    goto bail;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   140
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   141
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   142
  // We can be passed in Unicode objects here -- we don't support anything other
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   143
  // than UTF-8 for keys.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   144
  if (PyUnicode_Check(name)) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   145
    name_bytes = PyUnicode_AsUTF8String(name);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   146
    if (name_bytes == NULL) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   147
      goto bail;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   148
    }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   149
    namestr = PyBytes_AsString(name_bytes);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   150
  } else {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   151
    namestr = PyBytes_AsString(name);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   152
  }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   153
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   154
  if (namestr == NULL) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   155
    goto bail;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   156
  }
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   157
  // 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
   158
  if (!strncmp(namestr, "st_", 3)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   159
    namestr += 3;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   160
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   161
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   162
  n = PyTuple_GET_SIZE(obj->keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   163
  for (i = 0; i < n; i++) {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   164
    const char* item_name = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   165
    PyObject* key = PyTuple_GET_ITEM(obj->keys, i);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   166
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   167
    item_name = PyBytes_AsString(key);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   168
    if (!strcmp(item_name, namestr)) {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   169
      ret = PySequence_GetItem(obj->values, i);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   170
      goto bail;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   171
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   172
  }
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   173
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   174
  PyErr_Format(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   175
      PyExc_AttributeError, "bserobject has no attribute '%.400s'", namestr);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   176
bail:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   177
  Py_XDECREF(name_bytes);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   178
  return ret;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   179
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   180
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   181
// clang-format off
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   182
static PyMappingMethods bserobj_map = {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   183
  bserobj_tuple_length,     /* mp_length */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   184
  bserobj_getattrro,        /* mp_subscript */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   185
  0                         /* mp_ass_subscript */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   186
};
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   187
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   188
PyTypeObject bserObjectType = {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   189
  PyVarObject_HEAD_INIT(NULL, 0)
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   190
  "bserobj_tuple",           /* tp_name */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   191
  sizeof(bserObject),        /* tp_basicsize */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   192
  0,                         /* tp_itemsize */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   193
  bserobj_dealloc,           /* tp_dealloc */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   194
  0,                         /* tp_print */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   195
  0,                         /* tp_getattr */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   196
  0,                         /* tp_setattr */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   197
  0,                         /* tp_compare */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   198
  0,                         /* tp_repr */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   199
  0,                         /* tp_as_number */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   200
  &bserobj_sq,               /* tp_as_sequence */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   201
  &bserobj_map,              /* tp_as_mapping */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   202
  0,                         /* tp_hash  */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   203
  0,                         /* tp_call */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   204
  0,                         /* tp_str */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   205
  bserobj_getattrro,         /* tp_getattro */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   206
  0,                         /* tp_setattro */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   207
  0,                         /* tp_as_buffer */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   208
  Py_TPFLAGS_DEFAULT,        /* tp_flags */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   209
  "bserobj tuple",           /* tp_doc */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   210
  0,                         /* tp_traverse */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   211
  0,                         /* tp_clear */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   212
  0,                         /* tp_richcompare */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   213
  0,                         /* tp_weaklistoffset */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   214
  0,                         /* tp_iter */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   215
  0,                         /* tp_iternext */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   216
  0,                         /* tp_methods */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   217
  0,                         /* tp_members */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   218
  0,                         /* tp_getset */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   219
  0,                         /* tp_base */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   220
  0,                         /* tp_dict */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   221
  0,                         /* tp_descr_get */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   222
  0,                         /* tp_descr_set */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   223
  0,                         /* tp_dictoffset */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   224
  0,                         /* tp_init */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   225
  0,                         /* tp_alloc */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   226
  0,                         /* tp_new */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   227
};
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   228
// clang-format on
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   229
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   230
typedef struct loads_ctx {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   231
  int mutable;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   232
  const char* value_encoding;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   233
  const char* value_errors;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   234
  uint32_t bser_version;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   235
  uint32_t bser_capabilities;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   236
} unser_ctx_t;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   237
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   238
static PyObject*
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   239
bser_loads_recursive(const char** ptr, const char* end, const unser_ctx_t* ctx);
28432
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
static const char bser_true = BSER_TRUE;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   242
static const char bser_false = BSER_FALSE;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   243
static const char bser_null = BSER_NULL;
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   244
static const char bser_bytestring_hdr = BSER_BYTESTRING;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   245
static const char bser_array_hdr = BSER_ARRAY;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   246
static const char bser_object_hdr = BSER_OBJECT;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   247
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   248
static inline uint32_t next_power_2(uint32_t n) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   249
  n |= (n >> 16);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   250
  n |= (n >> 8);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   251
  n |= (n >> 4);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   252
  n |= (n >> 2);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   253
  n |= (n >> 1);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   254
  return n + 1;
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
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   257
// 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
   258
struct bser_buffer {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   259
  char* buf;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   260
  int wpos, allocd;
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   261
  uint32_t bser_version;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   262
  uint32_t capabilities;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   263
};
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   264
typedef struct bser_buffer bser_t;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   265
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   266
static int bser_append(bser_t* bser, const char* data, uint32_t len) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   267
  int newlen = next_power_2(bser->wpos + len);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   268
  if (newlen > bser->allocd) {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   269
    char* nbuf = realloc(bser->buf, newlen);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   270
    if (!nbuf) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   271
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   272
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   273
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   274
    bser->buf = nbuf;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   275
    bser->allocd = newlen;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   276
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   277
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   278
  memcpy(bser->buf + bser->wpos, data, len);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   279
  bser->wpos += len;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   280
  return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   281
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   282
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   283
static int bser_init(bser_t* bser, uint32_t version, uint32_t capabilities) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   284
  bser->allocd = 8192;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   285
  bser->wpos = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   286
  bser->buf = malloc(bser->allocd);
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   287
  bser->bser_version = version;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   288
  bser->capabilities = capabilities;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   289
  if (!bser->buf) {
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
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   293
// Leave room for the serialization header, which includes
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   294
// our overall length.  To make things simpler, we'll use an
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   295
// int32 for the header
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   296
#define EMPTY_HEADER "\x00\x01\x05\x00\x00\x00\x00"
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   297
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   298
// Version 2 also carries an integer indicating the capabilities. The
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   299
// capabilities integer comes before the PDU size.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   300
#define EMPTY_HEADER_V2 "\x00\x02\x00\x00\x00\x00\x05\x00\x00\x00\x00"
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   301
  if (version == 2) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   302
    bser_append(bser, EMPTY_HEADER_V2, sizeof(EMPTY_HEADER_V2) - 1);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   303
  } else {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   304
    bser_append(bser, EMPTY_HEADER, sizeof(EMPTY_HEADER) - 1);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   305
  }
28432
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
  return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   308
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   309
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   310
static void bser_dtor(bser_t* bser) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   311
  free(bser->buf);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   312
  bser->buf = NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   313
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   314
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   315
static int bser_long(bser_t* bser, int64_t val) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   316
  int8_t i8;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   317
  int16_t i16;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   318
  int32_t i32;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   319
  int64_t i64;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   320
  char sz;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   321
  int size = INT_SIZE(val);
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   322
  char* iptr;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   323
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   324
  switch (size) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   325
    case 1:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   326
      sz = BSER_INT8;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   327
      i8 = (int8_t)val;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   328
      iptr = (char*)&i8;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   329
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   330
    case 2:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   331
      sz = BSER_INT16;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   332
      i16 = (int16_t)val;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   333
      iptr = (char*)&i16;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   334
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   335
    case 4:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   336
      sz = BSER_INT32;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   337
      i32 = (int32_t)val;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   338
      iptr = (char*)&i32;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   339
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   340
    case 8:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   341
      sz = BSER_INT64;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   342
      i64 = (int64_t)val;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   343
      iptr = (char*)&i64;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   344
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   345
    default:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   346
      PyErr_SetString(PyExc_RuntimeError, "Cannot represent this long value!?");
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   347
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   348
  }
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
  if (!bser_append(bser, &sz, sizeof(sz))) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   351
    return 0;
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
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   354
  return bser_append(bser, iptr, size);
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
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   357
static int bser_bytestring(bser_t* bser, PyObject* sval) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   358
  char* buf = NULL;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   359
  Py_ssize_t len;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   360
  int res;
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   361
  PyObject* utf = NULL;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   362
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   363
  if (PyUnicode_Check(sval)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   364
    utf = PyUnicode_AsEncodedString(sval, "utf-8", "ignore");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   365
    sval = utf;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   366
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   367
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   368
  res = PyBytes_AsStringAndSize(sval, &buf, &len);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   369
  if (res == -1) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   370
    res = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   371
    goto out;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   372
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   373
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   374
  if (!bser_append(bser, &bser_bytestring_hdr, sizeof(bser_bytestring_hdr))) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   375
    res = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   376
    goto out;
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
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   379
  if (!bser_long(bser, len)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   380
    res = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   381
    goto out;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   382
  }
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 (len > UINT32_MAX) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   385
    PyErr_Format(PyExc_ValueError, "string too big");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   386
    res = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   387
    goto out;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   388
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   389
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   390
  res = bser_append(bser, buf, (uint32_t)len);
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
out:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   393
  if (utf) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   394
    Py_DECREF(utf);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   395
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   396
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   397
  return res;
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
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   400
static int bser_recursive(bser_t* bser, PyObject* val) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   401
  if (PyBool_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   402
    if (val == Py_True) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   403
      return bser_append(bser, &bser_true, sizeof(bser_true));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   404
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   405
    return bser_append(bser, &bser_false, sizeof(bser_false));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   406
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   407
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   408
  if (val == Py_None) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   409
    return bser_append(bser, &bser_null, sizeof(bser_null));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   410
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   411
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   412
// Python 3 has one integer type.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   413
#if PY_MAJOR_VERSION < 3
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   414
  if (PyInt_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   415
    return bser_long(bser, PyInt_AS_LONG(val));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   416
  }
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   417
#endif // PY_MAJOR_VERSION < 3
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   418
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   419
  if (PyLong_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   420
    return bser_long(bser, PyLong_AsLongLong(val));
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
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   423
  if (PyBytes_Check(val) || PyUnicode_Check(val)) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   424
    return bser_bytestring(bser, val);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   425
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   426
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   427
  if (PyFloat_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   428
    double dval = PyFloat_AS_DOUBLE(val);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   429
    char sz = BSER_REAL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   430
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   431
    if (!bser_append(bser, &sz, sizeof(sz))) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   432
      return 0;
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
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   435
    return bser_append(bser, (char*)&dval, sizeof(dval));
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
  if (PyList_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   439
    Py_ssize_t i, len = PyList_GET_SIZE(val);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   440
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   441
    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
   442
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   443
    }
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
    if (!bser_long(bser, len)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   446
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   447
    }
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
    for (i = 0; i < len; i++) {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   450
      PyObject* ele = PyList_GET_ITEM(val, i);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   451
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   452
      if (!bser_recursive(bser, ele)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   453
        return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   454
      }
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
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   457
    return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   458
  }
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 (PyTuple_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   461
    Py_ssize_t i, len = PyTuple_GET_SIZE(val);
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
    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
   464
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   465
    }
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
    if (!bser_long(bser, len)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   468
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   469
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   470
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   471
    for (i = 0; i < len; i++) {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   472
      PyObject* ele = PyTuple_GET_ITEM(val, i);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   473
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   474
      if (!bser_recursive(bser, ele)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   475
        return 0;
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
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   478
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   479
    return 1;
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
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   482
  if (PyMapping_Check(val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   483
    Py_ssize_t len = PyMapping_Length(val);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   484
    Py_ssize_t pos = 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   485
    PyObject *key, *ele;
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
    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
   488
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   489
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   490
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   491
    if (!bser_long(bser, len)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   492
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   493
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   494
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   495
    while (PyDict_Next(val, &pos, &key, &ele)) {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   496
      if (!bser_bytestring(bser, key)) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   497
        return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   498
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   499
      if (!bser_recursive(bser, ele)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   500
        return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   501
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   502
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   503
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   504
    return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   505
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   506
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   507
  PyErr_SetString(PyExc_ValueError, "Unsupported value type");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   508
  return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   509
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   510
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   511
static PyObject* bser_dumps(PyObject* self, PyObject* args, PyObject* kw) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   512
  PyObject *val = NULL, *res;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   513
  bser_t bser;
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   514
  uint32_t len, bser_version = 1, bser_capabilities = 0;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   515
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   516
  static char* kw_list[] = {"val", "version", "capabilities", NULL};
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   517
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   518
  if (!PyArg_ParseTupleAndKeywords(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   519
          args,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   520
          kw,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   521
          "O|ii:dumps",
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   522
          kw_list,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   523
          &val,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   524
          &bser_version,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   525
          &bser_capabilities)) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   526
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   527
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   528
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   529
  if (!bser_init(&bser, bser_version, bser_capabilities)) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   530
    return PyErr_NoMemory();
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   531
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   532
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   533
  if (!bser_recursive(&bser, val)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   534
    bser_dtor(&bser);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   535
    if (errno == ENOMEM) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   536
      return PyErr_NoMemory();
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   537
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   538
    // 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
   539
    return NULL;
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
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   542
  // Now fill in the overall length
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   543
  if (bser_version == 1) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   544
    len = bser.wpos - (sizeof(EMPTY_HEADER) - 1);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   545
    memcpy(bser.buf + 3, &len, sizeof(len));
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   546
  } else {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   547
    len = bser.wpos - (sizeof(EMPTY_HEADER_V2) - 1);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   548
    // The BSER capabilities block comes before the PDU length
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   549
    memcpy(bser.buf + 2, &bser_capabilities, sizeof(bser_capabilities));
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   550
    memcpy(bser.buf + 7, &len, sizeof(len));
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   551
  }
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   552
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   553
  res = PyBytes_FromStringAndSize(bser.buf, bser.wpos);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   554
  bser_dtor(&bser);
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
  return res;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   557
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   558
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   559
int bunser_int(const char** ptr, const char* end, int64_t* val) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   560
  int needed;
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   561
  const char* buf = *ptr;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   562
  int8_t i8;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   563
  int16_t i16;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   564
  int32_t i32;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   565
  int64_t i64;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   566
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   567
  switch (buf[0]) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   568
    case BSER_INT8:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   569
      needed = 2;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   570
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   571
    case BSER_INT16:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   572
      needed = 3;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   573
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   574
    case BSER_INT32:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   575
      needed = 5;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   576
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   577
    case BSER_INT64:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   578
      needed = 9;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   579
      break;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   580
    default:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   581
      PyErr_Format(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   582
          PyExc_ValueError, "invalid bser int encoding 0x%02x", buf[0]);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   583
      return 0;
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
  if (end - buf < needed) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   586
    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
   587
    return 0;
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
  *ptr = buf + needed;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   590
  switch (buf[0]) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   591
    case BSER_INT8:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   592
      memcpy(&i8, buf + 1, sizeof(i8));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   593
      *val = i8;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   594
      return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   595
    case BSER_INT16:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   596
      memcpy(&i16, buf + 1, sizeof(i16));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   597
      *val = i16;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   598
      return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   599
    case BSER_INT32:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   600
      memcpy(&i32, buf + 1, sizeof(i32));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   601
      *val = i32;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   602
      return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   603
    case BSER_INT64:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   604
      memcpy(&i64, buf + 1, sizeof(i64));
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   605
      *val = i64;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   606
      return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   607
    default:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   608
      return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   609
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   610
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   611
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   612
static int bunser_bytestring(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   613
    const char** ptr,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   614
    const char* end,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   615
    const char** start,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   616
    int64_t* len) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   617
  const char* buf = *ptr;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   618
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   619
  // skip string marker
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   620
  buf++;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   621
  if (!bunser_int(&buf, end, len)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   622
    return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   623
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   624
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   625
  if (buf + *len > end) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   626
    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
   627
    return 0;
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
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   630
  *ptr = buf + *len;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   631
  *start = buf;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   632
  return 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   633
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   634
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   635
static PyObject*
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   636
bunser_array(const char** ptr, const char* end, const unser_ctx_t* ctx) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   637
  const char* buf = *ptr;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   638
  int64_t nitems, i;
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   639
  int mutable = ctx->mutable;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   640
  PyObject* res;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   641
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   642
  // skip array header
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   643
  buf++;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   644
  if (!bunser_int(&buf, end, &nitems)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   645
    return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   646
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   647
  *ptr = buf;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   648
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   649
  if (nitems > LONG_MAX) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   650
    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
   651
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   652
  }
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 (mutable) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   655
    res = PyList_New((Py_ssize_t)nitems);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   656
  } else {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   657
    res = PyTuple_New((Py_ssize_t)nitems);
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
  for (i = 0; i < nitems; i++) {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   661
    PyObject* ele = bser_loads_recursive(ptr, end, ctx);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   662
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   663
    if (!ele) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   664
      Py_DECREF(res);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   665
      return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   666
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   667
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   668
    if (mutable) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   669
      PyList_SET_ITEM(res, i, ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   670
    } else {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   671
      PyTuple_SET_ITEM(res, i, ele);
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
    // 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
   674
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   675
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   676
  return res;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   677
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   678
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   679
static PyObject*
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   680
bunser_object(const char** ptr, const char* end, const unser_ctx_t* ctx) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   681
  const char* buf = *ptr;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   682
  int64_t nitems, i;
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   683
  int mutable = ctx->mutable;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   684
  PyObject* res;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   685
  bserObject* obj;
28432
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
  // skip array header
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   688
  buf++;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   689
  if (!bunser_int(&buf, end, &nitems)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   690
    return 0;
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
  *ptr = buf;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   693
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   694
  if (mutable) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   695
    res = PyDict_New();
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   696
  } else {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   697
    obj = PyObject_New(bserObject, &bserObjectType);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   698
    obj->keys = PyTuple_New((Py_ssize_t)nitems);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   699
    obj->values = PyTuple_New((Py_ssize_t)nitems);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   700
    res = (PyObject*)obj;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   701
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   702
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   703
  for (i = 0; i < nitems; i++) {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   704
    const char* keystr;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   705
    int64_t keylen;
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   706
    PyObject* key;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   707
    PyObject* ele;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   708
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   709
    if (!bunser_bytestring(ptr, end, &keystr, &keylen)) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   710
      Py_DECREF(res);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   711
      return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   712
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   713
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   714
    if (keylen > LONG_MAX) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   715
      PyErr_Format(PyExc_ValueError, "string too big for python");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   716
      Py_DECREF(res);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   717
      return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   718
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   719
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   720
    if (mutable) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   721
      // This will interpret the key as UTF-8.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   722
      key = PyUnicode_FromStringAndSize(keystr, (Py_ssize_t)keylen);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   723
    } else {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   724
      // For immutable objects we'll manage key lookups, so we can avoid going
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   725
      // through the Unicode APIs. This avoids a potentially expensive and
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   726
      // definitely unnecessary conversion to UTF-16 and back for Python 2.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   727
      // TODO: On Python 3 the Unicode APIs are smarter: we might be able to use
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   728
      // Unicode keys there without an appreciable performance loss.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   729
      key = PyBytes_FromStringAndSize(keystr, (Py_ssize_t)keylen);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   730
    }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   731
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   732
    if (!key) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   733
      Py_DECREF(res);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   734
      return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   735
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   736
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   737
    ele = bser_loads_recursive(ptr, end, ctx);
28432
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
    if (!ele) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   740
      Py_DECREF(key);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   741
      Py_DECREF(res);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   742
      return NULL;
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
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   745
    if (mutable) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   746
      PyDict_SetItem(res, key, ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   747
      Py_DECREF(key);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   748
      Py_DECREF(ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   749
    } else {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   750
      /* PyTuple_SET_ITEM steals ele, key */
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   751
      PyTuple_SET_ITEM(obj->values, i, ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   752
      PyTuple_SET_ITEM(obj->keys, i, key);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   753
    }
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
  return res;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   757
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   758
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   759
static PyObject*
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   760
bunser_template(const char** ptr, const char* end, const unser_ctx_t* ctx) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   761
  const char* buf = *ptr;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   762
  int64_t nitems, i;
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   763
  int mutable = ctx->mutable;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   764
  PyObject* arrval;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   765
  PyObject* keys;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   766
  Py_ssize_t numkeys, keyidx;
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   767
  unser_ctx_t keys_ctx = {0};
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   768
  if (mutable) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   769
    keys_ctx.mutable = 1;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   770
    // Decode keys as UTF-8 in this case.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   771
    keys_ctx.value_encoding = "utf-8";
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   772
    keys_ctx.value_errors = "strict";
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   773
  } else {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   774
    // Treat keys as bytestrings in this case -- we'll do Unicode conversions at
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   775
    // lookup time.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   776
  }
28432
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
  if (buf[1] != BSER_ARRAY) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   779
    PyErr_Format(PyExc_ValueError, "Expect ARRAY to follow TEMPLATE");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   780
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   781
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   782
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   783
  // skip header
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   784
  buf++;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   785
  *ptr = buf;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   786
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   787
  // Load template keys.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   788
  // For keys we don't want to do any decoding right now.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   789
  keys = bunser_array(ptr, end, &keys_ctx);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   790
  if (!keys) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   791
    return NULL;
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
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   794
  numkeys = PySequence_Length(keys);
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
  // Load number of array elements
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   797
  if (!bunser_int(ptr, end, &nitems)) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   798
    Py_DECREF(keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   799
    return 0;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   800
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   801
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   802
  if (nitems > LONG_MAX) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   803
    PyErr_Format(PyExc_ValueError, "Too many items for python");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   804
    Py_DECREF(keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   805
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   806
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   807
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   808
  arrval = PyList_New((Py_ssize_t)nitems);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   809
  if (!arrval) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   810
    Py_DECREF(keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   811
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   812
  }
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
  for (i = 0; i < nitems; i++) {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   815
    PyObject* dict = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   816
    bserObject* obj = NULL;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   817
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   818
    if (mutable) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   819
      dict = PyDict_New();
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   820
    } else {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   821
      obj = PyObject_New(bserObject, &bserObjectType);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   822
      if (obj) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   823
        obj->keys = keys;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   824
        Py_INCREF(obj->keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   825
        obj->values = PyTuple_New(numkeys);
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
      dict = (PyObject*)obj;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   828
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   829
    if (!dict) {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   830
    fail:
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   831
      Py_DECREF(keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   832
      Py_DECREF(arrval);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   833
      return NULL;
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
    for (keyidx = 0; keyidx < numkeys; keyidx++) {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   837
      PyObject* key;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   838
      PyObject* ele;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   839
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   840
      if (**ptr == BSER_SKIP) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   841
        *ptr = *ptr + 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   842
        ele = Py_None;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   843
        Py_INCREF(ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   844
      } else {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   845
        ele = bser_loads_recursive(ptr, end, ctx);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   846
      }
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
      if (!ele) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   849
        goto fail;
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
      if (mutable) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   853
        key = PyList_GET_ITEM(keys, keyidx);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   854
        PyDict_SetItem(dict, key, ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   855
        Py_DECREF(ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   856
      } else {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   857
        PyTuple_SET_ITEM(obj->values, keyidx, ele);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   858
        // 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
   859
      }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   860
    }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   861
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   862
    PyList_SET_ITEM(arrval, i, dict);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   863
    // 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
   864
  }
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
  Py_DECREF(keys);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   867
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   868
  return arrval;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   869
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   870
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   871
static PyObject* bser_loads_recursive(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   872
    const char** ptr,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   873
    const char* end,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   874
    const unser_ctx_t* ctx) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   875
  const char* buf = *ptr;
28432
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
  switch (buf[0]) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   878
    case BSER_INT8:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   879
    case BSER_INT16:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   880
    case BSER_INT32:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   881
    case BSER_INT64: {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   882
      int64_t ival;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   883
      if (!bunser_int(ptr, end, &ival)) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   884
        return NULL;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   885
      }
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   886
// Python 3 has one integer type.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   887
#if PY_MAJOR_VERSION >= 3
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   888
      return PyLong_FromLongLong(ival);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   889
#else
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   890
      if (ival < LONG_MIN || ival > LONG_MAX) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   891
        return PyLong_FromLongLong(ival);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   892
      }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   893
      return PyInt_FromSsize_t(Py_SAFE_DOWNCAST(ival, int64_t, Py_ssize_t));
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   894
#endif // PY_MAJOR_VERSION >= 3
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   895
    }
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   896
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   897
    case BSER_REAL: {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   898
      double dval;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   899
      memcpy(&dval, buf + 1, sizeof(dval));
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   900
      *ptr = buf + 1 + sizeof(double);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   901
      return PyFloat_FromDouble(dval);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   902
    }
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   903
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   904
    case BSER_TRUE:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   905
      *ptr = buf + 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   906
      Py_INCREF(Py_True);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   907
      return Py_True;
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
    case BSER_FALSE:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   910
      *ptr = buf + 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   911
      Py_INCREF(Py_False);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   912
      return Py_False;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   913
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   914
    case BSER_NULL:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   915
      *ptr = buf + 1;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   916
      Py_INCREF(Py_None);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   917
      return Py_None;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   918
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   919
    case BSER_BYTESTRING: {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   920
      const char* start;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   921
      int64_t len;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   922
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   923
      if (!bunser_bytestring(ptr, end, &start, &len)) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   924
        return NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   925
      }
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   926
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   927
      if (len > LONG_MAX) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   928
        PyErr_Format(PyExc_ValueError, "string too long for python");
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   929
        return NULL;
28432
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
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   932
      if (ctx->value_encoding != NULL) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   933
        return PyUnicode_Decode(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   934
            start, (long)len, ctx->value_encoding, ctx->value_errors);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   935
      } else {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   936
        return PyBytes_FromStringAndSize(start, (long)len);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   937
      }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   938
    }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   939
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   940
    case BSER_UTF8STRING: {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   941
      const char* start;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   942
      int64_t len;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   943
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   944
      if (!bunser_bytestring(ptr, end, &start, &len)) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   945
        return NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   946
      }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   947
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   948
      if (len > LONG_MAX) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   949
        PyErr_Format(PyExc_ValueError, "string too long for python");
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   950
        return NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   951
      }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   952
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   953
      return PyUnicode_Decode(start, (long)len, "utf-8", "strict");
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   954
    }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   955
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   956
    case BSER_ARRAY:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   957
      return bunser_array(ptr, end, ctx);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   958
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   959
    case BSER_OBJECT:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   960
      return bunser_object(ptr, end, ctx);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   961
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   962
    case BSER_TEMPLATE:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   963
      return bunser_template(ptr, end, ctx);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   964
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   965
    default:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   966
      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
   967
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   968
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   969
  return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   970
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   971
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   972
static int _pdu_info_helper(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   973
    const char* data,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   974
    const char* end,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   975
    uint32_t* bser_version_out,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   976
    uint32_t* bser_capabilities_out,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   977
    int64_t* expected_len_out,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   978
    off_t* position_out) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   979
  uint32_t bser_version;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   980
  uint32_t bser_capabilities = 0;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   981
  int64_t expected_len;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   982
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   983
  const char* start;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   984
  start = data;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   985
  // Validate the header and length
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   986
  if (memcmp(data, EMPTY_HEADER, 2) == 0) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   987
    bser_version = 1;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   988
  } else if (memcmp(data, EMPTY_HEADER_V2, 2) == 0) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   989
    bser_version = 2;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   990
  } else {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   991
    PyErr_SetString(PyExc_ValueError, "invalid bser header");
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   992
    return 0;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   993
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   994
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   995
  data += 2;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   996
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   997
  if (bser_version == 2) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   998
    // Expect an integer telling us what capabilities are supported by the
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
   999
    // remote server (currently unused).
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1000
    if (!memcpy(&bser_capabilities, &data, sizeof(bser_capabilities))) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1001
      return 0;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1002
    }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1003
    data += sizeof(bser_capabilities);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1004
  }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1005
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1006
  // 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
  1007
  // should be
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1008
  if (!bunser_int(&data, end, &expected_len)) {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1009
    return 0;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1010
  }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1011
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1012
  *bser_version_out = bser_version;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1013
  *bser_capabilities_out = (uint32_t)bser_capabilities;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1014
  *expected_len_out = expected_len;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1015
  *position_out = (off_t)(data - start);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1016
  return 1;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1017
}
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1018
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1019
// This function parses the PDU header and provides info about the packet
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1020
// Returns false if unsuccessful
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1021
static int pdu_info_helper(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1022
    PyObject* self,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1023
    PyObject* args,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1024
    uint32_t* bser_version_out,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1025
    uint32_t* bser_capabilities_out,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1026
    int64_t* total_len_out) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1027
  const char* start = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1028
  const char* data = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1029
  int datalen = 0;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1030
  const char* end;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1031
  int64_t expected_len;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1032
  off_t position;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1033
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1034
  if (!PyArg_ParseTuple(args, "s#", &start, &datalen)) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1035
    return 0;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1036
  }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1037
  data = start;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1038
  end = data + datalen;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1039
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1040
  if (!_pdu_info_helper(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1041
          data,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1042
          end,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1043
          bser_version_out,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1044
          bser_capabilities_out,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1045
          &expected_len,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1046
          &position)) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1047
    return 0;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1048
  }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1049
  *total_len_out = (int64_t)(expected_len + position);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1050
  return 1;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1051
}
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1052
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1053
// Expected use case is to read a packet from the socket and then call
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1054
// bser.pdu_info on the packet.  It returns the BSER version, BSER capabilities,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1055
// and the total length of the entire response that the peer is sending,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1056
// including the bytes already received. This allows the client  to compute the
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1057
// data size it needs to read before it can decode the data.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1058
static PyObject* bser_pdu_info(PyObject* self, PyObject* args) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1059
  uint32_t version, capabilities;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1060
  int64_t total_len;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1061
  if (!pdu_info_helper(self, args, &version, &capabilities, &total_len)) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1062
    return NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1063
  }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1064
  return Py_BuildValue("kkL", version, capabilities, total_len);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1065
}
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1066
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1067
static PyObject* bser_pdu_len(PyObject* self, PyObject* args) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1068
  uint32_t version, capabilities;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1069
  int64_t total_len;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1070
  if (!pdu_info_helper(self, args, &version, &capabilities, &total_len)) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1071
    return NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1072
  }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1073
  return Py_BuildValue("L", total_len);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1074
}
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1075
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1076
static PyObject* bser_loads(PyObject* self, PyObject* args, PyObject* kw) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1077
  const char* data = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1078
  int datalen = 0;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1079
  const char* start;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1080
  const char* end;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1081
  int64_t expected_len;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1082
  off_t position;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1083
  PyObject* mutable_obj = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1084
  const char* value_encoding = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1085
  const char* value_errors = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1086
  unser_ctx_t ctx = {1, 0};
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1087
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1088
  static char* kw_list[] = {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1089
      "buf", "mutable", "value_encoding", "value_errors", NULL};
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1090
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1091
  if (!PyArg_ParseTupleAndKeywords(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1092
          args,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1093
          kw,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1094
          "s#|Ozz:loads",
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1095
          kw_list,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1096
          &start,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1097
          &datalen,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1098
          &mutable_obj,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1099
          &value_encoding,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1100
          &value_errors)) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1101
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1102
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1103
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1104
  if (mutable_obj) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1105
    ctx.mutable = PyObject_IsTrue(mutable_obj) > 0 ? 1 : 0;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1106
  }
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1107
  ctx.value_encoding = value_encoding;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1108
  if (value_encoding == NULL) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1109
    ctx.value_errors = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1110
  } else if (value_errors == NULL) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1111
    ctx.value_errors = "strict";
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1112
  } else {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1113
    ctx.value_errors = value_errors;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1114
  }
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1115
  data = start;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1116
  end = data + datalen;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1117
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1118
  if (!_pdu_info_helper(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1119
          data,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1120
          end,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1121
          &ctx.bser_version,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1122
          &ctx.bser_capabilities,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1123
          &expected_len,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1124
          &position)) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1125
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1126
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1127
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1128
  data = start + position;
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1129
  // Verify
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1130
  if (expected_len + data != end) {
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1131
    PyErr_SetString(PyExc_ValueError, "bser data len != header len");
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1132
    return NULL;
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1133
  }
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1134
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1135
  return bser_loads_recursive(&data, end, &ctx);
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1136
}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1137
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1138
static PyObject* bser_load(PyObject* self, PyObject* args, PyObject* kw) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1139
  PyObject *load, *string;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1140
  PyObject* fp = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1141
  PyObject* mutable_obj = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1142
  const char* value_encoding = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1143
  const char* value_errors = NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1144
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1145
  static char* kw_list[] = {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1146
      "fp", "mutable", "value_encoding", "value_errors", NULL};
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1147
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1148
  if (!PyArg_ParseTupleAndKeywords(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1149
          args,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1150
          kw,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1151
          "OOzz:load",
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1152
          kw_list,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1153
          &fp,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1154
          &mutable_obj,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1155
          &value_encoding,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1156
          &value_errors)) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1157
    return NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1158
  }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1159
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1160
  load = PyImport_ImportModule("pywatchman.load");
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1161
  if (load == NULL) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1162
    return NULL;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1163
  }
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1164
  string = PyObject_CallMethod(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1165
      load, "load", "OOzz", fp, mutable_obj, value_encoding, value_errors);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1166
  Py_DECREF(load);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1167
  return string;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1168
}
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1169
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1170
// clang-format off
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1171
static PyMethodDef bser_methods[] = {
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1172
  {"loads", (PyCFunction)bser_loads, METH_VARARGS | METH_KEYWORDS,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1173
   "Deserialize string."},
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1174
  {"load", (PyCFunction)bser_load, METH_VARARGS | METH_KEYWORDS,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1175
   "Deserialize a file object"},
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1176
  {"pdu_info", (PyCFunction)bser_pdu_info, METH_VARARGS,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1177
   "Extract PDU information."},
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1178
  {"pdu_len", (PyCFunction)bser_pdu_len, METH_VARARGS,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1179
   "Extract total PDU length."},
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1180
  {"dumps",  (PyCFunction)bser_dumps, METH_VARARGS | METH_KEYWORDS,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1181
   "Serialize string."},
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1182
  {NULL, NULL, 0, NULL}
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1183
};
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1184
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1185
#if PY_MAJOR_VERSION >= 3
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1186
static struct PyModuleDef bser_module = {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1187
  PyModuleDef_HEAD_INIT,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1188
  "bser",
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1189
  "Efficient encoding and decoding of BSER.",
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1190
  -1,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1191
  bser_methods
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1192
};
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1193
// clang-format on
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1194
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1195
PyMODINIT_FUNC PyInit_bser(void) {
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1196
  PyObject* mod;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1197
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1198
  mod = PyModule_Create(&bser_module);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1199
  PyType_Ready(&bserObjectType);
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1200
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1201
  return mod;
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1202
}
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1203
#else
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1204
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1205
PyMODINIT_FUNC initbser(void) {
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1206
  (void)Py_InitModule("bser", bser_methods);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1207
  PyType_Ready(&bserObjectType);
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1208
}
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents: 28528
diff changeset
  1209
#endif // PY_MAJOR_VERSION >= 3
28432
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1210
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1211
/* vim:ts=2:sw=2:et:
2377c4ac4eec fsmonitor: dependencies for new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
  1212
 */