excelreader-native 7.0.0__py3-none-macosx_12_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,44 @@
1
+ """Python bindings for ExcelReader."""
2
+
3
+ from excelreader.reader import Sheet, Sheets, Workbook, open_workbook
4
+ from excelreader.sources import Source
5
+ from excelreader.types import (
6
+ Cell,
7
+ CellType,
8
+ ColumnSpec,
9
+ ColumnType,
10
+ ExcelReaderError,
11
+ OpenOptions,
12
+ PasswordIncorrectError,
13
+ PasswordRequiredError,
14
+ SheetVisibility,
15
+ StringColumn,
16
+ TypedTable,
17
+ WriteOptions,
18
+ )
19
+ from excelreader.writer import encrypt_package, write_workbook
20
+ from excelreader.writer_handle import SheetWriter, open_writer
21
+
22
+ __all__ = [
23
+ "Cell",
24
+ "CellType",
25
+ "ColumnSpec",
26
+ "ColumnType",
27
+ "ExcelReaderError",
28
+ "OpenOptions",
29
+ "PasswordIncorrectError",
30
+ "PasswordRequiredError",
31
+ "Sheet",
32
+ "SheetVisibility",
33
+ "SheetWriter",
34
+ "Sheets",
35
+ "Source",
36
+ "StringColumn",
37
+ "TypedTable",
38
+ "Workbook",
39
+ "WriteOptions",
40
+ "encrypt_package",
41
+ "open_workbook",
42
+ "open_writer",
43
+ "write_workbook",
44
+ ]
File without changes
excelreader/_native.py ADDED
@@ -0,0 +1,581 @@
1
+ """ctypes binding to the ExcelReader NativeAOT shared library.
2
+
3
+ Everything here mirrors src/ExcelReader.Native/include/excelreader.h. If you change one, change both.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import ctypes
9
+ import os
10
+ import platform
11
+ import threading
12
+ from collections.abc import Sequence
13
+ from functools import lru_cache
14
+ from pathlib import Path
15
+ from typing import TYPE_CHECKING
16
+
17
+ if TYPE_CHECKING:
18
+ from excelreader.types import OpenOptions, WriteOptions
19
+
20
+ XL_OK = 0
21
+ XL_EOF = -1
22
+ XL_BUFFER_TOO_SMALL = -2
23
+ XL_INVALID_HANDLE = -3
24
+ XL_INVALID_ARGUMENT = -4
25
+ XL_ERROR = -5
26
+ XL_STATUS_PASSWORD_REQUIRED = -6
27
+ XL_STATUS_PASSWORD_INCORRECT = -7
28
+
29
+ XL_ABI_VERSION = 6
30
+
31
+ XL_SHEET_VISIBLE = 0
32
+ XL_SHEET_HIDDEN = 1
33
+ XL_SHEET_VERY_HIDDEN = 2
34
+
35
+ XL_FORMAT_AUTO = 0
36
+ XL_FORMAT_XLS = 1
37
+ XL_FORMAT_XLSX = 2
38
+ XL_FORMAT_XLSB = 3
39
+ XL_FORMAT_CSV = 4
40
+ XL_INFER_PARSE_TEXT = 1
41
+ FORMATS = {
42
+ "auto": XL_FORMAT_AUTO,
43
+ "xls": XL_FORMAT_XLS,
44
+ "xlsx": XL_FORMAT_XLSX,
45
+ "xlsb": XL_FORMAT_XLSB,
46
+ "csv": XL_FORMAT_CSV,
47
+ }
48
+ WRITE_FORMATS = {name: value for name, value in FORMATS.items() if name != "auto"}
49
+
50
+ XL_OPT_DEFAULT = 0
51
+ XL_OPT_FALSE = 1
52
+ XL_OPT_TRUE = 2
53
+
54
+ XL_T_STRING = 0
55
+ XL_T_I64 = 1
56
+ XL_T_F64 = 2
57
+ XL_T_BOOL = 3
58
+ XL_T_DATE = 4
59
+ XL_T_TIME = 5
60
+ XL_T_TIMESTAMP = 6
61
+
62
+
63
+ class NativeColumnSpec(ctypes.Structure):
64
+ """Mirrors xl_column_spec. `names`/`name_lens`/`name_count` may be left NULL/NULL/0 to resolve by
65
+ `index` instead. Build one with `column_spec_by_name`/`column_spec_by_names`, never directly —
66
+ the `names`/`name_lens` pointers must stay alive as long as the struct is in use, and those
67
+ helpers keep the backing buffers alive via ctypes' `_objects` mechanism."""
68
+
69
+ _fields_ = [
70
+ ("names", ctypes.POINTER(ctypes.POINTER(ctypes.c_uint8))),
71
+ ("name_lens", ctypes.POINTER(ctypes.c_int32)),
72
+ ("name_count", ctypes.c_int32),
73
+ ("index", ctypes.c_int32),
74
+ ("type", ctypes.c_int32),
75
+ ("nullable", ctypes.c_int32),
76
+ ]
77
+
78
+
79
+ def column_spec_by_names(names: Sequence[str], type_: int, *, nullable: bool = False) -> NativeColumnSpec:
80
+ encoded = [name.encode("utf-8") for name in names]
81
+ buffers = [ctypes.create_string_buffer(e, len(e)) for e in encoded]
82
+ name_ptrs = (ctypes.POINTER(ctypes.c_uint8) * len(buffers))(
83
+ *(ctypes.cast(b, ctypes.POINTER(ctypes.c_uint8)) for b in buffers)
84
+ )
85
+ name_lens = (ctypes.c_int32 * len(encoded))(*(len(e) for e in encoded))
86
+ spec = NativeColumnSpec(
87
+ names=ctypes.cast(name_ptrs, ctypes.POINTER(ctypes.POINTER(ctypes.c_uint8))),
88
+ name_lens=name_lens,
89
+ name_count=len(encoded),
90
+ index=0,
91
+ type=type_,
92
+ nullable=int(nullable),
93
+ )
94
+ spec._name_storage = (buffers, name_ptrs, name_lens) # type: ignore[attr-defined]
95
+ return spec
96
+
97
+
98
+ def column_spec_by_name(name: str, type_: int, *, nullable: bool = False) -> NativeColumnSpec:
99
+ return column_spec_by_names([name], type_, nullable=nullable)
100
+
101
+
102
+ def column_spec_by_index(index: int, type_: int, *, nullable: bool = False) -> NativeColumnSpec:
103
+ return NativeColumnSpec(
104
+ names=None, name_lens=None, name_count=0, index=index, type=type_, nullable=int(nullable)
105
+ )
106
+
107
+
108
+ class NativeInferredColumnSpec(NativeColumnSpec):
109
+ """The OUTPUT direction of the same xl_column_spec (xl_infer_schema fills these in).
110
+
111
+ Layout is inherited, not restated: it is literally the same C struct, and a second copy of the
112
+ field list is a second place for it to drift from the header. Only the ownership rules differ,
113
+ which is why this carries its own name.
114
+
115
+ Always carries `name_count` 0 or 1 — inference never guesses more than one candidate name per
116
+ column. Unlike `column_spec_by_name`'s buffers, `names[0]` here is a raw pointer with no
117
+ guaranteed NUL terminator, so decode it with `ctypes.string_at(names[0], name_lens[0])`.
118
+ """
119
+
120
+
121
+ class NativeInferredSchema(ctypes.Structure):
122
+ """Mirrors xl_inferred_schema. `columns` is a native-owned array of `column_count` values, freed
123
+ (along with each column's own `name`) by `xl_free_schema`."""
124
+
125
+ _fields_ = [
126
+ ("columns", ctypes.POINTER(NativeInferredColumnSpec)),
127
+ ("column_count", ctypes.c_int32),
128
+ ]
129
+
130
+
131
+ class NativeColumn(ctypes.Structure):
132
+ """Mirrors xl_column. `data`/`data_len` are only meaningful for XL_T_STRING columns; `values` is
133
+ always the ONE allocation this column owns directly (see xl_column's doc comment in the header —
134
+ `data` is an interior pointer into `values` for strings, never a separate allocation)."""
135
+
136
+ _fields_ = [
137
+ ("type", ctypes.c_int32),
138
+ ("length", ctypes.c_int64),
139
+ ("values", ctypes.c_void_p),
140
+ ("validity", ctypes.POINTER(ctypes.c_uint8)),
141
+ ("data", ctypes.POINTER(ctypes.c_uint8)),
142
+ ("data_len", ctypes.c_int64),
143
+ ]
144
+
145
+
146
+ class NativeTable(ctypes.Structure):
147
+ _fields_ = [
148
+ ("column_count", ctypes.c_int32),
149
+ ("row_count", ctypes.c_int64),
150
+ ("columns", ctypes.POINTER(NativeColumn)),
151
+ ]
152
+
153
+
154
+ class ArrowSchema(ctypes.Structure):
155
+ pass
156
+
157
+
158
+ class ArrowArray(ctypes.Structure):
159
+ pass
160
+
161
+
162
+ ArrowSchema._fields_ = [
163
+ ("format", ctypes.c_char_p),
164
+ ("name", ctypes.c_char_p),
165
+ ("metadata", ctypes.c_char_p),
166
+ ("flags", ctypes.c_int64),
167
+ ("n_children", ctypes.c_int64),
168
+ ("children", ctypes.POINTER(ctypes.POINTER(ArrowSchema))),
169
+ ("dictionary", ctypes.POINTER(ArrowSchema)),
170
+ ("release", ctypes.c_void_p),
171
+ ("private_data", ctypes.c_void_p),
172
+ ]
173
+
174
+ ArrowArray._fields_ = [
175
+ ("length", ctypes.c_int64),
176
+ ("null_count", ctypes.c_int64),
177
+ ("offset", ctypes.c_int64),
178
+ ("n_buffers", ctypes.c_int64),
179
+ ("n_children", ctypes.c_int64),
180
+ ("buffers", ctypes.POINTER(ctypes.c_void_p)),
181
+ ("children", ctypes.POINTER(ctypes.POINTER(ArrowArray))),
182
+ ("dictionary", ctypes.POINTER(ArrowArray)),
183
+ ("release", ctypes.c_void_p),
184
+ ("private_data", ctypes.c_void_p),
185
+ ]
186
+
187
+ ARROW_FLAG_NULLABLE = 2
188
+
189
+
190
+ class ArrowArrayStream(ctypes.Structure):
191
+ pass
192
+
193
+
194
+ _ArrowStreamGetSchema = ctypes.CFUNCTYPE(
195
+ ctypes.c_int, ctypes.POINTER(ArrowArrayStream), ctypes.POINTER(ArrowSchema)
196
+ )
197
+ _ArrowStreamGetNext = ctypes.CFUNCTYPE(
198
+ ctypes.c_int, ctypes.POINTER(ArrowArrayStream), ctypes.POINTER(ArrowArray)
199
+ )
200
+ _ArrowStreamGetLastError = ctypes.CFUNCTYPE(ctypes.c_char_p, ctypes.POINTER(ArrowArrayStream))
201
+ _ArrowStreamRelease = ctypes.CFUNCTYPE(None, ctypes.POINTER(ArrowArrayStream))
202
+
203
+ ArrowArrayStream._fields_ = [
204
+ ("get_schema", _ArrowStreamGetSchema),
205
+ ("get_next", _ArrowStreamGetNext),
206
+ ("get_last_error", _ArrowStreamGetLastError),
207
+ ("release", _ArrowStreamRelease),
208
+ ("private_data", ctypes.c_void_p),
209
+ ]
210
+
211
+
212
+ class NativeBuffer(ctypes.Structure):
213
+ """Mirrors xl_buffer."""
214
+
215
+ _fields_ = [
216
+ ("data", ctypes.POINTER(ctypes.c_uint8)),
217
+ ("len", ctypes.c_int64),
218
+ ]
219
+
220
+
221
+ class NativeOpenOptions(ctypes.Structure):
222
+ """Mirrors xl_open_options. `struct_size` is set for you by `default_open_options()`; every other
223
+ numeric field is 0 (use the library default), and every XL_OPT_* field starts at XL_OPT_DEFAULT."""
224
+
225
+ _fields_ = [
226
+ ("struct_size", ctypes.c_int32),
227
+ ("csv_sniff_dialect", ctypes.c_int32),
228
+ ("csv_delimiter", ctypes.c_int32),
229
+ ("csv_quote", ctypes.c_int32),
230
+ ("csv_detect_bom", ctypes.c_int32),
231
+ ("csv_max_cell_bytes", ctypes.c_int32),
232
+ ("csv_intern_strings", ctypes.c_int32),
233
+ ("max_total_decompressed_bytes", ctypes.c_int64),
234
+ ("max_cell_bytes", ctypes.c_int32),
235
+ ("max_shared_string_bytes", ctypes.c_int64),
236
+ ("max_zip_entries", ctypes.c_int32),
237
+ ("prefetch_decompression", ctypes.c_int32),
238
+ ("intern_strings", ctypes.c_int32),
239
+ ("password", ctypes.POINTER(ctypes.c_uint8)),
240
+ ("password_len", ctypes.c_int32),
241
+ ("source_cache_bytes", ctypes.c_int64),
242
+ ("max_buffered_bytes", ctypes.c_int64),
243
+ ("source_block_size", ctypes.c_int32),
244
+ ("verify_zip_checksums", ctypes.c_int32),
245
+ ]
246
+
247
+
248
+ SourceReadAt = ctypes.CFUNCTYPE(ctypes.c_int64, ctypes.c_void_p, ctypes.c_int64, ctypes.c_void_p, ctypes.c_int64)
249
+ StreamRead = ctypes.CFUNCTYPE(ctypes.c_int64, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int64)
250
+ SourceRelease = ctypes.CFUNCTYPE(None, ctypes.c_void_p)
251
+
252
+
253
+ class NativeSource(ctypes.Structure):
254
+ """Mirrors xl_source."""
255
+
256
+ _fields_ = [
257
+ ("struct_size", ctypes.c_int32),
258
+ ("user_data", ctypes.c_void_p),
259
+ ("length", ctypes.c_int64),
260
+ ("read_at", SourceReadAt),
261
+ ("release", SourceRelease),
262
+ ]
263
+
264
+
265
+ class NativeStream(ctypes.Structure):
266
+ """Mirrors xl_stream."""
267
+
268
+ _fields_ = [
269
+ ("struct_size", ctypes.c_int32),
270
+ ("user_data", ctypes.c_void_p),
271
+ ("read", StreamRead),
272
+ ("release", SourceRelease),
273
+ ]
274
+
275
+
276
+ def default_open_options() -> NativeOpenOptions:
277
+ """A NativeOpenOptions with every field at its "use the library default" value and struct_size
278
+ filled in — start from this rather than constructing NativeOpenOptions() directly, since the raw
279
+ zero-value for struct_size is never valid."""
280
+ options = NativeOpenOptions()
281
+ options.struct_size = ctypes.sizeof(NativeOpenOptions)
282
+ return options
283
+
284
+
285
+ def _opt_state(value: bool | None) -> int:
286
+ if value is None:
287
+ return XL_OPT_DEFAULT
288
+ return XL_OPT_TRUE if value else XL_OPT_FALSE
289
+
290
+
291
+ def _opt_number(value: int | None) -> int:
292
+ return 0 if value is None else value
293
+
294
+
295
+ def to_native_open_options(options: OpenOptions) -> NativeOpenOptions:
296
+ """Converts a public `OpenOptions` into the raw ABI struct.
297
+
298
+ This is where the public API's single "None means default" convention splits back into the two
299
+ the ABI uses: 0 for an unset number, XL_OPT_DEFAULT for an unset boolean. Note the numeric
300
+ fields cannot express a deliberate 0 — the ABI spends that value on "default" — but no field
301
+ here has a meaningful 0 (a zero delimiter, or a zero-byte cell limit, is not a setting).
302
+
303
+ Values are passed through unvalidated on purpose: the native side owns the real bounds and
304
+ reports a rejection through xl_last_error, so checking them here too would give those bounds a
305
+ second place to drift from.
306
+ """
307
+ raw = default_open_options()
308
+ raw.csv_sniff_dialect = _opt_state(options.csv_sniff_dialect)
309
+ raw.csv_detect_bom = _opt_state(options.csv_detect_bom)
310
+ raw.prefetch_decompression = _opt_state(options.prefetch_decompression)
311
+ raw.intern_strings = _opt_state(options.intern_strings)
312
+ raw.verify_zip_checksums = _opt_state(options.verify_zip_checksums)
313
+ raw.csv_delimiter = _opt_number(options.csv_delimiter)
314
+ raw.csv_quote = _opt_number(options.csv_quote)
315
+ # The ABI's csv_* copies win over these for a CSV even when unset, so send the same value to both.
316
+ raw.csv_max_cell_bytes = _opt_number(options.max_cell_bytes)
317
+ raw.csv_intern_strings = raw.intern_strings
318
+ raw.max_total_decompressed_bytes = _opt_number(options.max_total_decompressed_bytes)
319
+ raw.max_cell_bytes = _opt_number(options.max_cell_bytes)
320
+ raw.max_shared_string_bytes = _opt_number(options.max_shared_string_bytes)
321
+ raw.max_zip_entries = _opt_number(options.max_zip_entries)
322
+ raw.source_cache_bytes = _opt_number(options.source_cache_bytes)
323
+ raw.max_buffered_bytes = _opt_number(options.max_buffered_bytes)
324
+ raw.source_block_size = _opt_number(options.source_block_size)
325
+ return raw
326
+
327
+
328
+ class NativeWriteOptions(ctypes.Structure):
329
+ """Mirrors xl_write_options. `struct_size` is set for you by `default_write_options()`; every other
330
+ numeric field is 0 (use the library default), and every XL_OPT_* field starts at XL_OPT_DEFAULT."""
331
+
332
+ _fields_ = [
333
+ ("struct_size", ctypes.c_int32),
334
+ ("sheet_name_len", ctypes.c_int32),
335
+ ("sheet_name", ctypes.c_char_p),
336
+ ("csv_delimiter", ctypes.c_int32),
337
+ ("csv_quote", ctypes.c_int32),
338
+ ("date1904", ctypes.c_int32),
339
+ ("use_shared_strings", ctypes.c_int32),
340
+ ]
341
+
342
+
343
+ def default_write_options() -> NativeWriteOptions:
344
+ """A NativeWriteOptions with every field at its "use the library default" value and struct_size
345
+ filled in — start from this rather than constructing NativeWriteOptions() directly, since the raw
346
+ zero-value for struct_size is never valid."""
347
+ options = NativeWriteOptions()
348
+ options.struct_size = ctypes.sizeof(NativeWriteOptions)
349
+ return options
350
+
351
+
352
+ def to_native_write_options(options: WriteOptions) -> NativeWriteOptions:
353
+ """Converts a public `WriteOptions` into the raw ABI struct.
354
+
355
+ Same split as `to_native_open_options()`: the public API's single "None means default" convention
356
+ becomes 0 for an unset number and XL_OPT_DEFAULT for an unset boolean. Values are passed through
357
+ unvalidated on purpose — the native side owns the real bounds and reports a rejection through
358
+ xl_last_error, so checking them here too would give those bounds a second place to drift from.
359
+ """
360
+ raw = default_write_options()
361
+ if options.sheet_name is not None:
362
+ encoded = options.sheet_name.encode("utf-8")
363
+ raw.sheet_name = encoded
364
+ raw.sheet_name_len = len(encoded)
365
+ raw.csv_delimiter = _opt_number(options.csv_delimiter)
366
+ raw.csv_quote = _opt_number(options.csv_quote)
367
+ raw.date1904 = _opt_state(options.date1904)
368
+ raw.use_shared_strings = _opt_state(options.use_shared_strings)
369
+ return raw
370
+
371
+
372
+ _LIB_NAMES = {
373
+ "Windows": "ExcelReader.Native.dll",
374
+ "Linux": "ExcelReader.Native.so",
375
+ "Darwin": "ExcelReader.Native.dylib",
376
+ }
377
+
378
+ def library_filename() -> str:
379
+ try:
380
+ return _LIB_NAMES[platform.system()]
381
+ except KeyError:
382
+ raise RuntimeError(f"unsupported platform: {platform.system()}") from None
383
+
384
+
385
+ def _candidate_paths() -> list[Path]:
386
+ override = os.environ.get("EXCELREADER_NATIVE_LIB")
387
+ if override:
388
+ return [Path(override)]
389
+ return [Path(__file__).resolve().parent / "_lib" / library_filename()]
390
+
391
+
392
+ _load_lock = threading.Lock()
393
+
394
+
395
+ @lru_cache(maxsize=1)
396
+ def load_library() -> ctypes.CDLL:
397
+ with _load_lock:
398
+ for path in _candidate_paths():
399
+ if not path.exists():
400
+ continue
401
+ lib = _bind(ctypes.CDLL(str(path)))
402
+ version = lib.xl_abi_version()
403
+ if version != XL_ABI_VERSION:
404
+ raise RuntimeError(
405
+ f"{path} is ABI version {version}, but this package expects {XL_ABI_VERSION}. "
406
+ f"Rebuild the native library with python python/scripts/build_native.py."
407
+ )
408
+ _warm_up(lib)
409
+ return lib
410
+ raise RuntimeError(
411
+ f"{library_filename()} not found. Build it with:\n"
412
+ f" python python/scripts/build_native.py\n"
413
+ f"or point EXCELREADER_NATIVE_LIB at an existing binary."
414
+ )
415
+
416
+
417
+ def _warm_up(lib: ctypes.CDLL) -> None:
418
+ data = b"a,b\n1,2\n3,4\n"
419
+ workbook = ctypes.c_void_p()
420
+ if lib.xl_open_memory(data, len(data), XL_FORMAT_CSV, None, ctypes.byref(workbook)) != XL_OK:
421
+ return
422
+ try:
423
+ cursor = ctypes.c_void_p()
424
+ if lib.xl_rows_open(workbook, 0, ctypes.byref(cursor)) != XL_OK:
425
+ return
426
+ try:
427
+ written = ctypes.c_int32()
428
+ capacity = 16
429
+ buffer = ctypes.create_string_buffer(capacity)
430
+ while True:
431
+ status = lib.xl_rows_next(cursor, buffer, capacity, ctypes.byref(written))
432
+ if status == XL_BUFFER_TOO_SMALL:
433
+ capacity = written.value
434
+ buffer = ctypes.create_string_buffer(capacity)
435
+ elif status != XL_OK:
436
+ return
437
+ finally:
438
+ lib.xl_rows_close(cursor)
439
+ finally:
440
+ lib.xl_close(workbook)
441
+
442
+
443
+ def _bind(lib: ctypes.CDLL) -> ctypes.CDLL:
444
+ c_int = ctypes.c_int32
445
+ p_int = ctypes.POINTER(ctypes.c_int32)
446
+ p_void = ctypes.c_void_p
447
+ pp_void = ctypes.POINTER(ctypes.c_void_p)
448
+ p_bytes = ctypes.c_char_p
449
+
450
+ p_open_options = ctypes.POINTER(NativeOpenOptions)
451
+
452
+ p_specs = ctypes.POINTER(NativeColumnSpec)
453
+
454
+ lib.xl_open_file.argtypes = [p_bytes, c_int, c_int, p_open_options, pp_void]
455
+ lib.xl_open_file.restype = c_int
456
+ lib.xl_open_memory.argtypes = [p_bytes, c_int, c_int, p_open_options, pp_void]
457
+ lib.xl_open_memory.restype = c_int
458
+ lib.xl_open_source.argtypes = [ctypes.POINTER(NativeSource), c_int, p_open_options, pp_void]
459
+ lib.xl_open_source.restype = c_int
460
+ lib.xl_open_stream.argtypes = [ctypes.POINTER(NativeStream), c_int, p_open_options, pp_void]
461
+ lib.xl_open_stream.restype = c_int
462
+ lib.xl_set_source_error.argtypes = [p_bytes, c_int]
463
+ lib.xl_set_source_error.restype = None
464
+ lib.xl_sheet_visibility_at.argtypes = [p_void, c_int, p_int]
465
+ lib.xl_sheet_visibility_at.restype = c_int
466
+ lib.xl_sheet_index.argtypes = [p_void, p_bytes, c_int, p_int]
467
+ lib.xl_sheet_index.restype = c_int
468
+ lib.xl_rows_open.argtypes = [p_void, c_int, pp_void]
469
+ lib.xl_rows_open.restype = c_int
470
+ lib.xl_rows_close.argtypes = [p_void]
471
+ lib.xl_rows_close.restype = c_int
472
+ lib.xl_rows_next.argtypes = [p_void, p_bytes, c_int, p_int]
473
+ lib.xl_rows_next.restype = c_int
474
+ lib.xl_parse_typed.argtypes = [p_void, c_int, p_specs, c_int, c_int, c_int, ctypes.POINTER(NativeTable)]
475
+ lib.xl_parse_typed.restype = c_int
476
+ lib.xl_typed_reader_open.argtypes = [p_void, c_int, p_specs, c_int, c_int, ctypes.c_int64, pp_void]
477
+ lib.xl_typed_reader_open.restype = c_int
478
+ lib.xl_parse_arrow.argtypes = [
479
+ p_void, c_int, p_specs, c_int, c_int, c_int, ctypes.POINTER(ArrowArray), ctypes.POINTER(ArrowSchema),
480
+ ]
481
+ lib.xl_parse_arrow.restype = c_int
482
+ lib.xl_parse_arrow_stream.argtypes = [
483
+ p_void, c_int, p_specs, c_int, c_int, ctypes.c_int64, ctypes.POINTER(ArrowArrayStream),
484
+ ]
485
+ lib.xl_parse_arrow_stream.restype = c_int
486
+ lib.xl_infer_schema.argtypes = [p_void, c_int, c_int, c_int, c_int, ctypes.POINTER(NativeInferredSchema)]
487
+ lib.xl_infer_schema.restype = c_int
488
+ lib.xl_close.argtypes = [p_void]
489
+ lib.xl_close.restype = c_int
490
+ lib.xl_sheet_count.argtypes = [p_void, p_int]
491
+ lib.xl_sheet_count.restype = c_int
492
+ lib.xl_sheet_name_at.argtypes = [p_void, c_int, p_bytes, c_int, p_int]
493
+ lib.xl_sheet_name_at.restype = c_int
494
+ lib.xl_is_date1904.argtypes = [p_void, p_int]
495
+ lib.xl_is_date1904.restype = c_int
496
+ lib.xl_last_error.argtypes = [p_bytes, c_int, p_int]
497
+ lib.xl_last_error.restype = c_int
498
+ lib.xl_last_error_ptr.argtypes = [p_int]
499
+ lib.xl_last_error_ptr.restype = ctypes.POINTER(ctypes.c_uint8)
500
+ lib.xl_free_table.argtypes = [ctypes.POINTER(NativeTable)]
501
+ lib.xl_free_table.restype = None
502
+ lib.xl_free_schema.argtypes = [ctypes.POINTER(NativeInferredSchema)]
503
+ lib.xl_free_schema.restype = None
504
+ lib.xl_typed_reader_next.argtypes = [p_void, ctypes.POINTER(NativeTable)]
505
+ lib.xl_typed_reader_next.restype = c_int
506
+ lib.xl_typed_reader_close.argtypes = [p_void]
507
+ lib.xl_typed_reader_close.restype = None
508
+ lib.xl_write_typed.argtypes = [
509
+ p_bytes, c_int, c_int,
510
+ ctypes.POINTER(NativeColumnSpec), ctypes.POINTER(NativeTable), ctypes.POINTER(NativeWriteOptions),
511
+ ]
512
+ lib.xl_write_typed.restype = c_int
513
+ lib.xl_write_typed_to_memory.argtypes = [
514
+ ctypes.c_int32, ctypes.POINTER(NativeColumnSpec), ctypes.POINTER(NativeTable),
515
+ ctypes.POINTER(NativeWriteOptions), ctypes.POINTER(NativeBuffer),
516
+ ]
517
+ lib.xl_write_typed_to_memory.restype = ctypes.c_int32
518
+ lib.xl_encrypt_package.argtypes = [p_bytes, c_int, p_bytes, c_int, p_bytes, c_int]
519
+ lib.xl_encrypt_package.restype = c_int
520
+ lib.xl_encrypt_package_to_memory.argtypes = [p_bytes, c_int, p_bytes, c_int, ctypes.POINTER(NativeBuffer)]
521
+ lib.xl_encrypt_package_to_memory.restype = c_int
522
+ lib.xl_abi_version.argtypes = []
523
+ lib.xl_abi_version.restype = c_int
524
+
525
+ lib.xl_open_write_handle.argtypes = [
526
+ ctypes.POINTER(ctypes.c_uint8), ctypes.c_int32, ctypes.c_int32,
527
+ ctypes.POINTER(NativeWriteOptions), ctypes.POINTER(ctypes.c_void_p),
528
+ ]
529
+ lib.xl_open_write_handle.restype = ctypes.c_int32
530
+
531
+ lib.xl_open_write_handle_to_memory.argtypes = [
532
+ ctypes.c_int32, ctypes.POINTER(NativeWriteOptions), ctypes.POINTER(ctypes.c_void_p),
533
+ ]
534
+ lib.xl_open_write_handle_to_memory.restype = ctypes.c_int32
535
+
536
+ lib.xl_start_sheet.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_uint8), ctypes.c_int32]
537
+ lib.xl_start_sheet.restype = ctypes.c_int32
538
+
539
+ lib.xl_start_row.argtypes = [ctypes.c_void_p]
540
+ lib.xl_start_row.restype = ctypes.c_int32
541
+
542
+ lib.xl_write_string.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_uint8), ctypes.c_int32]
543
+ lib.xl_write_string.restype = ctypes.c_int32
544
+
545
+ lib.xl_write_int64.argtypes = [ctypes.c_void_p, ctypes.c_int64]
546
+ lib.xl_write_int64.restype = ctypes.c_int32
547
+
548
+ lib.xl_write_float64.argtypes = [ctypes.c_void_p, ctypes.c_double]
549
+ lib.xl_write_float64.restype = ctypes.c_int32
550
+
551
+ lib.xl_write_bool.argtypes = [ctypes.c_void_p, ctypes.c_int32]
552
+ lib.xl_write_bool.restype = ctypes.c_int32
553
+
554
+ lib.xl_write_date.argtypes = [ctypes.c_void_p, ctypes.c_int32]
555
+ lib.xl_write_date.restype = ctypes.c_int32
556
+
557
+ lib.xl_write_time.argtypes = [ctypes.c_void_p, ctypes.c_int64]
558
+ lib.xl_write_time.restype = ctypes.c_int32
559
+
560
+ lib.xl_write_timestamp.argtypes = [ctypes.c_void_p, ctypes.c_int64]
561
+ lib.xl_write_timestamp.restype = ctypes.c_int32
562
+
563
+ lib.xl_write_null.argtypes = [ctypes.c_void_p, ctypes.c_int32]
564
+ lib.xl_write_null.restype = ctypes.c_int32
565
+
566
+ lib.xl_end_row.argtypes = [ctypes.c_void_p]
567
+ lib.xl_end_row.restype = ctypes.c_int32
568
+
569
+ lib.xl_end_sheet.argtypes = [ctypes.c_void_p]
570
+ lib.xl_end_sheet.restype = ctypes.c_int32
571
+
572
+ lib.xl_close_write_handle.argtypes = [ctypes.c_void_p]
573
+ lib.xl_close_write_handle.restype = ctypes.c_int32
574
+
575
+ lib.xl_write_handle_bytes.argtypes = [ctypes.c_void_p, ctypes.POINTER(NativeBuffer)]
576
+ lib.xl_write_handle_bytes.restype = ctypes.c_int32
577
+
578
+ lib.xl_free_buffer.argtypes = [ctypes.POINTER(NativeBuffer)]
579
+ lib.xl_free_buffer.restype = None
580
+
581
+ return lib