494{
495 const char* value;
496 int length;
497 unsigned long long u;
498 ByteString s;
500 __DCL_TRACE2_N(L
"[%d][%ls]\n", length, String::tryString(value, length).data());
501
503 switch (__type) {
504 case BOOLOID: {
505 u = *(uint8_t*)value;
506 break;
507 }
508 case INT2OID: {
509 u = (uint16_t)
__ntohs(*(uint16_t*)value);
510 break;
511 }
512 case INT4OID: {
513 u = (uint32_t)
__ntohl(*(uint32_t*)value);
514 break;
515 }
516 case INT8OID: {
517 u = (uint64_t)
__ntohll(*(uint64_t*)value);
518 break;
519 }
520 case FLOAT4OID: {
521 u = (uint64_t)
__ntohf(*(uint32_t*)value);
522 break;
523 }
524 case FLOAT8OID: {
525 u = (uint64_t)
__ntohd(*(uint64_t*)value);
526 break;
527 }
528 case MONEYOID:
529 case NUMERICOID: {
530 u = 0;
531 }
532 default: {
534 return false;
535 }
536 }
537 }
538 else {
539 ByteString s;
540 switch (__type) {
541 case BOOLOID: {
542 u = strchr("fF0", *value) ? 0 : 1;
543 break;
544 }
545 case INT2OID:
546 case INT4OID:
547 case INT8OID: {
548 errno = 0;
550 u = strtoull(value, &endptr, 10);
551 if (errno == ERANGE) {
553 u == ULONG_MAX
554 );
555
557 return false;
558 }
559 #if __UNNEED__
560 else if (errno == EINVAL) {
561
563 return false;
564 }
565 #endif
566 break;
567 }
568 case FLOAT4OID:
569 case FLOAT8OID: {
570 errno = 0;
572 double d = strtod(value, &endptr);
573 if (errno == ERANGE) {
575 +HUGE_VAL == d || -HUGE_VAL == d
576 || !(DBL_MIN < d)
577 );
578
580 return false;
581 }
582 #if __UNNEED__
583 else if (errno == EINVAL) {
584
586 return false;
587 }
588 #endif
589 double i;
590 (void)modf(d, &i);
591 if (i < (double)LLONG_MIN || (double)LLONG_MAX < i) {
593 return false;
594 }
595 u = (unsigned long long)i;
596 break;
597 }
598 case MONEYOID: {
599 s.assign(value, length);
600 s = s.replace_r("[^0-9\\.]", "", false);
601 value = s.data();
602 }
603 case NUMERICOID: {
604 errno = 0;
606 if ((Field::__precision - Field::__scale) <= 20) {
607 u = strtoull(value, &endptr, 10);
608 if (errno == ERANGE) {
610 u == ULONG_MAX
611 );
612
614 return false;
615 }
616 #if __UNNEED__
617 else if (errno == EINVAL) {
618
620 return false;
621 }
622 #endif
623 }
624 else {
625 double d = strtod(value, &endptr);
626 if (errno == ERANGE) {
628 +HUGE_VAL == d || -HUGE_VAL == d
629 || !(DBL_MIN < d)
630 );
631
633 return false;
634 }
635 #if __UNNEED__
636 else if (errno == EINVAL) {
637
639 return false;
640 }
641 #endif
642 double i;
643 (void)modf(d, &i);
644 if (i < 0 || (double)ULONG_MAX < i) {
646 return false;
647 }
648 u = (unsigned long long)i;
649 }
650 break;
651 }
652 default: {
654 return false;
655 }
656 }
657 }
658
659 switch (*_size) {
660 case sizeof(uint8_t) : {
663 return false;
664 }
665 *(uint8_t*)_buf = (uint8_t)u;
666 break;
667 }
668 case sizeof(uint16_t) : {
671 return false;
672 }
673 *(uint16_t*)_buf = (uint16_t)u;
674 break;
675 }
676 case sizeof(uint32_t) : {
679 return false;
680 }
681 *(uint32_t*)_buf = (uint32_t)u;
682 break;
683 }
684 case sizeof(uint64_t) : {
685 *(uint64_t*)_buf = (uint64_t)u;
686 break;
687 }
688 default: {
689 *_size = sizeof(uint64_t);
691 return false;
692 }
693 }
694
695 return true;
696}