append.cpp

Go to the documentation of this file.
00001 
00002 //=============================================================================
00003 /**
00004  *  @file     append.cpp
00005  *
00006  *  $Id: append.cpp 79339 2007-08-14 17:49:17Z sowayaa $
00007  *
00008  *   Appends a CDR stream to another CDR stream. Due to the
00009  *   stringent alignment requirements, it is not possible to simply
00010  *   append or memcpy. Instead we go thru the same CDR encoding rules
00011  *
00012  *
00013  *  @author  Copyright 1994-1995 by Sun Microsystems Inc.  and Aniruddha Gokhale
00014  */
00015 //=============================================================================
00016 
00017 
00018 #include "tao/AnyTypeCode/TypeCode.h"
00019 #include "tao/AnyTypeCode/Marshal.h"
00020 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
00021 #include "tao/AnyTypeCode/TypeCode_Constants.h"
00022 #include "tao/AnyTypeCode/OctetSeqA.h"
00023 #include "tao/AnyTypeCode/Any.h"
00024 #include "tao/debug.h"
00025 #include "tao/Valuetype_Adapter.h"
00026 #include "tao/ORB_Core.h"
00027 #include "tao/CDR.h"
00028 #include "tao/SystemException.h"
00029 
00030 #include "ace/Dynamic_Service.h"
00031 
00032 ACE_RCSID (AnyTypeCode,
00033            append,
00034            "$Id: append.cpp 79339 2007-08-14 17:49:17Z sowayaa $")
00035 
00036 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00037 
00038 // Encode instances of arbitrary data types based only on typecode.
00039 // "data" points to the data type; if it's not a primitve data type,
00040 // the TypeCode interpreter is used to recursively encode its
00041 // components.  "context" is the marshaling stream on which to encode
00042 // the data value.
00043 
00044 TAO::traverse_status
00045 TAO_Marshal_Primitive::append (CORBA::TypeCode_ptr tc,
00046                                TAO_InputCDR *src,
00047                                TAO_OutputCDR *dest)
00048 {
00049   CORBA::Boolean continue_append = true;
00050   TAO::traverse_status retval =
00051     TAO::TRAVERSE_CONTINUE; // status of encode operation
00052 
00053   CORBA::TCKind const k = tc->kind ();
00054 
00055   switch (k)
00056     {
00057     case CORBA::tk_null:
00058     case CORBA::tk_void:
00059       break;
00060     case CORBA::tk_short:
00061     case CORBA::tk_ushort:
00062       continue_append = dest->append_short (*src);
00063       break;
00064     case CORBA::tk_long:
00065     case CORBA::tk_ulong:
00066     case CORBA::tk_float:
00067     case CORBA::tk_enum:
00068       continue_append = dest->append_long (*src);
00069       break;
00070     case CORBA::tk_double:
00071     case CORBA::tk_longlong:
00072     case CORBA::tk_ulonglong:
00073       continue_append = dest->append_double (*src);
00074       break;
00075     case CORBA::tk_boolean:
00076       continue_append = dest->append_boolean (*src);
00077       break;
00078     case CORBA::tk_char:
00079     case CORBA::tk_octet:
00080       continue_append = dest->append_octet (*src);
00081       break;
00082     case CORBA::tk_longdouble:
00083       continue_append = dest->append_longdouble (*src);
00084       break;
00085     case CORBA::tk_wchar:
00086       continue_append = dest->append_wchar (*src);
00087       break;
00088     default:
00089       retval = TAO::TRAVERSE_STOP;
00090       // we are not a primitive type
00091     }
00092 
00093   if (retval == TAO::TRAVERSE_CONTINUE
00094       && continue_append == 1)
00095     return TAO::TRAVERSE_CONTINUE;
00096 
00097   if (TAO_debug_level > 0)
00098     ACE_DEBUG ((
00099         LM_DEBUG,
00100         ACE_TEXT ("TAO_Marshal_Primitive::append detected error\n")
00101       ));
00102 
00103   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00104 }
00105 
00106 TAO::traverse_status
00107 TAO_Marshal_Any::append (CORBA::TypeCode_ptr,
00108                          TAO_InputCDR *src,
00109                          TAO_OutputCDR *dest)
00110 {
00111   // Typecode of the element that makes the Any.
00112   CORBA::TypeCode_var elem_tc;
00113 
00114   if (!(*src >> elem_tc.inout ()))
00115     throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00116 
00117   if (!(*dest << elem_tc.in ()))
00118     throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00119 
00120   // append the data
00121   TAO::traverse_status retval =
00122     TAO_Marshal_Object::perform_append (elem_tc.in (), src, dest);
00123 
00124   if (retval != TAO::TRAVERSE_CONTINUE)
00125     {
00126       if (TAO_debug_level > 0)
00127         ACE_DEBUG ((LM_DEBUG,
00128                     ACE_TEXT ("TAO_Marshal_Any::append detected error\n")));
00129 
00130       throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00131     }
00132 
00133   return retval;
00134 }
00135 
00136 TAO::traverse_status
00137 TAO_Marshal_TypeCode::append (CORBA::TypeCode_ptr,
00138                               TAO_InputCDR *src,
00139                               TAO_OutputCDR *dest)
00140 {
00141   CORBA::Boolean continue_append = true;
00142   TAO::traverse_status retval =
00143     TAO::TRAVERSE_CONTINUE;
00144   CORBA::ULong kind;
00145 
00146   // Decode the "kind" field of the typecode from the src for further
00147   // use. However, also write it back into the destination
00148   continue_append = (CORBA::Boolean) (src->read_ulong (kind)
00149                                       ? dest->write_ulong (kind)
00150                                       : false);
00151 
00152   if (continue_append == true)
00153     {
00154       // Typecodes with empty parameter lists all have preallocated
00155       // constants.  We use those to reduce memory consumption and
00156       // heap access ... also, to speed things up!
00157       if ((kind < CORBA::TAO_TC_KIND_COUNT)
00158           || (kind == ~0u))
00159         {
00160           // Either a non-constant typecode or an indirected typecode.
00161           switch (kind)
00162             {
00163               // Need special handling for all kinds of typecodes that
00164               // have nonempty parameter lists ...
00165             default:
00166               // nothing to de done
00167               break;
00168             case CORBA::tk_string:
00169             case CORBA::tk_wstring:
00170               {
00171                 // read and write the bounds
00172                 retval =
00173                   TAO_Marshal_Object::perform_append (CORBA::_tc_long,
00174                                                       src,
00175                                                       dest);
00176               }
00177             break;
00178 
00179             // Indirected typecodes, illegal at "top level"
00180             case ~0u:
00181               {
00182                 // read and write the negative offset
00183                 retval =
00184                   TAO_Marshal_Object::perform_append (CORBA::_tc_long,
00185                                                       src,
00186                                                       dest);
00187               }
00188             break;
00189 
00190             // The rest have "complex" parameter lists that are
00191             // encoded as bulk octets ...
00192             case CORBA::tk_objref:
00193             case CORBA::tk_struct:
00194             case CORBA::tk_union:
00195             case CORBA::tk_enum:
00196             case CORBA::tk_sequence:
00197             case CORBA::tk_array:
00198             case CORBA::tk_alias:
00199             case CORBA::tk_except:
00200             case CORBA::tk_value:
00201             case CORBA::tk_value_box:
00202             case CORBA::tk_native:
00203             case CORBA::tk_abstract_interface:
00204             case CORBA::tk_local_interface:
00205             case CORBA::tk_component:
00206             case CORBA::tk_home:
00207             case CORBA::tk_event:
00208               {
00209                 // write the encapsulation i.e., octet sequence
00210                 retval =
00211                   TAO_Marshal_Object::perform_append (CORBA::_tc_OctetSeq,
00212                                                       src,
00213                                                       dest);
00214               }
00215             } // end of switch
00216         }
00217       else // bad kind_ value to be decoded
00218         {
00219           if (TAO_debug_level > 0)
00220             {
00221               ACE_DEBUG ((LM_DEBUG,
00222                           ACE_TEXT ("TAO_Marshal_TypeCode: ")
00223                           ACE_TEXT ("Bad kind_ value in CDR stream\n")));
00224             }
00225 
00226           throw ::CORBA::BAD_TYPECODE ();
00227         }
00228     }
00229 
00230   if (continue_append == 1 && retval == TAO::TRAVERSE_CONTINUE)
00231     {
00232       return TAO::TRAVERSE_CONTINUE;
00233     }
00234 
00235   if (TAO_debug_level > 0)
00236     {
00237       ACE_DEBUG ((LM_DEBUG,
00238                   ACE_TEXT ("TAO_Marshal_TypeCode::append detected error\n")));
00239     }
00240 
00241   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00242 }
00243 
00244 TAO::traverse_status
00245 TAO_Marshal_Principal::append (CORBA::TypeCode_ptr,
00246                                TAO_InputCDR *src,
00247                                TAO_OutputCDR *dest)
00248 {
00249   // write the octet sequence representing the Principal
00250   return TAO_Marshal_Object::perform_append (CORBA::_tc_OctetSeq, src, dest);
00251 }
00252 
00253 TAO::traverse_status
00254 TAO_Marshal_ObjRef::append (CORBA::TypeCode_ptr,
00255                             TAO_InputCDR *src,
00256                             TAO_OutputCDR *dest)
00257 {
00258   CORBA::Boolean continue_append = true;
00259 
00260   // First, append the type hint. This will be the type_id encoded in an
00261   // object reference.
00262   dest->append_string (*src);
00263 
00264   // Read the profiles, discarding all until an IIOP profile comes by.
00265   // Once we see an IIOP profile, ignore any further ones.
00266   //
00267   // XXX this will need to change someday to let different protocol
00268   // code be accessed, not just IIOP.  Protocol modules will be
00269   // dynamically loaded from shared libraries via ORB_init (), and we
00270   // just need to be able to access such preloaded libraries here as
00271   // we unmarshal objrefs.
00272 
00273   CORBA::ULong profiles = 0;
00274 
00275   // get the count of profiles that follow. This will tell us the
00276   // length of the sequence
00277   continue_append = (CORBA::Boolean) (src->read_ulong (profiles)
00278                                       ? dest->write_ulong (profiles)
00279                                       : 0);
00280 
00281   // No profiles means a NIL objref.
00282   while (profiles-- != 0 && continue_append)
00283     {
00284       CORBA::ULong tag = 0;
00285 
00286       // get the profile ID tag
00287       if ((continue_append = (CORBA::Boolean) (src->read_ulong (tag)
00288                                                ? dest->write_ulong (tag)
00289                                                : 0))  == 0)
00290         continue;
00291 
00292       CORBA::ULong length = 0;
00293       if ((continue_append = (CORBA::Boolean) (src->read_ulong (length)
00294                               ? dest->write_ulong (length)
00295                               : 0)) == 0)
00296         continue;
00297 
00298       // @@ This can be optimized! Pre-allocating on the destination
00299       //    and then copying directly into that.
00300       CORBA::Octet* body = 0;
00301       ACE_NEW_RETURN (body,
00302                       CORBA::Octet[length],
00303                       TAO::TRAVERSE_STOP);
00304       continue_append =
00305         (CORBA::Boolean) (src->read_octet_array (body, length)
00306                           ? dest->write_octet_array (body, length)
00307                           : 0);
00308       delete [] body;
00309     }
00310 
00311   if (continue_append == 1)
00312     return TAO::TRAVERSE_CONTINUE;
00313 
00314   if (TAO_debug_level > 0)
00315     ACE_DEBUG ((
00316         LM_DEBUG,
00317         ACE_TEXT ("TAO_Marshal_ObjRef::append detected error\n")
00318       ));
00319 
00320   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00321 }
00322 
00323 TAO::traverse_status
00324 TAO_Marshal_Struct::append (CORBA::TypeCode_ptr  tc,
00325                             TAO_InputCDR *src,
00326                             TAO_OutputCDR *dest)
00327 {
00328   TAO::traverse_status retval =
00329     TAO::TRAVERSE_CONTINUE;
00330   CORBA::TypeCode_var param;
00331 
00332   // Number of fields in the struct.
00333   const CORBA::ULong member_count =
00334     tc->member_count ();
00335 
00336   for (CORBA::ULong i = 0;
00337        i < member_count && retval == TAO::TRAVERSE_CONTINUE;
00338        ++i)
00339     {
00340       // get member type
00341       param = tc->member_type (i);
00342 
00343       retval = TAO_Marshal_Object::perform_append (param.in (), src, dest);
00344     }
00345 
00346   if (retval == TAO::TRAVERSE_CONTINUE)
00347     return TAO::TRAVERSE_CONTINUE;
00348 
00349   if (TAO_debug_level > 0)
00350     ACE_DEBUG ((LM_DEBUG,
00351                 ACE_TEXT ("TAO_Marshal_Struct::append detected error\n")));
00352 
00353   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00354 }
00355 
00356 TAO::traverse_status
00357 TAO_Marshal_Union::append (CORBA::TypeCode_ptr tc,
00358                            TAO_InputCDR *src,
00359                            TAO_OutputCDR *dest)
00360 {
00361   CORBA::TypeCode_var discrim_tc = tc->discriminator_type ();
00362 
00363   CORBA::ULong kind = discrim_tc->kind ();
00364 
00365   // Save the discriminator value in a temporary variable...
00366   CORBA::Short short_v = CORBA::Short();
00367   CORBA::UShort ushort_v = CORBA::UShort();
00368   CORBA::Long long_v = CORBA::Long();
00369   CORBA::ULong ulong_v = CORBA::ULong();
00370   CORBA::ULong enum_v = CORBA::ULong();
00371   CORBA::Char char_v = CORBA::Char();
00372   CORBA::WChar wchar_v = CORBA::WChar();
00373   CORBA::Boolean boolean_v = false;
00374 
00375   switch (kind)
00376     {
00377     case CORBA::tk_short:
00378       {
00379         if (!src->read_short (short_v)
00380             || !dest->write_short (short_v))
00381           return TAO::TRAVERSE_STOP;
00382       }
00383       break;
00384 
00385     case CORBA::tk_ushort:
00386       {
00387         if (!src->read_ushort (ushort_v)
00388             || !dest->write_ushort (ushort_v))
00389           return TAO::TRAVERSE_STOP;
00390       }
00391       break;
00392 
00393     case CORBA::tk_long:
00394       {
00395         if (!src->read_long (long_v)
00396             || !dest->write_long (long_v))
00397           return TAO::TRAVERSE_STOP;
00398       }
00399       break;
00400 
00401     case CORBA::tk_ulong:
00402       {
00403         if (!src->read_ulong (ulong_v)
00404             || !dest->write_ulong (ulong_v))
00405           return TAO::TRAVERSE_STOP;
00406       }
00407       break;
00408 
00409     case CORBA::tk_enum:
00410       {
00411         if (!src->read_ulong (enum_v)
00412             || !dest->write_ulong (enum_v))
00413           return TAO::TRAVERSE_STOP;
00414       }
00415       break;
00416 
00417     case CORBA::tk_char:
00418       {
00419         if (!src->read_char (char_v)
00420             || !dest->write_char (char_v))
00421           return TAO::TRAVERSE_STOP;
00422       }
00423       break;
00424 
00425     case CORBA::tk_wchar:
00426       {
00427         if (!src->read_wchar (wchar_v)
00428             || !dest->write_wchar (wchar_v))
00429           return TAO::TRAVERSE_STOP;
00430       }
00431       break;
00432 
00433     case CORBA::tk_boolean:
00434       {
00435         if (!src->read_boolean (boolean_v)
00436             || !dest->write_boolean (boolean_v))
00437           return TAO::TRAVERSE_STOP;
00438       }
00439       break;
00440 
00441     default:
00442       return TAO::TRAVERSE_STOP;
00443     }
00444 
00445   const CORBA::ULong member_count =
00446     tc->member_count ();
00447 
00448   const CORBA::ULong null_member = ~static_cast<CORBA::ULong> (0U);
00449 
00450   CORBA::ULong current_member = null_member;
00451   CORBA::ULong default_member = null_member;
00452 
00453   for (CORBA::ULong i = 0;
00454        i < member_count && current_member == null_member;
00455        ++i)
00456     {
00457       CORBA::Any_var any = tc->member_label (i);
00458 
00459       CORBA::Octet o;
00460 
00461       if ((any >>= CORBA::Any::to_octet (o)) && o == 0)
00462         {
00463           CORBA::ULong default_index =
00464             tc->default_index ();
00465 
00466           if (i != default_index)
00467             throw ::CORBA::BAD_TYPECODE ();
00468           // Found the default branch, save its position and continue
00469           // trying to find the current value...
00470           default_member = i;
00471           continue;
00472         }
00473 
00474       switch (kind)
00475         {
00476         case CORBA::tk_short:
00477           {
00478             CORBA::Short d;
00479             if ((any >>= d) && d == short_v)
00480               current_member = i;
00481           }
00482           break;
00483 
00484         case CORBA::tk_ushort:
00485           {
00486             CORBA::UShort d;
00487             if ((any >>= d) && d == ushort_v)
00488               current_member = i;
00489           }
00490           break;
00491 
00492         case CORBA::tk_long:
00493           {
00494             CORBA::Long d;
00495             if ((any >>= d) && d == long_v)
00496               current_member = i;
00497           }
00498           break;
00499 
00500         case CORBA::tk_ulong:
00501           {
00502             CORBA::ULong d;
00503             if ((any >>= d) && d == ulong_v)
00504               current_member = i;
00505           }
00506           break;
00507 
00508         case CORBA::tk_enum:
00509           {
00510             CORBA::ULong d;
00511             TAO::Any_Impl *impl = any->impl ();
00512 
00513             if (impl->encoded ())
00514               {
00515                 TAO::Unknown_IDL_Type * const unk =
00516                   dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
00517 
00518                 if (!unk)
00519                   throw ::CORBA::INTERNAL ();
00520 
00521                 // We don't want unk's rd_ptr to move, in case
00522                 // we are shared by another Any, so we use this
00523                 // to copy the state, not the buffer.
00524                 TAO_InputCDR for_reading (unk->_tao_get_cdr ());
00525 
00526                 for_reading.read_ulong (d);
00527               }
00528             else
00529               {
00530                 TAO_OutputCDR out;
00531                 impl->marshal_value (out);
00532                 TAO_InputCDR cdr (out);
00533                 cdr.read_ulong (d);
00534               }
00535 
00536             if (d == enum_v)
00537               {
00538                 current_member = i;
00539               }
00540           }
00541           break;
00542 
00543         case CORBA::tk_char:
00544           {
00545             CORBA::Char d;
00546             if ((any >>= CORBA::Any::to_char (d)) && d == char_v)
00547               current_member = i;
00548           }
00549           break;
00550 
00551         case CORBA::tk_wchar:
00552           {
00553             CORBA::WChar d;
00554             if ((any >>= CORBA::Any::to_wchar (d)) && d == wchar_v)
00555               current_member = i;
00556           }
00557           break;
00558 
00559         case CORBA::tk_boolean:
00560           {
00561             CORBA::Boolean d;
00562             if ((any >>= CORBA::Any::to_boolean (d)) && d == boolean_v)
00563               current_member = i;
00564           }
00565           break;
00566 
00567         default:
00568           return TAO::TRAVERSE_STOP;
00569         }
00570     }
00571 
00572   if (current_member == null_member)
00573     {
00574       // Cannot find the current member, check if there is a
00575       // default...
00576       if (default_member != null_member)
00577         {
00578           // Good, use the default to append...
00579           CORBA::TypeCode_var member_tc =
00580             tc->member_type (default_member);
00581           return TAO_Marshal_Object::perform_append (member_tc.in (),
00582                                                      src,
00583                                                      dest);
00584         }
00585 
00586       // If we're here, we have an implicit default case, and we
00587       // should just return without appending anything, since no
00588       // union member was marshaled in the first place.
00589       return TAO::TRAVERSE_CONTINUE;
00590     }
00591 
00592   // If we found the member successfully then just use that one...
00593   CORBA::TypeCode_var member_tc =
00594     tc->member_type (current_member);
00595   return TAO_Marshal_Object::perform_append (member_tc.in (),
00596                                              src,
00597                                              dest
00598                                             );
00599 }
00600 
00601 TAO::traverse_status
00602 TAO_Marshal_String::append (CORBA::TypeCode_ptr,
00603                             TAO_InputCDR *src,
00604                             TAO_OutputCDR *dest)
00605 {
00606   CORBA::Boolean continue_append = true;
00607 
00608   // On decode, omit the check against specified string bounds, and
00609   // cope with illegal "zero length" strings (all lengths on the wire
00610   // must include a NUL).
00611   //
00612   // This is on the principle of being gracious in what we accept; we
00613   // don't generate messages that fail to comply with protocol specs,
00614   // but we will accept them when it's clear how to do so.
00615 
00616   continue_append = dest->append_string (*src);
00617   if (continue_append == 1)
00618     return TAO::TRAVERSE_CONTINUE;
00619 
00620   if (TAO_debug_level > 0)
00621     ACE_DEBUG ((LM_DEBUG,
00622                 ACE_TEXT ("TAO_Marshal_TypeCode::append detected error\n")));
00623 
00624   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00625 }
00626 
00627 TAO::traverse_status
00628 TAO_Marshal_Sequence::append (CORBA::TypeCode_ptr  tc,
00629                               TAO_InputCDR *src,
00630                               TAO_OutputCDR *dest)
00631 {
00632   // Size of element.
00633   CORBA::ULong bounds;
00634 
00635   // First unmarshal the sequence length ... we trust it to be right
00636   // here, on the "be gracious in what you accept" principle.  We
00637   // don't generate illegal sequences (i.e. length > bounds).
00638 
00639   CORBA::Boolean continue_append =
00640     (CORBA::Boolean) (src->read_ulong (bounds)
00641                       ? dest->write_ulong (bounds)
00642                       : 0);
00643 
00644   if (!continue_append)
00645     {
00646       ACE_DEBUG ((
00647           LM_DEBUG,
00648           ACE_TEXT ("TAO_Marshal_Sequence::append detected error\n")
00649         ));
00650       throw ::CORBA::MARSHAL ();
00651     }
00652 
00653   if (bounds == 0)
00654     {
00655       return TAO::TRAVERSE_CONTINUE;
00656     }
00657 
00658   if (continue_append)
00659     {
00660       // Get element typecode.
00661       CORBA::TypeCode_var tc2 =
00662         tc->content_type ();
00663 
00664       TAO::traverse_status retval =
00665         TAO::TRAVERSE_CONTINUE;
00666 
00667       CORBA::TCKind kind = tc2->kind ();
00668 
00669       switch (kind)
00670         {
00671         case CORBA::tk_octet:
00672           {
00673             char* buf;
00674             if (dest->adjust (ACE_CDR::OCTET_SIZE * bounds,
00675                               ACE_CDR::OCTET_ALIGN, buf) == 0)
00676               {
00677                 if (src->read_octet_array ((ACE_CDR::Octet*)buf, bounds) == 0)
00678                   retval = TAO::TRAVERSE_STOP;
00679               }
00680           }
00681           break;
00682         case CORBA::tk_boolean:
00683           {
00684             char* buf;
00685             if (dest->adjust (ACE_CDR::OCTET_SIZE * bounds,
00686                               ACE_CDR::OCTET_ALIGN, buf) == 0)
00687               {
00688                 if (src->read_boolean_array ((ACE_CDR::Boolean*)buf, bounds) == 0)
00689                   retval = TAO::TRAVERSE_STOP;
00690               }
00691           }
00692           break;
00693         case CORBA::tk_char:
00694           {
00695             char* buf;
00696             if (dest->adjust (ACE_CDR::OCTET_SIZE * bounds,
00697                               ACE_CDR::OCTET_ALIGN, buf) == 0)
00698               {
00699                 if (src->read_char_array ((ACE_CDR::Char*)buf, bounds) == 0)
00700                   retval = TAO::TRAVERSE_STOP;
00701               }
00702           }
00703           break;
00704         case CORBA::tk_short:
00705           {
00706             char* buf;
00707             if (dest->adjust (ACE_CDR::SHORT_SIZE * bounds,
00708                               ACE_CDR::SHORT_ALIGN, buf) == 0)
00709               {
00710                 if (src->read_short_array ((ACE_CDR::Short*)buf, bounds) == 0)
00711                   retval = TAO::TRAVERSE_STOP;
00712               }
00713           }
00714           break;
00715         case CORBA::tk_ushort:
00716           {
00717             char* buf;
00718             if (dest->adjust (ACE_CDR::SHORT_SIZE * bounds,
00719                               ACE_CDR::SHORT_ALIGN, buf) == 0)
00720               {
00721                 if (src->read_ushort_array ((ACE_CDR::UShort*)buf, bounds) == 0)
00722                   retval = TAO::TRAVERSE_STOP;
00723               }
00724           }
00725           break;
00726         case CORBA::tk_wchar:
00727           {
00728             char* buf;
00729             if (dest->adjust (ACE_CDR::SHORT_SIZE * bounds,
00730                               ACE_CDR::SHORT_ALIGN, buf) == 0)
00731               {
00732                 if (src->read_wchar_array ((ACE_CDR::WChar*)buf, bounds) == 0)
00733                   retval = TAO::TRAVERSE_STOP;
00734               }
00735           }
00736           break;
00737         case CORBA::tk_long:
00738           {
00739             char* buf;
00740             if (dest->adjust (ACE_CDR::LONG_SIZE * bounds,
00741                               ACE_CDR::LONG_ALIGN, buf) == 0)
00742               {
00743                 if (src->read_long_array ((ACE_CDR::Long*)buf, bounds) == 0)
00744                   retval = TAO::TRAVERSE_STOP;
00745               }
00746           }
00747           break;
00748         case CORBA::tk_ulong:
00749           {
00750             char* buf;
00751             if (dest->adjust (ACE_CDR::LONG_SIZE * bounds,
00752                               ACE_CDR::LONG_ALIGN, buf) == 0)
00753               {
00754                 if (src->read_ulong_array ((ACE_CDR::ULong*)buf, bounds) == 0)
00755                   retval = TAO::TRAVERSE_STOP;
00756               }
00757           }
00758           break;
00759         case CORBA::tk_float:
00760           {
00761             char* buf;
00762             if (dest->adjust (ACE_CDR::LONG_SIZE * bounds,
00763                               ACE_CDR::LONG_ALIGN, buf) == 0)
00764               {
00765                 if (src->read_float_array ((ACE_CDR::Float*)buf, bounds) == 0)
00766                   retval = TAO::TRAVERSE_STOP;
00767               }
00768           }
00769           break;
00770         case CORBA::tk_double:
00771           {
00772             char* buf;
00773             if (dest->adjust (ACE_CDR::LONGLONG_SIZE * bounds,
00774                               ACE_CDR::LONGLONG_ALIGN, buf) == 0)
00775               {
00776                 if (src->read_double_array ((ACE_CDR::Double*)buf, bounds) == 0)
00777                   retval = TAO::TRAVERSE_STOP;
00778               }
00779           }
00780           break;
00781         case CORBA::tk_longlong:
00782           {
00783             char* buf;
00784             if (dest->adjust (ACE_CDR::LONGLONG_SIZE * bounds,
00785                               ACE_CDR::LONGLONG_ALIGN, buf) == 0)
00786               {
00787                 if (src->read_longlong_array ((ACE_CDR::LongLong*)buf, bounds) == 0)
00788                   retval = TAO::TRAVERSE_STOP;
00789               }
00790           }
00791           break;
00792         case CORBA::tk_ulonglong:
00793           {
00794             char* buf;
00795             if (dest->adjust (ACE_CDR::LONGLONG_SIZE * bounds,
00796                               ACE_CDR::LONGLONG_ALIGN, buf) == 0)
00797               {
00798                 if (src->read_ulonglong_array ((ACE_CDR::ULongLong*)buf, bounds) == 0)
00799                   retval = TAO::TRAVERSE_STOP;
00800               }
00801           }
00802           break;
00803         case CORBA::tk_longdouble:
00804           {
00805             char* buf;
00806             if (dest->adjust (ACE_CDR::LONGDOUBLE_SIZE * bounds,
00807                               ACE_CDR::LONGDOUBLE_ALIGN, buf) == 0)
00808               {
00809                 if (src->read_longdouble_array ((ACE_CDR::LongDouble*)buf, bounds) == 0)
00810                   retval = TAO::TRAVERSE_STOP;
00811               }
00812           }
00813           break;
00814 
00815         default:
00816           while (bounds-- && retval == TAO::TRAVERSE_CONTINUE)
00817             {
00818               retval = TAO_Marshal_Object::perform_append (tc2.in (),
00819                                                            src,
00820                                                            dest
00821                                                            );
00822             }
00823           break;
00824         }// end of switch
00825 
00826       if (retval == TAO::TRAVERSE_CONTINUE)
00827         return TAO::TRAVERSE_CONTINUE;
00828     }
00829   // error exit
00830   if (TAO_debug_level > 0)
00831     ACE_DEBUG ((
00832         LM_DEBUG,
00833         ACE_TEXT ("marshaling TAO_Marshal_Sequence::append detected error\n")
00834       ));
00835 
00836   throw ::CORBA::MARSHAL ();
00837 }
00838 
00839 TAO::traverse_status
00840 TAO_Marshal_Array::append (CORBA::TypeCode_ptr  tc,
00841                            TAO_InputCDR *src,
00842                            TAO_OutputCDR *dest)
00843 {
00844   // retrieve the bounds of the array
00845   CORBA::ULong bounds = tc->length ();
00846 
00847   // get element typecode
00848   CORBA::TypeCode_var tc2 = tc->content_type ();
00849 
00850   // For CORBA basic types, the copy can be optimized
00851   CORBA::TCKind kind = tc2->kind ();
00852 
00853   // Return status.
00854   TAO::traverse_status retval =
00855     TAO::TRAVERSE_CONTINUE;
00856 
00857   switch (kind)
00858     {
00859     case CORBA::tk_octet:
00860       {
00861         char* buf;
00862         if (dest->adjust (ACE_CDR::OCTET_SIZE * bounds,
00863                           ACE_CDR::OCTET_ALIGN, buf) == 0)
00864           {
00865             if (src->read_octet_array ((ACE_CDR::Octet*)buf, bounds) == 0)
00866               retval = TAO::TRAVERSE_STOP;
00867           }
00868       }
00869       break;
00870     case CORBA::tk_boolean:
00871       {
00872         char* buf;
00873         if (dest->adjust (ACE_CDR::OCTET_SIZE * bounds,
00874                           ACE_CDR::OCTET_ALIGN, buf) == 0)
00875           {
00876             if (src->read_boolean_array ((ACE_CDR::Boolean*)buf, bounds) == 0)
00877               retval = TAO::TRAVERSE_STOP;
00878           }
00879       }
00880       break;
00881     case CORBA::tk_char:
00882       {
00883         char* buf;
00884         if (dest->adjust (ACE_CDR::OCTET_SIZE * bounds,
00885                           ACE_CDR::OCTET_ALIGN, buf) == 0)
00886           {
00887             if (src->read_char_array ((ACE_CDR::Char*)buf, bounds) == 0)
00888               retval = TAO::TRAVERSE_STOP;
00889           }
00890       }
00891       break;
00892     case CORBA::tk_short:
00893       {
00894         char* buf;
00895         if (dest->adjust (ACE_CDR::SHORT_SIZE * bounds,
00896                           ACE_CDR::SHORT_ALIGN, buf) == 0)
00897           {
00898             if (src->read_short_array ((ACE_CDR::Short*)buf, bounds) == 0)
00899               retval = TAO::TRAVERSE_STOP;
00900           }
00901       }
00902       break;
00903     case CORBA::tk_ushort:
00904       {
00905         char* buf;
00906         if (dest->adjust (ACE_CDR::SHORT_SIZE * bounds,
00907                           ACE_CDR::SHORT_ALIGN, buf) == 0)
00908           {
00909             if (src->read_ushort_array ((ACE_CDR::UShort*)buf, bounds) == 0)
00910               retval = TAO::TRAVERSE_STOP;
00911           }
00912       }
00913       break;
00914     case CORBA::tk_wchar:
00915       {
00916         char* buf;
00917         if (dest->adjust (ACE_CDR::SHORT_SIZE * bounds,
00918                           ACE_CDR::SHORT_ALIGN, buf) == 0)
00919           {
00920             if (src->read_wchar_array ((ACE_CDR::WChar*)buf, bounds) == 0)
00921               retval = TAO::TRAVERSE_STOP;
00922           }
00923       }
00924       break;
00925     case CORBA::tk_long:
00926       {
00927         char* buf;
00928         if (dest->adjust (ACE_CDR::LONG_SIZE * bounds,
00929                           ACE_CDR::LONG_ALIGN, buf) == 0)
00930           {
00931             if (src->read_long_array ((ACE_CDR::Long*)buf, bounds) == 0)
00932               retval = TAO::TRAVERSE_STOP;
00933           }
00934       }
00935       break;
00936     case CORBA::tk_ulong:
00937       {
00938         char* buf;
00939         if (dest->adjust (ACE_CDR::LONG_SIZE * bounds,
00940                           ACE_CDR::LONG_ALIGN, buf) == 0)
00941           {
00942             if (src->read_ulong_array ((ACE_CDR::ULong*)buf, bounds) == 0)
00943               retval = TAO::TRAVERSE_STOP;
00944           }
00945       }
00946       break;
00947     case CORBA::tk_float:
00948       {
00949         char* buf;
00950         if (dest->adjust (ACE_CDR::LONG_SIZE * bounds,
00951                           ACE_CDR::LONG_ALIGN, buf) == 0)
00952           {
00953             if (src->read_float_array ((ACE_CDR::Float*)buf, bounds) == 0)
00954               retval = TAO::TRAVERSE_STOP;
00955           }
00956       }
00957       break;
00958     case CORBA::tk_double:
00959       {
00960         char* buf;
00961         if (dest->adjust (ACE_CDR::LONGLONG_SIZE * bounds,
00962                           ACE_CDR::LONGLONG_ALIGN, buf) == 0)
00963           {
00964             if (src->read_double_array ((ACE_CDR::Double*)buf, bounds) == 0)
00965               retval = TAO::TRAVERSE_STOP;
00966           }
00967       }
00968       break;
00969     case CORBA::tk_longlong:
00970       {
00971         char* buf;
00972         if (dest->adjust (ACE_CDR::LONGLONG_SIZE * bounds,
00973                           ACE_CDR::LONGLONG_ALIGN, buf) == 0)
00974           {
00975             if (src->read_longlong_array ((ACE_CDR::LongLong*)buf, bounds) == 0)
00976               retval = TAO::TRAVERSE_STOP;
00977           }
00978       }
00979       break;
00980     case CORBA::tk_ulonglong:
00981       {
00982         char* buf;
00983         if (dest->adjust (ACE_CDR::LONGLONG_SIZE * bounds,
00984                           ACE_CDR::LONGLONG_ALIGN, buf) == 0)
00985           {
00986             if (src->read_ulonglong_array ((ACE_CDR::ULongLong*)buf, bounds) == 0)
00987               retval = TAO::TRAVERSE_STOP;
00988           }
00989       }
00990       break;
00991     case CORBA::tk_longdouble:
00992       {
00993         char* buf;
00994         if (dest->adjust (ACE_CDR::LONGDOUBLE_SIZE * bounds,
00995                           ACE_CDR::LONGDOUBLE_ALIGN, buf) == 0)
00996           {
00997             if (src->read_longdouble_array ((ACE_CDR::LongDouble*)buf, bounds) == 0)
00998               retval = TAO::TRAVERSE_STOP;
00999           }
01000       }
01001       break;
01002     default:
01003       while (bounds-- && retval == TAO::TRAVERSE_CONTINUE)
01004         {
01005           retval = TAO_Marshal_Object::perform_append (tc2.in (),
01006                                                        src,
01007                                                        dest
01008                                                       );
01009         }
01010       break;
01011     }// end of switch
01012 
01013   if (retval == TAO::TRAVERSE_CONTINUE)
01014     return retval;
01015 
01016   // error exit
01017   if (TAO_debug_level > 0)
01018     ACE_DEBUG ((LM_DEBUG,
01019                 ACE_TEXT ("TAO_Marshal_Sequence::append detected error\n")));
01020 
01021   throw ::CORBA::MARSHAL ();
01022 }
01023 
01024 TAO::traverse_status
01025 TAO_Marshal_Alias::append (CORBA::TypeCode_ptr  tc,
01026                            TAO_InputCDR *src,
01027                            TAO_OutputCDR *dest)
01028 {
01029   // Typecode of the aliased type.
01030   CORBA::TypeCode_var tc2;
01031   CORBA::Boolean continue_append = true;
01032 
01033   // Status of decode operation.
01034   TAO::traverse_status retval =
01035     TAO::TRAVERSE_CONTINUE;
01036 
01037   tc2 = tc->content_type ();
01038 
01039   retval = TAO_Marshal_Object::perform_append (tc2.in (), src, dest);
01040 
01041   if (retval == TAO::TRAVERSE_CONTINUE
01042       && continue_append == true)
01043     return TAO::TRAVERSE_CONTINUE;
01044 
01045   if (TAO_debug_level > 0)
01046     ACE_DEBUG ((LM_DEBUG,
01047                 ACE_TEXT ("TAO_Marshal_Alias::append detected error\n")));
01048   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
01049 }
01050 
01051 // Decode exception For exceptions, the "hidden" type ID near the
01052 // front of the on-wire representation was previously unmarshaled and
01053 // mapped to the "tc" typcode we're using to traverse the memory ...
01054 // at the same time its vtable, refcount, and other state was
01055 // established.
01056 //
01057 // NOTE: This is asymmetric with respect to encoding exceptions.
01058 TAO::traverse_status
01059 TAO_Marshal_Except::append (CORBA::TypeCode_ptr  tc,
01060                             TAO_InputCDR *src,
01061                             TAO_OutputCDR *dest
01062                             )
01063 {
01064   TAO::traverse_status retval =
01065     TAO::TRAVERSE_CONTINUE;
01066   CORBA::Boolean continue_append = true;
01067   CORBA::TypeCode_var param;
01068 
01069   // first append the RepositoryID
01070   continue_append = dest->append_string (*src);
01071 
01072   // Number of fields in the struct.
01073   const CORBA::ULong member_count =
01074     tc->member_count ();
01075 
01076   for (CORBA::ULong i = 0;
01077        i < member_count
01078          && retval == TAO::TRAVERSE_CONTINUE
01079          && continue_append == 1;
01080        ++i)
01081     {
01082       param = tc->member_type (i);
01083 
01084       retval = TAO_Marshal_Object::perform_append (param.in (),
01085                                                    src,
01086                                                    dest);
01087     }
01088 
01089   if (retval == TAO::TRAVERSE_CONTINUE
01090       && continue_append == 1)
01091     return TAO::TRAVERSE_CONTINUE;
01092 
01093   if (TAO_debug_level > 0)
01094     ACE_DEBUG ((LM_DEBUG,
01095                 ACE_TEXT ("TAO_Marshal_Except::append detected error\n")));
01096 
01097   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
01098 }
01099 
01100 TAO::traverse_status
01101 TAO_Marshal_WString::append (CORBA::TypeCode_ptr,
01102                              TAO_InputCDR *src,
01103                              TAO_OutputCDR *dest
01104                              )
01105 {
01106   CORBA::Boolean continue_append = true;
01107 
01108   // On decode, omit the check against specified wstring bounds, and
01109   // cope with illegal "zero length" strings (all lengths on the wire
01110   // must include a NUL).
01111   //
01112   // This is on the principle of being gracious in what we accept; we
01113   // don't generate messages that fail to comply with protocol specs,
01114   // but we will accept them when it's clear how to do so.
01115 
01116   continue_append = dest->append_wstring (*src);
01117 
01118   if (continue_append == 1)
01119     return TAO::TRAVERSE_CONTINUE;
01120 
01121   if (TAO_debug_level > 0)
01122     ACE_DEBUG ((LM_DEBUG,
01123                 ACE_TEXT ("TAO_Marshal_WString::append detected error\n")));
01124 
01125   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
01126 }
01127 
01128 TAO::traverse_status
01129 TAO_Marshal_Value::append (CORBA::TypeCode_ptr  tc,
01130                            TAO_InputCDR *src,
01131                            TAO_OutputCDR *dest
01132                            )
01133 {
01134   TAO::traverse_status retval =
01135     TAO::TRAVERSE_CONTINUE;
01136 
01137   // Use the same method to append our base valuetype.
01138   // To achive this we'll need to distinguish between
01139   // first-time/nested appends so that we won't attempt to
01140   // append rep_id several times.
01141   //
01142   if (this->nested_processing_ == 0)
01143     {
01144       this->nested_processing_ = 1;
01145 
01146       CORBA::ULong value_tag;
01147 
01148       if (!src->read_ulong (value_tag) ||
01149           !dest->write_ulong (value_tag))
01150         {
01151           return TAO::TRAVERSE_STOP;
01152         }
01153 
01154       TAO_ORB_Core *orb_core = src->orb_core ();
01155       if (orb_core == 0)
01156         {
01157           orb_core = TAO_ORB_Core_instance ();
01158 
01159           if (TAO_debug_level > 0)
01160             {
01161               ACE_DEBUG ((LM_WARNING,
01162                           "TAO (%P|%t) WARNING: extracting "
01163                           "valuetype using default ORB_Core\n"));
01164             }
01165         }
01166 
01167       TAO_Valuetype_Adapter *adapter = orb_core->valuetype_adapter();
01168 
01169       if (value_tag == 0) // Null value type pointer.
01170         {
01171           //We are done.
01172           return retval;
01173         }
01174       else if (value_tag & adapter->type_info_single ())
01175         {
01176           // Append repository id which is of type string.
01177           dest->append_string (*src);
01178         }
01179       else
01180         {
01181           //@@ boris: VT CDR
01182           return TAO::TRAVERSE_STOP;
01183         }
01184     }
01185 
01186   // Handle our base valuetype if any.
01187   CORBA::TypeCode_var param =
01188     tc->concrete_base_type ();
01189 
01190   CORBA::TCKind const param_kind = param->kind ();
01191 
01192   if (param_kind != CORBA::tk_null)
01193     {
01194       retval = this->append (param.in (),
01195                              src,
01196                              dest
01197                             );
01198 
01199       if (retval != TAO::TRAVERSE_CONTINUE)
01200         {
01201           return retval;
01202         }
01203     }
01204 
01205   // Number of fields in the struct.
01206   const CORBA::ULong member_count =
01207     tc->member_count ();
01208 
01209   for (CORBA::ULong i = 0;
01210        i < member_count && retval == TAO::TRAVERSE_CONTINUE;
01211        ++i)
01212     {
01213       // get member type
01214       param = tc->member_type (i);
01215 
01216       retval =
01217         TAO_Marshal_Object::perform_append (param.in (),
01218                                             src,
01219                                             dest
01220                                            );
01221     }
01222 
01223   if (retval == TAO::TRAVERSE_CONTINUE)
01224     return TAO::TRAVERSE_CONTINUE;
01225 
01226   if (TAO_debug_level > 0)
01227     ACE_DEBUG ((LM_DEBUG,
01228                 ACE_TEXT ("TAO_Marshal_Value::append detected error\n")));
01229 
01230   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
01231 }
01232 
01233 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Sun Jan 27 13:21:06 2008 for TAO_AnyTypeCode by doxygen 1.3.6