-
Notifications
You must be signed in to change notification settings - Fork 3
/
PyObject.cs
137 lines (113 loc) · 3.61 KB
/
PyObject.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
using System;
using System.IO;
namespace eveMarshal
{
public abstract class PyObject
{
/// <summary>
/// Enables recording RawSource and RawOffset data. More than doubles memory footprint of eveMarshal.
/// </summary>
public static bool EnableInspection;
public byte[] RawSource { get; set; }
public long RawOffset { get; set; }
public PyObjectType Type
{
get; private set;
}
protected PyObject(PyObjectType type)
{
Type = type;
}
public abstract void Decode(Unmarshal context, MarshalOpcode op, BinaryReader source);
public void Encode(BinaryWriter output)
{
RawOffset = output.BaseStream.Position;
EncodeInternal(output);
if (EnableInspection)
{
var postOffset = output.BaseStream.Position;
output.BaseStream.Seek(RawOffset, SeekOrigin.Begin);
RawSource = new byte[postOffset - RawOffset];
output.BaseStream.Read(RawSource, 0, (int)(postOffset - RawOffset));
}
}
protected abstract void EncodeInternal(BinaryWriter output);
public T As<T>() where T : PyObject
{
return this as T;
}
public virtual PyObject this[int index]
{
get
{
throw new NotSupportedException("Can't subscript a PyObject");
}
set
{
throw new NotSupportedException("Can't subscript a PyObject");
}
}
public virtual PyObject this[string key]
{
get
{
throw new NotSupportedException("Can't subscript a PyObject");
}
set
{
throw new NotSupportedException("Can't subscript a PyObject");
}
}
public double FloatValue
{
get
{
if (this is PyFloat)
return (this as PyFloat).Value;
return IntValue;
}
}
public string StringValue
{
get
{
if (this is PyString)
return (this as PyString).Value;
if (this is PyToken)
return (this as PyToken).Token;
return null;
}
}
public long IntValue
{
get
{
if (this is PyNone)
return 0;
if (this is PyFloat)
return (long)As<PyFloat>().Value;
if (this is PyBool)
return As<PyBool>().Value ? 1 : 0;
if (this is PyInt)
return As<PyInt>().Value;
if (this is PyLongLong)
return As<PyLongLong>().Value;
if (this is PyIntegerVar)
{
var iv = this as PyIntegerVar;
if (iv.Raw.Length <= 8)
{
var copy = new byte[8];
iv.Raw.CopyTo(copy, 0);
return BitConverter.ToInt64(copy, 0);
}
}
throw new InvalidDataException("Not an integer");
}
}
public override string ToString()
{
return "<" + Type + ">";
}
}
}