int read()

in pedalboard/io/PythonInputStream.h [97:157]


  int read(void *buffer, int bytesToRead) noexcept override {
    // The buffer should never be null, and a negative size is probably a
    // sign that something is broken!
    jassert(buffer != nullptr && bytesToRead >= 0);
    ScopedDowngradeToReadLockWithGIL lock(objectLock);

    py::gil_scoped_acquire acquire;
    if (PythonException::isPending())
      return 0;

    try {
      auto readResult = fileLike.attr("read")(bytesToRead);

      if (!py::isinstance<py::bytes>(readResult)) {
        std::string message =
            "File-like object passed to AudioFile was expected to return "
            "bytes from its read(...) method, but "
            "returned " +
            py::str(readResult.get_type().attr("__name__"))
                .cast<std::string>() +
            ".";

        if (py::hasattr(fileLike, "mode") &&
            py::str(fileLike.attr("mode")).cast<std::string>() == "r") {
          message += " (Try opening the stream in \"rb\" mode instead of "
                     "\"r\" mode if possible.)";
        }

        throw py::type_error(message);
        return 0;
      }

      py::bytes bytesObject = readResult.cast<py::bytes>();
      char *pythonBuffer = nullptr;
      py::ssize_t pythonLength = 0;

      if (PYBIND11_BYTES_AS_STRING_AND_SIZE(bytesObject.ptr(), &pythonBuffer,
                                            &pythonLength)) {
        throw py::buffer_error(
            "Internal error: failed to read bytes from bytes object!");
      }

      if (!buffer && pythonLength > 0) {
        throw py::buffer_error("Internal error: bytes pointer is null, but a "
                               "non-zero number of bytes were returned!");
      }

      if (buffer && pythonLength) {
        std::memcpy(buffer, pythonBuffer, pythonLength);
      }

      lastReadWasSmallerThanExpected = bytesToRead > pythonLength;
      return pythonLength;
    } catch (py::error_already_set e) {
      e.restore();
      return 0;
    } catch (const py::builtin_exception &e) {
      e.set_error();
      return 0;
    }
  }