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.
13
1
namespace BitField {
15
3
private static GLib.Tree<string, Type?> list_of_types;
17
private static GLib.Tree<FieldInfo?, uint16> mask_cache;
5
private static GLib.Tree<FieldInfo?, uint16> mask_cash;
20
8
list_of_types = new GLib.Tree<string, Type?> ((a, b) => {
21
9
return (GLib.strcmp (a,b));
24
mask_cache = new GLib.Tree<FieldInfo?, uint16> ((a, b) => {
12
mask_cash = new GLib.Tree<FieldInfo?, uint16> ((a, b) => {
25
13
return a.compare (b);
73
47
var a = lst.nth_data (i);
74
48
// We valitade the items whilst we are at it.
75
49
if (a.validate ()) {
76
GLib.critical ("Validtion of FieldInfo object failed: (%s)",
80
52
for (uint8 j = i + 1; i < lst.length (); j++) {
81
var b = lst.nth_data (j);
53
var b = lst.nth_data (i);
85
56
if (a.overlap (b)) {
86
GLib.critical ("Overlappinng fields in \"%s\": (%s) (%s).\n" +
57
GLib.critical ("Overlappinng fields in %s: (%s) (%s).\n" +
87
58
"\t Will not add bitmap type defitions.",
59
lst.nth_data (i).to_string (),
60
lst.nth_data (j).to_string ());
98
68
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 ());
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:
74
public void set_8 (ref uint8 field_id, string type_name, uint8 data) {
175
80
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;
190
86
public int compare (FieldInfo other) {
191
87
if (this.field_id != other.field_id) {
192
return this.field_id - other.field_id;
88
return other.field_id - this.field_id;
193
89
} else if (this.start != other.start) {
194
return this.start - other.start;
90
return other.start - this.start;
195
91
} else if (this.end != other.end) {
196
return this.end - other.end;
92
return other.end - this.end;
197
93
} else if (this.length != other.length) {
198
return this.length - other.length;
94
return other.length - this.length;
258
154
public uint16 generate_mask () {
260
156
for (size_t i = 0; i < this.length; i++) {
261
mask >>= 1; // shit it over to the right one.
262
157
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.
272
167
public extern static uint16 static_generate_mask (FieldInfo info);
170
private struct Type {
276
171
FieldInfo[] fields;
279
174
fields = new FieldInfo[16];
280
for (uint8 i = 0; i < 16; i++) {
281
fields[i] = {255,255,255,255};
285
177
public string to_string () {