Issue with filter

I'm getting a duplicate in my array and I cannot figure out how, here's my output and code below
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
107
108
109
110
111
Process started >>>
Win32: Allocating Device Array...
Success! Preping Device Types...
Allocating ID Index Arrays...
		ini->VID: 0100; ink->VID: 0051
		ini->VID: 0051; ink->VID: 0051
			ini->PID: 0000; ink->PID: 0000
		ini->VID: 1E7D; ink->VID: 0051
		ini->VID: 1E7D; ink->VID: 0100
		ini->VID: 1E7D; ink->VID: 0051
		ini->VID: 1E7D; ink->VID: 0100
		ini->VID: 1E7D; ink->VID: 1E7D
			ini->PID: 2F76; ink->PID: 2F76
		ini->VID: 056A; ink->VID: 0051
		ini->VID: 056A; ink->VID: 0100
		ini->VID: 056A; ink->VID: 1E7D
		ini->VID: 056A; ink->VID: 0051
		ini->VID: 056A; ink->VID: 0100
		ini->VID: 056A; ink->VID: 1E7D
		ini->VID: 056A; ink->VID: 056A
			ini->PID: 0065; ink->PID: 0065
		ini->VID: 056A; ink->VID: 0051
		ini->VID: 056A; ink->VID: 0100
		ini->VID: 056A; ink->VID: 1E7D
		ini->VID: 056A; ink->VID: 056A
			ini->PID: 0065; ink->PID: 0065
		ini->VID: 0080; ink->VID: 0051
		ini->VID: 0080; ink->VID: 0100
		ini->VID: 0080; ink->VID: 1E7D
		ini->VID: 0080; ink->VID: 056A
		ini->VID: 0100; ink->VID: 0051
		ini->VID: 0100; ink->VID: 0100
			ini->PID: 0005; ink->PID: 0005
		ini->VID: 0000; ink->VID: 0051
		ini->VID: 0000; ink->VID: 0100
		ini->VID: 0000; ink->VID: 1E7D
		ini->VID: 0000; ink->VID: 056A
		ini->VID: 0000; ink->VID: 0080
		ini->VID: 0000; ink->VID: 0051
		ini->VID: 0000; ink->VID: 0100
		ini->VID: 0000; ink->VID: 1E7D
		ini->VID: 0000; ink->VID: 056A
		ini->VID: 0000; ink->VID: 0080
		ini->VID: 0000; ink->VID: 0000
			ini->PID: 0000; ink->PID: 0000
		ini->VID: 0000; ink->VID: 0051
		ini->VID: 0000; ink->VID: 0100
		ini->VID: 0000; ink->VID: 1E7D
		ini->VID: 0000; ink->VID: 056A
		ini->VID: 0000; ink->VID: 0080
		ini->VID: 0000; ink->VID: 0000
			ini->PID: 0000; ink->PID: 0000
		ini->VID: 0000; ink->VID: 0051
		ini->VID: 0000; ink->VID: 0100
		ini->VID: 0000; ink->VID: 1E7D
		ini->VID: 0000; ink->VID: 056A
		ini->VID: 0000; ink->VID: 0080
		ini->VID: 0000; ink->VID: 0000
			ini->PID: 0000; ink->PID: 0000
		ini->VID: 0000; ink->VID: 0051
		ini->VID: 0000; ink->VID: 0100
		ini->VID: 0000; ink->VID: 1E7D
		ini->VID: 0000; ink->VID: 056A
		ini->VID: 0000; ink->VID: 0080
		ini->VID: 0000; ink->VID: 0000
			ini->PID: 0000; ink->PID: 0000
		ini->VID: 0000; ink->VID: 0051
		ini->VID: 0000; ink->VID: 0100
		ini->VID: 0000; ink->VID: 1E7D
		ini->VID: 0000; ink->VID: 056A
		ini->VID: 0000; ink->VID: 0080
		ini->VID: 0000; ink->VID: 0000
			ini->PID: 0000; ink->PID: 0000
		ini->VID: 0000; ink->VID: 0051
		ini->VID: 0000; ink->VID: 0100
		ini->VID: 0000; ink->VID: 1E7D
		ini->VID: 0000; ink->VID: 056A
		ini->VID: 0000; ink->VID: 0080
		ini->VID: 0000; ink->VID: 0000
			ini->PID: 0000; ink->PID: 0000
		ini->VID: 0000; ink->VID: 0051
		ini->VID: 0000; ink->VID: 0100
		ini->VID: 0000; ink->VID: 1E7D
		ini->VID: 0000; ink->VID: 056A
		ini->VID: 0000; ink->VID: 0080
		ini->VID: 0000; ink->VID: 0000
			ini->PID: 0000; ink->PID: 0000
		ini->VID: 0000; ink->VID: 0051
		ini->VID: 0000; ink->VID: 0100
		ini->VID: 0000; ink->VID: 1E7D
		ini->VID: 0000; ink->VID: 056A
		ini->VID: 0000; ink->VID: 0080
		ini->VID: 0000; ink->VID: 0000
			ini->PID: 0000; ink->PID: 0000
		ini->VID: 0000; ink->VID: 0051
		ini->VID: 0000; ink->VID: 0100
		ini->VID: 0000; ink->VID: 1E7D
		ini->VID: 0000; ink->VID: 056A
		ini->VID: 0000; ink->VID: 0080
		ini->VID: 0000; ink->VID: 0000
			ini->PID: 0000; ink->PID: 0000
