/bitfield/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/bitfield/trunk

« back to all changes in this revision

Viewing changes to src/bit_map.vala

  • Committer: Gustav Hartvigsson
  • Date: 2020-06-05 21:05:07 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20200605210507-cf47ohzmnet3ohc4
* encountered a bug in Valac:
https://gitlab.gnome.org/GNOME/vala/-/issues/1003

This makes it so I can't continue with this in any sane way.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* (c) Gustav Hartvigsson 2020
2
 
 
3
 
                        Cool Licence 1.0
4
 
 
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.
11
 
 */
12
 
 
13
1
namespace BitField {
14
2
  
15
3
  private static GLib.Tree<string, Type?> list_of_types;
16
4
  
17
 
  private static GLib.Tree<FieldInfo?, uint16> mask_cache;
 
5
  private static GLib.Tree<FieldInfo?, uint16> mask_cash;
18
6
  
19
7
  void init () {
20
8
    list_of_types = new GLib.Tree<string, Type?> ((a, b) => {
21
9
      return (GLib.strcmp (a,b));
22
10
    });
23
11
    
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);
26
14
    });
27
15
  }
34
22
    });
35
23
  }
36
24
  
37
 
  static bool add_type_v (string name, FieldInfo first_field, ...) {
 
25
  /**
 
26
   * @Return true on error.
 
27
   */
 
28
  public bool add_type (string name, FieldInfo first_field, ...) {
38
29
    var va = va_list ();
39
30
    
40
31
    GLib.List<FieldInfo?> lst = new GLib.List<FieldInfo?> ();
45
36
      lst.append (fi);
46
37
    }
47
38
    
48
 
    FieldInfo[] lst2 = new FieldInfo[lst.length ()];
49
 
    
50
 
    add_type (name, lst2);
51
 
    
52
 
    return false;
53
 
  }
54
 
  
55
 
  /**
56
 
   * @Return true on error.
57
 
   */
58
 
  public bool add_type (string name, FieldInfo[] fields) {
59
 
    GLib.List<FieldInfo?> lst = new GLib.List<FieldInfo?> ();
60
 
    
61
 
    foreach  (FieldInfo fi in fields) {
62
 
      lst.append (fi);
63
 
    }
64
 
    
65
39
    if (lst.length () >= 16) {
66
40
      return true;
67
41
    }
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)",
77
 
                       a.to_string ());
78
50
        return true;
79
51
      }
80
52
      for (uint8 j = i + 1; i < lst.length (); j++) {
81
 
        var b = lst.nth_data (j);
82
 
        if (b == null) {
83
 
          break;
84
 
        }
 
53
        var b = lst.nth_data (i);
 
54
        
 
55
        
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.",
88
 
                         name,
89
 
                         a.to_string (),
90
 
                         b.to_string ());
 
59
                         lst.nth_data (i).to_string (),
 
60
                         lst.nth_data (j).to_string ());
91
61
          return true;
92
62
        }
93
63
      }
98
68
      t.fields[i] = lst.nth_data (i);
99
69
    }
100
70
    
101
 
    list_of_types.insert (name, t);
102
 
    
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 ());
107
 
    });
108
 
    
109
 
    
110
71
    return false;
111
72
  }
112
73
  
113
 
  public void set (ref uint16 data,
114
 
                   string type_name,
115
 
                   int field_id,
116
 
                   uint16 in_data) {
117
 
    
118
 
    var tt = list_of_types.lookup (type_name);
119
 
    if (tt == null) {
120
 
      GLib.critical ("Name \"%s\" dose not exist among the types valid types.",
121
 
                     type_name);
122
 
      return;
123
 
    }
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.
128
 
    
129
 
    uint16 tmp_mask = 1;
130
 
    for (uint8 i = 0; i < fi.length; i++) {
131
 
      tmp_mask <<= 1;
132
 
      tmp_mask += 1;
133
 
    }
134
 
    
135
 
    uint16 tmp2 = in_data & tmp_mask;
136
 
    
137
 
    
138
 
    uint16 distance = 15 - fi.end;
139
 
    
140
 
    
141
 
    tmp2 = tmp2 << distance;
142
 
    
143
 
    
144
 
    tmp2 = tmp2 | tmp;
145
 
    
146
 
    data = tmp2;
147
 
  }
