hgext/fsmonitor/pywatchman/load.py
author Matt Harbison <matt_harbison@yahoo.com>
Mon, 19 Apr 2021 20:38:52 -0400
changeset 46992 5fa019ceb499
parent 43385 6469c23a40a2
child 48875 6000f5b25c9b
permissions -rw-r--r--
mail: force SMTPException to bytes before wrapping in error.Abort Pytype wasn't complaining about this for some reason, but PyCharm was and we already handle another instance of this exception the same way in this function. Differential Revision: https://phab.mercurial-scm.org/D10473
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
     1
# Copyright 2016 Facebook, Inc.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
     2
# All rights reserved.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
     3
#
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
     4
# Redistribution and use in source and binary forms, with or without
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
     5
# modification, are permitted provided that the following conditions are met:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
     6
#
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
     7
#  * Redistributions of source code must retain the above copyright notice,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
     8
#    this list of conditions and the following disclaimer.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
     9
#
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    10
#  * Redistributions in binary form must reproduce the above copyright notice,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    11
#    this list of conditions and the following disclaimer in the documentation
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    12
#    and/or other materials provided with the distribution.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    13
#
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    14
#  * Neither the name Facebook nor the names of its contributors may be used to
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    15
#    endorse or promote products derived from this software without specific
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    16
#    prior written permission.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    17
#
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    18
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    19
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    20
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    21
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    22
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    23
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    24
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    25
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    26
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    27
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    28
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    29
# no unicode literals
43385
6469c23a40a2 fsmonitor: refresh pywatchman with upstream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30656
diff changeset
    30
from __future__ import absolute_import, division, print_function
6469c23a40a2 fsmonitor: refresh pywatchman with upstream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30656
diff changeset
    31
6469c23a40a2 fsmonitor: refresh pywatchman with upstream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30656
diff changeset
    32
import ctypes
6469c23a40a2 fsmonitor: refresh pywatchman with upstream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30656
diff changeset
    33
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    34
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    35
try:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    36
    from . import bser
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    37
except ImportError:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    38
    from . import pybser as bser
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    39
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    40
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    41
EMPTY_HEADER = b"\x00\x01\x05\x00\x00\x00\x00"
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    42
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    43
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    44
def _read_bytes(fp, buf):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    45
    """Read bytes from a file-like object
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    46
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    47
    @param fp: File-like object that implements read(int)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    48
    @type fp: file
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    49
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    50
    @param buf: Buffer to read into
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    51
    @type buf: bytes
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    52
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    53
    @return: buf
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    54
    """
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    55
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    56
    # Do the first read without resizing the input buffer
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    57
    offset = 0
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    58
    remaining = len(buf)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    59
    while remaining > 0:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    60
        l = fp.readinto((ctypes.c_char * remaining).from_buffer(buf, offset))
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    61
        if l is None or l == 0:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    62
            return offset
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    63
        offset += l
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    64
        remaining -= l
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    65
    return offset
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    66
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    67
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    68
def load(fp, mutable=True, value_encoding=None, value_errors=None):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    69
    """Deserialize a BSER-encoded blob.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    70
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    71
    @param fp: The file-object to deserialize.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    72
    @type file:
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    73
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    74
    @param mutable: Whether to return mutable results.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    75
    @type mutable: bool
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    76
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    77
    @param value_encoding: Optional codec to use to decode values. If
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    78
                           unspecified or None, return values as bytestrings.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    79
    @type value_encoding: str
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    80
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    81
    @param value_errors: Optional error handler for codec. 'strict' by default.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    82
                         The other most common argument is 'surrogateescape' on
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    83
                         Python 3. If value_encoding is None, this is ignored.
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    84
    @type value_errors: str
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    85
    """
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    86
    buf = ctypes.create_string_buffer(8192)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    87
    SNIFF_BUFFER_SIZE = len(EMPTY_HEADER)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    88
    header = (ctypes.c_char * SNIFF_BUFFER_SIZE).from_buffer(buf)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    89
    read_len = _read_bytes(fp, header)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    90
    if read_len < len(header):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    91
        return None
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    92
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    93
    total_len = bser.pdu_len(buf)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    94
    if total_len > len(buf):
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    95
        ctypes.resize(buf, total_len)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    96
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
    97
    body = (ctypes.c_char * (total_len - len(header))).from_buffer(
43385
6469c23a40a2 fsmonitor: refresh pywatchman with upstream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30656
diff changeset
    98
        buf, len(header)
6469c23a40a2 fsmonitor: refresh pywatchman with upstream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30656
diff changeset
    99
    )
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
   100
    read_len = _read_bytes(fp, body)
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
   101
    if read_len < len(body):
43385
6469c23a40a2 fsmonitor: refresh pywatchman with upstream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30656
diff changeset
   102
        raise RuntimeError("bser data ended early")
30656
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
   103
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
   104
    return bser.loads(
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
   105
        (ctypes.c_char * total_len).from_buffer(buf, 0),
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
   106
        mutable,
16f4b341288d fsmonitor: refresh pywatchman to upstream
Zack Hricz <zphricz@fb.com>
parents:
diff changeset
   107
        value_encoding,
43385
6469c23a40a2 fsmonitor: refresh pywatchman with upstream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30656
diff changeset
   108
        value_errors,
6469c23a40a2 fsmonitor: refresh pywatchman with upstream
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30656
diff changeset
   109
    )