Skip to content

Commit 32c97d5

Browse files
committed
Add a function strings_to_ctypes_array to convert a sequence of strings into a ctypes array
1 parent 32e3cb3 commit 32c97d5

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

pygmt/clib/conversion.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
Functions to convert data types into ctypes friendly formats.
33
"""
44

5+
import ctypes as ctp
56
import warnings
7+
from collections.abc import Sequence
68

79
import numpy as np
810
from pygmt.exceptions import GMTInvalidInput
@@ -280,6 +282,32 @@ def kwargs_to_ctypes_array(argument, kwargs, dtype):
280282
return None
281283

282284

285+
def strings_to_ctypes_array(strings: Sequence[str]):
286+
"""
287+
Convert a sequence (e.g., a list) of strings into a ctypes array.
288+
289+
Parameters
290+
----------
291+
strings
292+
A sequence of strings.
293+
294+
Returns
295+
-------
296+
ctypes_array
297+
A ctypes array of strings.
298+
299+
Examples
300+
--------
301+
>>> strings = ["first", "second", "third"]
302+
>>> ctypes_array = strings_to_ctypes_array(strings)
303+
>>> type(ctypes_array)
304+
<class 'pygmt.clib.conversion.c_char_p_Array_3'>
305+
>>> [s.decode() for s in ctypes_array]
306+
['first', 'second', 'third']
307+
"""
308+
return (ctp.c_char_p * len(strings))(*[s.encode() for s in strings])
309+
310+
283311
def array_to_datetime(array):
284312
"""
285313
Convert a 1-D datetime array from various types into numpy.datetime64.

pygmt/clib/session.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
as_c_contiguous,
2121
dataarray_to_matrix,
2222
kwargs_to_ctypes_array,
23+
strings_to_ctypes_array,
2324
vectors_to_arrays,
2425
)
2526
from pygmt.clib.loading import load_libgmt
@@ -890,13 +891,9 @@ def put_vector(self, dataset, column, vector):
890891

891892
gmt_type = self._check_dtype_and_dim(vector, ndim=1)
892893
if gmt_type in (self["GMT_TEXT"], self["GMT_DATETIME"]):
893-
vector_pointer = (ctp.c_char_p * len(vector))()
894894
if gmt_type == self["GMT_DATETIME"]:
895-
vector_pointer[:] = np.char.encode(
896-
np.datetime_as_string(array_to_datetime(vector))
897-
)
898-
else:
899-
vector_pointer[:] = np.char.encode(vector)
895+
vector = np.datetime_as_string(array_to_datetime(vector))
896+
vector_pointer = strings_to_ctypes_array(vector)
900897
else:
901898
vector_pointer = vector.ctypes.data_as(ctp.c_void_p)
902899
status = c_put_vector(
@@ -953,13 +950,12 @@ def put_strings(self, dataset, family, strings):
953950
restype=ctp.c_int,
954951
)
955952

956-
strings_pointer = (ctp.c_char_p * len(strings))()
957-
strings_pointer[:] = np.char.encode(strings)
958-
959953
family_int = self._parse_constant(
960954
family, valid=FAMILIES, valid_modifiers=METHODS
961955
)
962956

957+
strings_pointer = strings_to_ctypes_array(strings)
958+
963959
status = c_put_strings(
964960
self.session_pointer, family_int, dataset, strings_pointer
965961
)

0 commit comments

Comments
 (0)