/// <summary> /// Is a slot name valid. /// </summary> /// <param name="slotName">the name of the slot</param> /// <returns>whether a slot name is present in the object</returns> public bool HasSlot(string slotName) { using (var s = new ProtectedPointer(Engine, GetFunction <Rf_mkString>()(InternalString.NativeUtf8FromString(slotName)))) { return(this.GetFunction <R_has_slot>()(this.DangerousGetHandle(), s)); } }
/// <summary> /// Gets the element at the specified index. /// </summary> /// <remarks>Used for pre-R 3.5 </remarks> /// <param name="index">The zero-based index of the element to get.</param> /// <returns>The element at the specified index.</returns> protected override string GetValue(int index) { int offset = GetOffset(index); IntPtr pointerItem = Marshal.ReadIntPtr(DataPointer, offset); if (pointerItem == Engine.NaStringPointer) { return(null); } IntPtr pointer = IntPtr.Add(pointerItem, Marshal.SizeOf(typeof(Internals.PreALTREP.VECTOR_SEXPREC))); return(InternalString.StringFromNativeUtf8(pointer)); }
private SymbolicExpression Parse(string statement, StringBuilder incompleteStatement, REnvironment environment = null) { incompleteStatement.Append(statement); var s = GetFunction <Rf_mkString>()(InternalString.NativeUtf8FromString(incompleteStatement.ToString())); string errorStatement; using (new ProtectedPointer(this, s)) { ParseStatus status; var vector = new ExpressionVector(this, GetFunction <R_ParseVector>()(s, -1, out status, NilValue.DangerousGetHandle())); switch (status) { case ParseStatus.OK: incompleteStatement.Clear(); if (vector.Length == 0) { return(null); } using (new ProtectedPointer(vector)) { SymbolicExpression result; if (!vector.First().TryEvaluate((environment == null) ? GlobalEnvironment : environment, out result)) { throw new EvaluationException(LastErrorMessage); } if (AutoPrint && !result.IsInvalid && GetVisible()) { GetFunction <Rf_PrintValue>()(result.DangerousGetHandle()); } return(result); } case ParseStatus.Incomplete: return(null); case ParseStatus.Error: // TODO: use LastErrorMessage if below is just a subset var parseErrorMsg = this.GetAnsiString("R_ParseErrorMsg"); errorStatement = incompleteStatement.ToString(); incompleteStatement.Clear(); throw new ParseException(status, errorStatement, parseErrorMsg); default: errorStatement = incompleteStatement.ToString(); incompleteStatement.Clear(); throw new ParseException(status, errorStatement, ""); } } }
private string ReadString(IntPtr pointer, int offset) { pointer = Marshal.ReadIntPtr(pointer, offset); if (Engine.Compatibility == REngine.CompatibilityMode.ALTREP) { pointer = GetFunction <DATAPTR_OR_NULL>()(pointer); } else { pointer = IntPtr.Add(pointer, Marshal.SizeOf(Engine.GetVectorSexprecType())); } return(InternalString.StringFromNativeUtf8(pointer)); }
/// <summary> /// Gets all value names. /// </summary> /// <returns>The names of attributes</returns> public string[] GetAttributeNames() { int length = this.GetFunction <Rf_length>()(this.sexp.attrib); var names = new string[length]; IntPtr pointer = this.sexp.attrib; for (int index = 0; index < length; index++) { var node = (SEXPREC)Marshal.PtrToStructure(pointer, typeof(SEXPREC)); var attribute = (SEXPREC)Marshal.PtrToStructure(node.listsxp.tagval, typeof(SEXPREC)); IntPtr name = attribute.symsxp.pname; names[index] = new InternalString(Engine, name); pointer = node.listsxp.cdrval; } return(names); }
/// <summary> /// Gets the element at the specified index. /// </summary> /// <remarks>Used for R 3.5 and higher, to account for ALTREP objects</remarks> /// <param name="index">The zero-based index of the element to get.</param> /// <returns>The element at the specified index.</returns> protected override string GetValueAltRep(int index) { // To work with ALTREP (introduced in R 3.5.0) and non-ALTREP objects, we will get strings // via STRING_ELT, instead of offseting the DataPointer. This lets R manage the details of // ALTREP conversion for us. IntPtr objPointer = GetFunction <STRING_ELT>()(this.DangerousGetHandle(), (IntPtr)index); if (objPointer == Engine.NaStringPointer) { return(null); } IntPtr stringData = GetFunction <DATAPTR_OR_NULL>()(objPointer); return(InternalString.StringFromNativeUtf8(stringData)); }
/// <summary> /// Gets the element at the specified index. /// </summary> /// <remarks>Used for R 3.5 and higher, to account for ALTREP objects</remarks> /// <param name="index">The zero-based index of the element to get.</param> /// <returns>The element at the specified index.</returns> protected override string GetValueAltRep(int index) { // To work with ALTREP (introduced in R 3.5.0) and non-ALTREP objects, we will get strings // via STRING_ELT, instead of offseting the DataPointer. This lets R manage the details of // ALTREP conversion for us. IntPtr objPointer = GetFunction <STRING_ELT>()(this.DangerousGetHandle(), (ulong)index); if (objPointer == Engine.NaStringPointer) { return(null); } IntPtr stringData = IntPtr.Add(objPointer, Marshal.SizeOf(typeof(Internals.ALTREP.VECTOR_SEXPREC))); return(InternalString.StringFromNativeUtf8(stringData)); }
/// <summary> /// Gets all value names. /// </summary> /// <returns>The names of attributes</returns> public string[] GetAttributeNames() { int length = this.GetFunction <Rf_length>()(this.sexp.attrib); var names = new string[length]; IntPtr pointer = this.sexp.attrib; var sexprecType = engine.GetSEXPRECType(); for (int index = 0; index < length; index++) { dynamic node = Convert.ChangeType(Marshal.PtrToStructure(pointer, sexprecType), sexprecType); var attribute = Convert.ChangeType(Marshal.PtrToStructure(node.listsxp.tagval, sexprecType), sexprecType); IntPtr name = attribute.symsxp.pname; names[index] = new InternalString(Engine, name); pointer = node.listsxp.cdrval; } return(names); }
/// <summary> /// 通过给定的文件流,判断文件的编码类型 /// </summary> /// <param name="ss">字节流</param> /// <returns>文件的编码类型</returns> public static System.Text.Encoding GetType(byte[] ss) { byte[] unicode = new byte[] { 0xFF, 0xFE, 0x41 }; byte[] unicodeBig = new byte[] { 0xFE, 0xFF, 0x00 }; byte[] utf8 = new byte[] { 0xEF, 0xBB, 0xBF }; //带BOM sbyte[] tsbyte = (sbyte[])(Array)ss; Encoding reVal = Encoding.Default; if (InternalString.UTF8Probability(tsbyte) > 0 || (ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF)) { reVal = Encoding.UTF8; } else if (ss[0] == 0xFE && ss[1] == 0xFF && ss[2] == 0x00) { reVal = Encoding.BigEndianUnicode; } else if (ss[0] == 0xFF && ss[1] == 0xFE && ss[2] == 0x41) { reVal = Encoding.Unicode; } return(reVal); }
private string ReadString(IntPtr pointer, int offset) { pointer = Marshal.ReadIntPtr(pointer, offset); pointer = IntPtr.Add(pointer, Marshal.SizeOf(Engine.GetVectorSexprecType())); return(InternalString.StringFromNativeUtf8(pointer)); }
private string ReadString(IntPtr pointer, int offset) { pointer = Marshal.ReadIntPtr(pointer, offset); pointer = IntPtr.Add(pointer, Marshal.SizeOf(typeof(VECTOR_SEXPREC))); return(InternalString.StringFromNativeUtf8(pointer)); }
/// <summary> /// Gets/sets the value of a slot /// </summary> /// <param name="name"></param> /// <returns></returns> public SymbolicExpression this[string name] { get { checkSlotName(name); IntPtr slotValue; using (var s = new ProtectedPointer(Engine, GetFunction <Rf_mkString>()(InternalString.NativeUtf8FromString(name)))) { slotValue = this.GetFunction <R_do_slot>()(this.DangerousGetHandle(), s); } return(new SymbolicExpression(Engine, slotValue)); } set { checkSlotName(name); using (var s = new ProtectedPointer(Engine, GetFunction <Rf_mkString>()(InternalString.NativeUtf8FromString(name)))) { using (new ProtectedPointer(this)) { this.GetFunction <R_do_slot_assign>()(this.DangerousGetHandle(), s, value.DangerousGetHandle()); } } } }