mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-02 15:45:25 +00:00
Refactor the common buffer manipulation in rdataslab.c in macros
The rdataslab.c was full of code like this: length = raw[0] * 256 + raw[1]; and count2 = *current2++ * 256; count2 += *current2++; Refactor code like this into peek_uint16() and get_uint16 macros to prevent code repetition and possible mistakes when copy and pasting the same code over and over. As a side note for an entertainment of a careful reader of the commit messages: The byte manipulation was changed from multiplication and addition to shift with or. The difference in the assembly looks like this: MUL and ADD: movzx eax, BYTE PTR [rdi] movzx edi, BYTE PTR [rdi+1] sal eax, 8 or edi, eax SHIFT and OR: movzx edi, WORD PTR [rdi] rol di, 8 movzx edi, di If the result and/or buffer is then being used after the macro call, there's more differences in favor of the SHIFT+OR solution.
This commit is contained in:
@@ -89,6 +89,15 @@ struct xrdata {
|
|||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define peek_uint16(buffer) \
|
||||||
|
({ ((uint16_t) * (buffer) << 8) | *((buffer) + 1); })
|
||||||
|
#define get_uint16(buffer) \
|
||||||
|
({ \
|
||||||
|
uint16_t __ret = peek_uint16(buffer); \
|
||||||
|
buffer += sizeof(uint16_t); \
|
||||||
|
__ret; \
|
||||||
|
})
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rdataset_disassociate(dns_rdataset_t *rdataset DNS__DB_FLARG);
|
rdataset_disassociate(dns_rdataset_t *rdataset DNS__DB_FLARG);
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
@@ -381,25 +390,20 @@ free_rdatas:
|
|||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
dns_rdataslab_size(unsigned char *slab, unsigned int reservelen) {
|
dns_rdataslab_size(unsigned char *slab, unsigned int reservelen) {
|
||||||
unsigned int count, length;
|
|
||||||
unsigned char *current = NULL;
|
|
||||||
|
|
||||||
REQUIRE(slab != NULL);
|
REQUIRE(slab != NULL);
|
||||||
|
|
||||||
current = slab + reservelen;
|
unsigned char *current = slab + reservelen;
|
||||||
count = *current++ * 256;
|
uint16_t count = get_uint16(current);
|
||||||
count += *current++;
|
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
current += (4 * count);
|
current += (4 * count);
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
while (count > 0) {
|
|
||||||
count--;
|
while (count-- > 0) {
|
||||||
length = *current++ * 256;
|
uint16_t length = get_uint16(current);
|
||||||
length += *current++;
|
|
||||||
#if DNS_RDATASET_FIXED
|
|
||||||
current += length + 2;
|
|
||||||
#else /* if DNS_RDATASET_FIXED */
|
|
||||||
current += length;
|
current += length;
|
||||||
|
#if DNS_RDATASET_FIXED
|
||||||
|
current += 2;
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,26 +412,22 @@ dns_rdataslab_size(unsigned char *slab, unsigned int reservelen) {
|
|||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
dns_rdataslab_rdatasize(unsigned char *slab, unsigned int reservelen) {
|
dns_rdataslab_rdatasize(unsigned char *slab, unsigned int reservelen) {
|
||||||
unsigned int count, length, rdatalen = 0;
|
|
||||||
unsigned char *current = NULL;
|
|
||||||
|
|
||||||
REQUIRE(slab != NULL);
|
REQUIRE(slab != NULL);
|
||||||
|
|
||||||
current = slab + reservelen;
|
uint16_t rdatalen = 0;
|
||||||
count = *current++ * 256;
|
unsigned char *current = slab + reservelen;
|
||||||
count += *current++;
|
uint16_t count = get_uint16(current);
|
||||||
|
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
current += (4 * count);
|
current += (4 * count);
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
while (count > 0) {
|
|
||||||
count--;
|
while (count-- > 0) {
|
||||||
length = *current++ * 256;
|
uint16_t length = get_uint16(current);
|
||||||
length += *current++;
|
|
||||||
rdatalen += length;
|
rdatalen += length;
|
||||||
#if DNS_RDATASET_FIXED
|
|
||||||
current += length + 2;
|
|
||||||
#else /* if DNS_RDATASET_FIXED */
|
|
||||||
current += length;
|
current += length;
|
||||||
|
#if DNS_RDATASET_FIXED
|
||||||
|
current += 2;
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,14 +436,11 @@ dns_rdataslab_rdatasize(unsigned char *slab, unsigned int reservelen) {
|
|||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
dns_rdataslab_count(unsigned char *slab, unsigned int reservelen) {
|
dns_rdataslab_count(unsigned char *slab, unsigned int reservelen) {
|
||||||
unsigned int count;
|
|
||||||
unsigned char *current = NULL;
|
|
||||||
|
|
||||||
REQUIRE(slab != NULL);
|
REQUIRE(slab != NULL);
|
||||||
|
|
||||||
current = slab + reservelen;
|
unsigned char *current = slab + reservelen;
|
||||||
count = *current++ * 256;
|
uint16_t count = get_uint16(current);
|
||||||
count += *current++;
|
|
||||||
return (count);
|
return (count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,11 +455,8 @@ rdata_from_slab(unsigned char **current, dns_rdataclass_t rdclass,
|
|||||||
dns_rdatatype_t type, dns_rdata_t *rdata) {
|
dns_rdatatype_t type, dns_rdata_t *rdata) {
|
||||||
unsigned char *tcurrent = *current;
|
unsigned char *tcurrent = *current;
|
||||||
isc_region_t region;
|
isc_region_t region;
|
||||||
unsigned int length;
|
|
||||||
bool offline = false;
|
bool offline = false;
|
||||||
|
uint16_t length = get_uint16(tcurrent);
|
||||||
length = *tcurrent++ * 256;
|
|
||||||
length += *tcurrent++;
|
|
||||||
|
|
||||||
if (type == dns_rdatatype_rrsig) {
|
if (type == dns_rdatatype_rrsig) {
|
||||||
if ((*tcurrent & DNS_RDATASLAB_OFFLINE) != 0) {
|
if ((*tcurrent & DNS_RDATASLAB_OFFLINE) != 0) {
|
||||||
@@ -493,23 +487,19 @@ static bool
|
|||||||
rdata_in_slab(unsigned char *slab, unsigned int reservelen,
|
rdata_in_slab(unsigned char *slab, unsigned int reservelen,
|
||||||
dns_rdataclass_t rdclass, dns_rdatatype_t type,
|
dns_rdataclass_t rdclass, dns_rdatatype_t type,
|
||||||
dns_rdata_t *rdata) {
|
dns_rdata_t *rdata) {
|
||||||
unsigned int count, i;
|
unsigned char *current = slab + reservelen;
|
||||||
unsigned char *current = NULL;
|
|
||||||
dns_rdata_t trdata = DNS_RDATA_INIT;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
current = slab + reservelen;
|
uint16_t count = get_uint16(current);
|
||||||
count = *current++ * 256;
|
|
||||||
count += *current++;
|
|
||||||
|
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
current += (4 * count);
|
current += (4 * count);
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
dns_rdata_t trdata = DNS_RDATA_INIT;
|
||||||
rdata_from_slab(¤t, rdclass, type, &trdata);
|
rdata_from_slab(¤t, rdclass, type, &trdata);
|
||||||
|
|
||||||
n = dns_rdata_compare(&trdata, rdata);
|
int n = dns_rdata_compare(&trdata, rdata);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
@@ -552,15 +542,13 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
|
|||||||
REQUIRE(oslab != NULL && nslab != NULL);
|
REQUIRE(oslab != NULL && nslab != NULL);
|
||||||
|
|
||||||
ocurrent = oslab + reservelen;
|
ocurrent = oslab + reservelen;
|
||||||
ocount = *ocurrent++ * 256;
|
ocount = get_uint16(ocurrent);
|
||||||
ocount += *ocurrent++;
|
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
ocurrent += (4 * ocount);
|
ocurrent += (4 * ocount);
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
ostart = ocurrent;
|
ostart = ocurrent;
|
||||||
ncurrent = nslab + reservelen;
|
ncurrent = nslab + reservelen;
|
||||||
ncount = *ncurrent++ * 256;
|
ncount = get_uint16(ncurrent);
|
||||||
ncount += *ncurrent++;
|
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
ncurrent += (4 * ncount);
|
ncurrent += (4 * ncount);
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
@@ -579,8 +567,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
|
|||||||
*/
|
*/
|
||||||
olength = 0;
|
olength = 0;
|
||||||
for (count = 0; count < ocount; count++) {
|
for (count = 0; count < ocount; count++) {
|
||||||
length = *ocurrent++ * 256;
|
length = get_uint16(ocurrent);
|
||||||
length += *ocurrent++;
|
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
olength += length + 8;
|
olength += length + 8;
|
||||||
ocurrent += length + 2;
|
ocurrent += length + 2;
|
||||||
@@ -679,7 +666,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
|
|||||||
ocurrent = ostart;
|
ocurrent = ostart;
|
||||||
INSIST(ocount != 0);
|
INSIST(ocount != 0);
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
oorder = ocurrent[2] * 256 + ocurrent[3];
|
oorder = peek_uint16(&ocurrent[2]);
|
||||||
INSIST(oorder < ocount);
|
INSIST(oorder < ocount);
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
rdata_from_slab(&ocurrent, rdclass, type, &ordata);
|
rdata_from_slab(&ocurrent, rdclass, type, &ordata);
|
||||||
@@ -693,7 +680,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
|
|||||||
do {
|
do {
|
||||||
dns_rdata_reset(&nrdata);
|
dns_rdata_reset(&nrdata);
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
norder = ncurrent[2] * 256 + ncurrent[3];
|
norder = peek_uint16(&ncurrent[2]);
|
||||||
|
|
||||||
INSIST(norder < oncount);
|
INSIST(norder < oncount);
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
@@ -732,7 +719,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
|
|||||||
if (oadded < ocount) {
|
if (oadded < ocount) {
|
||||||
dns_rdata_reset(&ordata);
|
dns_rdata_reset(&ordata);
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
oorder = ocurrent[2] * 256 + ocurrent[3];
|
oorder = peek_uint16(&ocurrent[2]);
|
||||||
INSIST(oorder < ocount);
|
INSIST(oorder < ocount);
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
rdata_from_slab(&ocurrent, rdclass, type,
|
rdata_from_slab(&ocurrent, rdclass, type,
|
||||||
@@ -760,8 +747,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
|
|||||||
do {
|
do {
|
||||||
dns_rdata_reset(&nrdata);
|
dns_rdata_reset(&nrdata);
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
norder = ncurrent[2] * 256 +
|
norder = peek_uint16(&ncurrent[2]);
|
||||||
ncurrent[3];
|
|
||||||
INSIST(norder < oncount);
|
INSIST(norder < oncount);
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
rdata_from_slab(&ncurrent, rdclass,
|
rdata_from_slab(&ncurrent, rdclass,
|
||||||
@@ -806,11 +792,9 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab,
|
|||||||
REQUIRE(mslab != NULL && sslab != NULL);
|
REQUIRE(mslab != NULL && sslab != NULL);
|
||||||
|
|
||||||
mcurrent = mslab + reservelen;
|
mcurrent = mslab + reservelen;
|
||||||
mcount = *mcurrent++ * 256;
|
mcount = get_uint16(mcurrent);
|
||||||
mcount += *mcurrent++;
|
|
||||||
scurrent = sslab + reservelen;
|
scurrent = sslab + reservelen;
|
||||||
scount = *scurrent++ * 256;
|
scount = get_uint16(scurrent);
|
||||||
scount += *scurrent++;
|
|
||||||
INSIST(mcount > 0 && scount > 0);
|
INSIST(mcount > 0 && scount > 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -910,15 +894,14 @@ dns_rdataslab_subtract(unsigned char *mslab, unsigned char *sslab,
|
|||||||
* Copy the parts of mslab not in sslab.
|
* Copy the parts of mslab not in sslab.
|
||||||
*/
|
*/
|
||||||
mcurrent = mslab + reservelen;
|
mcurrent = mslab + reservelen;
|
||||||
mcount = *mcurrent++ * 256;
|
mcount = get_uint16(mcurrent);
|
||||||
mcount += *mcurrent++;
|
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
mcurrent += (4 * mcount);
|
mcurrent += (4 * mcount);
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
for (i = 0; i < mcount; i++) {
|
for (i = 0; i < mcount; i++) {
|
||||||
unsigned char *mrdatabegin = mcurrent;
|
unsigned char *mrdatabegin = mcurrent;
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
order = mcurrent[2] * 256 + mcurrent[3];
|
order = peek_uint16(&mcurrent[2]);
|
||||||
INSIST(order < mcount);
|
INSIST(order < mcount);
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
rdata_from_slab(&mcurrent, rdclass, type, &mrdata);
|
rdata_from_slab(&mcurrent, rdclass, type, &mrdata);
|
||||||
@@ -967,12 +950,10 @@ dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2,
|
|||||||
unsigned int length1, length2;
|
unsigned int length1, length2;
|
||||||
|
|
||||||
current1 = slab1 + reservelen;
|
current1 = slab1 + reservelen;
|
||||||
count1 = *current1++ * 256;
|
count1 = get_uint16(current1);
|
||||||
count1 += *current1++;
|
|
||||||
|
|
||||||
current2 = slab2 + reservelen;
|
current2 = slab2 + reservelen;
|
||||||
count2 = *current2++ * 256;
|
count2 = get_uint16(current2);
|
||||||
count2 += *current2++;
|
|
||||||
|
|
||||||
if (count1 != count2) {
|
if (count1 != count2) {
|
||||||
return (false);
|
return (false);
|
||||||
@@ -983,12 +964,9 @@ dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2,
|
|||||||
current2 += (4 * count2);
|
current2 += (4 * count2);
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
|
|
||||||
while (count1 > 0) {
|
while (count1-- > 0) {
|
||||||
length1 = *current1++ * 256;
|
length1 = get_uint16(current1);
|
||||||
length1 += *current1++;
|
length2 = get_uint16(current2);
|
||||||
|
|
||||||
length2 = *current2++ * 256;
|
|
||||||
length2 += *current2++;
|
|
||||||
|
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
current1 += 2;
|
current1 += 2;
|
||||||
@@ -1003,8 +981,6 @@ dns_rdataslab_equal(unsigned char *slab1, unsigned char *slab2,
|
|||||||
|
|
||||||
current1 += length1;
|
current1 += length1;
|
||||||
current2 += length1;
|
current2 += length1;
|
||||||
|
|
||||||
count1--;
|
|
||||||
}
|
}
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
@@ -1019,12 +995,10 @@ dns_rdataslab_equalx(unsigned char *slab1, unsigned char *slab2,
|
|||||||
dns_rdata_t rdata2 = DNS_RDATA_INIT;
|
dns_rdata_t rdata2 = DNS_RDATA_INIT;
|
||||||
|
|
||||||
current1 = slab1 + reservelen;
|
current1 = slab1 + reservelen;
|
||||||
count1 = *current1++ * 256;
|
count1 = get_uint16(current1);
|
||||||
count1 += *current1++;
|
|
||||||
|
|
||||||
current2 = slab2 + reservelen;
|
current2 = slab2 + reservelen;
|
||||||
count2 = *current2++ * 256;
|
count2 = get_uint16(current2);
|
||||||
count2 += *current2++;
|
|
||||||
|
|
||||||
if (count1 != count2) {
|
if (count1 != count2) {
|
||||||
return (false);
|
return (false);
|
||||||
@@ -1200,11 +1174,8 @@ rdataset_disassociate(dns_rdataset_t *rdataset DNS__DB_FLARG) {
|
|||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
rdataset_first(dns_rdataset_t *rdataset) {
|
rdataset_first(dns_rdataset_t *rdataset) {
|
||||||
unsigned char *raw = NULL;
|
unsigned char *raw = rdataset->slab.raw;
|
||||||
unsigned int count;
|
uint16_t count = peek_uint16(raw);
|
||||||
|
|
||||||
raw = rdataset->slab.raw;
|
|
||||||
count = raw[0] * 256 + raw[1];
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
rdataset->slab.iter_pos = NULL;
|
rdataset->slab.iter_pos = NULL;
|
||||||
rdataset->slab.iter_count = 0;
|
rdataset->slab.iter_count = 0;
|
||||||
@@ -1232,11 +1203,7 @@ rdataset_first(dns_rdataset_t *rdataset) {
|
|||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
rdataset_next(dns_rdataset_t *rdataset) {
|
rdataset_next(dns_rdataset_t *rdataset) {
|
||||||
unsigned int count;
|
uint16_t count = rdataset->slab.iter_count;
|
||||||
unsigned int length;
|
|
||||||
unsigned char *raw = NULL;
|
|
||||||
|
|
||||||
count = rdataset->slab.iter_count;
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
rdataset->slab.iter_pos = NULL;
|
rdataset->slab.iter_pos = NULL;
|
||||||
return (ISC_R_NOMORE);
|
return (ISC_R_NOMORE);
|
||||||
@@ -1246,12 +1213,12 @@ rdataset_next(dns_rdataset_t *rdataset) {
|
|||||||
/*
|
/*
|
||||||
* Skip forward one record (length + 4) or one offset (4).
|
* Skip forward one record (length + 4) or one offset (4).
|
||||||
*/
|
*/
|
||||||
raw = rdataset->slab.iter_pos;
|
unsigned char *raw = rdataset->slab.iter_pos;
|
||||||
#if DNS_RDATASET_FIXED
|
#if DNS_RDATASET_FIXED
|
||||||
if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) == 0)
|
if ((rdataset->attributes & DNS_RDATASETATTR_LOADORDER) == 0)
|
||||||
#endif /* DNS_RDATASET_FIXED */
|
#endif /* DNS_RDATASET_FIXED */
|
||||||
{
|
{
|
||||||
length = raw[0] * 256 + raw[1];
|
uint16_t length = peek_uint16(raw);
|
||||||
raw += length;
|
raw += length;
|
||||||
}
|
}
|
||||||
rdataset->slab.iter_pos = raw + DNS_RDATASET_ORDER +
|
rdataset->slab.iter_pos = raw + DNS_RDATASET_ORDER +
|
||||||
@@ -1284,7 +1251,7 @@ rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
|
|||||||
}
|
}
|
||||||
#endif /* if DNS_RDATASET_FIXED */
|
#endif /* if DNS_RDATASET_FIXED */
|
||||||
|
|
||||||
length = raw[0] * 256 + raw[1];
|
length = peek_uint16(raw);
|
||||||
|
|
||||||
raw += DNS_RDATASET_ORDER + DNS_RDATASET_LENGTH;
|
raw += DNS_RDATASET_ORDER + DNS_RDATASET_LENGTH;
|
||||||
|
|
||||||
@@ -1322,7 +1289,7 @@ rdataset_count(dns_rdataset_t *rdataset) {
|
|||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
|
||||||
raw = rdataset->slab.raw;
|
raw = rdataset->slab.raw;
|
||||||
count = raw[0] * 256 + raw[1];
|
count = get_uint16(raw);
|
||||||
|
|
||||||
return (count);
|
return (count);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user