Success, ID Count 6; Total 10
Allocating Device Index Arrays...
	VID: 0051; PID: 0000
	VID: 0100; PID: 0005
	VID: 1E7D; PID: 2F76
	VID: 056A; PID: 0065
	VID: 0080; PID: 0005
	VID: 0080; PID: 0005
Success!
Device Count: 20

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
while ( i < h->count )
	{
		ini = &info[i];
		size = b2bgetdevinfo( h->array[i].hDevice, ini );
		if ( vid != 0 )
		{
			if ( flags & B2BDEVV_FIND_FILTEROUT_VID )
			{
				if ( ini->hid.dwVendorId == vid )
					goto omit;
			}
			else if ( ini->hid.dwVendorId != vid )
				goto omit;
		}
		if ( pid != 0 )
		{
			if ( flags & B2BDEVV_FIND_FILTEROUT_PID )
			{
				if ( ini->hid.dwProductId == pid )
					goto omit;
			}
			else if ( ini->hid.dwProductId != pid )
				goto omit;
		}
		if ( vid == 0 && pid == 0 )
		{
			for ( j = 0; j < dst->count; ++j )
			{
				k = dst->array[j];
				ink = &info[k];
				b2btprintf( B2BT("\t\tini->VID: %04X; ink->VID: %04X\n"),
					ini->hid.dwVendorId, ink->hid.dwVendorId);
				if (ini->hid.dwVendorId == ink->hid.dwVendorId)
				{
					b2btprintf( B2BT("\t\t\tini->PID: %04X; ink->PID: %04X\n"),
						ini->hid.dwProductId, ink->hid.dwProductId);
					if (ini->hid.dwProductId == ink->hid.dwProductId)
						goto omit;
				}
			}
		}
		b2bv_uint_push( dst, i );
		omit:
		++i;
	}
What? What even is this?
I'm trying to filter raw input devices (with some mapped functions) by vendor id and product id and insert the new ones into an unsigned int array by which I can then see how many devices (keyboards, mice, dualshock controllers etc) are actually present as opposed to each sub device being reported ias though it were a seperate device. The first list in the output is just the values about to be compared, the second list is to confirm duplicate vendor id and product id combinations are filtered out - unfortunatly at the end of that list I somehow get a duplicate which is not what should happen.
http://www.eelis.net/iso-c++/testcase.xhtml
(if you have more than one file, upload to github. Also, try to remove the fat, like the logging)

> goto omit;

