Uploaded image for project: 'Qpid'
  1. Qpid
  2. QPID-4553

C++ qpid::types::Variant::uint8_t not treated as integer during string conversion

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Won't Fix
    • 0.21
    • 0.21
    • C++ Broker
    • None
    • Linux/windows broker/client Messaging

    Description

      There are unexpected conversion side effects when a uint8_t is created from a string. I expected the string value to be decoded into a binary value 0..255, the same as I expect for uint16_t, uint32_t, and uint64_t and their expected values. Instead uint8_t receives the first character of a one-character string as if there's an implicit string-to-single-character conversion. This behavior is not a regression.

      Am I mistaken expecting a 0..255 value from the .asUint8() function?

      The underlying cause is Boost being invoked through a template that works one way for three of the four cases and a different way for the uint8_t case. I'd like to get rid of that and replace it with a single, common string decode into a 64-bit integer. Then for the smaller subtypes mask the value down to the size of the respective type and throw if there's a range error.

      Here's a test where I'm looking at the recent "-0" conversion fix. In all cases I expect the value to be a binary zero. In the uint8_t case it is not. The only case where the conversion does not throw returns a value of 48 '0'.

      void testZeroValueAs(const Variant theValue)
      {
          std::string phase;
          try
          {
              phase = "64bit - ";
              uint64_t myu64 = theValue.asUint64();
              if (myu64 != 0) 
                  std::cout << "Failed at uint64 : "  
                            << myu64 << std::endl;
      
              phase = "32bit - ";
              uint32_t myu32 = theValue.asUint32();
              if (myu32 != 0) 
                  std::cout << "Failed at uint32 : "  
                            << myu32 << std::endl;
      
              phase = "16bit - ";
              uint16_t myu16 = theValue.asUint16();
              if (myu16 != 0) 
                  std::cout << "Failed at uint16 : "  
                            << myu16 << std::endl;
      
              phase = "8bit - ";
              uint8_t myu8 = theValue.asUint8();
              if (myu8 != 0) 
                  std::cout << "Failed at uint8 : " 
                            << myu8 << std::endl;
      
          } catch (const std::exception& error) {
              std::cout << "Exception in phase " 
                        << phase 
                        << error.what() 
                        << std::endl;
          }
      }
      
      
          Variant value;
          value = "0";
          testZeroValueAs(value);
          value = "00";
          testZeroValueAs(value);
          value = "-00";
          testZeroValueAs(value);
      

      at run time this example produces:

      Failed at uint8 : 0
      Exception in phase 8bit - invalid conversion: Cannot convert 00 (..\..\qpid\cpp\src\qpid\types\Variant.cpp:126)
      Exception in phase 8bit - invalid conversion: Cannot convert -00 (..\..\qpid\cpp\src\qpid\types\Variant.cpp:126)
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            chug Charles E. Rolke
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: