-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathPyString.cs
More file actions
135 lines (120 loc) · 4.25 KB
/
PyString.cs
File metadata and controls
135 lines (120 loc) · 4.25 KB
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
using System;
using System.IO;
using System.Text;
namespace eveMarshal
{
public class PyString : PyObject
{
public string Value { get; private set; }
public byte[] Raw { get; private set; }
public bool ForceUTF8 { get; private set; }
public PyString()
: base(PyObjectType.String)
{
}
public PyString(string data)
: base(PyObjectType.String)
{
Raw = Encoding.ASCII.GetBytes(data);
Value = data;
}
public PyString(string data, bool forceUTF8)
: base(PyObjectType.String)
{
Raw = Encoding.UTF8.GetBytes(data);
Value = data;
ForceUTF8 = forceUTF8;
}
public PyString(byte[] raw)
: base(PyObjectType.String)
{
Raw = raw;
Value = Encoding.ASCII.GetString(raw);
}
private void Update(string data)
{
Raw = Encoding.ASCII.GetBytes(data);
Value = data;
}
private void Update(byte[] data, bool isUnicode = false)
{
Raw = data;
Value = isUnicode ? Encoding.Unicode.GetString(Raw) : Encoding.ASCII.GetString(Raw);
}
private void UpdateUTF8(byte[] data)
{
Raw = data;
Value = Encoding.UTF8.GetString(Raw);
}
public override void Decode(Unmarshal context, MarshalOpcode op, BinaryReader source)
{
if (op == MarshalOpcode.StringEmpty)
Update(new byte[0]);
else if (op == MarshalOpcode.StringChar)
Update(new[]{source.ReadByte()});
else if (op == MarshalOpcode.WStringUTF8)
UpdateUTF8(source.ReadBytes((int)source.ReadSizeEx()));
else if (op == MarshalOpcode.WStringUCS2Char)
Update(new[]{source.ReadByte(), source.ReadByte()}, true);
else if (op == MarshalOpcode.WStringEmpty)
Update(new byte[0]);
else if (op == MarshalOpcode.WStringUCS2)
Update(source.ReadBytes((int)source.ReadSizeEx()), true);
else if (op == MarshalOpcode.StringShort)
Update(source.ReadBytes(source.ReadByte()));
else if (op == MarshalOpcode.StringLong)
Update(source.ReadBytes((int)source.ReadSizeEx()));
else if (op == MarshalOpcode.StringTable)
{
byte index = source.ReadByte();
Update(StringTable.Entries[index-1]);
}
}
protected override void EncodeInternal(BinaryWriter output)
{
if (ForceUTF8)
{
output.WriteOpcode(MarshalOpcode.WStringUTF8);
output.WriteSizeEx(Raw.Length);
output.Write(Raw);
return;
}
int idx;
if (Raw.Length == 0)
output.WriteOpcode(MarshalOpcode.StringEmpty);
else if (Raw.Length == 1)
{
output.WriteOpcode(MarshalOpcode.StringChar);
output.Write(Raw[0]);
}
else if ((idx = StringTable.Entries.IndexOf(Value)) >= 0)
{
output.WriteOpcode(MarshalOpcode.StringTable);
output.Write((byte)(idx+1));
}
else
{
/*if (Raw.Length < 0xFF)
{
output.WriteOpcode(MarshalOpcode.StringShort);
output.Write((byte)Raw.Length);
output.Write(Raw);
}
else*/
{
output.WriteOpcode(MarshalOpcode.StringLong);
output.WriteSizeEx(Raw.Length);
output.Write(Raw);
}
}
}
public override string ToString()
{
if (Value.Length <= 0)
return "<empty string>";
if (char.IsLetterOrDigit(Value[0]))
return "<" + Value + ">";
return "<" + BitConverter.ToString(Raw) + ">";
}
}
}