continue; (you'll need a for loop)

you may use functions
1
2
3
for(auto &x: info)
   if( not member(x, destination) )
      insert(x, destination);
Last edited on
Well, in the code you've shown you're not doing any duplicate checking, as far as I can see. Without knowing what framework or library you're working with, the assertion "there should be no duplicates" is an unfounded assumption.

As a matter of fact, in what I guess is the input data to your filter, I can see a duplicate:
ini->PID: 0005; ink->PID: 0005

ini->VID: 0000; ink->VID: 0051
ini->VID: 0000; ink->VID: 0100
ini->VID: 0000; ink->VID: 1E7D
ini->VID: 0000; ink->VID: 056A
ini->VID: 0000; ink->VID: 0080
ini->VID: 0000; ink->VID: 0051
ini->VID: 0000; ink->VID: 0100
ini->VID: 0000; ink->VID: 1E7D
ini->VID: 0000; ink->VID: 056A
ini->VID: 0000; ink->VID: 0080
ini->VID: 0000; ink->VID: 0000
which matches the duplicate in what I'm guessing is the filter's output:
VID: 0051; PID: 0000
VID: 0100; PID: 0005
VID: 1E7D; PID: 2F76
VID: 056A; PID: 0065
VID: 0080; PID: 0005
VID: 0080; PID: 0005


You need to work on your communication skills. Remember that other people aren't psychic. It's impossible to understand a question if no context is given.
continue; is no good in this case since I need to skip the outer loop from a sub loop as you can see toward the bottom of the outer loop.

Also I do NOT want c++, c# or objc solutions, c89/c99 only since this is planned to be wrapped around by an optional c++ layer (I'm one those compartmentising types).

Also I won't upload to github yet until I'm happy it's working correctly on the core part, extendid code will begin at that point.
Just seen your post helios, if this is not duplicate checking then I don't know what is:
1
2
3
4
5
6
7
8
9
				b2btprintf( B2BT("\t\tini->VID: %04X; ink->VID: %04X\n"),
					ini->hid.dwVendorId, ink->hid.dwVendorId);
				if (ini->hid.dwVendorId == ink->hid.dwVendorId)
				{
					b2btprintf( B2BT("\t\t\tini->PID: %04X; ink->PID: %04X\n"),
						ini->hid.dwProductId, ink->hid.dwProductId);
					if (ini->hid.dwProductId == ink->hid.dwProductId)
						goto omit;
				}
What does your display routine look like? The one that prints this:
VID: 0051; PID: 0000
VID: 0100; PID: 0005
VID: 1E7D; PID: 2F76
VID: 056A; PID: 0065
VID: 0080; PID: 0005
VID: 0080; PID: 0005
I've fiddled here and there trying to glean possible causes but I keep coming back to the loop above.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
b2bv_uint_t productv = b2bv_uint_init(10);
		if ( !productv.array ) goto fail_productv;
		b2bdevv_find( &devv, &productv, 0, 0, 0 );
		(void)b2btprintf(B2BT("Succes! ID Count %u; Total %u\n"), productv.count, productv.total );
		b2bv_uint_t *device, *devicev = malloc(sizeof(b2bv_uint_t) * productv.count);
		if ( !devicev ) goto fail_devicev;
		for ( c = 0; c < productv.count; ++c )
		{
			device = &devicev[c];
			info_size = b2bgetdevinfo(
				devv.array[productv.array[c]].hDevice, &info );
			b2btprintf( B2BT("\tVID: %04X;"), info.hid.dwVendorId );
			b2btprintf( B2BT(" PID: %04X\n"), info.hid.dwProductId );
			b2bdevv_find( &devv, device,
				info.hid.dwVendorId, info.hid.dwProductId,
				// Create array with 10 initial elements
				B2BDEVV_FIND_INIT__INDEXES | 0x10 );
			// Cleanup and exit
			if ( !device->array ) goto fail;
		}
And for reference the b2bv_uint_push() just passes onto this rutine:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void* b2bvect_push( b2bvect_t *h, void *v ) {
	if ( !h ) return NULL;
	if ( h->count < h->total ) goto fill;
	b2bsize_t size = (h->total + 1) * h->tsize;
	char *ptr = realloc( h->array, size );
	if ( ptr ) {
		h->array = ptr;
		h->vsize = size;
		h->total++;
		fill:
		return memcpy( &(((char*)h->array)[h->tsize * h->count++]), v, h->tsize );
	}
	return NULL;
}
Also post b2bgetdevinfo().
1
2
3
4
5
b2bsize_t b2bgetdevinfo( b2bobj_t handle, b2bdevinfo_t *info ) {
	if ( !info ) return 0;
	b2bsize_t size = info->cbSize = sizeof(b2bdevinfo_t);
	return b2b_getdevinfo( handle, B2B_DEVINFO, (void*)info, &size );
}

And since you'll want it
1
2
3
4
5
6
7
8
9
10
11
12
#ifdef _WIN32
typedef RAWINPUTDEVICELIST b2bdev_t;
typedef RID_DEVICE_INFO b2bdevinfo_t;
#define B2B_DEVTYPEMOUSE RIM_TYPEMOUSE
#define B2B_DEVTYPEKEYBD RIM_TYPEKEYBOARD
#define B2B_DEVTYPEOTHER RIM_TYPEHID
#define b2b_getdevlist GetRawInputDeviceList
#define B2B_DEVNAME RIDI_DEVICENAME
#define B2B_DEVINFO RIDI_DEVICEINFO
#define B2B_DEVPREV RIDI_PREPARSEDDATA
#define b2b_getdevinfo GetRawInputDeviceInfo
#else 

Also I'm going to bed now so take your time with your responses since I'll probably forget up until I leave for work tomorrow
I'd tell you to post b2b_getdevinfo() also, but it looks like it's going to be a fairly complex function, so to avoid an endless back-and-forth, I'll just tell you my suspicion:
I don't think the final array contains any actual duplicates. I think the array contains

{
{ 0x0051, 0x0000},
{ 0x0100, 0x0005},
{ 0x1E7D, 0x2F76},
{ 0x056A, 0x0065},
{ 0x0080, 0x0005},
{ 0x0000, 0x0000}
}

where the first number is the VID and the second number is the PID.
I think the problem is that b2bgetdevinfo() is not modifying the contents of info when both VID and PID are zero, so you end just printing the previous element again.
dst is a ptr to an object existing in the calling function (in this case main()). The info array is allocated and released within this called function for the sole purpose of identifying VIDs & PIDs and going back to identify what has already been found. I have since modified the array slightly (and ripped out the b2btprintfs) to this:
1
2
3
4
5
6
7
8
9
10
11
12
		if ( vid == 0 && pid == 0 )
		{
			for ( j = 0; j < i; ++j )
			{
				ink = &info[j];
				if (ini->hid.dwVendorId == ink->hid.dwVendorId)
				{
					if (ini->hid.dwProductId == ink->hid.dwProductId)
						goto omit;
				}
			}
		}

But I still have the same problem
I was referring to the structure of type b2bdevinfo_t named info that gets passed to b2bgetdevinfo(), not to the array named info. (At this point, I think it's worthwhile to complain about the choice of names.)

I'm saying this info is not getting updated:
1
2
3
4
info_size = b2bgetdevinfo(
	devv.array[productv.array[c]].hDevice, &info );
b2btprintf( B2BT("\tVID: %04X;"), info.hid.dwVendorId );
b2btprintf( B2BT(" PID: %04X\n"), info.hid.dwProductId );
As you can see by the code I posted last night on windows I have mapped it directly to the API I based it off, also I've just modified the function to this:
1
2
3
4
5
6
b2bsize_t b2bgetdevinfo( b2bobj_t handle, b2bdevinfo_t *info ) {
	if ( !info ) return 0;
	(void)memset(info,0,sizeof(b2bdevinfo_t);
	b2bsize_t size = info->cbSize = sizeof(b2bdevinfo_t);
	return b2b_getdevinfo( handle, B2B_DEVINFO, (void*)info, &size );
}

And I'm still getting the same result, you see why I'm having trouble spotting the issue now?
No idea, then. That's as far as I can get without debugging it.
Okay was getting the same result only because I didn't notice that compile was skipped because of a typo, fixed it and now the list ends with zeroed out values instead of a duplicate
Topic archived. No new replies allowed.