• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Tehreer / SheenBidi / 20870845662

10 Jan 2026 01:50AM UTC coverage: 96.403% (+0.8%) from 95.579%
20870845662

push

github

mta452
Add support for attribute values with custom sizes

136 of 141 new or added lines in 6 files covered. (96.45%)

1 existing line in 1 file now uncovered.

3940 of 4087 relevant lines covered (96.4%)

455618.5 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.91
/Source/API/SBAttributeRegistry.c
1
/*
2
 * Copyright (C) 2025-2026 Muhammad Tayyab Akram
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
#include <stddef.h>
18
#include <stdlib.h>
19
#include <string.h>
20

21
#include <API/SBAttributeInfo.h>
22
#include <API/SBBase.h>
23
#include <Core/Object.h>
24

25
#include "SBAttributeRegistry.h"
26

27
static int AttributeInfoComparison(const void *first, const void *second)
268✔
28
{
29
    const SBAttributeInfo *info1 = first;
268✔
30
    const SBAttributeInfo *info2 = second;
268✔
31

32
    return strcmp(info1->name, info2->name);
268✔
33
}
34

35
static int AttributeNameComparison(const void *key, const void *array)
88✔
36
{
37
    const char *name = key;
88✔
38
    const SBAttributeInfo *attributeInfo = array;
88✔
39

40
    return strcmp(name, attributeInfo->name);
88✔
41
}
42

43
static SBUInteger CountCombinedNamesLength(
44✔
44
    const SBAttributeInfo *attributeInfos, SBUInteger attributeCount)
45
{
46
    SBUInteger combinedLength = 0;
44✔
47
    SBUInteger index;
48

49
    for (index = 0; index < attributeCount; index++) {
192✔
50
        const SBAttributeInfo *currentInfo = &attributeInfos[index];
148✔
51
        SBUInteger nameLength = strlen(currentInfo->name) + 1;
148✔
52
        combinedLength += nameLength;
148✔
53
    }
54

55
    return combinedLength;
44✔
56
}
57

58
#define ATTRIBUTE_REGISTRY  0
59
#define ATTRIBUTE_INFOS     1
60
#define ATTRIBUTE_NAMES     2
61
#define COUNT               3
62

63
static SBAttributeRegistry *AllocateAttributeRegistry(
44✔
64
    SBUInteger attributeCount, SBUInteger namesLength, char **namesPointer)
65
{
66
    void *pointers[COUNT] = { NULL };
44✔
67
    SBUInteger sizes[COUNT] = { 0 };
44✔
68
    SBAttributeRegistry *attributeRegistry;
69

70
    sizes[ATTRIBUTE_REGISTRY] = sizeof(SBAttributeRegistry);
44✔
71
    sizes[ATTRIBUTE_INFOS]    = sizeof(SBAttributeInfo) * attributeCount;
44✔
72
    sizes[ATTRIBUTE_NAMES]    = namesLength;
44✔
73

74
    attributeRegistry = ObjectCreate(sizes, COUNT, pointers, NULL);
44✔
75

76
    if (attributeRegistry) {
44✔
77
        attributeRegistry->attributeInfos = pointers[ATTRIBUTE_INFOS];
44✔
78
        *namesPointer = pointers[ATTRIBUTE_NAMES];
44✔
79
    }
80

81
    return attributeRegistry;
44✔
82
}
83

84
#undef ATTRIBUTE_REGISTRY
85
#undef ATTRIBUTE_INFOS
86
#undef ATTRIBUTE_NAMES
87
#undef COUNT
88

89
static SBAttributeInfo *GetAttributeInfoForID(SBAttributeRegistryRef registry, SBAttributeID id)
266✔
90
{
91
    SBUInteger index = SBAttributeIDGetIndex(id);
266✔
92

93
    if (index < registry->count) {
266✔
94
        return &registry->attributeInfos[index];
265✔
95
    }
96

97
    return NULL;
1✔
98
}
99

100
SB_INTERNAL const void *SBAttributeRegistryRetainAttribute(SBAttributeRegistryRef registry,
142✔
101
    const void *attributeValue)
102
{
103
    SBAttributeValueRetainCallback retain = registry->_valueCallbacks.retain;
142✔
104

105
    if (retain) {
142✔
106
        return retain(attributeValue);
88✔
107
    }
108

109
    return attributeValue;
54✔
110
}
111

112
SB_INTERNAL void SBAttributeRegistryReleaseAttribute(SBAttributeRegistryRef registry,
142✔
113
    const void *attributeValue)
114
{
115
    SBAttributeValueReleaseCallback release = registry->_valueCallbacks.release;
142✔
116

117
    if (release) {
142✔
118
        release(attributeValue);
88✔
119
    }
120
}
142✔
121

122
SB_INTERNAL SBBoolean SBAttributeRegistryIsEqualAttribute(SBAttributeRegistryRef registry,
237✔
123
    SBAttributeID attributeID, const void *first, const void *second)
124
{
125
    SBAttributeValueEqualCallback equal = registry->_valueCallbacks.equal;
237✔
126

127
    if (equal) {
237✔
128
        return equal(first, second);
219✔
129
    }
130

131
    return SBAttributeItemIsEqualValue(attributeID, first, second);
18✔
132
}
133

134
SB_INTERNAL const SBAttributeInfo *SBAttributeRegistryGetInfoReference(
266✔
135
    SBAttributeRegistryRef registry, SBAttributeID attributeID)
136
{
137
    return GetAttributeInfoForID(registry, attributeID);
266✔
138
}
139

140
SBAttributeRegistryRef SBAttributeRegistryCreate(const SBAttributeInfo *attributeInfos,
44✔
141
    SBUInteger count, SBUInt8 valueSize, const SBAttributeValueCallbacks *valueCallbacks)
142
{
143
    SBUInteger namesLength = CountCombinedNamesLength(attributeInfos, count);
44✔
144
    char *namesPointer;
44✔
145
    SBAttributeRegistry *attributeRegistry;
146

147
    attributeRegistry = AllocateAttributeRegistry(count, namesLength, &namesPointer);
44✔
148

149
    if (attributeRegistry) {
44✔
150
        SBAttributeInfo *destination = attributeRegistry->attributeInfos;
44✔
151
        SBUInteger index;
152

153
        for (index = 0; index < count; index++) {
192✔
154
            destination[index].name = namesPointer;
148✔
155
            destination[index].group = attributeInfos[index].group;
148✔
156
            destination[index].scope = attributeInfos[index].scope;
148✔
157

158
            strcpy(namesPointer, attributeInfos[index].name);
148✔
159
            namesPointer += strlen(attributeInfos[index].name) + 1;
148✔
160
        }
161

162
        attributeRegistry->count = count;
44✔
163
        attributeRegistry->valueSize = valueSize;
44✔
164

165
        if (valueCallbacks) {
44✔
166
            attributeRegistry->_valueCallbacks = *valueCallbacks;
30✔
167
        } else {
168
            attributeRegistry->_valueCallbacks.equal = NULL;
14✔
169
            attributeRegistry->_valueCallbacks.release = NULL;
14✔
170
            attributeRegistry->_valueCallbacks.retain = NULL;
14✔
171
        }
172

173
        qsort(attributeRegistry->attributeInfos, count, sizeof(SBAttributeInfo), AttributeInfoComparison);
44✔
174
    }
175

176
    return attributeRegistry;
44✔
177
}
178

179
SBBoolean SBAttributeRegistryGetAttributeInfo(SBAttributeRegistryRef registry,
×
180
    SBAttributeID attributeID, SBAttributeInfo *attributeInfo)
181
{
182
    SBBoolean idExists = SBFalse;
×
183

NEW
184
    if (SBAttributeIDIsValid(attributeID)) {
×
NEW
185
        SBUInteger index = SBAttributeIDGetIndex(attributeID);
×
186

NEW
187
        *attributeInfo = registry->attributeInfos[index];
×
UNCOV
188
        idExists = SBTrue;
×
189
    }
190

191
    return idExists;
×
192
}
193

194
SBAttributeID SBAttributeRegistryGetAttributeID(
51✔
195
    SBAttributeRegistryRef registry, const char *name)
196
{
197
    SBAttributeInfo *attributeInfo = bsearch(name, registry->attributeInfos, registry->count,
51✔
198
        sizeof(SBAttributeInfo), AttributeNameComparison);
199

200
    if (attributeInfo) {
51✔
201
        SBUInteger index = attributeInfo - registry->attributeInfos;
51✔
202
        SBUInt8 size = registry->valueSize;
51✔
203

204
        return SBAttributeIDMake(index, size);
51✔
205
    }
206

207
    return SBAttributeIDNone;
×
208
}
209

210
SBAttributeRegistryRef SBAttributeRegistryRetain(SBAttributeRegistryRef registry)
168✔
211
{
212
    return ObjectRetain((ObjectRef)registry);
168✔
213
}
214

215
void SBAttributeRegistryRelease(SBAttributeRegistryRef registry)
212✔
216
{
217
    ObjectRelease((ObjectRef)registry);
212✔
218
}
212✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc