--- orig/Object_KeyC.cpp 2005-04-08 10:17:40.978604800 +0200 +++ Object_KeyC.cpp 2005-04-08 10:17:41.879900800 +0200 @@ -37,6 +37,10 @@ #pragma option -w-rvl -w-rch -w-ccc -w-aus -w-sig #endif /* __BORLANDC__ */ +#include "ace/ACE.h" +#include "ace/OS_NS_string.h" +#include "ace/os_include/os_ctype.h" + // TAO_IDL - Generated from // be\be_visitor_arg_traits.cpp:69 @@ -88,6 +92,150 @@ TAO::ObjectKey::~ObjectKey (void) {} +// Hand crafted. + +void +TAO::ObjectKey::encode_sequence_to_string (char * &str, + const TAO_Unbounded_Sequence &seq) +{ + // We must allocate a buffer which is (gag) 3 times the length + // of the sequence, which is the length required in the worst-case + // scenario of all non-printable characters. + // + // There are two strategies here...we could allocate all that space here, + // fill it up, then copy-allocate new space of just the right length. + // OR, we could just return this space. The classic time-space tradeoff, + // and for now we'll let time win out, which means that we only do the + // allocation once. + u_int len = 3 * seq.length (); /* space for zero termination not needed */; + str = CORBA::string_alloc (len); + + char *cp = str; + + for (u_int i = 0; + cp < (str + len) && i < seq.length(); + ++i) + { + u_char bt = seq[i]; + if (is_legal (bt)) + { + *cp++ = (char) bt; + continue; + } + + *cp++ = '%'; + *cp++ = ACE::nibble2hex ((bt >> 4) & 0x0f); + *cp++ = ACE::nibble2hex (bt & 0x0f); + } + // Zero terminate + *cp = '\0'; +} + +int TAO::ObjectKey::is_legal (u_char & c) +{ + if (isalnum(c)) + { + return 1; + } + else + { + return ( c == ';' || c == '/' ||c == ':' || c == '?' || + c == '@' || c == '&' ||c == '=' || c == '+' || + c == '$' || c == ',' ||c == '_' || c == '.' || + c == '!' || c == '~' ||c == '*' || c == '\'' || + c == '-' || c == '(' || c == ')' ); + } +} + +void +TAO::ObjectKey::decode_string_to_sequence (TAO_Unbounded_Sequence &seq, + const char *str) +{ + if (str == 0) + { + seq.length (0); + return; + } + + u_int length = ACE_OS::strlen (str); + const char *eos = str + length; + const char *cp = str; + + // Set the length of the sequence to be as long as + // we'll possibly need...we'll reset it to the actual + // length later. + seq.length (length); + + u_int i = 0; + for (; + cp < eos && i < seq.length (); + ++i) + { + if (*cp == '%' || *cp == '\\') + { + // This is an escaped non-printable, + // so we decode the hex values into + // the sequence's octet + seq[i] = (u_char) (ACE::hex2byte (cp[1]) << 4); + seq[i] |= (u_char) ACE::hex2byte (cp[2]); + cp += 3; + } + else + // Copy it in + seq[i] = *cp++; + } + + // Set the length appropriately + seq.length (i); +} + +/*static*/ CORBA::Boolean +TAO::ObjectKey::demarshal_key (TAO::ObjectKey &key, + TAO_InputCDR &strm) +{ + CORBA::ULong _tao_seq_len; + + if (strm >> _tao_seq_len) + { + // Add a check to the length of the sequence + // to make sure it does not exceed the length + // of the stream. (See bug 58.) + if (_tao_seq_len > strm.length ()) + { + return 0; + } + + // Set the length of the sequence. + key.length (_tao_seq_len); + + // If length is 0 we return true. + if (0 >= _tao_seq_len) + { + return 1; + } + + // Retrieve all the elements. +#if (TAO_NO_COPY_OCTET_SEQUENCES == 1) + if (ACE_BIT_DISABLED (strm.start ()->flags (), + ACE_Message_Block::DONT_DELETE)) + { + TAO_Unbounded_Sequence *oseq = + static_cast*> (&key); + oseq->replace (_tao_seq_len, strm.start ()); + oseq->mb ()->wr_ptr (oseq->mb()->rd_ptr () + _tao_seq_len); + strm.skip_bytes (_tao_seq_len); + return 1; + } + return strm.read_octet_array (key.get_buffer (), + _tao_seq_len); +#else /* TAO_NO_COPY_OCTET_SEQUENCES == 0 */ + return strm.read_octet_array (key.get_buffer (), key.length ()); +#endif /* TAO_NO_COPY_OCTET_SEQUENCES == 0 */ + + } + return 0; +} + #endif /* end #if !defined */ // TAO_IDL - Generated from --- orig/Object_KeyC.h 2005-04-08 10:17:40.978604800 +0200 +++ Object_KeyC.h 2005-04-08 10:17:41.879900800 +0200 @@ -117,6 +117,25 @@ ) : TAO_Unbounded_Sequence (length, mb) {} #endif /* TAO_NO_COPY_OCTET_SEQUENCE == 1 */ + + // Hand crafted. + + static void encode_sequence_to_string ( + char * &str, + const TAO_Unbounded_Sequence &seq + ); + static void decode_string_to_sequence ( + TAO_Unbounded_Sequence &seq, + const char *str + ); + static int is_legal (u_char & c); + + /// A special method that gives no regard to how the ORB has + /// configured the resource factory. This will be used only + /// during Profile decoding and should be safe. This is a solution + /// for the bug report [BUG 1616] + static CORBA::Boolean demarshal_key (ObjectKey &key, + TAO_InputCDR &cdr); }; #endif /* end #if !defined */