bitop.c (25970B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * Bit Array routines 8 */ 9 10 #include <shared/bitop.h> 11 #include <sal/core/libc.h> 12 13 /* Same as shr_bitop_range_null, but for a single SHR_BITDCL. 14 The following constraints are kept: 15 a. first < SHR_BITWID 16 b. first + bit_count <= SHR_BITWID 17 */ 18 STATIC INLINE int 19 shr_bitop_range_null_one_bitdcl(CONST SHR_BITDCL bits, 20 CONST int first, 21 CONST int bit_count) 22 { 23 SHR_BITDCL mask = ~0; 24 25 mask >>= (SHR_BITWID - bit_count); 26 /* Move the mask to start from 'first' offset */ 27 mask <<= first; 28 return (bits & mask) == 0; 29 } 30 31 /* returns 1 if the bit array is empty */ 32 int 33 shr_bitop_range_null(CONST SHR_BITDCL *bits, 34 CONST int first, 35 int bit_count) 36 { 37 CONST SHR_BITDCL *ptr; 38 int woff_first, wremain; 39 40 if(bit_count <= 0) { 41 return 1; 42 } 43 44 /* Pointer to first SHR_BITDCL in 'bits' that contains 'first' */ 45 ptr = bits + (first / SHR_BITWID); 46 47 /* Offset of 'first' bit within this SDH_BITDCL */ 48 woff_first = first % SHR_BITWID; 49 50 /* Check if 'first' is SHR_BITWID aligned */ 51 if (woff_first != 0) { 52 /* Get remaining bits in this SDH_BITDCL */ 53 wremain = SHR_BITWID - woff_first; 54 if (bit_count <= wremain) { 55 /* All the range is in one SHR_BITDCL */ 56 return shr_bitop_range_null_one_bitdcl(*ptr, 57 woff_first, 58 bit_count); 59 } 60 /* We should check the first SHR_BITDCL, and might also continue */ 61 if (!shr_bitop_range_null_one_bitdcl(*ptr, woff_first, wremain)) { 62 return 0; 63 } 64 bit_count -= wremain; 65 ++ptr; 66 } 67 while (bit_count >= SHR_BITWID) { 68 /* We're testing a full SHR_BITDCL */ 69 if (*(ptr++)) { 70 return 0; 71 } 72 bit_count -= SHR_BITWID; 73 } 74 /* This is the last SHR_BITDCL, and it is not SHR_BITWID */ 75 if(bit_count > 0) { 76 return shr_bitop_range_null_one_bitdcl(*ptr, 0, bit_count); 77 } 78 return 1; 79 } 80 81 /* Same as shr_bitop_range_eq, but for a single SHR_BITDCL. 82 The following constraints are kept: 83 a. first < SHR_BITWID 84 b. first + range <= SHR_BITWID 85 */ 86 STATIC INLINE int 87 shr_bitop_range_eq_one_bitdcl(CONST SHR_BITDCL bits1, 88 CONST SHR_BITDCL bits2, 89 CONST int first, 90 CONST int range) 91 { 92 SHR_BITDCL mask = ~0; 93 mask >>= (SHR_BITWID - range); 94 /* Move the mask to start from 'first' offset */ 95 mask <<= first; 96 return (bits1 & mask) == (bits2 & mask); 97 } 98 99 /* returns 1 if the two bitmaps are equal */ 100 int 101 shr_bitop_range_eq(CONST SHR_BITDCL *bits1, 102 CONST SHR_BITDCL *bits2, 103 CONST int first, 104 int range) 105 { 106 CONST SHR_BITDCL *ptr1; 107 CONST SHR_BITDCL *ptr2; 108 int woff_first, wremain; 109 110 if(range <= 0) { 111 return 1; 112 } 113 114 ptr1 = bits1 + (first / SHR_BITWID); 115 ptr2 = bits2 + (first / SHR_BITWID); 116 117 woff_first = first % SHR_BITWID; 118 119 if (woff_first != 0) { 120 wremain = SHR_BITWID - woff_first; 121 if (range <= wremain) { 122 return shr_bitop_range_eq_one_bitdcl(*ptr1, 123 *ptr2, 124 woff_first, 125 range); 126 } 127 if (!shr_bitop_range_eq_one_bitdcl(*ptr1, 128 *ptr2, 129 woff_first, 130 wremain)) { 131 return 0; 132 } 133 range -= wremain; 134 ++ptr1, ++ptr2; 135 } 136 while (range >= SHR_BITWID) { 137 if (*(ptr1++) != *(ptr2++)) { 138 return 0; 139 } 140 range -= SHR_BITWID; 141 } 142 if(range > 0) { 143 return shr_bitop_range_eq_one_bitdcl(*ptr1, *ptr2, 0, range); 144 } 145 return 1; 146 } 147 148 STATIC INLINE int 149 shr_bitop_range_count_uchar(CONST uint8 bits) 150 { 151 uint8 tmp_res; 152 153 /* Efficient algorithm to count bits */ 154 tmp_res = (bits & 0x55) + ((bits & 0xaa) >> 1); 155 tmp_res = (tmp_res & 0x33) + ((tmp_res & 0xcc) >> 2); 156 return (int) ((tmp_res & 0xf) + ((tmp_res & 0xf0) >> 4)); 157 } 158 159 STATIC INLINE int 160 shr_bitop_range_count_bitdcl_all_bits(CONST SHR_BITDCL bits) 161 { 162 int count = 0, i; 163 for(i = 0; i < sizeof(SHR_BITWID); ++i) { 164 count += shr_bitop_range_count_uchar((bits >> (8*i)) & 0xff); 165 } 166 return count; 167 } 168 169 /* Same as shr_bitop_range_count, but for a single SHR_BITDCL. 170 The following constraints are kept: 171 a. first < SHR_BITWID 172 b. first + range <= SHR_BITWID 173 */ 174 STATIC INLINE int 175 shr_bitop_range_count_one_bitdcl(CONST SHR_BITDCL bits, 176 CONST int first, 177 CONST int range) 178 { 179 SHR_BITDCL mask = ~0; 180 mask >>= (SHR_BITWID - range); 181 mask <<= first; 182 return shr_bitop_range_count_bitdcl_all_bits(bits & mask); 183 } 184 185 /* returns the number of set bits is the specified range for the bitmap */ 186 void 187 shr_bitop_range_count(CONST SHR_BITDCL *bits, 188 CONST int first, 189 int range, 190 int *count) 191 { 192 CONST SHR_BITDCL *ptr; 193 int woff_first, wremain; 194 195 ptr = bits + (first / SHR_BITWID); 196 197 woff_first = first % SHR_BITWID; 198 199 *count = 0; 200 201 if(range <= 0) { 202 return; 203 } 204 205 if (woff_first != 0) { 206 wremain = SHR_BITWID - woff_first; 207 if (range <= wremain) { 208 *count = shr_bitop_range_count_one_bitdcl(*ptr, woff_first, range); 209 return; 210 } 211 *count += shr_bitop_range_count_one_bitdcl(*ptr, woff_first, wremain); 212 range -= wremain; 213 ++ptr; 214 } 215 while (range >= SHR_BITWID) { 216 *count += shr_bitop_range_count_bitdcl_all_bits(*(ptr++)); 217 range -= SHR_BITWID; 218 } 219 if(range > 0) { 220 *count += shr_bitop_range_count_one_bitdcl(*ptr, 0, range); 221 } 222 } 223 224 /* Same as shr_bitop_range_copy, but for a single SHR_BITDCL. 225 The following constraints are kept: 226 a. dst_first, src_first < SHR_BITWID 227 b. dst_first + range, src_first + range <= SHR_BITWID 228 */ 229 STATIC INLINE void 230 shr_bitop_range_copy_one_bitdcl(SHR_BITDCL *dst_ptr, 231 CONST int dst_first, 232 CONST SHR_BITDCL src, 233 CONST int src_first, 234 CONST int range) 235 { 236 SHR_BITDCL data; 237 SHR_BITDCL mask; 238 239 /* no need to check that dst_first == 0 and src_first == 0, 240 It must be becuse of the constrains */ 241 if ((range) == SHR_BITWID) { 242 *(dst_ptr) = src; 243 return; 244 } 245 /* get the data */ 246 data = src >> (src_first); 247 /* align the data to the place it may be inserted */ 248 data <<= (dst_first); 249 250 /* We might have bits in src_ptr above src_first + range 251 that need to be cleared */ 252 mask = ~0; 253 mask >>= SHR_BITWID - range; 254 mask <<= dst_first; 255 data &= mask; 256 *(dst_ptr) &= ~mask; 257 *(dst_ptr) |= data; 258 } 259 260 void 261 shr_bitop_range_copy(SHR_BITDCL *dst_ptr, 262 CONST int dst_first, 263 CONST SHR_BITDCL *src_ptr, 264 CONST int src_first, 265 int range) 266 { 267 if(range <= 0) { 268 return; 269 } 270 271 if ((((dst_first) % SHR_BITWID) == 0) && 272 (((src_first) % SHR_BITWID) == 0) && 273 (((range) % SHR_BITWID) == 0)) { 274 sal_memcpy(&((dst_ptr)[(dst_first) / SHR_BITWID]), 275 &((src_ptr)[(src_first) / SHR_BITWID]), 276 SHR_BITALLOCSIZE(range)); 277 } else { 278 SHR_BITDCL *cur_dst; 279 CONST SHR_BITDCL *cur_src; 280 281 int woff_src, woff_dst, wremain; 282 283 cur_dst = (dst_ptr) + ((dst_first) / SHR_BITWID); 284 cur_src = (src_ptr) + ((src_first) / SHR_BITWID); 285 286 woff_src = src_first % SHR_BITWID; 287 woff_dst = dst_first % SHR_BITWID; 288 289 if (woff_dst >= woff_src) { 290 wremain = SHR_BITWID - woff_dst; 291 } else { 292 wremain = SHR_BITWID - woff_src; 293 } 294 if (range <= wremain) { 295 shr_bitop_range_copy_one_bitdcl(cur_dst, 296 woff_dst, 297 *cur_src, 298 woff_src, 299 range); 300 return; 301 } 302 shr_bitop_range_copy_one_bitdcl(cur_dst, 303 woff_dst, 304 *cur_src, 305 woff_src, 306 wremain); 307 range -= wremain; 308 while (range >= SHR_BITWID) { 309 if (woff_dst >= woff_src) { 310 ++cur_dst; 311 wremain = woff_dst - woff_src; 312 if(wremain > 0) { 313 shr_bitop_range_copy_one_bitdcl(cur_dst, 314 0, 315 *cur_src, 316 SHR_BITWID - wremain, 317 wremain); 318 } 319 } else { 320 ++cur_src; 321 wremain = woff_src - woff_dst; 322 shr_bitop_range_copy_one_bitdcl(cur_dst, 323 SHR_BITWID - wremain, 324 *cur_src, 325 0, 326 wremain); 327 } 328 range -= wremain; 329 wremain = SHR_BITWID - wremain; 330 if (woff_dst >= woff_src) { 331 ++cur_src; 332 shr_bitop_range_copy_one_bitdcl(cur_dst, 333 SHR_BITWID - wremain, 334 *cur_src, 335 0, 336 wremain); 337 } else { 338 ++cur_dst; 339 shr_bitop_range_copy_one_bitdcl(cur_dst, 340 0, 341 *cur_src, 342 SHR_BITWID - wremain, 343 wremain); 344 } 345 range -= wremain; 346 } 347 348 if (woff_dst >= woff_src) { 349 ++cur_dst; 350 wremain = woff_dst - woff_src; 351 if (range <= wremain) { 352 if(range > 0) { 353 shr_bitop_range_copy_one_bitdcl(cur_dst, 354 0, 355 *cur_src, 356 SHR_BITWID - wremain, 357 range); 358 } 359 return; 360 } 361 if(wremain > 0) { 362 shr_bitop_range_copy_one_bitdcl(cur_dst, 363 0, 364 *cur_src, 365 SHR_BITWID - wremain, 366 wremain); 367 } 368 } else { 369 ++cur_src; 370 wremain = woff_src - woff_dst; 371 if (range <= wremain) { 372 if(range > 0) { 373 shr_bitop_range_copy_one_bitdcl(cur_dst, 374 SHR_BITWID - wremain, 375 *cur_src, 376 0, 377 range); 378 } 379 return; 380 } 381 shr_bitop_range_copy_one_bitdcl(cur_dst, 382 SHR_BITWID - wremain, 383 *cur_src, 384 0, 385 wremain); 386 } 387 range -= wremain; 388 389 if(range > 0) { 390 wremain = SHR_BITWID - wremain; 391 if (woff_dst >= woff_src) { 392 ++cur_src; 393 shr_bitop_range_copy_one_bitdcl(cur_dst, 394 SHR_BITWID - wremain, 395 *cur_src, 396 0, 397 range); 398 } else { 399 ++cur_dst; 400 shr_bitop_range_copy_one_bitdcl(cur_dst, 401 0, 402 *cur_src, 403 SHR_BITWID - wremain, 404 range); 405 } 406 } 407 } 408 } 409 410 /* The same as _SHR_BITOP_RANGE, but for a single SHR_BITDCL. 411 The following constraints are kept: 412 * a. _first < SHR_BITWID 413 * b. _first + _bit_count < SHR_BITWID. 414 */ 415 #define _SHR_BITOP_RANGE_ONE_BITDCL(_bits1, \ 416 _bits2, \ 417 _first, \ 418 _bit_count, \ 419 _dest, \ 420 _op) \ 421 { \ 422 SHR_BITDCL _mask = ~0; \ 423 SHR_BITDCL _data; \ 424 _mask >>= (SHR_BITWID - (_bit_count)); \ 425 _mask <<=_first; \ 426 _data = ((_bits1) _op (_bits2)) & _mask; \ 427 *(_dest) &= ~_mask; \ 428 *(_dest) |= _data; \ 429 } 430 431 #define _SHR_BITOP_RANGE(_bits1, _bits2, _first, _bit_count, _dest, _op) \ 432 { \ 433 CONST SHR_BITDCL *_ptr_bits1; \ 434 CONST SHR_BITDCL *_ptr_bits2; \ 435 SHR_BITDCL *_ptr_dest; \ 436 int _woff_first, _wremain; \ 437 \ 438 _ptr_bits1 = \ 439 (_bits1) + ((_first) / SHR_BITWID); \ 440 _ptr_bits2 = \ 441 (_bits2) + ((_first) / SHR_BITWID); \ 442 _ptr_dest = \ 443 (_dest) + ((_first) / SHR_BITWID); \ 444 _woff_first = ((_first) % SHR_BITWID); \ 445 \ 446 _wremain = SHR_BITWID - _woff_first; \ 447 if ((_bit_count) <= _wremain) { \ 448 _SHR_BITOP_RANGE_ONE_BITDCL(*_ptr_bits1,\ 449 *_ptr_bits2, \ 450 _woff_first, \ 451 (_bit_count), \ 452 _ptr_dest, _op); \ 453 return; \ 454 } \ 455 _SHR_BITOP_RANGE_ONE_BITDCL(*_ptr_bits1, \ 456 *_ptr_bits2, _woff_first, _wremain, \ 457 _ptr_dest, _op); \ 458 (_bit_count) -= _wremain; \ 459 ++_ptr_bits1; ++_ptr_bits2; ++_ptr_dest;\ 460 while ((_bit_count) >= SHR_BITWID) { \ 461 *_ptr_dest = \ 462 (*_ptr_bits1) _op (*_ptr_bits2); \ 463 (_bit_count) -= SHR_BITWID; \ 464 ++_ptr_bits1; ++_ptr_bits2; ++_ptr_dest;\ 465 } \ 466 if((_bit_count) > 0) { \ 467 _SHR_BITOP_RANGE_ONE_BITDCL( \ 468 *_ptr_bits1, \ 469 *_ptr_bits2, \ 470 0, \ 471 (_bit_count), \ 472 _ptr_dest, \ 473 _op); \ 474 } \ 475 } 476 477 void 478 shr_bitop_range_and(CONST SHR_BITDCL *bits1, 479 CONST SHR_BITDCL *bits2, 480 CONST int first, 481 int bit_count, 482 SHR_BITDCL *dest) 483 { 484 if(bit_count > 0) { 485 _SHR_BITOP_RANGE(bits1, bits2, first, bit_count, dest, &); 486 } 487 } 488 489 void 490 shr_bitop_range_or(CONST SHR_BITDCL *bits1, 491 CONST SHR_BITDCL *bits2, 492 CONST int first, 493 int bit_count, 494 SHR_BITDCL *dest) 495 { 496 if(bit_count > 0) { 497 _SHR_BITOP_RANGE(bits1, bits2, first, bit_count, dest, |); 498 } 499 } 500 501 void 502 shr_bitop_range_xor(CONST SHR_BITDCL *bits1, 503 CONST SHR_BITDCL *bits2, 504 CONST int first, 505 int bit_count, 506 SHR_BITDCL *dest) 507 { 508 if(bit_count > 0) { 509 _SHR_BITOP_RANGE(bits1, bits2, first, bit_count, dest, ^); 510 } 511 } 512 513 void 514 shr_bitop_range_remove(CONST SHR_BITDCL *bits1, 515 CONST SHR_BITDCL *bits2, 516 CONST int first, 517 int bit_count, 518 SHR_BITDCL *dest) 519 { 520 if(bit_count > 0) { 521 _SHR_BITOP_RANGE(bits1, bits2, first, bit_count, dest, & ~); 522 } 523 } 524 525 /* The same as _SHR_BITNEGATE_RANGE, but for a single SHR_BITDCL. 526 The following constraints are kept: 527 * a. _first < SHR_BITWID 528 * b. _first + _bit_count < SHR_BITWID. 529 */ 530 #define _SHR_BITNEGATE_RANGE_ONE_BITDCL(_bits1, _first, _bit_count, _dest) \ 531 { \ 532 SHR_BITDCL _mask = ~0; \ 533 SHR_BITDCL _data; \ 534 _mask >>= (SHR_BITWID - (_bit_count)); \ 535 _mask <<=_first; \ 536 _data = ~(_bits1) & _mask; \ 537 *(_dest) &= ~_mask; \ 538 *(_dest) |= _data; \ 539 } 540 541 #define _SHR_BITNEGATE_RANGE(_bits1, _first, _bit_count, _dest) \ 542 { \ 543 CONST SHR_BITDCL *_ptr_bits1; \ 544 SHR_BITDCL *_ptr_dest; \ 545 int _woff_first, _wremain; \ 546 \ 547 _ptr_bits1 = \ 548 (_bits1) + ((_first) / SHR_BITWID); \ 549 _ptr_dest = \ 550 (_dest) + ((_first) / SHR_BITWID); \ 551 _woff_first = ((_first) % SHR_BITWID); \ 552 \ 553 _wremain = SHR_BITWID - _woff_first; \ 554 if ((_bit_count) <= _wremain) { \ 555 _SHR_BITNEGATE_RANGE_ONE_BITDCL( \ 556 *_ptr_bits1, \ 557 _woff_first, \ 558 (_bit_count), \ 559 _ptr_dest); \ 560 return; \ 561 } \ 562 _SHR_BITNEGATE_RANGE_ONE_BITDCL(*_ptr_bits1,\ 563 _woff_first, _wremain, _ptr_dest); \ 564 (_bit_count) -= _wremain; \ 565 ++_ptr_bits1; ++_ptr_dest; \ 566 while ((_bit_count) >= SHR_BITWID) { \ 567 *_ptr_dest = ~(*_ptr_bits1); \ 568 (_bit_count) -= SHR_BITWID; \ 569 ++_ptr_bits1; ++_ptr_dest; \ 570 } \ 571 if((_bit_count) > 0) { \ 572 _SHR_BITNEGATE_RANGE_ONE_BITDCL( \ 573 *_ptr_bits1, \ 574 0, \ 575 (_bit_count), \ 576 _ptr_dest); \ 577 } \ 578 } 579 580 void 581 shr_bitop_range_negate(CONST SHR_BITDCL *bits1, 582 CONST int first, 583 int bit_count, 584 SHR_BITDCL *dest) 585 { 586 if(bit_count > 0) { 587 _SHR_BITNEGATE_RANGE(bits1, first, bit_count, dest); 588 } 589 } 590 591 /* The same as shr_bitop_range_clear, but for a single SHR_BITDCL. 592 The following constraints are kept: 593 * a. b < SHR_BITWID 594 * b. b + c < SHR_BITWID. 595 */ 596 STATIC INLINE void 597 shr_bitop_range_clear_one_bitdcl(SHR_BITDCL *a, CONST int b, CONST int c) 598 { 599 SHR_BITDCL mask = ~0; 600 mask >>= (SHR_BITWID - c); 601 mask <<= b; 602 *a &= ~mask; 603 } 604 605 void 606 shr_bitop_range_clear(SHR_BITDCL *a, CONST int b, int c) 607 { 608 SHR_BITDCL *ptr; 609 int woff_first, wremain; 610 611 if(c <= 0) { 612 return; 613 } 614 615 ptr = a + (b / SHR_BITWID); 616 617 woff_first = b % SHR_BITWID; 618 619 if (woff_first != 0) { 620 wremain = SHR_BITWID - woff_first; 621 if (c <= wremain) { 622 shr_bitop_range_clear_one_bitdcl(ptr, woff_first, c); 623 return; 624 } 625 shr_bitop_range_clear_one_bitdcl(ptr, woff_first, wremain); 626 c -= wremain; 627 ++ptr; 628 } 629 while (c >= SHR_BITWID) { 630 *(ptr++) = 0; 631 c -= SHR_BITWID; 632 } 633 634 if(c > 0) { 635 shr_bitop_range_clear_one_bitdcl(ptr, 0, c); 636 } 637 } 638 639 /* The same as shr_bitop_range_set, but for a single SHR_BITDCL. 640 The following constraints are kept: 641 * a. b < SHR_BITWID 642 * b. b + c < SHR_BITWID. 643 */ 644 STATIC INLINE void 645 shr_bitop_range_set_one_bitdcl(SHR_BITDCL *a, CONST int b, CONST int c) 646 { 647 SHR_BITDCL mask = ~0; 648 mask >>= (SHR_BITWID - c); 649 mask <<= b; 650 *a |= mask; 651 } 652 653 void 654 shr_bitop_range_set(SHR_BITDCL *a, CONST int b, int c) 655 { 656 SHR_BITDCL *ptr; 657 int woff_first, wremain; 658 659 if(c <= 0) { 660 return; 661 } 662 663 ptr = a + (b / SHR_BITWID); 664 665 woff_first = b % SHR_BITWID; 666 667 if (woff_first != 0) { 668 wremain = SHR_BITWID - woff_first; 669 if (c <= wremain) { 670 shr_bitop_range_set_one_bitdcl(ptr, woff_first, c); 671 return; 672 } 673 shr_bitop_range_set_one_bitdcl(ptr, woff_first, wremain); 674 c -= wremain; 675 ++ptr; 676 } 677 while (c >= SHR_BITWID) { 678 *(ptr++) = ~0; 679 c -= SHR_BITWID; 680 } 681 if(c > 0) { 682 shr_bitop_range_set_one_bitdcl(ptr, 0, c); 683 } 684 } 685 686 /* 687 * Function: shr_bitop_str_decode 688 * 689 * decode a string in hex format into a bitmap 690 * returns 0 on success, -1 on error 691 * 692 * The string can be more than 32 bits worth of 693 * data if it is in hex format (0x...). If not 694 * hex, it is treated as a single value and not 695 * as a bit map, meaning only a single bit will 696 * be set. 697 */ 698 699 int 700 shr_bitop_str_decode(char *str_value, 701 SHR_BITDCL *dst_ptr, 702 int max_words) 703 { 704 char *e; 705 uint32 v; 706 int bit; 707 708 shr_bitop_range_clear(dst_ptr, 0, SHR_BITWID * max_words); 709 710 if (str_value[0] == '0' && (str_value[1] == 'x' || str_value[1] == 'X')) 711 { 712 /* get end of string */ 713 str_value += 2; 714 for (e = str_value; *e; e++) ; 715 716 e -= 1; 717 /* back up to beginning of string, setting ports as we go */ 718 bit = 0; 719 while (e >= str_value) 720 { 721 if (*e >= '0' && *e <= '9') { 722 v = *e - '0'; 723 } else if (*e >= 'a' && *e <= 'f') { 724 v = *e - 'a' + 10; 725 } else if (*e >= 'A' && *e <= 'F') { 726 v = *e - 'A' + 10; 727 } else { 728 /* error: invalid hex digits */ 729 return -1; 730 } 731 e -= 1; 732 /* now set a nibble's worth of ports */ 733 if ((v & 1) && bit < SHR_BITWID * max_words) { 734 SHR_BITSET(dst_ptr, bit); 735 } 736 bit += 1; 737 if ((v & 2) && bit < SHR_BITWID * max_words) { 738 SHR_BITSET(dst_ptr, bit); 739 } 740 bit += 1; 741 if ((v & 4) && bit < SHR_BITWID * max_words) { 742 SHR_BITSET(dst_ptr, bit); 743 } 744 bit += 1; 745 if ((v & 8) && bit < SHR_BITWID * max_words) { 746 SHR_BITSET(dst_ptr, bit); 747 } 748 bit += 1; 749 } 750 } 751 else 752 { 753 v = 0; 754 /* get decimal nuber */ 755 while (*str_value >= '0' && *str_value <= '9') 756 { 757 v = v * 10 + (*str_value++ - '0'); 758 } 759 760 if (*str_value != '\0') 761 { 762 /* error: invalid decimal digits */ 763 return -1; 764 } 765 766 /* set only recieved decimal value */ 767 if (v < SHR_BITWID * max_words) 768 { 769 SHR_BITSET(dst_ptr, v); 770 } 771 } 772 return 0; 773 } 774 775 void 776 shr_bitop_str_encode(SHR_BITDCL *source_bitmap, 777 int bit_count, 778 char *destination_str, 779 int destination_str_max_length) 780 { 781 char local_buffer[20]; 782 int bitmap_words = (bit_count / SHR_BITWID) + (bit_count % SHR_BITWID == 0 ? 0 : 1); 783 int word; 784 785 /** if the bitmap needed words is 0, set it to contain at least one word to print 0 properly without infinite loops */ 786 if(bitmap_words == 0) 787 { 788 bitmap_words = 1; 789 } 790 791 /* clear str */ 792 *destination_str = '\0'; 793 794 /* if bitmap can fit in str*/ 795 if(bitmap_words * SHR_BITWORD_HEX_STR_CHARS + 1 < destination_str_max_length) 796 { 797 /* populate str */ 798 sal_snprintf(local_buffer, sizeof(local_buffer) -1, "0x"); 799 sal_strncat(destination_str, local_buffer, sizeof(local_buffer) -1); 800 801 for(word = 0; word < bitmap_words; ++word) 802 { 803 sal_snprintf(local_buffer, sizeof(local_buffer) -1, "%08x", source_bitmap[word]); 804 sal_strncat(destination_str, local_buffer, sizeof(local_buffer) -1); 805 } 806 } 807 }