kdb_c_api/
lib.rs

1//! **!!Notice!!** This crate was migrated to [kdbplus](https://crates.io/crates/kdbplus) which has IPC module as well.
2//! 
3//! Rust crate mirroring the C API header file (`k.h`) for kdb+. The expected usage is to build a
4//!  shared library for kdb+ in Rust.
5//! 
6//! In order to avoid writing too large `unsafe` block leading to poor optimization, most of native C API functions were provided
7//!  with a wrapper funtion with a bit of ergonomic safety and with intuitive implementation as a trait method. The only exceptions
8//!  are `knk` and `k` which are using elipsis (`...`) as its argument. These functions are provided under `native` namespace with the other C API functions.
9//! 
10//! # Note
11//! - This library is for kdb+ version >= 3.0.
12//! - Meangless C macros are excluded but accessors of an underlying array like `kC`, `kJ`, `kK` etc. are provided in Rust way.
13//! 
14//! ## Examples
15//! 
16//! The examples of using C API wrapper are included in `c_api_examples` folder. The examples are mirroring the examples in the document of `kdb_c_api` library and the functions are also used for simple tests of the library. The test is conducted in the `test.q` under `tests/` by loading the functions defined in a shared library built from the examples.
17//! 
18//! Here are some examples:
19//! 
20//! ### C API Style
21//! 
22//! ```rust
23//! use kdb_c_api::*;
24//! use kdb_c_api::native::*;
25//! 
26//! #[no_mangle]
27//! pub extern "C" fn create_symbol_list(_: K) -> K{
28//!   unsafe{
29//!     let mut list=ktn(qtype::SYMBOL as i32, 0);
30//!     js(&mut list, ss(str_to_S!("Abraham")));
31//!     js(&mut list, ss(str_to_S!("Isaac")));
32//!     js(&mut list, ss(str_to_S!("Jacob")));
33//!     js(&mut list, sn(str_to_S!("Josephine"), 6));
34//!     list
35//!   }
36//! }
37//!  
38//! #[no_mangle]
39//! pub extern "C" fn catchy(func: K, args: K) -> K{
40//!   unsafe{
41//!     let result=ee(dot(func, args));
42//!     if (*result).qtype == qtype::ERROR{
43//!       println!("error: {}", S_to_str((*result).value.symbol));
44//!       // Decrement reference count of the error object
45//!       r0(result);
46//!       KNULL
47//!     }
48//!     else{
49//!       result
50//!     }
51//!   }
52//! }
53//! 
54//! #[no_mangle]
55//! pub extern "C" fn dictionary_list_to_table() -> K{
56//!   unsafe{
57//!     let dicts=knk(3);
58//!     let dicts_slice=dicts.as_mut_slice::<K>();
59//!     for i in 0..3{
60//!       let keys=ktn(qtype::SYMBOL as i32, 2);
61//!       let keys_slice=keys.as_mut_slice::<S>();
62//!       keys_slice[0]=ss(str_to_S!("a"));
63//!       keys_slice[1]=ss(str_to_S!("b"));
64//!       let values=ktn(qtype::INT as i32, 2);
65//!       values.as_mut_slice::<I>()[0..2].copy_from_slice(&[i*10, i*100]);
66//!       dicts_slice[i as usize]=xD(keys, values);
67//!     }
68//!     // Format list of dictionary as a table.
69//!     // ([] a: 0 10 20i; b: 0 100 200i)
70//!     k(0, str_to_S!("{[dicts] -1 _ dicts, (::)}"), dicts, KNULL)
71//!   } 
72//! }
73//! ```
74//! 
75//! q can use these functions like this:
76//! 
77//! ```q
78//! q)summon:`libc_api_examples 2: (`create_symbol_list; 1)
79//! q)summon[]
80//! `Abraham`Isaac`Jacob`Joseph
81//! q)`Abraham`Isaac`Jacob`Joseph ~ summon[]
82//! q)catchy: `libc_api_examples 2: (`catchy; 2);
83//! q)catchy[$; ("J"; "42")]
84//! 42
85//! q)catchy[+; (1; `a)]
86//! error: type
87//! q)unfortunate_fact: `libc_api_examples 2: (`dictionary_list_to_table; 1);
88//! q)unfortunate_fact[]
89//! a  b  
90//! ------
91//! 0  0  
92//! 10 100
93//! 20 200
94//! ```
95//! 
96//! ### Rust Style
97//! 
98//! The examples below are written without `unsafe` code. You can see how comfortably breathing are the wrapped functions in the code.
99//! 
100//! ```rust
101//! use kdb_c_api::*;
102//! 
103//! #[no_mangle]
104//! pub extern "C" fn create_symbol_list2(_: K) -> K{
105//!   let mut list=new_simple_list(qtype::SYMBOL, 0);
106//!   list.push_symbol("Abraham").unwrap();
107//!   list.push_symbol("Isaac").unwrap();
108//!   list.push_symbol("Jacob").unwrap();
109//!   list.push_symbol_n("Josephine", 6).unwrap();
110//!   list
111//! }
112//! 
113//! #[no_mangle]
114//! fn no_panick(func: K, args: K) -> K{
115//!   let result=error_to_string(apply(func, args));
116//!   if result.get_type() == qtype::ERROR{
117//!     println!("FYI: {}", result.get_symbol().unwrap());
118//!     // Decrement reference count of the error object which is no longer used.
119//!     decrement_reference_count(result);
120//!     KNULL
121//!   }
122//!   else{
123//!     println!("success!");
124//!     result
125//!   }
126//! }
127//! 
128//! #[no_mangle]
129//! pub extern "C" fn create_table2(_: K) -> K{
130//!   // Build keys
131//!   let keys=new_simple_list(qtype::SYMBOL, 2);
132//!   let keys_slice=keys.as_mut_slice::<S>();
133//!   keys_slice[0]=internalize(str_to_S!("time"));
134//!   keys_slice[1]=internalize_n(str_to_S!("temperature_and_humidity"), 11);
135//! 
136//!   // Build values
137//!   let values=new_simple_list(qtype::COMPOUND, 2);
138//!   let time=new_simple_list(qtype::TIMESTAMP, 3);
139//!   // 2003.10.10D02:24:19.167018272 2006.05.24D06:16:49.419710368 2008.08.12D23:12:24.018691392
140//!   time.as_mut_slice::<J>().copy_from_slice(&[119067859167018272_i64, 201766609419710368, 271897944018691392]);
141//!   let temperature=new_simple_list(qtype::FLOAT, 3);
142//!   temperature.as_mut_slice::<F>().copy_from_slice(&[22.1_f64, 24.7, 30.5]);
143//!   values.as_mut_slice::<K>().copy_from_slice(&[time, temperature]);
144//!   
145//!   flip(new_dictionary(keys, values))
146//! }
147//! ```
148//! 
149//! And q code is here:
150//! 
151//! ```q
152//! q)summon:`libc_api_examples 2: (`create_symbol_list2; 1)
153//! q)summon[]
154//! `Abraham`Isaac`Jacob`Joseph
155//! q)chill: `libc_api_examples 2: (`no_panick; 2);
156//! q)chill[$; ("J"; "42")]
157//! success!
158//! 42
159//! q)chill[+; (1; `a)]
160//! FYI: type
161//! q)climate_change: libc_api_examples 2: (`create_table2; 1);
162//! q)climate_change[]
163//! time                          temperature
164//! -----------------------------------------
165//! 2003.10.10D02:24:19.167018272 22.1       
166//! 2006.05.24D06:16:49.419710368 24.7       
167//! 2008.08.12D23:12:24.018691392 30.5  
168//! ```
169
170#![allow(non_upper_case_globals)]
171#![allow(non_camel_case_types)]
172#![allow(non_snake_case)]
173
174//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
175//                            Load Libraries                            //
176//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
177
178use std::str;
179use std::ffi::CStr;
180use std::os::raw::{c_char, c_double, c_float, c_int, c_longlong, c_short, c_schar, c_uchar, c_void};
181use std::convert::TryInto;
182pub mod native;
183
184//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
185//                          Global Variables                            //
186//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
187
188pub mod qtype{
189  //! This module provides a list of q types. The motivation to contain them in a module is to 
190  //!  tie them up as related items rather than scattered values. Hence user should use these
191  //!  indicators with `qtype::` prefix, e.g., `qtype::BOOL`.
192  
193  use std::os::raw::c_schar;
194  
195  /// Type indicator of q mixed list.
196  ///  Access function: `kK`
197  pub const COMPOUND:c_schar=0;
198  /// Type indicator of q bool.
199  ///  Access fucntion: `kG`
200  pub const BOOL:c_schar=1;
201  /// Type indicator of q GUID.
202  ///  Access function: `kU`
203  pub const GUID:c_schar=2;
204  /// Type indicator of q byte
205  ///  Access function: `kG`
206  pub const BYTE:c_schar=4;
207  /// Type indicator of q short.
208  ///  Access function: `kH`
209  pub const SHORT:c_schar=5;
210  /// Type indicator of q int.
211  ///  Access function: `kI`
212  pub const INT:c_schar=6;
213  /// Type indicator of q long.
214  ///  Access function: `kJ`
215  pub const LONG:c_schar=7;
216  /// Type indicator of q real.
217  ///  Access function: `kE`
218  pub const REAL:c_schar=8;
219  /// Type indicator of q float.
220  ///  Access function: `kF`
221  pub const FLOAT:c_schar=9;
222  /// Type indicator of q char.
223  ///  Access function: `kC`
224  pub const CHAR:c_schar=10;
225  /// Type indicator of q symbol.
226  ///  Access function: `kS`
227  pub const SYMBOL:c_schar=11;
228  /// Type indicator of q timestamp.
229  ///  Access function: `kJ`
230  pub const TIMESTAMP:c_schar=12;
231  /// Type indicator of q month.
232  ///  Access function: `kI`
233  pub const MONTH:c_schar=13;
234  /// Type indicator of q date.
235  ///  Access function: `kI`
236  pub const DATE:c_schar=14;
237  /// Type indicator of q datetime.
238  ///  Access function: `kF`
239  pub const DATETIME:c_schar=15;
240  /// Type indicator of q timespan.
241  ///  Access function: `kJ`
242  pub const TIMESPAN:c_schar=16;
243  /// Type indicator of q minute.
244  ///  Access function: `kI`
245  pub const MINUTE:c_schar=17;
246  /// Type indicator of q second.
247  ///  Access function: `kI`
248  pub const SECOND:c_schar=18;
249  /// Type indicator of q time.
250  ///  Access function: `kI`
251  pub const TIME:c_schar=19;
252  /// Type indicator of q table.
253  ///  `*(qstruct).k` is q dictionary.
254  pub const TABLE:c_schar=98;
255  /// Type indicator of q dictionary.
256  /// - `kK(x)[0]`: keys
257  /// - `kK(x)[1]`: values
258  pub const DICTIONARY:c_schar=99;
259  /// Type indicator of q foreign object.
260  pub const FOREIGN:c_schar=112;
261  /// Type indicator of q sorted dictionary
262  pub const SORTED_DICTIONARY:c_schar=127;
263  /// Type indicator of q error
264  pub const ERROR:c_schar=-128;
265  /// Type indicator of q general null
266  pub const NULL:c_schar=101;
267
268}
269
270pub mod qattribute{
271  //! This module provides a list of q attributes. The motivation to contain them in a module is to 
272  //!  tie them up as related items rather than scattered values. Hence user should use these
273  //!  indicators with `qattribute::` prefix, e.g., `qattribute::UNIQUE`.
274  
275  use std::os::raw::c_char;
276  /// Indicates no attribute is appended on the q object. 
277  pub const NONE: c_char=0;
278  /// Sorted attribute, meaning that the q list is sorted in ascending order.
279  pub const SORTED: c_char=1;
280  /// Unique attribute, meaning that each element in the q list has a unique value within the list.
281  pub const UNIQUE: c_char=2;
282  /// Parted attribute, meaning that all the elements with the same value in the q object appear in a chunk.
283  pub const PARTED: c_char=3;
284  /// Grouped attribute, meaning that the elements of the q list are grouped with their indices by values implicitly.
285  pub const GROUPED: c_char=4;
286
287}
288
289/// `K` nullptr. This value is used as general null returned value (`(::)`).
290/// # Example
291/// ```
292/// use kdb_c_api::*;
293/// 
294/// #[no_mangle]
295/// pub extern "C" fn vanity(_: K) -> K{
296///   println!("Initialized something, probably it is your mindset.");
297///   KNULL
298/// }
299/// ```
300pub const KNULL:K=0 as K;
301
302//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
303//                                Macros                                //
304//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
305
306//%% Utility %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
307
308/// Convert `&str` to `S` (null-terminated character array).
309/// # Example
310/// ```no_run
311/// use kdb_c_api::*;
312/// 
313/// #[no_mangle]
314/// pub extern "C" fn pingpong(_: K) -> K{
315///   unsafe{native::k(0, str_to_S!("ping"), new_int(77), KNULL)}
316/// }
317/// ```
318/// ```q
319/// q)ping:{[int] `$string[int], "_pong!!"}
320/// q)pingpong: `libc_api_examples 2: (`pingpong; 1);
321/// q)pingpong[]
322/// `77_pong!!
323/// ```
324/// # Note
325/// This macro cannot be created as a function due to freeing resource of Rust (not sure).
326#[macro_export]
327macro_rules! str_to_S {
328  ($string: expr) => {
329    [$string.as_bytes(), &[b'\0']].concat().as_mut_ptr() as S
330  };
331}
332
333//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
334//                               Structs                                //
335//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
336
337//%% Alias %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
338
339/// `char*` in C. Also used to access symbol of q.
340pub type S = *mut c_char;
341/// `const char*` in C.
342pub type const_S = *const c_char; 
343/// `char` in C. Also used to access char of q.
344pub type C = c_char;
345/// `unsigned char` in C. Also used to access byte of q.
346pub type G = c_uchar;
347/// `i16` in C. Also used to access short of q.
348pub type H = c_short;
349/// `i32` in C. Also used to access int and compatible types (month, date, minute, second and time) of q.
350pub type I = c_int;
351/// `i64` in C. Also used to access long and compatible types (timestamp and timespan) of q.
352pub type J = c_longlong;
353/// `f32` in C. Also used to access real of q.
354pub type E = c_float;
355/// `f64` in C. Also used to access float and datetime of q.
356pub type F = c_double;
357/// `void` in C.
358pub type V = c_void;
359
360//%% U %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
361
362/// Struct representing 16-bytes GUID.
363#[derive(Clone, Copy, Debug)]
364#[repr(C)]
365pub struct U{
366  pub guid: [G; 16]
367}
368
369//%% K %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
370
371/// Underlying list value of q object.
372/// # Note
373/// Usually this struct does not need to be accessed this struct directly unless user wants to
374///  access via a raw pointer for non-trivial stuff. 
375#[derive(Clone, Copy, Debug)]
376#[repr(C)]
377pub struct k0_list_info{
378  /// Length of the list.
379  pub n: J,
380  /// Pointer referring to the head of the list. This pointer will be interpreted
381  ///  as various types when accessing `K` object to edit the list with
382  ///  [`as_mut_slice`](trait.KUtility.html#tymethod.as_mut_slice).
383  pub G0: [G; 1]
384}
385
386/// Underlying atom value of q object.
387/// # Note
388/// Usually this struct does not need to be accessed directly unless user wants to
389///  access via a raw pointer for non-trivial stuff. 
390#[derive(Clone, Copy)]
391#[repr(C)]
392pub union k0_inner{
393  /// Byte type holder.
394  pub byte: G,
395  /// Short type holder.
396  pub short: H,
397  /// Int type holder.
398  pub int: I,
399  /// Long type older.
400  pub long: J,
401  /// Real type holder.
402  pub real: E,
403  /// Float type holder.
404  pub float: F,
405  /// Symbol type holder.
406  pub symbol: S,
407  /// Table type holder.
408  pub table: *mut k0,
409  /// List type holder.
410  pub list: k0_list_info
411}
412
413/// Underlying struct of `K` object.
414#[repr(C)]
415#[derive(Clone, Copy)]
416pub struct k0{
417  /// For internal usage. 
418  pub m: c_schar,
419  /// For internal usage.
420  pub a: c_schar,
421  /// Type indicator.
422  pub qtype: c_schar,
423  /// Attribute of list.
424  pub attribute: C,
425  /// Reference count of the object.
426  pub refcount: I,
427  /// Underlying value.
428  pub value: k0_inner
429}
430
431/// Struct representing q object.
432pub type K=*mut k0;
433
434//%% KList %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
435
436pub trait KUtility{
437  /// Derefer `K` as a mutable slice of the specified type. The supported types are:
438  /// - `G`: Equivalent to C API macro `kG`.
439  /// - `H`: Equivalent to C API macro `kH`.
440  /// - `I`: Equivalent to C API macro `kI`.
441  /// - `J`: Equivalent to C API macro `kJ`.
442  /// - `E`: Equivalent to C API macro `kE`.
443  /// - `F`: Equivalent to C API macro `kF`.
444  /// - `C`: Equivalent to C API macro `kC`.
445  /// - `S`: Equivalent to C API macro `kS`.
446  /// - `K`: Equivalent to C API macro `kK`.
447  /// # Example
448  /// ```
449  /// use kdb_c_api::*;
450  /// 
451  /// #[no_mangle]
452  /// pub extern "C" fn modify_long_list_a_bit(long_list: K) -> K{
453  ///   if long_list.len() >= 2{
454  ///     // Derefer as a mutable i64 slice.
455  ///     long_list.as_mut_slice::<J>()[1]=30000_i64;
456  ///     // Increment the counter to reuse on q side.
457  ///     increment_reference_count(long_list)
458  ///   }
459  ///   else{
460  ///     new_error("this list is not long enough. how ironic...\0")
461  ///   }
462  /// }
463  /// ```
464  /// ```q
465  /// q)ironic: `libc_api_examples 2: (`modify_long_list_a_bit; 1);
466  /// q)list:1 2 3;
467  /// q)ironic list
468  /// 1 30000 3
469  /// q)ironic enlist 1
470  /// ```
471  /// # Note
472  /// Intuitively the parameter should be `&mut self` but it restricts a manipulating
473  ///  `K` objects in the form of slice simultaneously. As copying a pointer is not
474  ///  an expensive operation, using `self` should be fine.
475  fn as_mut_slice<'a, T>(self) -> &'a mut[T];
476
477  /// Get an underlying q byte.
478  /// # Example
479  /// ```no_run
480  /// use kdb_c_api::*;
481  /// 
482  /// #[no_mangle]
483  /// pub extern "C" fn print_bool(atom: K) -> K{
484  ///   match atom.get_bool(){
485  ///     Ok(boolean) => {
486  ///       println!("bool: {}", boolean);
487  ///       KNULL
488  ///     },
489  ///     Err(error) => new_error(error)
490  ///   }
491  /// }
492  /// ```
493  /// ```q
494  /// q)print_boole: `libc_api_examples 2: (`print_bool; 1);
495  /// q)print_bool[1b]
496  /// bool: true
497  /// ```
498  fn get_bool(&self) -> Result<bool, &'static str>;
499
500  /// Get an underlying q byte.
501  /// # Example
502  /// ```no_run
503  /// use kdb_c_api::*;
504  /// 
505  /// #[no_mangle]
506  /// pub extern "C" fn print_guid(atom: K) -> K{
507  ///   match atom.get_guid(){
508  ///     Ok(guid) => {
509  ///       let strguid=guid.iter().map(|b| format!("{:02x}", b)).collect::<String>();
510  ///       println!("GUID: {}-{}-{}-{}-{}", &strguid[0..4], &strguid[4..6], &strguid[6..8], &strguid[8..10], &strguid[10..16]);
511  ///       KNULL
512  ///     },
513  ///     Err(error) => new_error(error)
514  ///   }
515  /// }
516  /// ```
517  /// ```q
518  /// q)print_guid: `libc_api_examples 2: (`print_guid; 1);
519  /// q)guid: first 1?0Ng;
520  /// q)print_guid[guid]
521  /// GUID: 8c6b-8b-64-68-156084
522  /// ```
523  fn get_guid(&self) -> Result<[u8; 16], &'static str>;
524
525  /// Get an underlying q byte.
526  /// # Example
527  /// ```no_run
528  /// use kdb_c_api::*;
529  /// 
530  /// #[no_mangle]
531  /// pub extern "C" fn print_byte(atom: K) -> K{
532  ///   match atom.get_byte(){
533  ///     Ok(byte) => {
534  ///       println!("byte: {:#4x}", byte);
535  ///       KNULL
536  ///     },
537  ///     Err(error) => new_error(error)
538  ///   }
539  /// }
540  /// ```
541  /// ```q
542  /// q)print_byte: `libc_api_examples 2: (`print_byte; 1);
543  /// q)print_byte[0xc4]
544  /// byte: 0xc4
545  /// ```
546  fn get_byte(&self) -> Result<u8, &'static str>;
547
548  /// Get an underlying q short.
549  /// # Example
550  /// ```no_run
551  /// use kdb_c_api::*;
552  /// 
553  /// #[no_mangle]
554  /// pub extern "C" fn print_short(atom: K) -> K{
555  ///   match atom.get_short(){
556  ///     Ok(short) => {
557  ///       println!("short: {}", short);
558  ///       KNULL
559  ///     },
560  ///     Err(error) => new_error(error)
561  ///   }
562  /// }
563  /// ```
564  /// ```q
565  /// q)print_short: `libc_api_examples 2: (`print_short; 1);
566  /// q)print_short[10h]
567  /// short: 10
568  /// ```
569  fn get_short(&self) -> Result<i16, &'static str>;
570
571  /// Get an underlying q int.
572  /// # Example
573  /// ```no_run
574  /// use kdb_c_api::*;
575  /// 
576  /// #[no_mangle]
577  /// pub extern "C" fn print_int(atom: K) -> K{
578  ///   match atom.get_int(){
579  ///     Ok(int) => {
580  ///       println!("int: {}", int);
581  ///       KNULL
582  ///     },
583  ///     Err(error) => new_error(error)
584  ///   }
585  /// }
586  /// ```
587  /// ```q
588  /// q)print_int: `libc_api_examples 2: (`print_int; 1);
589  /// q)print_int[03:57:20]
590  /// int: 14240
591  /// ```
592  fn get_int(&self) -> Result<i32, &'static str>;
593
594  /// Get an underlying q long.
595  /// # Example
596  /// ```no_run
597  /// use kdb_c_api::*;
598  /// 
599  /// #[no_mangle]
600  /// pub extern "C" fn print_long(atom: K) -> K{
601  ///   match atom.get_long(){
602  ///     Ok(long) => {
603  ///       println!("long: {}", long);
604  ///       KNULL
605  ///     },
606  ///     Err(error) => new_error(error)
607  ///   }
608  /// }
609  /// ```
610  /// ```q
611  /// q)print_long: `libc_api_examples 2: (`print_long; 1);
612  /// q)print_long[2000.01.01D12:00:00.123456789]
613  /// long: 43200123456789
614  /// ```
615  fn get_long(&self) -> Result<i64, &'static str>;
616
617  /// Get an underlying q real.
618  /// # Example
619  /// ```no_run
620  /// use kdb_c_api::*;
621  /// 
622  /// #[no_mangle]
623  /// pub extern "C" fn print_real(atom: K) -> K{
624  ///   match atom.get_real(){
625  ///     Ok(real) => {
626  ///       println!("real: {}", real);
627  ///       KNULL
628  ///     },
629  ///     Err(error) => new_error(error)
630  ///   }
631  /// }
632  /// ```
633  /// ```q
634  /// q)print_real: `libc_api_examples 2: (`print_real; 1);
635  /// q)print_real[193810.32e]
636  /// real: 193810.31
637  /// ```
638  fn get_real(&self) -> Result<f32, &'static str>;
639
640  /// Get an underlying q float.
641  /// # Example
642  /// ```no_run
643  /// use kdb_c_api::*;
644  /// 
645  /// #[no_mangle]
646  /// pub extern "C" fn print_float(atom: K) -> K{
647  ///   match atom.get_float(){
648  ///     Ok(float) => {
649  ///       println!("float: {:.8}", float);
650  ///       KNULL
651  ///     },
652  ///     Err(error) => new_error(error)
653  ///   }
654  /// }
655  /// ```
656  /// ```q
657  /// q)print_float: `libc_api_examples 2: (`print_float; 1);
658  /// q)print_float[2002.01.12T10:03:45.332]
659  /// float: 742.41927468
660  /// ```
661  fn get_float(&self) -> Result<f64, &'static str>;
662
663  /// Get an underlying q char.
664  /// # Example
665  /// ```no_run
666  /// use kdb_c_api::*;
667  /// 
668  /// #[no_mangle]
669  /// pub extern "C" fn print_char(atom: K) -> K{
670  ///   match atom.get_char(){
671  ///     Ok(character) => {
672  ///       println!("char: \"{}\"", character);
673  ///       KNULL
674  ///     },
675  ///     Err(error) => new_error(error)
676  ///   }
677  /// }
678  /// ```
679  /// ```q
680  /// q)print_char: `libc_api_examples 2: (`print_char; 1);
681  /// q)print_char["k"]
682  /// char: "k"
683  /// ```
684  fn get_char(&self) -> Result<char, &'static str>;
685
686  /// Get an underlying q symbol.
687  /// # Example
688  /// ```no_run
689  /// use kdb_c_api::*;
690  /// 
691  /// #[no_mangle]
692  /// pub extern "C" fn print_symbol2(atom: K) -> K{
693  ///   match atom.get_symbol(){
694  ///     Ok(symbol) => {
695  ///       println!("symbol: `{}", symbol);
696  ///       KNULL
697  ///     },
698  ///     Err(error) => new_error(error)
699  ///   }
700  /// }
701  /// ```
702  /// ```q
703  /// q)print_symbol2: `libc_api_examples 2: (`print_symbol2; 1);
704  /// q)print_symbol2[`locust]
705  /// symbol: `locust
706  /// ```
707  fn get_symbol(&self) -> Result<&str, &'static str>;
708
709  /// Get an underlying q string as `&str`.
710  /// # Example
711  /// ```no_run
712  /// use kdb_c_api::*;
713  /// 
714  /// #[no_mangle]
715  /// pub extern "C" fn print_string(string: K) -> K{
716  ///   match string.get_str(){
717  ///     Ok(string_) => {
718  ///       println!("string: \"{}\"", string_);
719  ///       KNULL
720  ///     },
721  ///     Err(error) => new_error(error)
722  ///   }
723  /// }
724  /// ```
725  /// ```q
726  /// q)print_string: `libc_api_examples 2: (`print_string; 1);
727  /// q)print_string["gnat"]
728  /// string: "gnat"
729  /// ```
730  fn get_str(&self) -> Result<&str, &'static str>;
731
732  /// Get an underlying q string as `String`.
733  /// # Example
734  /// ```no_run
735  /// use kdb_c_api::*;
736  /// 
737  /// #[no_mangle]
738  /// pub extern "C" fn print_string2(string: K) -> K{
739  ///   match string.get_string(){
740  ///     Ok(string_) => {
741  ///       println!("string: \"{}\"", string_);
742  ///       KNULL
743  ///     },
744  ///     Err(error) => new_error(error)
745  ///   }
746  /// }
747  /// ```
748  /// ```q
749  /// q)print_string: `libc_api_examples 2: (`print_string; 1);
750  /// q)print_string["grasshopper"]
751  /// string: "grasshopper"
752  /// ```
753  fn get_string(&self) -> Result<String, &'static str>;
754
755  /// Get a flipped underlying q table as `K` (dictionary).
756  /// # Example
757  /// ```no_run
758  /// use kdb_c_api::*;
759  /// 
760  /// #[no_mangle]
761  /// pub extern "C" fn hidden_key(table: K) -> K{
762  ///   match table.get_dictionary(){
763  ///     Ok(dictionary) => dictionary.as_mut_slice::<K>()[0].q_ipc_encode(3).unwrap(),
764  ///     Err(error) => new_error(error)
765  ///   }
766  /// }
767  /// ```
768  /// ```q
769  /// q)perceive_the_man: `libc_api_examples 2: (`hidden_key; 1);
770  /// q)perceive_the_man ([] t: `timestamp$.z.p+1e9*til 9; chr:"ljppkgfgs"; is: 7 8 12 14 21 316 400 1000 6000i)
771  /// 0x01000000170000000b0003000000740063687200697300
772  /// ```
773  /// # Note
774  /// This method is provided because the ony way to examine the value of table type is to access the underlying dictionary (flipped table).
775  ///  Also when some serialization is necessary for a table, you can reuse a serializer for a dictionary if it is already provided. Actually
776  ///  when q serialize a table object with `-8!` (q function) or `b9` (C code), it just serializes the underlying dictionary with an additional
777  ///  marker indicating a table type.
778  fn get_dictionary(&self) -> Result<K, &'static str>;
779
780  /// Get an attribute of a q object.
781  /// # Example
782  /// ```no_run
783  /// use kdb_c_api::*;
784  /// 
785  /// #[no_mangle]
786  /// pub extern "C" fn murmur(list: K) -> K{
787  ///   match list.get_attribute(){
788  ///     qattribute::SORTED => {
789  ///       new_string("Clean")
790  ///     },
791  ///     qattribute::UNIQUE => {
792  ///       new_symbol("Alone")
793  ///     },
794  ///     _ => KNULL
795  ///   }
796  /// }
797  /// ```
798  fn get_attribute(&self) -> C;
799
800  /// Get a reference count of a q object.
801  fn get_refcount(&self) -> I;
802
803  /// Append a q list object to a q list.
804  ///  Returns a pointer to the (potentially reallocated) `K` object.
805  /// ```no_run
806  /// use kdb_c_api::*;
807  /// 
808  /// #[no_mangle]
809  /// pub extern "C" fn concat_list2(mut list1: K, list2: K) -> K{
810  ///   if let Err(err) = list1.append(list2){
811  ///     new_error(err)
812  ///   }
813  ///   else{
814  ///     increment_reference_count(list1)
815  ///   }
816  /// }
817  /// ```
818  /// ```q
819  /// q)plunder: `libc_api_examples 2: (`concat_list2; 2);
820  /// q)plunder[(::; `metals; `fire); ("clay"; 316)]
821  /// ::
822  /// `metals
823  /// `fire
824  /// "clay"
825  /// 316
826  /// q)plunder[1 2 3; 4 5]
827  /// 1 2 3 4 5
828  /// q)plunder[`a`b`c; `d`e]
829  /// `a`b`c`d`e
830  /// ```
831  fn append(&mut self, list: K)->Result<K, &'static str>;
832
833  /// Add a q object to a q compound list.
834  ///  Returns a pointer to the (potentially reallocated) `K` object.
835  /// # Example
836  /// ```no_run
837  /// use kdb_c_api::*;
838  /// 
839  /// #[no_mangle]
840  /// pub extern "C" fn create_compound_list(int: K) -> K{
841  ///   let mut list=new_simple_list(qtype::COMPOUND, 0);
842  ///   for i in 0..5{
843  ///     list.push(new_long(i)).unwrap();
844  ///   }
845  ///   list.push(increment_reference_count(int)).unwrap();
846  ///   list
847  /// }
848  /// ```
849  /// ```q
850  /// q)nums: `libc_api_examples 2: (`create_compound_list2; 1);
851  /// q)nums[5i]
852  /// 0
853  /// 1
854  /// 2
855  /// 3
856  /// 4
857  /// 5i
858  /// ```
859  /// # Note
860  /// In this example we did not allocate an array as `new_simple_list(qtype::COMPOUND, 0)` to use `push`.
861  ///  As `new_simple_list` initializes the internal list size `n` with its argument, preallocating memory with `new_simple_list` and
862  ///  then using `push` will crash. If you want to allocate a memory in advance, you can substitute a value
863  ///  after converting the q list object into a slice with [`as_mut_slice`](rait.KUtility.html#tymethod.as_mut_slice).
864  fn push(&mut self, atom: K)->Result<K, &'static str>;
865
866  /// Add a raw value to a q simple list and returns a pointer to the (potentially reallocated) `K` object.
867  /// # Example
868  /// ```no_run
869  /// use kdb_c_api::*;
870  /// 
871  /// #[no_mangle]
872  /// pub extern "C" fn create_simple_list2(_: K) -> K{
873  ///   let mut list=new_simple_list(qtype::DATE, 0);
874  ///   for i in 0..5{
875  ///     list.push_raw(i).unwrap();
876  ///   }
877  ///   list
878  /// }
879  /// ```
880  /// ```q
881  /// q)simple_is_the_best: `lic_api_example 2: (`create_simple_list2; 1);
882  /// q)simple_is_the_best[]
883  /// 2000.01.01 2000.01.02 2000.01.03 2000.01.04 2000.01.05
884  /// ```
885  /// # Note
886  /// - Concrete type of `T` is not checked. Its type must be either of `I`, `J` and `F` and it must be compatible
887  ///  with the list type. For example, timestamp list requires `J` type atom.
888  /// - For symbol list, use [`push_symbol`](#fn.push_symbol) or [`push_symbol_n`](#fn.push_symbol_n).
889  fn push_raw<T>(&mut self, atom: T)->Result<K, &'static str>;
890
891  /// Add an internalized char array to symbol list.
892  ///  Returns a pointer to the (potentially reallocated) `K` object.
893  /// # Example
894  /// ```no_run
895  /// use kdb_c_api::*;
896  /// 
897  /// #[no_mangle]
898  /// pub extern "C" fn create_symbol_list2(_: K) -> K{
899  ///   let mut list=new_simple_list(qtype::SYMBOL, 0);
900  ///   list.push_symbol("Abraham").unwrap();
901  ///   list.push_symbol("Isaac").unwrap();
902  ///   list.push_symbol("Jacob").unwrap();
903  ///   list.push_symbol_n("Josephine", 6).unwrap();
904  ///   list
905  /// }
906  /// ```
907  /// ```q
908  /// q)summon:`libc_api_examples 2: (`create_symbol_list2; 1)
909  /// q)summon[]
910  /// `Abraham`Isaac`Jacob`Joseph
911  /// q)`Abraham`Isaac`Jacob`Joseph ~ summon[]
912  /// 1b
913  /// ```
914  /// # Note
915  /// In this example we did not allocate an array as `new_simple_list(qtype::SYMBOL as I, 0)` to use `push_symbol`.
916  ///  As `new_simple_list` initializes the internal list size `n` with its argument, preallocating memory with `new_simple_list`
917  ///  and then using `push_symbol` will crash. If you want to allocate a memory in advance, you can substitute a value
918  ///  after converting the q list object into a slice with [`as_mut_slice`](trait.KUtility.html#tymethod.as_mut_slice).
919  fn push_symbol(&mut self, symbol: &str)->Result<K, &'static str>;
920
921  /// Add an internalized char array to symbol list.
922  ///  Returns a pointer to the (potentially reallocated) `K` object.
923  /// # Example
924  /// See the example of [`push_symbol`](#fn.push_symbol).
925  fn push_symbol_n(&mut self, symbol: &str, n: I)->Result<K, &'static str>;
926
927  /// Get a length of the list. More specifically, a value of `k0.value.list.n` for list types.
928  ///  Otherwise 2 for table and 1 for atom and null.
929  /// # Example
930  /// ```no_run
931  /// use kdb_c_api::*;
932  /// 
933  /// #[no_mangle]
934  /// pub extern "C" fn numbers(obj: K) -> K{
935  ///   let count=format!("{} people are in numbers", obj.len());
936  ///   new_string(&count)
937  /// }
938  /// ```
939  /// ```q
940  /// q)census: `libc_api_examples 2: (`numbers; 1);
941  /// q)census[(::)]
942  /// "1 people are in numbers"
943  /// q)census[til 4]
944  /// "4 people are in numbers"
945  /// q)census[`a`b!("many"; `split`asunder)]
946  /// "2 people are in numbers"
947  /// q)census[([] id: til 1000)]
948  /// "1000 people are in numbers"
949  /// ```
950  fn len(&self) -> i64;
951
952  /// Get a type of `K` object.
953  fn get_type(&self) -> i8;
954
955  /// Set a type of `K` object.
956  /// # Example
957  /// See the example of [`load_as_q_function](fn.load_as_q_function.html).
958  fn set_type(&self, qtype: i8);
959
960  /// Serialize q object and return serialized q byte list object on success: otherwise null. 
961  ///  Mode is either of:
962  /// - -1: Serialize within the same process.
963  /// - 1: retain enumerations, allow serialization of timespan and timestamp: Useful for passing data between threads
964  /// - 2: unenumerate, allow serialization of timespan and timestamp
965  /// - 3: unenumerate, compress, allow serialization of timespan and timestamp
966  /// # Example
967  /// ```no_run
968  /// use kdb_c_api::*;
969  /// 
970  /// #[no_mangle]
971  /// pub extern "C" fn encrypt(object: K)->K{
972  ///   match object.q_ipc_encode(3){
973  ///     Ok(bytes) => bytes,
974  ///     Err(error) => new_error(error)
975  ///   }
976  /// }
977  /// ```
978  /// ```q
979  /// q)disguise: `libc_api_examples 2: (`encrypt; 1);
980  /// q)list: (til 3; "abc"; 2018.02.18D04:30:00.000000000; `revive);
981  /// q)disguise list
982  /// 0x010000004600000000000400000007000300000000000000000000000100000000000000020..
983  /// ```
984  fn q_ipc_encode(&self, mode: I) -> Result<K, &'static str>;
985
986  /// Deserialize a bytes into q object.
987  /// # Example
988  /// ```no_run
989  /// use kdb_c_api::*;
990  /// 
991  /// #[no_mangle]
992  /// pub extern "C" fn decrypt(bytes: K)->K{
993  ///   match bytes.q_ipc_decode(){
994  ///     Ok(object) => object,
995  ///     Err(error) => new_error(error)
996  ///   }
997  /// }
998  /// ```
999  /// ```q
1000  /// q)uncover: `libc_api_examples 2: (`decrypt; 1);
1001  /// q)uncover -8!"What is the purpose of CREATION?"
1002  /// "What is the purpose of CREATION?"
1003  /// ```
1004  fn q_ipc_decode(&self) -> Result<K, &'static str>;
1005}
1006
1007//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
1008//                            Implementation                            //
1009//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
1010
1011//%% U %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
1012
1013impl U{
1014  /// Create 16-byte GUID object.
1015  pub fn new(guid: [u8; 16]) -> Self{
1016    U{guid:guid}
1017  }
1018}
1019
1020//%% K %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
1021
1022unsafe impl Send for k0_inner{}
1023unsafe impl Send for k0{}
1024
1025impl KUtility for K{
1026  #[inline]
1027  fn as_mut_slice<'a, T>(self) -> &'a mut[T]{
1028    unsafe{
1029      std::slice::from_raw_parts_mut((*self).value.list.G0.as_mut_ptr() as *mut T, (*self).value.list.n as usize)
1030    }
1031  }
1032
1033  #[inline]
1034  fn get_bool(&self) -> Result<bool, &'static str>{
1035    match unsafe{(**self).qtype}.saturating_mul(-1){
1036      qtype::BOOL => Ok(unsafe{(**self).value.byte != 0}),
1037      _ => Err("not a bool\0")
1038    }
1039  }
1040
1041  #[inline]
1042  fn get_guid(&self) -> Result<[u8; 16], &'static str>{
1043    match unsafe{(**self).qtype}.saturating_mul(-1){
1044      qtype::GUID => {
1045        Ok(unsafe{std::slice::from_raw_parts((**self).value.list.G0.as_ptr(), 16)}.try_into().unwrap())
1046      },
1047      _ => Err("not a GUID\0")
1048    }
1049  }
1050
1051  #[inline]
1052  fn get_byte(&self) -> Result<u8, &'static str>{
1053    match unsafe{(**self).qtype}.saturating_mul(-1){
1054      qtype::BYTE => Ok(unsafe{(**self).value.byte}),
1055      _ => Err("not a byte\0")
1056    }
1057  }
1058
1059  #[inline]
1060  fn get_short(&self) -> Result<i16, &'static str>{
1061    match unsafe{(**self).qtype}.saturating_mul(-1){
1062      qtype::SHORT => Ok(unsafe{(**self).value.short}),
1063      _ => Err("not a short\0")
1064    }
1065  }
1066
1067  #[inline]
1068  fn get_int(&self) -> Result<i32, &'static str>{
1069    match unsafe{(**self).qtype}.saturating_mul(-1){
1070      qtype::INT | qtype::MONTH | qtype::DATE | qtype::MINUTE | qtype::SECOND | qtype::TIME => Ok(unsafe{(**self).value.int}),
1071      _ => Err("not an int\0")
1072    }
1073  }
1074
1075  #[inline]
1076  fn get_long(&self) -> Result<i64, &'static str>{
1077    match unsafe{(**self).qtype}.saturating_mul(-1){
1078      qtype::LONG | qtype::TIMESTAMP | qtype::TIMESPAN => Ok(unsafe{(**self).value.long}),
1079      _ => Err("not a long\0")
1080    }
1081  }
1082
1083  #[inline]
1084  fn get_real(&self) -> Result<f32, &'static str>{
1085    match unsafe{(**self).qtype}.saturating_mul(-1){
1086      qtype::REAL => Ok(unsafe{(**self).value.real}),
1087      _ => Err("not a real\0")
1088    }
1089  }
1090
1091  #[inline]
1092  fn get_float(&self) -> Result<f64, &'static str>{
1093    match unsafe{(**self).qtype}.saturating_mul(-1){
1094      qtype::FLOAT | qtype::DATETIME => Ok(unsafe{(**self).value.float}),
1095      _ => Err("not a float\0")
1096    }
1097  }
1098
1099  #[inline]
1100  fn get_char(&self) -> Result<char, &'static str>{
1101    match unsafe{(**self).qtype}.saturating_mul(-1){
1102      qtype::CHAR => Ok(unsafe{(**self).value.byte as char}),
1103      _ => Err("not a char\0")
1104    }
1105  }
1106
1107  #[inline]
1108  fn get_symbol(&self) -> Result<&str, &'static str>{
1109    if (unsafe{(**self).qtype} == -qtype::SYMBOL) || (unsafe{(**self).qtype} == qtype::ERROR){
1110      Ok(S_to_str(unsafe{(**self).value.symbol}))
1111    }
1112    else{
1113      Err("not a symbol\0")
1114    }
1115  }
1116
1117  #[inline]
1118  fn get_str(&self) -> Result<&str, &'static str>{
1119    match unsafe{(**self).qtype}{
1120      qtype::CHAR => {
1121        Ok(unsafe{str::from_utf8_unchecked_mut(self.as_mut_slice::<G>())})
1122      },
1123      _ => Err("not a string\0")
1124    }
1125  }
1126
1127  #[inline]
1128  fn get_string(&self) -> Result<String, &'static str>{
1129    match unsafe{(**self).qtype}{
1130      qtype::CHAR => {
1131        Ok(unsafe{String::from_utf8_unchecked(self.as_mut_slice::<G>().to_vec())})
1132      },
1133      _ => Err("not a string\0")
1134    }
1135  }
1136
1137  #[inline]
1138  fn get_dictionary(&self) -> Result<K, &'static str>{
1139    match unsafe{(**self).qtype}{
1140      qtype::TABLE => {
1141        Ok(unsafe{(**self).value.table})
1142      },
1143      _ => Err("not a table\0")
1144    }
1145  }
1146
1147  #[inline]
1148  fn get_attribute(&self) -> i8{
1149    unsafe{(**self).attribute}
1150  }
1151
1152  #[inline]
1153  fn get_refcount(&self) -> i32{
1154    unsafe{(**self).refcount}
1155  }
1156
1157  #[inline]
1158  fn append(&mut self, list: K)->Result<K, &'static str>{
1159    if unsafe{(**self).qtype} >= 0 && unsafe{(**self).qtype} == unsafe{(*list).qtype}{
1160      Ok(unsafe{native::jv(self, list)})
1161    }
1162    else{
1163      Err("not a list or types do not match\0")
1164    }
1165  }
1166
1167  #[inline]
1168  fn push(&mut self, atom: K)->Result<K, &'static str>{
1169    if unsafe{(**self).qtype} == 0 {
1170      Ok(unsafe{native::jk(self, atom)})
1171    }
1172    else{
1173      Err("not a list or types do not match\0")
1174    }
1175  }
1176
1177  #[inline]
1178  fn push_raw<T>(&mut self, mut atom: T)->Result<K, &'static str>{
1179    match unsafe{(**self).qtype}{
1180      _t@1..=19 => Ok(unsafe{native::ja(self, std::mem::transmute::<*mut T, *mut V>(&mut atom))}),
1181      _ => Err("not a simple list or types do not match\0")
1182    }
1183  }
1184
1185  #[inline]
1186  fn push_symbol(&mut self, symbol: &str)->Result<K, &'static str>{
1187    if unsafe{(**self).qtype} == qtype::SYMBOL {
1188      Ok(unsafe{native::js(self, native::ss(str_to_S!(symbol)))})
1189    }
1190    else{
1191      Err("not a symbol list\0")
1192    }
1193  }
1194
1195  #[inline]
1196  fn push_symbol_n(&mut self, symbol: &str, n: I)->Result<K, &'static str>{
1197    if unsafe{(**self).qtype} == qtype::SYMBOL {
1198      Ok(unsafe{native::js(self, native::sn(str_to_S!(symbol), n))})
1199    }
1200    else{
1201      Err("not a symbol list or types do not match\0")
1202    }
1203  }
1204
1205  #[inline]
1206  fn len(&self) -> i64{
1207    unsafe{
1208      if (**self).qtype < 0 || (**self).qtype == qtype::NULL{
1209        // Atom or (::)
1210        1
1211      }
1212      else if (**self).qtype == qtype::TABLE{
1213        // Table
1214        // Access underlying table (dictionary structure) and retrieve values of the dictionary.
1215        // The values (columns) is assured to be a list of lists as it is a table. so cast it to list of `K`.
1216        // Size of the table is a length of the first column.
1217        (*((**self).value.table).as_mut_slice::<K>()[1].as_mut_slice::<K>()[0]).value.list.n
1218      }
1219      else if (**self).qtype == qtype::DICTIONARY{
1220        // Dictionary
1221        // Access to keys of the dictionary and retrieve its length.
1222        (*(*self).as_mut_slice::<K>()[0]).value.list.n
1223      }
1224      else{
1225        // List
1226        (**self).value.list.n
1227      }
1228    }
1229  }
1230
1231  #[inline]
1232  fn get_type(&self) -> i8{
1233    unsafe{(**self).qtype}
1234  }
1235
1236  #[inline]
1237  fn set_type(&self, qtype: i8){
1238    unsafe{(**self).qtype=qtype};
1239  }
1240
1241  #[inline]
1242  fn q_ipc_encode(&self, mode: I) -> Result<K, &'static str>{
1243    let result=error_to_string(unsafe{
1244      native::b9(mode, *self)
1245    });
1246    match unsafe{(*result).qtype}{
1247      qtype::ERROR => {
1248        decrement_reference_count(result);
1249        Err("failed to encode\0")
1250      },
1251      _ => Ok(result)
1252    }
1253  }
1254
1255  #[inline]
1256  fn q_ipc_decode(&self) -> Result<K, &'static str>{
1257    match unsafe{(**self).qtype}{
1258      qtype::BYTE => {
1259        let result=error_to_string(unsafe{
1260          native::d9(*self)
1261        });
1262        match unsafe{(*result).qtype}{
1263          qtype::ERROR => {
1264            decrement_reference_count(result);
1265            Err("failed to decode\0")
1266          },
1267          _ => Ok(result)
1268        }
1269      },
1270      _ => Err("not bytes\0")
1271    }
1272  }
1273}
1274
1275impl k0{
1276  /// Derefer `k0` as a mutable slice. For supported types, see [`as_mut_slice`](trait.KUtility.html#tymethod.as_mut_slice).
1277  /// # Note
1278  /// Used if `K` needs to be sent to another thread. `K` cannot implement `Send` and therefore
1279  ///  its inner struct must be sent instead.
1280  /// # Example
1281  /// See the example of [`setm`](native/fn.setm.html).
1282  #[inline]
1283  pub fn as_mut_slice<'a, T>(&mut self) -> &'a mut[T]{
1284    unsafe{
1285      std::slice::from_raw_parts_mut(self.value.list.G0.as_mut_ptr() as *mut T, self.value.list.n as usize)
1286    }
1287  }
1288}
1289
1290//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
1291//                              Utility                                 //
1292//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
1293
1294//%% Utility %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
1295
1296/// Convert `S` to `&str`. This function is intended to convert symbol type (null-terminated char-array) to `str`.
1297/// # Extern
1298/// ```no_run 
1299/// use kdb_c_api::*;
1300/// 
1301/// #[no_mangle]
1302/// pub extern "C" fn print_symbol(symbol: K) -> K{
1303///   unsafe{
1304///     if (*symbol).qtype == -qtype::SYMBOL{
1305///       println!("symbol: `{}", S_to_str((*symbol).value.symbol));
1306///     }
1307///     // return null
1308///     KNULL
1309///   }
1310/// }
1311/// ```
1312/// ```q
1313/// q)print_symbol:`libc_api_examples 2: (`print_symbol; 1)
1314/// q)a:`kx
1315/// q)print_symbol a
1316/// symbol: `kx
1317/// ```
1318#[inline]
1319pub fn S_to_str<'a>(cstring: S) -> &'a str{
1320  unsafe{
1321    CStr::from_ptr(cstring).to_str().unwrap()
1322  }
1323}
1324
1325/// Convert null-terminated `&str` to `S`.
1326/// # Example
1327/// ```no_run
1328/// use kdb_c_api::*;
1329/// 
1330/// #[no_mangle]
1331/// pub extern "C" fn pingpong2(_: K) -> K{
1332///   unsafe{native::k(0, null_terminated_str_to_S("ping\0"), new_int(77), KNULL)}
1333/// }
1334/// ```
1335/// ```q
1336/// q)ping:{[int] `$string[int], "_pong!!"};
1337/// q)pingpong: `libc_api_examples 2: (`pingpong2; 1);
1338/// q)pingpong[]
1339/// `77_pong!!
1340/// ```
1341#[inline]
1342pub fn null_terminated_str_to_S(string: &str) -> S {
1343  unsafe{
1344    CStr::from_bytes_with_nul_unchecked(string.as_bytes()).as_ptr() as S
1345  }
1346}
1347
1348/// Convert null terminated `&str` into `const_S`. Expected usage is to build
1349///  a q error object with `krr`.
1350/// # Example
1351/// ```no_run
1352/// use kdb_c_api::*;
1353/// use kdb_c_api::native::*;
1354/// 
1355/// pub extern "C" fn must_be_int2(obj: K) -> K{
1356///   unsafe{
1357///     if (*obj).qtype != -qtype::INT{
1358///       krr(null_terminated_str_to_const_S("not an int\0"))
1359///     }
1360///     else{
1361///       KNULL
1362///     }
1363///   }
1364/// }
1365/// ```
1366/// ```q
1367/// q)check:`libc_api_examples 2: (`must_be_int; 1)
1368/// q)a:100
1369/// q)check a
1370/// 'not an int
1371///   [0]  check a
1372///        ^
1373/// q)a:42i
1374/// q)check a
1375/// ```
1376pub fn null_terminated_str_to_const_S(string: &str) -> const_S {
1377  string.as_bytes().as_ptr() as const_S
1378}
1379
1380//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
1381//                              Re-export                               //
1382//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
1383
1384//%% Constructor %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
1385
1386/// Constructor of q bool object. Relabeling of `kb`.
1387/// # Example
1388/// ```no_run
1389/// use kdb_c_api::*;
1390/// 
1391/// #[no_mangle]
1392/// pub extern "C" fn create_bool(_: K) -> K{
1393///   new_bool(0)
1394/// }
1395/// ```
1396/// ```q
1397/// q)no: `libc_api_examples 2: (`create_bool; 1);
1398/// q)no[]
1399/// 0b
1400/// ```
1401#[inline]
1402pub fn new_bool(boolean: I) -> K{
1403  unsafe{
1404    native::kb(boolean)
1405  }
1406}
1407
1408/// Constructor of q GUID object. Relabeling of `ku`.
1409/// # Example
1410/// ```no_run
1411/// use kdb_c_api::*;
1412/// 
1413/// #[no_mangle]
1414/// pub extern "C" fn create_guid(_: K) -> K{
1415///   new_guid([0x1e_u8, 0x11, 0x17, 0x0c, 0x42, 0x24, 0x25, 0x2c, 0x1c, 0x14, 0x1e, 0x22, 0x4d, 0x3d, 0x46, 0x24])
1416/// }
1417/// ```
1418/// ```q
1419/// q)create_guid: `libc_api_examples 2: (`create_guid; 1);
1420/// q)create_guid[]
1421/// 1e11170c-4224-252c-1c14-1e224d3d4624
1422/// ```
1423#[inline]
1424pub fn new_guid(guid: [G; 16]) -> K{
1425  unsafe{
1426    native::ku(U::new(guid))
1427  }
1428}
1429
1430/// Constructor of q byte object. Relabeling of `kg`.
1431/// # Example
1432/// ```no_run
1433/// use kdb_c_api::*;
1434/// 
1435/// #[no_mangle]
1436/// pub extern "C" fn create_byte(_: K) -> K{
1437///   new_byte(0x3c)
1438/// }
1439/// ```
1440/// ```q
1441/// q)create_byte: `libc_api_examples 2: (`create_byte; 1);
1442/// q)create_byte[]
1443/// 0x3c
1444/// ```
1445#[inline]
1446pub fn new_byte(byte: I) -> K{
1447  unsafe{
1448    native::kg(byte)
1449  }
1450}
1451
1452/// Constructor of q short object. Relabeling of `kh`.
1453/// # Example
1454/// ```no_run
1455/// use kdb_c_api::*;
1456/// 
1457/// #[no_mangle]
1458/// pub extern "C" fn create_short(_: K) -> K{
1459///   new_short(-144)
1460/// }
1461/// ```
1462/// ```q
1463/// q)shortage: `libc_api_examples 2: (`create_short; 1);
1464/// q)shortage[]
1465/// -144h
1466/// ```
1467#[inline]
1468pub fn new_short(short: I) -> K{
1469  unsafe{
1470    native::kh(short)
1471  }
1472}
1473
1474/// Constructor of q int object. Relabeling of `ki`.
1475/// # Example
1476/// ```no_run
1477/// use kdb_c_api::*;
1478/// 
1479/// #[no_mangle]
1480/// pub extern "C" fn create_int(_: K) -> K{
1481///   new_int(86400000)
1482/// }
1483/// ```
1484/// ```q
1485/// q)trvial: `libc_api_examples 2: (`create_int; 1);
1486/// q)trivial[]
1487/// 86400000i
1488/// ```
1489#[inline]
1490pub fn new_int(int: I) -> K{
1491  unsafe{
1492    native::ki(int)
1493  }
1494}
1495
1496/// Constructor of q long object. Relabeling of `kj`.
1497/// # Example
1498/// ```no_run
1499/// use kdb_c_api::*;
1500/// 
1501/// #[no_mangle]
1502/// pub extern "C" fn create_long(_: K) -> K{
1503///   new_long(-668541276001729000)
1504/// }
1505/// ```
1506/// ```q
1507/// q)lengthy: `libc_api_examples 2: (`create_long; 1);
1508/// q)lengthy[]
1509/// -668541276001729000
1510/// ```
1511#[inline]
1512pub fn new_long(long: J) -> K{
1513  unsafe{
1514    native::kj(long)
1515  }
1516}
1517
1518/// Constructor of q real object. Relabeling of `ke`.
1519/// # Example
1520/// ```no_run
1521/// use kdb_c_api::*;
1522/// 
1523/// #[no_mangle]
1524/// pub extern "C" fn create_real(_: K) -> K{
1525///   new_real(0.00324)
1526/// }
1527/// ```
1528/// ```q
1529/// q)reality: `libc_api_examples 2: (`create_real; 1);
1530/// q)reality[]
1531/// 0.00324e
1532/// ```
1533#[inline]
1534pub fn new_real(real: F) -> K{
1535  unsafe{
1536    native::ke(real)
1537  }
1538}
1539
1540/// Constructor of q float object. Relabeling of `kf`.
1541/// # Example
1542/// ```
1543/// use kdb_c_api::*;
1544/// 
1545/// #[no_mangle]
1546/// pub extern "C" fn create_float(_: K) -> K{
1547///   new_float(-6302.620)
1548/// }
1549/// ```
1550/// ```q
1551/// q)coffee_float: `libc_api_examples 2: (`create_float; 1);
1552/// q)coffee_float[]
1553/// -6302.62
1554/// ```
1555#[inline]
1556pub fn new_float(float: F) -> K{
1557  unsafe{
1558    native::kf(float)
1559  }
1560}
1561
1562///  Constructor of q char object. Relabeling of `kc`.
1563/// # Example
1564/// ```no_run
1565/// use kdb_c_api::*;
1566/// 
1567/// #[no_mangle]
1568/// pub extern "C" fn create_char2(_: K) -> K{
1569///   new_char('t')
1570/// }
1571/// ```
1572/// ```q
1573/// q)heavy: `libc_api_examples 2: (`create_char2; 1);
1574/// q)heavy[]
1575/// "t"
1576/// ```
1577#[inline]
1578pub fn new_char(character: char) -> K{
1579  unsafe{
1580    native::kc(character as I)
1581  }
1582}
1583
1584/// Constructor of q symbol object. Relabeling of `ks`.
1585/// # Example
1586/// ```no_run
1587/// use kdb_c_api::*;
1588/// 
1589/// #[no_mangle]
1590/// pub extern "C" fn create_symbol2(_: K) -> K{
1591///   new_symbol("symbolic")
1592/// }
1593/// ```
1594/// ```q
1595/// q)hard: `libc_api_examples 2: (`create_symbol2; 1);
1596/// q)hard[]
1597/// `symbolic
1598/// q)`symbolic ~ hard[]
1599/// 1b
1600/// ```
1601#[inline]
1602pub fn new_symbol(symbol: &str) -> K{
1603  unsafe{
1604    native::ks(str_to_S!(symbol))
1605  }
1606}
1607
1608/// Constructor of q timestamp from elapsed time in nanoseconds since kdb+ epoch (`2000.01.01`). Relabeling of `ktj`.
1609/// ```no_run
1610/// use kdb_c_api::*;
1611/// 
1612/// #[no_mangle]
1613/// pub extern "C" fn create_timestamp2(_: K) -> K{
1614///   // 2015.03.16D00:00:00:00.000000000
1615///   new_timestamp(479779200000000000)
1616/// }
1617/// ```
1618/// ```q
1619/// q)stamp: `libc_api_examples 2: (`create_timestamp2; 1);
1620/// q)stamp[]
1621/// 2015.03.16D00:00:00.000000000
1622/// ```
1623#[inline]
1624pub fn new_timestamp(nanoseconds: J) -> K{
1625  unsafe{
1626    native::ktj(-qtype::TIMESTAMP as I, nanoseconds)
1627  }
1628}
1629
1630/// Create a month object from the number of months since kdb+ epoch (`2000.01.01`).
1631///  This is a complememtal constructor of missing month type.
1632/// # Example
1633/// ```no_run
1634/// use kdb_c_api::*;
1635/// 
1636/// #[no_mangle]
1637/// pub extern "C" fn create_month(_: K) -> K{
1638///   // 2010.07m
1639///   new_month(126)
1640/// }
1641/// ```
1642/// ```q
1643/// q)create_month: `libc_api_examples 2: (`create_month; 1);
1644/// q)create_month[]
1645/// 2010.07m
1646/// ```
1647#[inline]
1648pub fn new_month(months: I) -> K{
1649  unsafe{
1650    let month=native::ka(-qtype::MONTH as I);
1651    (*month).value.int=months;
1652    month
1653  }
1654}
1655
1656/// Constructor of q date object. Relabeling of `kd`.
1657/// # Example
1658/// ```no_run
1659/// use kdb_c_api::*;
1660/// 
1661/// #[no_mangle]
1662/// pub extern "C" fn create_date(_: K) -> K{
1663///   // 1999.12.25
1664///   new_date(-7)
1665/// }
1666/// ```
1667/// ```q
1668/// q)nostradamus: `libc_api_examples 2: (`create_date; 1);
1669/// q)nostradamus[]
1670/// 1999.12.25
1671/// ```
1672#[inline]
1673pub fn new_date(days: I) -> K{
1674  unsafe{
1675    native::kd(days)
1676  }
1677}
1678
1679/// Constructor of q datetime object from the number of days since kdb+ epoch (`2000.01.01`). Relabeling of `kz`.
1680/// ```no_run
1681/// use kdb_c_api::*;
1682/// 
1683/// #[no_mangle]
1684/// pub extern "C" fn create_datetime(_: K) -> K{
1685///   // 2015.03.16T12:00:00:00.000
1686///   new_datetime(5553.5)
1687/// }
1688/// ```
1689/// ```q
1690/// q)omega_date: libc_api_examples 2: (`create_datetime; 1);
1691/// q)omega_date[]
1692/// 2015.03.16T12:00:00.000
1693/// ```
1694#[inline]
1695pub fn new_datetime(days: F) -> K{
1696  unsafe{
1697    native::kz(days)
1698  }
1699}
1700
1701/// Constructor of q timespan object from nanoseconds. Relabeling of `ktj`.
1702/// ```no_run
1703/// use kdb_c_api::*;
1704/// 
1705/// #[no_mangle]
1706/// pub extern "C" fn create_timespan2(_: K) -> K{
1707///   // -1D01:30:00.001234567
1708///   new_timespan(-91800001234567)
1709/// }
1710/// ```
1711/// ```q
1712/// q)duration: libc_api_examples 2: (`create_timespan2; 1);
1713/// q)duration[]
1714/// -1D01:30:00.001234567
1715/// ```
1716#[inline]
1717pub fn new_timespan(nanoseconds: J) -> K{
1718  unsafe{
1719    native::ktj(-qtype::TIMESPAN as I, nanoseconds)
1720  }
1721}
1722
1723/// Create a month object. This is a complememtal constructor of
1724///  missing minute type.
1725/// # Example
1726/// ```no_run
1727/// use kdb_c_api::*;
1728/// 
1729/// #[no_mangle]
1730/// pub extern "C" fn create_minute(_: K) -> K{
1731///   // 10:40
1732///   new_minute(640)
1733/// }
1734/// ```
1735/// ```q
1736/// q)minty: `libc_api_examples 2: (`create_minute; 1);
1737/// q)minty[]
1738/// 10:40
1739/// ```
1740#[inline]
1741pub fn new_minute(minutes: I) -> K{
1742  unsafe{
1743    let minute=native::ka(-qtype::MINUTE as I);
1744    (*minute).value.int=minutes;
1745    minute
1746  }
1747}
1748
1749/// Create a month object. This is a complememtal constructor of
1750///  missing second type.
1751/// # Example
1752/// ```no_run
1753/// use kdb_c_api::*;
1754/// 
1755/// #[no_mangle]
1756/// pub extern "C" fn create_second(_: K) -> K{
1757///   // -02:00:00
1758///   new_second(-7200)
1759/// }
1760/// ```
1761/// ```q
1762/// q)third: `libc_api_examples 2: (`create_second; 1);
1763/// q)third[]
1764/// -02:00:00
1765/// ```
1766#[inline]
1767pub fn new_second(seconds: I) -> K{
1768  unsafe{
1769    let second=native::ka(-qtype::SECOND as I);
1770    (*second).value.int=seconds;
1771    second
1772  }
1773}
1774
1775/// Constructor of q time object. Relabeling of `kt`.
1776/// # Example
1777/// ```no_run
1778/// use kdb_c_api::*;
1779/// 
1780/// #[no_mangle]
1781/// pub extern "C" fn create_time(_: K) -> K{
1782///   // -01:30:00.123
1783///   new_time(-5400123)
1784/// }
1785/// ```
1786/// ```q
1787/// q)ancient: libc_api_examples 2: (`create_time; 1);
1788/// q)ancient[]
1789/// -01:30:00.123
1790/// ```
1791#[inline]
1792pub fn new_time(milliseconds: I) -> K{
1793  unsafe{
1794    native::kt(milliseconds)
1795  }
1796}
1797
1798/// Constructor of q simple list.
1799/// # Example
1800/// See the example of [`new_dictionary`](fn.new_dictionary.html).
1801#[inline]
1802pub fn new_simple_list(qtype: i8, length: J) -> K{
1803  unsafe{
1804    native::ktn(qtype as I, length)
1805  }
1806}
1807
1808/// Constructor of q string object.
1809/// # Example
1810/// ```no_run
1811/// use kdb_c_api::*;
1812/// 
1813/// #[no_mangle]
1814/// pub extern "C" fn create_string(_: K) -> K{
1815///   new_string("this is a text.")
1816/// }
1817/// ```
1818/// ```q
1819/// q)text: libc_api_examples 2: (`create_string; 1);
1820/// q)text[]
1821/// "this is a text."
1822/// ```
1823#[inline]
1824pub fn new_string(string: &str) -> K{
1825  unsafe{
1826    native::kp(str_to_S!(string))
1827  }
1828}
1829
1830/// Constructor if q string object with a fixed length.
1831/// # Example
1832/// ```no_run
1833/// use kdb_c_api::*;
1834/// 
1835/// #[no_mangle]
1836/// pub extern "C" fn create_string2(_: K) -> K{
1837///   new_string_n("The meeting was too long and I felt it s...", 24)
1838/// }
1839/// ```
1840/// ```q
1841/// q)speak_inwardly: libc_api_examples 2: (`create_string2; 1);
1842/// q)speak_inwardly[]
1843/// "The meeting was too long"
1844/// ```
1845#[inline]
1846pub fn new_string_n(string: &str, length: J) -> K{
1847  unsafe{
1848    native::kpn(str_to_S!(string), length)
1849  }
1850}
1851
1852/// Constructor of q dictionary object.
1853/// # Example
1854/// ```no_run
1855/// use kdb_c_api::*;
1856/// 
1857/// #[no_mangle]
1858/// pub extern "C" fn create_dictionary() -> K{
1859///   let keys=new_simple_list(qtype::INT, 2);
1860///   keys.as_mut_slice::<I>()[0..2].copy_from_slice(&[0, 1]);
1861///   let values=new_simple_list(qtype::COMPOUND, 2);
1862///   let date_list=new_simple_list(qtype::DATE, 3);
1863///   // 2000.01.01 2000.01.02 2000.01.03
1864///   date_list.as_mut_slice::<I>()[0..3].copy_from_slice(&[0, 1, 2]);
1865///   let string=new_string("I'm afraid I would crash the application...");
1866///   values.as_mut_slice::<K>()[0..2].copy_from_slice(&[date_list, string]);
1867///   new_dictionary(keys, values)
1868/// }
1869/// ```
1870/// ```q
1871/// q)create_dictionary: `libc_api_examples 2: (`create_dictionary; 1);
1872/// q)create_dictionary[]
1873/// 0| 2000.01.01 2000.01.02 2000.01.03
1874/// 1| "I'm afraid I would crash the application..."
1875/// ```
1876#[inline]
1877pub fn new_dictionary(keys: K, values: K) -> K{
1878  unsafe{
1879    native::xD(keys, values)
1880  }
1881}
1882
1883/// Constructor of q error. The input must be null-terminated.
1884/// # Example
1885/// ```no_run
1886/// use kdb_c_api::*;
1887/// 
1888/// pub extern "C" fn thai_kick(_: K) -> K{
1889///   new_error("Thai kick unconditionally!!\0")
1890/// }
1891/// ```
1892/// ```q
1893/// q)monstrous: `libc_api_examples 2: (`thai_kick; 1);
1894/// q)monstrous[]
1895/// 'Thai kick unconditionally!!
1896/// [0]  monstrous[]
1897///      ^
1898/// ```
1899#[inline]
1900pub fn new_error(message: &str) -> K{
1901  unsafe{
1902    native::krr(null_terminated_str_to_const_S(message))
1903  }
1904}
1905
1906/// Similar to `new_error` but this function appends a system-error message to string `S` before passing it to internal `krr`.
1907///  The input must be null-terminated.
1908#[inline]
1909pub fn new_error_os(message: &str) -> K{
1910  unsafe{
1911    native::orr(null_terminated_str_to_const_S(message))
1912  }
1913}
1914
1915/// Convert an error object into usual K object which has the error string in the field `s`.
1916/// # Example
1917/// ```no_run
1918/// use kdb_c_api::*;
1919/// 
1920/// extern "C" fn no_panick(func: K, args: K) -> K{
1921///   let result=error_to_string(apply(func, args));
1922///   if result.get_type() == qtype::ERROR{
1923///     println!("FYI: {}", result.get_symbol().unwrap());
1924///     // Decrement reference count of the error object which is no longer used.
1925///     decrement_reference_count(result);
1926///     KNULL
1927///   }
1928///   else{
1929///     result
1930///   }
1931/// }
1932/// ```
1933/// ```q
1934/// q)chill: `libc_api_examples 2: (`no_panick; 2);
1935/// q)chill[$; ("J"; "42")]
1936/// success!
1937/// 42
1938/// q)chill[+; (1; `a)]
1939/// FYI: type
1940/// ```
1941#[inline]
1942pub fn error_to_string(error: K) -> K{
1943  unsafe{
1944    native::ee(error)
1945  }
1946}
1947
1948//%% Symbol %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
1949
1950/// Intern `n` chars from a char array.
1951///  Returns an interned char array and should be used to add char array to a symbol vector.
1952/// # Example
1953/// See the example of [`flip`](fn.flip.html).
1954#[inline]
1955pub fn internalize_n(string: S, n: I) -> S{
1956  unsafe{
1957    native::sn(string, n)
1958  }
1959}
1960
1961/// Intern a null-terminated char array.
1962///  Returns an interned char array and should be used to add char array to a symbol vector.
1963/// # Example
1964/// See the example of [`flip`](fn.flip.html).
1965#[inline]
1966pub fn internalize(string: S) -> S{
1967  unsafe{
1968    native::ss(string)
1969  }
1970}
1971
1972//%% Table %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
1973
1974/// Constructor of q table object from a q dictionary object.
1975/// # Note
1976/// Basically this is a `flip` command of q. Hence the value of the dictionary must have
1977///  lists as its elements.
1978/// ```no_run
1979/// use kdb_c_api::*;
1980/// 
1981/// #[no_mangle]
1982/// pub extern "C" fn create_table2(_: K) -> K{
1983///   // Build keys
1984///   let keys=new_simple_list(qtype::SYMBOL, 2);
1985///   let keys_slice=keys.as_mut_slice::<S>();
1986///   keys_slice[0]=internalize(str_to_S!("time"));
1987///   keys_slice[1]=internalize_n(str_to_S!("temperature_and_humidity"), 11);
1988///   
1989///   // Build values
1990///   let values=new_simple_list(qtype::COMPOUND, 2);
1991///   let time=new_simple_list(qtype::TIMESTAMP, 3);
1992///   // 2003.10.10D02:24:19.167018272 2006.05.24D06:16:49.419710368 2008.08.12D23:12:24.018691392
1993///   time.as_mut_slice::<J>().copy_from_slice(&[119067859167018272_i64, 201766609419710368, 271897944018691392]);
1994///   let temperature=new_simple_list(qtype::FLOAT, 3);
1995///   temperature.as_mut_slice::<F>().copy_from_slice(&[22.1_f64, 24.7, 30.5]);
1996///   values.as_mut_slice::<K>().copy_from_slice(&[time, temperature]);
1997///   
1998///   flip(new_dictionary(keys, values))
1999/// }
2000/// ```
2001/// ```q
2002/// q)climate_change: libc_api_examples 2: (`create_table2; 1);
2003/// q)climate_change[]
2004/// time                          temperature
2005/// -----------------------------------------
2006/// 2003.10.10D02:24:19.167018272 22.1       
2007/// 2006.05.24D06:16:49.419710368 24.7       
2008/// 2008.08.12D23:12:24.018691392 30.5    
2009/// ```
2010#[inline]
2011pub fn flip(dictionary: K) -> K{
2012  match unsafe{(*dictionary).qtype}{
2013    qtype::DICTIONARY => unsafe{native::xT(dictionary)},
2014    _ => unsafe{native::krr(null_terminated_str_to_const_S("not a dictionary\0"))}
2015  }
2016}
2017
2018/// Constructor of simple q table object from a q keyed table object.
2019/// # Example
2020/// ```no_run
2021/// use kdb_c_api::*;
2022/// 
2023/// #[no_mangle]
2024/// pub extern "C" fn create_table2(_: K) -> K{
2025///   // Build keys
2026///   let keys=new_simple_list(qtype::SYMBOL, 2);
2027///   let keys_slice=keys.as_mut_slice::<S>();
2028///   keys_slice[0]=internalize(str_to_S!("time"));
2029///   keys_slice[1]=internalize_n(str_to_S!("temperature_and_humidity"), 11);
2030///   
2031///   // Build values
2032///   let values=new_simple_list(qtype::COMPOUND, 2);
2033///   let time=new_simple_list(qtype::TIMESTAMP, 3);
2034///   // 2003.10.10D02:24:19.167018272 2006.05.24D06:16:49.419710368 2008.08.12D23:12:24.018691392
2035///   time.as_mut_slice::<J>().copy_from_slice(&[119067859167018272_i64, 201766609419710368, 271897944018691392]);
2036///   let temperature=new_simple_list(qtype::FLOAT, 3);
2037///   temperature.as_mut_slice::<F>().copy_from_slice(&[22.1_f64, 24.7, 30.5]);
2038///   values.as_mut_slice::<K>().copy_from_slice(&[time, temperature]);
2039///   
2040///   flip(new_dictionary(keys, values))
2041/// }
2042/// 
2043/// #[no_mangle]
2044/// pub extern "C" fn create_keyed_table(dummy: K) -> K{
2045///   enkey(create_table2(dummy), 1)
2046/// }
2047/// 
2048/// #[no_mangle]
2049/// pub extern "C" fn keyed_to_simple_table(dummy: K) -> K{
2050///   unkey(create_keyed_table(dummy))
2051/// }
2052/// ```
2053/// ```q
2054/// q)unkey: libc_api_examples 2: (`keyed_to_simple_table; 1);
2055/// q)unkey[]
2056/// time                          temperature
2057/// -----------------------------------------
2058/// 2003.10.10D02:24:19.167018272 22.1       
2059/// 2006.05.24D06:16:49.419710368 24.7       
2060/// 2008.08.12D23:12:24.018691392 30.5    
2061/// ```
2062#[inline]
2063pub fn unkey(keyed_table: K) -> K{
2064  match unsafe{(*keyed_table).qtype}{
2065    qtype::DICTIONARY => unsafe{native::ktd(keyed_table)},
2066    _ => unsafe{native::krr(null_terminated_str_to_const_S("not a keyed table\0"))}
2067  }
2068}
2069
2070/// Constructor of q keyed table object.
2071/// # Parameters
2072/// - `table`: q table object to be enkeyed.
2073/// - `n`: The number of key columns from the left.
2074/// # Example
2075/// ```no_run
2076/// use kdb_c_api::*;
2077/// 
2078/// #[no_mangle]
2079/// pub extern "C" fn create_table2(_: K) -> K{
2080///   // Build keys
2081///   let keys=new_simple_list(qtype::SYMBOL, 2);
2082///   let keys_slice=keys.as_mut_slice::<S>();
2083///   keys_slice[0]=internalize(str_to_S!("time"));
2084///   keys_slice[1]=internalize_n(str_to_S!("temperature_and_humidity"), 11);
2085///   
2086///   // Build values
2087///   let values=new_simple_list(qtype::COMPOUND, 2);
2088///   let time=new_simple_list(qtype::TIMESTAMP, 3);
2089///   // 2003.10.10D02:24:19.167018272 2006.05.24D06:16:49.419710368 2008.08.12D23:12:24.018691392
2090///   time.as_mut_slice::<J>().copy_from_slice(&[119067859167018272_i64, 201766609419710368, 271897944018691392]);
2091///   let temperature=new_simple_list(qtype::FLOAT, 3);
2092///   temperature.as_mut_slice::<F>().copy_from_slice(&[22.1_f64, 24.7, 30.5]);
2093///   values.as_mut_slice::<K>().copy_from_slice(&[time, temperature]);
2094///   
2095///   flip(new_dictionary(keys, values))
2096/// }
2097/// 
2098/// #[no_mangle]
2099/// pub extern "C" fn create_keyed_table(dummy: K) -> K{
2100///   enkey(create_table2(dummy), 1)
2101/// }
2102/// ```
2103/// ```q
2104/// q)locker: libc_api_examples 2: (`create_keyed_table; 1);
2105/// q)locker[]
2106/// time                         | temperature
2107/// -----------------------------| -----------
2108/// 2003.10.10D02:24:19.167018272| 22.1       
2109/// 2006.05.24D06:16:49.419710368| 24.7       
2110/// 2008.08.12D23:12:24.018691392| 30.5  
2111/// ```
2112#[inline]
2113pub fn enkey(table: K, n: J) -> K{ 
2114  match unsafe{(*table).qtype}{
2115    qtype::TABLE => unsafe{native::knt(n, table)},
2116    _ => unsafe{native::krr(null_terminated_str_to_const_S("not a table\0"))}
2117  }
2118}
2119
2120//%% Reference Count %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
2121
2122/// Decrement reference count of the q object. The decrement must be done when `k` function gets an error
2123///  object whose type is `qtype::ERROR` and when you created an object but do not intend to return it to
2124///  q side. See details on [the reference page](https://code.kx.com/q/interfaces/c-client-for-q/#managing-memory-and-reference-counting).
2125/// # Example
2126/// ```no_run
2127/// use kdb_c_api::*;
2128/// 
2129/// #[no_mangle]
2130/// pub extern "C" fn agriculture(_: K)->K{
2131///   // Produce an apple.
2132///   let fruit=new_symbol("apple");
2133///   // Sow the apple seed.
2134///   decrement_reference_count(fruit);
2135///   // Return null.
2136///   KNULL
2137/// }
2138/// ```
2139/// ```q
2140/// q)do_something: libc_api_examples 2: (`agriculture; 1);
2141/// q)do_something[]
2142/// q)
2143/// ```
2144#[inline]
2145pub fn decrement_reference_count(qobject: K) -> V{
2146  unsafe{native::r0(qobject)}
2147}
2148
2149/// Increment reference count of the q object. Increment must be done when you passed arguments
2150///  to Rust function and intends to return it to q side or when you pass some `K` objects to `k`
2151///  function and intend to use the argument after the call.
2152///  See details on [the reference page](https://code.kx.com/q/interfaces/c-client-for-q/#managing-memory-and-reference-counting).
2153/// # Example
2154/// ```no_run
2155/// use kdb_c_api::*;
2156/// 
2157/// fn eat(apple: K){
2158///   println!("おいしい!");
2159/// }
2160/// 
2161/// #[no_mangle]
2162/// pub extern "C" fn satisfy_5000_men(apple: K) -> K{
2163///   for _ in 0..10{
2164///     eat(apple);
2165///   }
2166///   unsafe{native::k(0, str_to_S!("eat"), increment_reference_count(apple), KNULL);}
2167///   increment_reference_count(apple)  
2168/// }
2169/// ```
2170/// ```q
2171/// q)eat:{[apple] show "Collect the clutter of apples!";}
2172/// q)bread_is_a_sermon: libc_api_examples 2: (`satisfy_5000_men; 1);
2173/// q)bread_is_a_sermon[`green_apple]
2174/// おいしい!
2175/// おいしい!
2176/// おいしい!
2177/// おいしい!
2178/// おいしい!
2179/// おいしい!
2180/// おいしい!
2181/// おいしい!
2182/// おいしい!
2183/// おいしい!
2184/// "Collect the clutter of apples!"
2185/// ```
2186#[inline]
2187pub fn increment_reference_count(qobject: K) -> K{
2188  unsafe{native::r1(qobject)}
2189}
2190
2191//%% Callback %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
2192
2193/// Remove callback from the associated kdb+ socket and call `kclose`.
2194///  Return null if the socket is invalid or not the one which had been registered by `sd1`.
2195/// # Note
2196/// A function which calls this function must be executed at the exit of the process.
2197#[inline]
2198pub fn destroy_socket(socket: I){
2199  unsafe{
2200    native::sd0(socket);
2201  }
2202}
2203
2204/// Remove callback from the associated kdb+ socket and call `kclose` if the given condition is satisfied.
2205///  Return null if the socket is invalid or not the one which had been registered by `sd1`.
2206/// # Note
2207/// A function which calls this function must be executed at the exit of the process.
2208#[inline]
2209pub fn destroy_socket_if(socket: I, condition: bool){
2210  unsafe{
2211    native::sd0x(socket, condition as I);
2212  }
2213}
2214
2215/// Register callback to the associated kdb+ socket.
2216/// ```no_run
2217/// use kdb_c_api::*;
2218/// 
2219/// static mut PIPE:[I; 2]=[-1, -1];
2220///
2221/// // Callback for some message queue.
2222/// extern "C" fn callback(socket: I)->K{
2223///   let mut buffer: [K; 1]=[0 as K];
2224///   unsafe{libc::read(socket, buffer.as_mut_ptr() as *mut V, 8)};
2225///   // Call `shout` function on q side with the received data.
2226///   let result=error_to_string(unsafe{native::k(0, str_to_S!("shout"), buffer[0], KNULL)});
2227///   if result.get_type() == qtype::ERROR{
2228///     eprintln!("Execution error: {}", result.get_symbol().unwrap());
2229///     decrement_reference_count(result);
2230///   };
2231///   KNULL
2232/// }
2233/// 
2234/// #[no_mangle]
2235/// pub extern "C" fn plumber(_: K) -> K{
2236///   if 0 != unsafe{libc::pipe(PIPE.as_mut_ptr())}{
2237///     return new_error("Failed to create pipe\0");
2238///   }
2239///   if KNULL == register_callback(unsafe{PIPE[0]}, callback){
2240///     return new_error("Failed to register callback\0");
2241///   }
2242///   // Lock symbol in a worker thread.
2243///   pin_symbol();
2244///   let handle=std::thread::spawn(move ||{
2245///     let mut precious=new_simple_list(qtype::SYMBOL, 3);
2246///     let precious_array=precious.as_mut_slice::<S>();
2247///     precious_array[0]=internalize(null_terminated_str_to_S("belief\0"));
2248///     precious_array[1]=internalize(null_terminated_str_to_S("love\0"));
2249///     precious_array[2]=internalize(null_terminated_str_to_S("hope\0"));
2250///     unsafe{libc::write(PIPE[1], std::mem::transmute::<*mut K, *mut V>(&mut precious), 8)};
2251///   });
2252///   handle.join().unwrap();
2253///   unpin_symbol();
2254///   KNULL
2255/// }
2256/// ```
2257/// ```q
2258/// q)shout:{[precious] -1 "What are the three largest elements?: ", .Q.s1 precious;};
2259/// q)fall_into_pipe: `libc_api_example 2: (`plumber; 1);
2260/// q)fall_into_pipe[]
2261/// What are the three largest elements?: `belief`love`hope
2262/// ```
2263#[inline]
2264pub fn register_callback(socket: I, function: extern fn(I) -> K) -> K{
2265  unsafe{
2266    native::sd1(socket, function)
2267  }
2268}
2269
2270//%% Miscellaneous %%//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv/
2271
2272/// Apply a function to q list object `.[func; args]`.
2273/// # Example
2274/// See the example of [`error_to_string`](fn.error_to_string.html).
2275#[inline]
2276pub fn apply(func: K, args: K) -> K{
2277  unsafe{native::dot(func, args)}
2278}
2279
2280/// Lock a location of internalized symbol in remote threads.
2281///  Returns the previously set value.
2282/// # Example
2283/// See the example of [`register_callback`](fn.register_callback.html).
2284#[inline]
2285pub fn pin_symbol() -> I{
2286  unsafe{
2287    native::setm(1)
2288  }
2289}
2290
2291/// Unlock a location of internalized symbol in remote threads. 
2292/// # Example
2293/// See the example of [`register_callback`](fn.register_callback.html).
2294#[inline]
2295pub fn unpin_symbol() -> I{
2296  unsafe{
2297    native::setm(0)
2298  }
2299}
2300
2301/// Drop Rust object inside q. Passed as the first element of a foreign object.
2302/// # Parameters
2303/// - `obj`: List of (function to free the object; foreign object).
2304/// # Example
2305/// See the example of [`load_as_q_function`](fn.load_as_q_function.html).
2306pub extern "C" fn drop_q_object(obj: K) -> K{
2307  let obj_slice=obj.as_mut_slice::<K>();
2308  // Take ownership of `K` object from a raw pointer and drop at the end of this scope.
2309  unsafe{Box::from_raw(obj_slice[1])};
2310  // Fill the list with null.
2311  obj_slice.copy_from_slice(&[KNULL, KNULL]);
2312  obj
2313}
2314
2315/// Load C function as a q function (`K` object).
2316/// # Parameters
2317/// - `func`: A function takes a C function that would take `n` `K` objects as arguments and returns a `K` object.
2318/// - `n`: The number of arguments for the function.
2319/// # Example
2320/// ```no_run
2321/// use kdb_c_api::*;
2322/// 
2323/// #[derive(Clone, Debug)]
2324/// struct Planet{
2325///   name: String,
2326///   population: i64,
2327///   water: bool
2328/// }
2329/// 
2330/// impl Planet{
2331///   /// Constructor of `Planet`.
2332///   fn new(name: &str, population: i64, water: bool) -> Self{
2333///     Planet{
2334///       name: name.to_string(),
2335///       population: population,
2336///       water: water
2337///     }
2338///   }
2339/// 
2340///   /// Description of the planet.
2341///   fn description(&self)->String{
2342///     let mut desc=format!("The planet {} is a beautiful planet where {} people reside.", self.name, self.population);
2343///     if self.water{
2344///       desc+=" Furthermore water is flowing on the surface of it.";
2345///     }
2346///     desc
2347///   }
2348/// }
2349/// 
2350/// /// Example of `set_type`.
2351/// #[no_mangle]
2352/// pub extern "C" fn eden(_: K) -> K{
2353///   let earth=Planet::new("earth", 7500_000_000, true);
2354///   let foreign=new_simple_list(qtype::COMPOUND, 2);
2355///   let foreign_slice=foreign.as_mut_slice::<K>();
2356///   foreign_slice[0]=drop_q_object as K;
2357///   foreign_slice[1]=Box::into_raw(Box::new(earth)) as K;
2358///   // Set as foreign object.
2359///   foreign.set_type(qtype::FOREIGN);
2360///   foreign
2361/// }
2362/// 
2363/// extern "C" fn invade(planet: K, action: K) -> K{
2364///   let obj=planet.as_mut_slice::<K>()[1] as *const Planet;
2365///   println!("{:?}", unsafe{obj.as_ref()}.unwrap());
2366///   let mut desc=unsafe{obj.as_ref()}.unwrap().description();
2367///   if action.get_bool().unwrap(){
2368///     desc+=" You shall not curse what God blessed.";
2369///   }
2370///   else{
2371///     desc+=" I perceived I could find favor of God by blessing them.";
2372///   }
2373///   new_string(&desc)
2374/// }
2375/// 
2376/// /// Example of `load_as_q_function`.
2377/// #[no_mangle]
2378/// pub extern "C" fn probe(planet: K)->K{
2379///   // Return monadic function
2380///   unsafe{native::k(0, str_to_S!("{[func; planet] func[planet]}"), load_as_q_function(invade as *const V, 2), planet, KNULL)}
2381/// }
2382/// ```
2383/// ```q
2384/// q)eden: libc_api_example 2: (`eden; 1);
2385/// q)earth: eden[]
2386/// q)type earth
2387/// 112h
2388/// q)probe: libc_api_example 2: (`probe; 1);
2389/// q)invade: probe[earth];
2390/// q)\c 25 200
2391/// q)invade 1b
2392/// "The planet earth is a beautiful planet where 7500000000 people reside. Furthermore water is flowing on the surface of it. You shall not curse what God blessed."
2393/// ```
2394#[inline]
2395pub fn load_as_q_function(func: *const V, n: J) -> K{
2396  unsafe{
2397    native::dl(func, n)
2398  }
2399}
2400
2401/// Convert ymd to the number of days from `2000.01.01`.
2402/// # Example
2403/// ```no_run
2404/// use kdb_c_api::*;
2405/// 
2406/// fn main(){
2407/// 
2408///   let days=ymd_to_days(2020, 4, 1);
2409///   assert_eq!(days, 7396);
2410/// 
2411/// }
2412/// ```
2413#[inline]
2414pub fn ymd_to_days(year: I, month: I, date:I) -> I{
2415  unsafe{
2416    native::ymd(year, month, date)
2417  }
2418}
2419
2420/// Convert the number of days from `2000.01.01` to a number expressed as `yyyymmdd`.
2421/// # Example
2422/// ```no_run
2423/// use kdb_c_api::*;
2424/// 
2425/// fn main(){
2426/// 
2427///   let number=days_to_ymd(7396);
2428///   assert_eq!(number, 20200401);
2429/// 
2430/// }
2431/// ```
2432#[inline]
2433pub fn days_to_ymd(days: I) -> I{
2434  unsafe{
2435    native::dj(days)
2436  }
2437}