Skip to content

Commit

Permalink
Add inline Var and Num construction
Browse files Browse the repository at this point in the history
- Support reading new license key format
- Deprecate request_offline_key
- Add get_license_key
  • Loading branch information
benruijl committed Jun 5, 2024
1 parent 98a503b commit 99b9001
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 70 deletions.
14 changes: 6 additions & 8 deletions src/api/cpp.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::ffi::{c_char, CStr, CString};
use std::ffi::{c_char, CStr};
use std::fmt::Write;
use std::os::raw::c_ulonglong;
use std::sync::Arc;
Expand Down Expand Up @@ -79,13 +79,11 @@ unsafe extern "C" fn request_trial_license(
/// Get a license key for offline use, generated from a licensed Symbolica session. The key will remain valid for 24 hours.
/// The key is written into `key`, which must be a buffer of at least 100 bytes.
#[no_mangle]
unsafe extern "C" fn get_offline_license_key(key: *mut c_char) -> bool {
match LicenseManager::get_offline_license_key() {
Ok(k) => {
let cs = CString::new(k).unwrap();
key.copy_from_nonoverlapping(cs.as_ptr(), cs.as_bytes_with_nul().len());
true
}
unsafe extern "C" fn get_license_key(email: *const c_char) -> bool {
let email = unsafe { CStr::from_ptr(email) }.to_str().unwrap();

match LicenseManager::get_license_key(email) {
Ok(()) => true,
Err(e) => {
eprintln!("{}", e);
false
Expand Down
10 changes: 6 additions & 4 deletions src/api/python.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ fn symbolica(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(request_hobbyist_license, m)?)?;
m.add_function(wrap_pyfunction!(request_trial_license, m)?)?;
m.add_function(wrap_pyfunction!(request_sublicense, m)?)?;
m.add_function(wrap_pyfunction!(get_offline_license_key, m)?)?;
m.add_function(wrap_pyfunction!(get_license_key, m)?)?;

m.add("__version__", env!("CARGO_PKG_VERSION"))?;

Expand Down Expand Up @@ -147,10 +147,12 @@ fn request_sublicense(
.map_err(exceptions::PyConnectionError::new_err)
}

/// Get a license key for offline use, generated from a licensed Symbolica session. The key will remain valid for 24 hours.
/// Get the license key for the account registered with the provided email address.
#[pyfunction]
fn get_offline_license_key() -> PyResult<String> {
LicenseManager::get_offline_license_key().map_err(exceptions::PyValueError::new_err)
fn get_license_key(email: String) -> PyResult<()> {
LicenseManager::get_license_key(&email)
.map(|_| println!("A license key was sent to your e-mail address."))
.map_err(exceptions::PyConnectionError::new_err)
}

/// Specifies the type of the atom.
Expand Down
14 changes: 14 additions & 0 deletions src/atom.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
mod coefficient;
pub mod representation;

use representation::{InlineNum, InlineVar};

use crate::{
coefficient::Coefficient,
parser::Token,
Expand Down Expand Up @@ -203,6 +205,18 @@ impl<'a> AsAtomView<'a> for AtomView<'a> {
}
}

impl<'a> AsAtomView<'a> for &'a InlineVar {
fn as_atom_view(self) -> AtomView<'a> {
self.as_view()
}
}

impl<'a> AsAtomView<'a> for &'a InlineNum {
fn as_atom_view(self) -> AtomView<'a> {
self.as_view()
}
}

impl<'a, T: AsRef<Atom>> AsAtomView<'a> for &'a T {
fn as_atom_view(self) -> AtomView<'a> {
self.as_ref().as_view()
Expand Down
92 changes: 92 additions & 0 deletions src/atom/representation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,98 @@ const ZERO_DATA: [u8; 3] = [NUM_ID, 1, 0];

pub type RawAtom = Vec<u8>;

/// An inline variable.
pub struct InlineVar {
data: [u8; 16],
size: u8,
}

impl InlineVar {
/// Create a new inline variable.
pub fn new(symbol: Symbol) -> InlineVar {
let mut data = [0; 16];
let mut flags = VAR_ID;
match symbol.wildcard_level {
0 => {}
1 => flags |= VAR_WILDCARD_LEVEL_1,
2 => flags |= VAR_WILDCARD_LEVEL_2,
_ => flags |= VAR_WILDCARD_LEVEL_3,
}

if symbol.is_symmetric {
flags |= FUN_SYMMETRIC_FLAG;
}
if symbol.is_linear {
flags |= FUN_LINEAR_FLAG;
}
if symbol.is_antisymmetric {
flags |= VAR_ANTISYMMETRIC_FLAG;
}

data[0] = flags;

let size = 1 + (symbol.id as u64, 1).get_packed_size() as u8;
(symbol.id as u64, 1).write_packed_fixed(&mut data[1..]);
InlineVar { data, size }
}

pub fn get_data(&self) -> &[u8] {
&self.data[..self.size as usize]
}

pub fn as_var_view(&self) -> VarView {
VarView {
data: &self.data[..self.size as usize],
}
}

pub fn as_view(&self) -> AtomView {
AtomView::Var(VarView {
data: &self.data[..self.size as usize],
})
}
}

impl From<Symbol> for InlineVar {
fn from(symbol: Symbol) -> InlineVar {
InlineVar::new(symbol)
}
}

/// An inline rational number that has 64-bit components.
pub struct InlineNum {
data: [u8; 24],
size: u8,
}

impl InlineNum {
/// Create a new inline number. The gcd of num and den should be 1.
pub fn new(num: i64, den: i64) -> InlineNum {
let mut data = [0; 24];
data[0] = NUM_ID;

let size = 1 + (num, den).get_packed_size() as u8;
(num, den).write_packed_fixed(&mut data[1..]);
InlineNum { data, size }
}

pub fn get_data(&self) -> &[u8] {
&self.data[..self.size as usize]
}

pub fn as_num_view(&self) -> NumView {
NumView {
data: &self.data[..self.size as usize],
}
}

pub fn as_view(&self) -> AtomView {
AtomView::Num(NumView {
data: &self.data[..self.size as usize],
})
}
}

impl Atom {
/// Read from a binary stream. The format is the byte-length first
/// followed by the data.
Expand Down
Loading

0 comments on commit 99b9001

Please sign in to comment.