|
4 | 4 |
|
5 | 5 | #![allow(clippy::missing_safety_doc)] // C header file does not need `Safety` section |
6 | 6 |
|
7 | | -pub(crate) mod cstr; |
| 7 | +pub(crate) mod c_mem; |
8 | 8 | mod spring_config; |
9 | 9 | pub mod spring_errno; |
10 | 10 | pub mod spring_last_err; |
11 | 11 | mod spring_pipeline; |
12 | 12 | mod spring_row; |
13 | 13 |
|
14 | 14 | use std::{ |
15 | | - ffi::CStr, |
16 | | - os::raw::{c_char, c_float, c_int, c_long, c_short}, |
| 15 | + ffi::{c_void, CStr}, |
| 16 | + os::raw::{c_char, c_float, c_int, c_long, c_short, c_uint}, |
17 | 17 | panic::{catch_unwind, UnwindSafe}, |
18 | 18 | ptr, |
19 | 19 | }; |
20 | 20 |
|
21 | 21 | use crate::{ |
22 | | - cstr::strcpy, |
| 22 | + c_mem::{memcpy, strcpy}, |
23 | 23 | spring_config::SpringConfig, |
24 | 24 | spring_errno::SpringErrno, |
25 | 25 | spring_last_err::{update_last_error, LastError}, |
@@ -327,6 +327,39 @@ pub unsafe extern "C" fn spring_column_long( |
327 | 327 | } |
328 | 328 | } |
329 | 329 |
|
| 330 | +/// Get a 4-byte unsigned integer column. |
| 331 | +/// |
| 332 | +/// # Parameters |
| 333 | +/// |
| 334 | +/// - `row`: A `SpringRow` pointer to get a column value from. |
| 335 | +/// - `i_col`: The column index to get a value from. |
| 336 | +/// - `out`: A pointer to a buffer to store the column value. |
| 337 | +/// |
| 338 | +/// # Returns |
| 339 | +/// |
| 340 | +/// - `Ok`: On success. |
| 341 | +/// - `Unavailable`: |
| 342 | +/// - Column pointed by `i_col` is already fetched. |
| 343 | +/// - `i_col` is out of range. |
| 344 | +/// - `CNull`: Column value is NULL. |
| 345 | +#[no_mangle] |
| 346 | +pub unsafe extern "C" fn spring_column_unsigned_int( |
| 347 | + row: *const SpringRow, |
| 348 | + i_col: u16, |
| 349 | + out: *mut c_uint, |
| 350 | +) -> SpringErrno { |
| 351 | + let row = (*row).as_row(); |
| 352 | + let i_col = i_col as usize; |
| 353 | + let result = with_catch(|| row.get_not_null_by_index(i_col as usize)); |
| 354 | + match result { |
| 355 | + Ok(v) => { |
| 356 | + *out = v; |
| 357 | + SpringErrno::Ok |
| 358 | + } |
| 359 | + Err(e) => e, |
| 360 | + } |
| 361 | +} |
| 362 | + |
330 | 363 | /// Get a text column. |
331 | 364 | /// |
332 | 365 | /// # Parameters |
@@ -363,6 +396,42 @@ pub unsafe extern "C" fn spring_column_text( |
363 | 396 | } |
364 | 397 | } |
365 | 398 |
|
| 399 | +/// Get a BLOB column. |
| 400 | +/// |
| 401 | +/// # Parameters |
| 402 | +/// |
| 403 | +/// - `row`: A `SpringRow` pointer to get a column value from. |
| 404 | +/// - `i_col`: The column index to get a value from. |
| 405 | +/// - `out`: A pointer to a buffer to store the column value. |
| 406 | +/// - `out_len`: The length of the buffer pointed by `out`. |
| 407 | +/// |
| 408 | +/// # Returns |
| 409 | +/// |
| 410 | +/// - `> 0`: Length of the text. |
| 411 | +/// - `Unavailable`: |
| 412 | +/// - Column pointed by `i_col` is already fetched. |
| 413 | +/// - `i_col` is out of range. |
| 414 | +/// - `CNull`: Column value is NULL. |
| 415 | +#[no_mangle] |
| 416 | +pub unsafe extern "C" fn spring_column_blob( |
| 417 | + row: *const SpringRow, |
| 418 | + i_col: u16, |
| 419 | + out: *mut c_void, |
| 420 | + out_len: c_int, |
| 421 | +) -> c_int { |
| 422 | + let row = (*row).as_row(); |
| 423 | + let i_col = i_col as usize; |
| 424 | + let result: Result<Vec<u8>, SpringErrno> = |
| 425 | + with_catch(|| row.get_not_null_by_index(i_col as usize)); |
| 426 | + match result { |
| 427 | + Ok(v) => { |
| 428 | + let v_len = memcpy(&v, out, out_len); |
| 429 | + v_len as c_int |
| 430 | + } |
| 431 | + Err(e) => e as c_int, |
| 432 | + } |
| 433 | +} |
| 434 | + |
366 | 435 | /// Get a bool column. |
367 | 436 | /// |
368 | 437 | /// # Parameters |
|
0 commit comments