我正在构建一个JavaScript库,该库在Ocaml中实现,并使用js_of_ocaml
编译为JavaScript。
我的Ocaml函数之一返回带有二进制数据的public partial class Booking
{
public Booking()
{
BookingDetail = new HashSet<BookingDetail>();
Invoice = new HashSet<Invoice>();
}
[Column(TypeName = "bigint(20)")]
public long Id { get; set; }
[Required]
[Column(TypeName = "varchar(50)")]
public string TempId { get; set; }
[InverseProperty("Booking")]
public ICollection<BookingDetail> BookingDetail { get; set; }
[InverseProperty("Booking")]
public ICollection<Invoice> Invoice { get; set; }
}
public partial class BookingDetail
{
public BookingDetail()
{
Invoice = new HashSet<Invoice>();
}
[Column(TypeName = "bigint(20)")]
public long Id { get; set; }
[Required]
[Column(TypeName = "varchar(50)")]
public string CreatedBy { get; set; }
[Column(TypeName = "datetime")]
public DateTime CreatedOn { get; set; }
[Required]
[Column(TypeName = "varchar(50)")]
public string ModifiedBy { get; set; }
[Column(TypeName = "datetime")]
public DateTime ModifiedOn { get; set; }
[Column(TypeName = "bigint(20)")]
public long BookingId { get; set; }
[ForeignKey("BookingId")]
[InverseProperty("BookingDetail")]
public Booking Booking { get; set; }
[InverseProperty("BookingDetail")]
public ICollection<Invoice> Invoice { get; set; }
}
public partial class Invoice
{
[Column(TypeName = "bigint(20)")]
public long Id { get; set; }
[Column(TypeName = "bigint(20)")]
public long BookingId { get; set; }
[Column(TypeName = "bigint(20)")]
public long BookingDetailId { get; set; }
[Column(TypeName = "datetime")]
public DateTime CreatedOn { get; set; }
[Column(TypeName = "datetime")]
public DateTime CreatedBy { get; set; }
[Column(TypeName = "datetime")]
public DateTime ModifiedOn { get; set; }
[Required]
[Column(TypeName = "varchar(50)")]
public string ModifiedBy { get; set; }
[ForeignKey("BookingId")]
[InverseProperty("Invoice")]
public Booking Booking { get; set; }
[ForeignKey("BookingDetailId")]
[InverseProperty("Invoice")]
public BookingDetail BookingDetail { get; set; }
}
public class Class1
{
HMEBookingContext context = new HMEBookingContext();
#region declarations
public long BookingId { get; set; }
public string CustomerEmailId { get; set; } = "admin@holidayme.com";
#endregion
Random rnd = new Random();
public void insert()
{
try
{
Booking booking = new Booking();
booking.TempBookingId = BookingRefNumber.ToString();
var bookingDetail = new List<BookingDetail>();
BookingDetail detail = new BookingDetail();
detail.CreatedBy = CustomerEmailId;
detail.CreatedOn = DateTime.Now;
detail.ModifiedBy = "1";
detail.ModifiedOn = DateTime.UtcNow;
detail.BookingStatusId = 1;
var invoices = new List<Invoice>();
Invoice invoice = new Invoice();
invoices.Add(invoice);
detail.Invoice = invoices;
bookingDetail.Add(detail);
booking.BookingDetail = bookingDetail;
context.Add(booking);
context.SaveChanges(true);
BookingId=booking.Id
}
catch(DbUpdateException upd)
{
}
catch(Exception ex)
{
}
}
}
。我如何使用string
作为js_of_ocaml
来公开它?
答案 0 :(得分:7)
当您编译为javascript时,在string
s中处理二进制数据非常容易出错!
根本原因是对js_of_ocaml
的选择存在疑问:
因为javascript字符串是用UTF16编码的,而OCaml的字符串是(隐式的)以UTF8编码的,所以js_of_ocaml
试图在2之间进行导航。因此,当它遇到代码大于127的“字符”时,{{1} }如果将其转换为原始二进制数据,那将是一场灾难!
解决方案是操纵js_of_ocaml
而不是bigstring
。
大字符串在原始OCaml中是string
,但是越来越多的库将它们作为别名。
尤其是,它们是(char, Bigarray.int8_unsigned_elt, Bigarray.c_layout)
Bigarray.Array1.t
中的Typed_array.Bigstring.t
(您可以在其中看到要与js_of_ocaml
进行转换的函数)
如果您的函数在用javascript编译后确实可以通过魔术作用于字符串,则在大字符串和字符串之间的多个位置都有转换函数。
例如,bigstring库:http://c-cube.github.io/ocaml-bigstring/,但这些功能在lwt的ArrayBuffer
您可以在同一主题上看到另一个问题(包括使用javascript处理OCaml字符串而不用Lwt_bytes
完全触摸它们的方式)
https://discuss.ocaml.org/t/handling-binary-data-in-ocaml-and-javascript/1519