/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-06 21:16:24 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20200606211624-z9wi800azah1wllx
* It works. :-)

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
 
1
13
namespace BitField {
2
14
  
3
15
  private static GLib.Tree<string, Type?> list_of_types;
4
16
  
5
 
  private static GLib.Tree<FieldInfo?, uint16> mask_cash;
 
17
  private static GLib.Tree<FieldInfo?, uint16> mask_cache;
6
18
  
7
19
  void init () {
8
20
    list_of_types = new GLib.Tree<string, Type?> ((a, b) => {
9
21
      return (GLib.strcmp (a,b));
10
22
    });
11
23
    
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);
14
26
    });
15
27
  }
22
34
    });
23
35
  }
24
36
  
25
 
  /**
26
 
   * @Return true on error.
27
 
   */
28
 
  public bool add_type (string name, FieldInfo first_field, ...) {
 
37
  static bool add_type_v (string name, FieldInfo first_field, ...) {
29
38
    var va = va_list ();
30
39
    
31
40
    GLib.List<FieldInfo?> lst = new GLib.List<FieldInfo?> ();
36
45
      lst.append (fi);
37
46
    }
38
47
    
 
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
    
39
65
    if (lst.length () >= 16) {
40
66
      return true;
41
67
    }
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)",
 
77
                       a.to_string ());
50
78
        return true;
51
79
      }
52
80
      for (uint8 j = i + 1; i < lst.length (); j++) {
53
 
        var b = lst.nth_data (i);
54
 
        
55
 
        
 
81
        var b = lst.nth_data (j);
 
82
        if (b == null) {
 
83
          break;
 
84
        }
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 ());
 
88
                         name,
 
89
                         a.to_string (),
 
90
                         b.to_string ());
61
91
          return true;
62
92
        }
63
93
      }
68
98
      t.fields[i] = lst.nth_data (i);
69
99
    }
70
100
    
 
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
    
71
110
    return false;
72
111
  }
73
112
  
74
 
  public void set_8 (ref uint8 field_id, string type_name, uint8 data) {
75
 
    
76
 
    
77
 
    
78
 
  }
79
 
  
 
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
   */
80
175
  public struct FieldInfo {
81
 
    uint8 field_id;
 
176
    int field_id;
82
177
    uint8 start;
83
178
    uint8 end;
84
179
    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
    }
85
189
    
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;
95
199
      }
96
200
      
97
201
      #if 0
130
234
    
131
235
    
132
236
    public string to_string () {
133
 
      return "start: %i, end: %i, length: %i".printf (this.start,
 
237
      return "field_id: %i start: %i, end: %i, length: %i".printf (
 
238
                                                      this.field_id,
 
239
                                                      this.start,
134
240
                                                      this.end,
135
241
                                                      this.length);
136
242
    }
139
245
     * returns true on error;
140
246
     */
141
247
    public bool validate () {
142
 
      var distance = this.start - this.end;
 
248
      var distance = this.end - this.start + 1;
143
249
      if (distance < 1 || distance != this.length) {
144
 
        GLib.critical ("Validtion if FieldInfo object failed: (%s)",
145
 
                       this.to_string ());
146
250
        return true;
147
251
      }
148
252
      return false;
154
258
    public uint16 generate_mask () {
155
259
      uint16 mask = 0;
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.
159
263
      }
160
264
      
161
 
      mask >> this.start;
 
265
      // Shift over the mask to where it should start.
 
266
      mask >>= this.start; 
162
267
      
163
268
      return mask;
164
269
    }
167
272
    public extern static uint16 static_generate_mask (FieldInfo info);
168
273
  }
169
274
  
170
 
  private struct Type {
 
275
  public struct Type {
171
276
    FieldInfo[] fields;
172
277
    
173
278
    Type () {
174
279
        fields = new FieldInfo[16];
 
280
        for (uint8 i = 0; i < 16; i++) {
 
281
          fields[i] = {255,255,255,255};
 
282
        }
175
283
    }
176
284
    
177
285
    public string to_string () {
188
296
      sb.append (")\n");
189
297
      return sb.str;
190
298
    }
 
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
    
191
313
  }
192
314
  
193
 
  
194
 
  
195
 
  
196
315
}