148
 
  
149
 
  public uint16 get (uint16 data,
150
 
                     string type_name,
151
 
                     int field_id) {
152
 
    
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.
156
 
    
157
 
    
158
 
    uint16 distance = 15 - fi.end;
159
 
    
160
 
    
161
 
    tmp = tmp >> distance;
162
 
    return tmp;
163
 
  }
164
 
  
165
 
  Type? get_type (string name) {
166
 
    return list_of_types.lookup (name);
167
 
  } 
168
 
  
169
 
  /**
170
 
   * Create a new FieldInfo using the following syntax:
171
 
   * {{{
172
 
   * }}}
173
 
   * 
174
 
   */
 
74
  public void set_8 (ref uint8 field_id, string type_name, uint8 data) {
 
75
    
 
76
    
 
77
    
 
78
  }
 
79
  
175
80
  public struct FieldInfo {
176
 
    int field_id;
 
81
    uint8 field_id;
177
82
    uint8 start;
178
83
    uint8 end;
179
84
    uint8 length;
180
 
    GLib.pointer padding;
181
 
    
182
 
    public FieldInfo (int field_id, uint8 start, uint8 end, uint8 length) {
183
 
      this.field_id = field_id;
184
 
      this.start = start;
185
 
      this.end = end;
186
 
      this.length = length; 
187
 
      this.padding = null;
188
 
    }
189
85
    
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;
199
95
      }
200
96
      
201
97
      #if 0
234
130
    
235
131
    
236
132
    public string to_string () {
237
 
      return "field_id: %i start: %i, end: %i, length: %i".printf (
238
 
                                                      this.field_id,
239
 
                                                      this.start,
 
133
      return "start: %i, end: %i, length: %i".printf (this.start,
240
134
                                                      this.end,
241
135
                                                      this.length);
242
136
    }
245
139
     * returns true on error;
246
140
     */
247
141
    public bool validate () {
248
 
      var distance = this.end - this.start + 1;
 
142
      var distance = this.start - this.end;
249
143
      if (distance < 1 || distance != this.length) {
 
144
        GLib.critical ("Validtion if FieldInfo object failed: (%s)",
 
145
                       this.to_string ());
250
146
        return true;
251
147
      }
252
148
      return false;
258
154
    public uint16 generate_mask () {
259
155
      uint16 mask = 0;
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.
263
159
      }
264
160
      
265
 
      // Shift over the mask to where it should start.
266
 
      mask >>= this.start; 
 
161
      mask >> this.start;
267
162
      
268
163
      return mask;
269
164
    }
272
167
    public extern static uint16 static_generate_mask (FieldInfo info);
273
168
  }
274
169
  
275
 
  public struct Type {
 
170
  private struct Type {
276
171
    FieldInfo[] fields;
277
172
    
278
173
    Type () {
279
174
        fields = new FieldInfo[16];
280
 
        for (uint8 i = 0; i < 16; i++) {
281
 
          fields[i] = {255,255,255,255};
282
 
        }
283
175
    }
284
176
    
285
177
    public string to_string () {
296
188
      sb.append (")\n");
297
189
      return sb.str;
298
190
    }
299
 
    
300
 
    public FieldInfo get_field_info (int field_id) {
301
 
      
302
 
      FieldInfo ii = {0};
303
 
      
304
 
      foreach (FieldInfo ij in fields) {
305
 
        if (ij.field_id == field_id) {
306
 
          ii = ij;
307
 
        }
308
 
      }
309
 
      
310
 
      return ii;
311
 
    }
312
 
    
313
191
  }
314
192
  
 
193
  
 
194
  
 
195
  
315
196
}