MCPcopy Create free account
hub / github.com/ashvardanian/StringZilla / Str_write_to

Function Str_write_to

python/stringzilla.c:2460–2528  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2458 " None.";
2459
2460static PyObject *Str_write_to(PyObject *self, PyObject *const *args, Py_ssize_t positional_args_count,
2461 PyObject *args_names_tuple) {
2462
2463 int is_member = self != NULL && PyObject_TypeCheck(self, &StrType);
2464 if (positional_args_count != !is_member + 1) {
2465 PyErr_SetString(PyExc_TypeError, "Invalid number of arguments");
2466 return NULL;
2467 }
2468
2469 PyObject *text_obj = is_member ? self : args[0];
2470 PyObject *path_obj = args[!is_member + 0];
2471
2472 // Parse keyword arguments
2473 if (args_names_tuple) {
2474 PyErr_Format(PyExc_TypeError, "Got an unexpected keyword argument");
2475 return NULL;
2476 }
2477
2478 sz_string_view_t text;
2479 sz_string_view_t path;
2480
2481 // Validate and convert `text` and `path`
2482 if (!sz_py_export_string_like(text_obj, &text.start, &text.length) ||
2483 !sz_py_export_string_like(path_obj, &path.start, &path.length)) {
2484 wrap_current_exception("Text and path must be string-like");
2485 return NULL;
2486 }
2487
2488 // There is a chance, the path isn't NULL-terminated, so copy it to a new buffer.
2489 // Many OSes have fairly low limit for the maximum path length.
2490 // On Windows its 260, but up to __around__ 32,767 characters are supported in extended API.
2491 // But it's better to be safe than sorry and use malloc :)
2492 //
2493 // https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry
2494 // https://doc.owncloud.com/server/next/admin_manual/troubleshooting/path_filename_length.html
2495 sz_ptr_t path_buffer = (sz_ptr_t)malloc(path.length + 1);
2496 if (path_buffer == NULL) {
2497 PyErr_SetString(PyExc_MemoryError, "Unable to allocate memory for the path");
2498 return NULL;
2499 }
2500 sz_copy(path_buffer, path.start, path.length);
2501 path_buffer[path.length] = '\0';
2502
2503 // Unlock the Global Interpreter Lock (GIL) to allow other threads to run
2504 // while the current thread is waiting for the file to be written.
2505 PyThreadState *gil_state = PyEval_SaveThread();
2506 FILE *file_pointer = fopen(path_buffer, "wb");
2507 if (file_pointer == NULL) {
2508 PyEval_RestoreThread(gil_state);
2509 PyErr_SetFromErrnoWithFilename(PyExc_OSError, path_buffer);
2510 free(path_buffer);
2511 PyEval_RestoreThread(gil_state);
2512 return NULL;
2513 }
2514
2515 setbuf(file_pointer, NULL); // Set the stream to unbuffered
2516 int status = fwrite(text.start, 1, text.length, file_pointer);
2517 PyEval_RestoreThread(gil_state);

Callers

nothing calls this directly

Calls 3

sz_py_export_string_likeFunction · 0.85
wrap_current_exceptionFunction · 0.85
sz_copyFunction · 0.50

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…