File: JOYSubElement.m

package info (click to toggle)
sameboy 1.0.2%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 10,632 kB
  • sloc: ansic: 29,954; objc: 22,249; asm: 1,424; pascal: 1,373; makefile: 1,064; xml: 111
file content (106 lines) | stat: -rw-r--r-- 2,968 bytes parent folder | download | duplicates (2)
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
#import "JOYSubElement.h"

@interface JOYElement ()
{
    @public uint16_t _usage;
    @public uint16_t _usagePage;
    @public uint32_t _uniqueID;
    @public int32_t _min;
    @public int32_t _max;
    @public int32_t _reportID;
    @public int32_t _parentID;
}
@end

@implementation JOYSubElement
{
    JOYElement *_parent;
    size_t _size; // in bits
    size_t _offset; // in bits
}

- (instancetype)initWithRealElement:(JOYElement *)element
                               size:(size_t) size // in bits
                             offset:(size_t) offset // in bits
                          usagePage:(uint16_t)usagePage
                              usage:(uint16_t)usage
                                min:(int32_t)min
                                max:(int32_t)max
{
    if ((self = [super init])) {
        _parent = element;
        _size = size;
        _offset = offset;
        _usage = usage;
        _usagePage = usagePage;
        _uniqueID = (uint32_t)((_parent.uniqueID << 16) | offset);
        _min = min;
        _max = max;
        _reportID = _parent.reportID;
        _parentID = _parent.parentID;
    }
    return self;
}

- (int32_t)value
{
    NSData *parentValue = [_parent dataValue];
    if (!parentValue) return 0;
    if (_size > 32) return 0;
    if (_size + (_offset % 8) > 32) return 0;
    size_t parentLength = parentValue.length;
    if (_size > parentLength * 8) return 0;
    if (_size + _offset >= parentLength * 8) return 0;
    const uint8_t *bytes = parentValue.bytes;
    
    uint8_t temp[4] = {0,};
    memcpy(temp, bytes + _offset / 8, (_offset + _size - 1) / 8 - _offset / 8 + 1);
    uint32_t ret = (*(uint32_t *)temp) >> (_offset % 8);
    ret &= (1 << _size) - 1;
    //
    if (_min < 0 || _max < 0) { // Uses unsigned values
        if (ret & (1 << (_size - 1)) ) { // Is negative
            ret |= ~((1 << _size) - 1); // Fill with 1s
        }
    }
    
    if (_max < _min) {
        return _max + _min - ret;
    }

    return ret;
}

- (IOReturn)setValue: (uint32_t) value
{
    NSMutableData *dataValue = [[_parent dataValue] mutableCopy];
    if (!dataValue) return -1;
    if (_size > 32) return -1;
    if (_size + (_offset % 8) > 32) return -1;
    size_t parentLength = dataValue.length;
    if (_size > parentLength * 8) return -1;
    if (_size + _offset >= parentLength * 8) return -1;
    uint8_t *bytes = dataValue.mutableBytes;
    
    uint8_t temp[4] = {0,};
    memcpy(temp, bytes + _offset / 8, (_offset + _size - 1) / 8 - _offset / 8 + 1);
    (*(uint32_t *)temp) &= ~((1 << (_size - 1)) << (_offset % 8));
    (*(uint32_t *)temp) |= (value) << (_offset % 8);
    memcpy(bytes + _offset / 8, temp, (_offset + _size - 1) / 8 - _offset / 8 + 1);
    return [_parent setDataValue:dataValue];
}

- (NSData *)dataValue
{
    [self doesNotRecognizeSelector:_cmd];
    return nil;
}

- (IOReturn)setDataValue:(NSData *)data
{
    [self doesNotRecognizeSelector:_cmd];
    return -1;
}


@end