1
/* (c) Gustav Hartvigsson 2020
5
0) You is granted to copy, redistrubute, modify, redistrubute
6
modified copies of the software, in any shape or form.
7
1) You are not obligated to give credit the original author(s) of
8
the sofware, but it would be cool of you if you did.
9
2) You are allowed to removed the copyright notice if you want to,
10
it is up to you, but it would be cool if you did not.
1
13
namespace BitField {
3
15
private static GLib.Tree<string, Type?> list_of_types;
5
private static GLib.Tree<FieldInfo?, uint16> mask_cash;
17
private static GLib.Tree<FieldInfo?, uint16> mask_cache;
8
20
list_of_types = new GLib.Tree<string, Type?> ((a, b) => {
9
21
return (GLib.strcmp (a,b));
12
mask_cash = new GLib.Tree<FieldInfo?, uint16> ((a, b) => {
24
mask_cache = new GLib.Tree<FieldInfo?, uint16> ((a, b) => {
13
25
return a.compare (b);
47
73
var a = lst.nth_data (i);
48
74
// We valitade the items whilst we are at it.
49
75
if (a.validate ()) {
76
GLib.critical ("Validtion of FieldInfo object failed: (%s)",
52
80
for (uint8 j = i + 1; i < lst.length (); j++) {
53
var b = lst.nth_data (i);
81
var b = lst.nth_data (j);
56
85
if (a.overlap (b)) {
57
GLib.critical ("Overlappinng fields in %s: (%s) (%s).\n" +
86
GLib.critical ("Overlappinng fields in \"%s\": (%s) (%s).\n" +
58
87
"\t Will not add bitmap type defitions.",
59
lst.nth_data (i).to_string (),
60
lst.nth_data (j).to_string ());
68
98
t.fields[i] = lst.nth_data (i);
101
list_of_types.insert (name, t);
103
// add the masks to the mask cach, so we don't have to re-calculate them
104
// each time we need them.
105
lst.foreach ((ii) => {
106
mask_cache.insert (ii, ii.generate_mask ());
74
public void set_8 (ref uint8 field_id, string type_name, uint8 data) {
113
public void set (ref uint16 data,
118
var tt = list_of_types.lookup (type_name);
120
GLib.critical ("Name \"%s\" dose not exist among the types valid types.",
124
var fi = tt.get_field_info (field_id);
125
uint16 mask = mask_cache.lookup (fi);
126
uint16 invert_mask = ~mask;
127
uint16 tmp = data & invert_mask; // everything exept the field.
130
for (uint8 i = 0; i < fi.length; i++) {
135
uint16 tmp2 = in_data & tmp_mask;
138
uint16 distance = 15 - fi.end;
141
tmp2 = tmp2 << distance;
149
public uint16 get (uint16 data,
153
var fi = list_of_types.lookup (type_name).get_field_info (field_id);
154
uint16 mask = mask_cache.lookup (fi);
155
uint16 tmp = data & mask; // only what is in the field.
158
uint16 distance = 15 - fi.end;
161
tmp = tmp >> distance;
165
Type? get_type (string name) {
166
return list_of_types.lookup (name);
170
* Create a new FieldInfo using the following syntax:
80
175
public struct FieldInfo {
180
GLib.pointer padding;
182
public FieldInfo (int field_id, uint8 start, uint8 end, uint8 length) {
183
this.field_id = field_id;
186
this.length = length;
86
190
public int compare (FieldInfo other) {
87
191
if (this.field_id != other.field_id) {
88
return other.field_id - this.field_id;
192
return this.field_id - other.field_id;
89
193
} else if (this.start != other.start) {
90
return other.start - this.start;
194
return this.start - other.start;
91
195
} else if (this.end != other.end) {
92
return other.end - this.end;
196
return this.end - other.end;
93
197
} else if (this.length != other.length) {
94
return other.length - this.length;
198
return this.length - other.length;
154
258
public uint16 generate_mask () {
156
260
for (size_t i = 0; i < this.length; i++) {
261
mask >>= 1; // shit it over to the right one.
157
262
mask += 0x8000; // set the left-most bit in the field
158
mask >> 1; // shit it over to the right one.
265
// Shift over the mask to where it should start.
167
272
public extern static uint16 static_generate_mask (FieldInfo info);
170
private struct Type {
171
276
FieldInfo[] fields;
174
279
fields = new FieldInfo[16];
280
for (uint8 i = 0; i < 16; i++) {
281
fields[i] = {255,255,255,255};
177
285
public string to_string () {