skip.cpp

Go to the documentation of this file.
00001 
00002 //=============================================================================
00003 /**
00004  *  @file     skip.cpp
00005  *
00006  *  $Id: skip.cpp 78246 2007-05-02 13:33:04Z johnnyw $
00007  *
00008  *   Code for skipping different data types
00009  *
00010  *   Data types encoded as CDR streams need to be skipped when they
00011  *   are part of an Any.
00012  *
00013  *
00014  *  @author  Aniruddha Gokhale
00015  */
00016 //=============================================================================
00017 
00018 
00019 #include "tao/AnyTypeCode/Marshal.h"
00020 #include "tao/AnyTypeCode/TypeCode.h"
00021 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
00022 #include "tao/AnyTypeCode/Any.h"
00023 
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            skip,
00034            "$Id: skip.cpp 78246 2007-05-02 13:33:04Z johnnyw $")
00035 
00036 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00037 
00038 TAO::traverse_status
00039 TAO_Marshal_Primitive::skip (CORBA::TypeCode_ptr  tc, TAO_InputCDR *stream)
00040 {
00041   CORBA::Boolean continue_skipping = true;
00042 
00043   // Status of skip operation.
00044   TAO::traverse_status retval = TAO::TRAVERSE_CONTINUE;
00045 
00046   CORBA::TCKind const k = tc->kind ();
00047 
00048   switch (k)
00049     {
00050     case CORBA::tk_null:
00051     case CORBA::tk_void:
00052       break;
00053     case CORBA::tk_short:
00054     case CORBA::tk_ushort:
00055       continue_skipping = stream->skip_short ();
00056       break;
00057     case CORBA::tk_long:
00058     case CORBA::tk_ulong:
00059     case CORBA::tk_float:
00060     case CORBA::tk_enum:
00061       continue_skipping = stream->skip_long ();
00062       break;
00063     case CORBA::tk_double:
00064     case CORBA::tk_longlong:
00065     case CORBA::tk_ulonglong:
00066       continue_skipping = stream->skip_longlong ();
00067       break;
00068     case CORBA::tk_boolean:
00069       continue_skipping = stream->skip_boolean ();
00070       break;
00071     case CORBA::tk_char:
00072     case CORBA::tk_octet:
00073       continue_skipping = stream->skip_char ();
00074       break;
00075     case CORBA::tk_longdouble:
00076       continue_skipping = stream->skip_longdouble ();
00077       break;
00078     case CORBA::tk_wchar:
00079       continue_skipping = stream->skip_wchar ();
00080       break;
00081     default:
00082       retval = TAO::TRAVERSE_STOP;
00083       // we are not a primitive type
00084     }
00085   if (retval == TAO::TRAVERSE_CONTINUE && continue_skipping)
00086     return TAO::TRAVERSE_CONTINUE;
00087   else
00088     {
00089       if (TAO_debug_level > 0)
00090         ACE_DEBUG ((
00091             LM_DEBUG,
00092             ACE_TEXT ("TAO_Marshal_Primitive::skip detected error\n")
00093           ));
00094       throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00095     }
00096 }
00097 
00098 TAO::traverse_status
00099 TAO_Marshal_Any::skip (CORBA::TypeCode_ptr, TAO_InputCDR *stream)
00100 {
00101   // Typecode of the element that makes the Any.
00102   CORBA::TypeCode_var elem_tc;
00103 
00104   // Status of encode operation.
00105   if (!(*stream >> elem_tc.inout ()))
00106     return TAO::TRAVERSE_STOP;
00107 
00108   return TAO_Marshal_Object::perform_skip (elem_tc.in (), stream);
00109 }
00110 
00111 TAO::traverse_status
00112 TAO_Marshal_TypeCode::skip (CORBA::TypeCode_ptr, TAO_InputCDR *stream)
00113 {
00114   CORBA::Boolean continue_skipping = true;
00115 
00116   // Typecode kind.
00117   CORBA::ULong kind;
00118 
00119   // Decode the "kind" field of the typecode from the stream.
00120   continue_skipping = stream->read_ulong (kind);
00121 
00122   if (continue_skipping)
00123     {
00124       // Typecodes with empty parameter lists all have preallocated
00125       // constants.  We use those to reduce memory consumption and
00126       // heap access ... also, to speed things up!
00127       if ((kind < CORBA::TAO_TC_KIND_COUNT) ||
00128           (kind == ~0u))
00129         {
00130           // Either a non-constant typecode or an indirected typecode.
00131           switch (kind)
00132             {
00133               // Need special handling for all kinds of typecodes that
00134               // have nonempty parameter lists ...
00135             default:
00136               // simple typecodes, nothing to do
00137               break;
00138             case CORBA::tk_string:
00139             case CORBA::tk_wstring:
00140               {
00141                 // skip the bounds
00142                 continue_skipping = stream->skip_ulong ();
00143               }
00144             break;
00145 
00146             // Indirected typecodes, illegal at "top level".
00147             case ~0u:
00148               {
00149                 // skip the long indicating the encapsulation offset,
00150                 continue_skipping = stream->skip_long ();
00151               }
00152             break;
00153 
00154             // The rest have "complex" parameter lists that are
00155             // encoded as bulk octets ...
00156             case CORBA::tk_objref:
00157             case CORBA::tk_struct:
00158             case CORBA::tk_union:
00159             case CORBA::tk_enum:
00160             case CORBA::tk_sequence:
00161             case CORBA::tk_array:
00162             case CORBA::tk_alias:
00163             case CORBA::tk_except:
00164             case CORBA::tk_value:
00165             case CORBA::tk_value_box:
00166             case CORBA::tk_native:
00167             case CORBA::tk_abstract_interface:
00168             case CORBA::tk_local_interface:
00169             case CORBA::tk_component:
00170             case CORBA::tk_home:
00171             case CORBA::tk_event:
00172               {
00173                 CORBA::ULong length;
00174 
00175                 // get the encapsulation length
00176                 continue_skipping = stream->read_ulong (length);
00177                 if (!continue_skipping)
00178                   break;
00179                 // skip the encapsulation
00180                 continue_skipping = stream->skip_bytes (length);
00181               }
00182             } // end of switch
00183         }
00184       else // bad kind_ value to be decoded
00185         {
00186           if (TAO_debug_level > 0)
00187             ACE_DEBUG ((LM_DEBUG,
00188                         ACE_TEXT ("TAO_Marshal_TypeCode::skip: ")
00189                         ACE_TEXT ("Bad kind_ value in CDR stream\n")));
00190           throw ::CORBA::BAD_TYPECODE ();
00191         }
00192     }
00193 
00194   if (continue_skipping)
00195     return TAO::TRAVERSE_CONTINUE;
00196   else
00197     {
00198       if (TAO_debug_level > 0)
00199         ACE_DEBUG ((
00200             LM_DEBUG,
00201             ACE_TEXT ("TAO_Marshal_TypeCode::skip detected error\n")
00202           ));
00203       throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00204     }
00205 }
00206 
00207 TAO::traverse_status
00208 TAO_Marshal_Principal::skip (CORBA::TypeCode_ptr, TAO_InputCDR *stream)
00209 {
00210   CORBA::Boolean continue_skipping = true;
00211 
00212   // specifies the number of bytes in the Principal
00213   CORBA::ULong len;
00214 
00215   continue_skipping = stream->read_ulong (len);
00216   if (len > 0 && continue_skipping)
00217     {
00218       continue_skipping = stream->skip_bytes (len);
00219     }
00220 
00221   if (continue_skipping)
00222     return TAO::TRAVERSE_CONTINUE;
00223   else
00224     {
00225       if (TAO_debug_level > 0)
00226         ACE_DEBUG ((
00227             LM_DEBUG,
00228             ACE_TEXT ("TAO_Marshal_Principal::skip detected error\n")
00229           ));
00230       throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00231     }
00232 }
00233 
00234 TAO::traverse_status
00235 TAO_Marshal_ObjRef::skip (CORBA::TypeCode_ptr, TAO_InputCDR *stream)
00236 {
00237   CORBA::Boolean continue_skipping = true;
00238 
00239   // return status
00240   TAO::traverse_status retval = TAO::TRAVERSE_CONTINUE;
00241 
00242   // First, skip the type hint. This will be the type_id encoded in an
00243   // object reference.
00244   stream->skip_string ();
00245 
00246   // Read the profiles, discarding all until an IIOP profile comes by.
00247   // Once we see an IIOP profile, ignore any further ones.
00248   //
00249   // XXX this will need to change someday to let different protocol
00250   // code be accessed, not just IIOP.  Protocol modules will be
00251   // dynamically loaded from shared libraries via ORB_init (), and we
00252   // just need to be able to access such preloaded libraries here as
00253   // we unmarshal objrefs.
00254   CORBA::ULong profiles = 0;
00255 
00256   // get the count of profiles that follow
00257   continue_skipping = stream->read_ulong (profiles);
00258 
00259   while (profiles-- != 0 && continue_skipping)
00260       {
00261         CORBA::ULong tag;
00262 
00263         // get the profile ID tag
00264         if ( (continue_skipping = stream->read_ulong (tag)) == 0)
00265           continue;
00266 
00267         CORBA::ULong encap_len;
00268         // ProfileData is encoded as a sequence of octet. So first get
00269         // the length of the sequence.
00270         // Create the decoding stream from the encapsulation in the
00271         // buffer, and skip the encapsulation.
00272         if ( (continue_skipping = stream->read_ulong (encap_len)) == 0)
00273           continue;
00274 
00275         continue_skipping = stream->skip_bytes (encap_len);
00276       }
00277 
00278   if (retval == TAO::TRAVERSE_CONTINUE && continue_skipping)
00279     return TAO::TRAVERSE_CONTINUE;
00280   else
00281     {
00282       if (TAO_debug_level > 0)
00283         ACE_DEBUG ((
00284             LM_DEBUG,
00285             ACE_TEXT ("TAO_Marshal_ObjRef::skip detected error\n")
00286           ));
00287       throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00288     }
00289 }
00290 
00291 TAO::traverse_status
00292 TAO_Marshal_Struct::skip (CORBA::TypeCode_ptr  tc, TAO_InputCDR *stream)
00293 {
00294   TAO::traverse_status retval = TAO::TRAVERSE_CONTINUE;
00295   CORBA::TypeCode_var param;
00296 
00297   // Number of fields in the struct.
00298   CORBA::ULong const member_count =
00299     tc->member_count ();
00300 
00301   for (CORBA::ULong i = 0;
00302        i < member_count && retval == TAO::TRAVERSE_CONTINUE;
00303        ++i)
00304     {
00305       param = tc->member_type (i);
00306 
00307       retval = TAO_Marshal_Object::perform_skip (param.in (), stream);
00308     }
00309 
00310   if (retval == TAO::TRAVERSE_CONTINUE)
00311     return TAO::TRAVERSE_CONTINUE;
00312 
00313   if (TAO_debug_level > 0)
00314     ACE_DEBUG ((LM_DEBUG,
00315                 ACE_TEXT ("TAO_Marshal_Struct::skip detected error\n")));
00316 
00317   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00318 }
00319 
00320 TAO::traverse_status
00321 TAO_Marshal_Union::skip (CORBA::TypeCode_ptr  tc, TAO_InputCDR *src)
00322 {
00323   CORBA::TypeCode_var discrim_tc =
00324     tc->discriminator_type ();
00325 
00326   CORBA::ULong const kind =
00327     discrim_tc->kind ();
00328 
00329   // Save the discriminator value in a temporary variable...
00330   CORBA::Short short_v = CORBA::Short();
00331   CORBA::UShort ushort_v = CORBA::UShort();
00332   CORBA::Long long_v = CORBA::Long();
00333   CORBA::ULong ulong_v = CORBA::ULong();
00334   CORBA::ULong enum_v = CORBA::ULong();
00335   CORBA::Char char_v = CORBA::Char();
00336   CORBA::WChar wchar_v = CORBA::WChar();
00337   CORBA::Boolean boolean_v = false;
00338 
00339   switch (kind)
00340     {
00341     case CORBA::tk_short:
00342       {
00343         if (!src->read_short (short_v))
00344           return TAO::TRAVERSE_STOP;
00345       }
00346       break;
00347 
00348     case CORBA::tk_ushort:
00349       {
00350         if (!src->read_ushort (ushort_v))
00351           return TAO::TRAVERSE_STOP;
00352       }
00353       break;
00354 
00355     case CORBA::tk_long:
00356       {
00357         if (!src->read_long (long_v))
00358           return TAO::TRAVERSE_STOP;
00359       }
00360       break;
00361 
00362     case CORBA::tk_ulong:
00363       {
00364         if (!src->read_ulong (ulong_v))
00365           return TAO::TRAVERSE_STOP;
00366       }
00367       break;
00368 
00369     case CORBA::tk_enum:
00370       {
00371         if (!src->read_ulong (enum_v))
00372           return TAO::TRAVERSE_STOP;
00373       }
00374       break;
00375 
00376     case CORBA::tk_char:
00377       {
00378         if (!src->read_char (char_v))
00379           return TAO::TRAVERSE_STOP;
00380       }
00381       break;
00382 
00383     case CORBA::tk_wchar:
00384       {
00385         if (!src->read_wchar (wchar_v))
00386           return TAO::TRAVERSE_STOP;
00387       }
00388       break;
00389 
00390     case CORBA::tk_boolean:
00391       {
00392         if (!src->read_boolean (boolean_v))
00393           return TAO::TRAVERSE_STOP;
00394       }
00395       break;
00396 
00397     default:
00398       return TAO::TRAVERSE_STOP;
00399     }
00400 
00401   const CORBA::ULong member_count =
00402     tc->member_count ();
00403 
00404   const CORBA::ULong null_member = ~static_cast<CORBA::ULong> (0U);
00405 
00406   CORBA::ULong current_member = null_member;
00407   CORBA::ULong default_member = null_member;
00408 
00409   for (CORBA::ULong i = 0;
00410        i < member_count && current_member == null_member;
00411        ++i)
00412     {
00413       CORBA::Any_var any = tc->member_label (i);
00414 
00415       CORBA::Octet o;
00416       if ((any >>= CORBA::Any::to_octet (o)) && o == 0)
00417         {
00418           CORBA::ULong default_index =
00419             tc->default_index ();
00420 
00421           if (i != default_index)
00422             throw ::CORBA::BAD_TYPECODE ();
00423           // Found the default branch, save its position and continue
00424           // trying to find the current value...
00425           default_member = i;
00426           continue;
00427         }
00428 
00429       switch (kind)
00430         {
00431         case CORBA::tk_short:
00432           {
00433             CORBA::Short d;
00434             if ((any >>= d) && d == short_v)
00435               current_member = i;
00436           }
00437           break;
00438 
00439         case CORBA::tk_ushort:
00440           {
00441             CORBA::UShort d;
00442             if ((any >>= d) && d == ushort_v)
00443               current_member = i;
00444           }
00445           break;
00446 
00447         case CORBA::tk_long:
00448           {
00449             CORBA::Long d;
00450             if ((any >>= d) && d == long_v)
00451               current_member = i;
00452           }
00453           break;
00454 
00455         case CORBA::tk_ulong:
00456           {
00457             CORBA::ULong d;
00458             if ((any >>= d) && d == ulong_v)
00459               current_member = i;
00460           }
00461           break;
00462 
00463         case CORBA::tk_enum:
00464           {
00465             CORBA::ULong d;
00466             TAO::Any_Impl *impl = any->impl ();
00467 
00468             if (impl->encoded ())
00469               {
00470                 TAO::Unknown_IDL_Type * const unk =
00471                   dynamic_cast<TAO::Unknown_IDL_Type *> (impl);
00472 
00473                 if (!unk)
00474                   throw ::CORBA::INTERNAL ();
00475 
00476                 // We don't want unk's rd_ptr to move, in case
00477                 // we are shared by another Any, so we use this
00478                 // to copy the state, not the buffer.
00479                 TAO_InputCDR for_reading (unk->_tao_get_cdr ());
00480 
00481                 for_reading.read_ulong (d);
00482               }
00483             else
00484               {
00485                 TAO_OutputCDR out;
00486                 impl->marshal_value (out);
00487                 TAO_InputCDR cdr (out);
00488                 cdr.read_ulong (d);
00489               }
00490 
00491             if (d == enum_v)
00492               {
00493                 current_member = i;
00494               }
00495           }
00496           break;
00497 
00498         case CORBA::tk_char:
00499           {
00500             CORBA::Char d;
00501             if ((any >>= CORBA::Any::to_char (d)) && d == char_v)
00502               current_member = i;
00503           }
00504           break;
00505 
00506         case CORBA::tk_wchar:
00507           {
00508             CORBA::WChar d;
00509             if ((any >>= CORBA::Any::to_wchar (d)) && d == wchar_v)
00510               current_member = i;
00511           }
00512           break;
00513 
00514         case CORBA::tk_boolean:
00515           {
00516             CORBA::Boolean d;
00517             if ((any >>= CORBA::Any::to_boolean (d)) && d == boolean_v)
00518               current_member = i;
00519           }
00520           break;
00521 
00522         default:
00523           return TAO::TRAVERSE_STOP;
00524         }
00525     }
00526 
00527   if (current_member == null_member)
00528     {
00529       // Cannot find the current member, check if there is a
00530       // default...
00531       if (default_member != null_member)
00532         {
00533           // Good, use the default to append...
00534           CORBA::TypeCode_var member_tc =
00535             tc->member_type (default_member);
00536           return TAO_Marshal_Object::perform_skip (member_tc.in (), src);
00537         }
00538 
00539       // If we're here, we have an implicit default case, and we
00540       // should just return without skipping anything, since no
00541       // union member was marshaled in the first place.
00542       return TAO::TRAVERSE_CONTINUE;
00543     }
00544 
00545   // If we found the member successfully then just use that one...
00546   CORBA::TypeCode_var member_tc =
00547     tc->member_type (current_member);
00548 
00549   return TAO_Marshal_Object::perform_skip (member_tc.in (), src);
00550 }
00551 
00552 TAO::traverse_status
00553 TAO_Marshal_String::skip (CORBA::TypeCode_ptr, TAO_InputCDR *stream)
00554 {
00555   CORBA::Boolean continue_skipping = true;
00556 
00557   // On decode, omit the check against specified string bounds, and
00558   // cope with illegal "zero length" strings (all lengths on the wire
00559   // must include a NUL).
00560   //
00561   // This is on the principle of being gracious in what we accept; we
00562   // don't generate messages that fail to comply with protocol specs,
00563   // but we will accept them when it's clear how to do so.
00564 
00565   continue_skipping = stream->skip_string ();
00566   if (continue_skipping)
00567     return TAO::TRAVERSE_CONTINUE;
00568   else
00569     {
00570       if (TAO_debug_level > 0)
00571         ACE_DEBUG ((LM_DEBUG,
00572                     ACE_TEXT ("TAO_Marshal_String::skip detected error\n")));
00573       throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00574     }
00575 }
00576 
00577 TAO::traverse_status
00578 TAO_Marshal_Sequence::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *stream)
00579 {
00580   // Size of element.
00581   CORBA::ULong bounds;
00582 
00583   // First unmarshal the sequence length ... we trust it to be right
00584   // here, on the "be gracious in what you accept" principle.  We
00585   // don't generate illegal sequences (i.e. length > bounds).
00586 
00587   CORBA::Boolean continue_skipping =
00588     stream->read_ulong (bounds);
00589 
00590   if (!continue_skipping)
00591     {
00592       ACE_DEBUG ((LM_DEBUG,
00593                   ACE_TEXT ("TAO_Marshal_Sequence::skip detected error\n")));
00594       throw ::CORBA::MARSHAL ();
00595     }
00596 
00597   // No point decoding an empty sequence.
00598   if (bounds == 0)
00599     return TAO::TRAVERSE_CONTINUE;
00600 
00601   // Get element typecode.
00602   CORBA::TypeCode_var tc2 =
00603     tc->content_type ();
00604 
00605   // For CORBA basic types, the skip can be optimized
00606   CORBA::TCKind const kind = tc2->kind ();
00607 
00608   char *dummy = 0;
00609   switch (kind)
00610     {
00611     case CORBA::tk_octet:
00612     case CORBA::tk_boolean:
00613     case CORBA::tk_char:
00614       {
00615         stream->adjust (0, ACE_CDR::OCTET_ALIGN, dummy);
00616         continue_skipping =
00617           stream->skip_bytes (ACE_CDR::OCTET_SIZE * bounds);
00618       }
00619       break;
00620     case CORBA::tk_short:
00621     case CORBA::tk_ushort:
00622     case CORBA::tk_wchar:
00623       {
00624         stream->adjust (0, ACE_CDR::SHORT_ALIGN, dummy);
00625         continue_skipping =
00626           stream->skip_bytes (ACE_CDR::SHORT_SIZE * bounds);
00627       }
00628       break;
00629     case CORBA::tk_long:
00630     case CORBA::tk_ulong:
00631     case CORBA::tk_float:
00632       {
00633         stream->adjust (0, ACE_CDR::LONG_ALIGN, dummy);
00634         continue_skipping =
00635           stream->skip_bytes (ACE_CDR::LONG_SIZE * bounds);
00636       }
00637       break;
00638     case CORBA::tk_double:
00639     case CORBA::tk_longlong:
00640     case CORBA::tk_ulonglong:
00641       {
00642         stream->adjust (0, ACE_CDR::LONGLONG_ALIGN, dummy);
00643         continue_skipping =
00644           stream->skip_bytes (ACE_CDR::LONGLONG_SIZE * bounds);
00645       }
00646       break;
00647     case CORBA::tk_longdouble:
00648       {
00649         stream->adjust (0, ACE_CDR::LONGDOUBLE_ALIGN, dummy);
00650         continue_skipping =
00651           stream->skip_bytes (ACE_CDR::LONGDOUBLE_SIZE * bounds);
00652       }
00653       break;
00654 
00655     default:
00656       while (bounds-- && continue_skipping)
00657         {
00658           continue_skipping =
00659             TAO_Marshal_Object::perform_skip (tc2.in (), stream);
00660         }
00661       break;
00662     }// end of switch
00663 
00664   if (continue_skipping)
00665     return TAO::TRAVERSE_CONTINUE;
00666 
00667   // error exit
00668   if (TAO_debug_level > 0)
00669     ACE_DEBUG ((LM_DEBUG,
00670                 ACE_TEXT ("TAO_Marshal_Sequence::skip detected error\n")));
00671 
00672   throw ::CORBA::MARSHAL ();
00673 }
00674 
00675 TAO::traverse_status
00676 TAO_Marshal_Array::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *stream)
00677 {
00678   CORBA::Boolean continue_skipping = true;
00679 
00680   // retrieve the bounds of the array
00681   CORBA::ULong bounds = tc->length ();
00682 
00683   // get element typecode
00684   // Typecode of the element.
00685   CORBA::TypeCode_var tc2 = tc->content_type ();
00686 
00687   // For CORBA basic types, the skip can be optimized
00688   CORBA::TCKind const kind = tc2->kind ();
00689 
00690   char *dummy;
00691   switch (kind)
00692     {
00693     case CORBA::tk_octet:
00694     case CORBA::tk_boolean:
00695     case CORBA::tk_char:
00696       {
00697         stream->adjust (0, ACE_CDR::OCTET_ALIGN, dummy);
00698         continue_skipping =
00699           stream->skip_bytes (ACE_CDR::OCTET_SIZE * bounds);
00700       }
00701       break;
00702     case CORBA::tk_short:
00703     case CORBA::tk_ushort:
00704     case CORBA::tk_wchar:
00705       {
00706         stream->adjust (0, ACE_CDR::SHORT_ALIGN, dummy);
00707         continue_skipping =
00708           stream->skip_bytes (ACE_CDR::SHORT_SIZE * bounds);
00709       }
00710       break;
00711     case CORBA::tk_long:
00712     case CORBA::tk_ulong:
00713     case CORBA::tk_float:
00714       {
00715         stream->adjust (0, ACE_CDR::LONG_ALIGN, dummy);
00716         continue_skipping =
00717           stream->skip_bytes (ACE_CDR::LONG_SIZE * bounds);
00718       }
00719       break;
00720     case CORBA::tk_double:
00721     case CORBA::tk_longlong:
00722     case CORBA::tk_ulonglong:
00723       {
00724         stream->adjust (0, ACE_CDR::LONGLONG_ALIGN, dummy);
00725         continue_skipping =
00726           stream->skip_bytes (ACE_CDR::LONGLONG_SIZE * bounds);
00727       }
00728       break;
00729     case CORBA::tk_longdouble:
00730       {
00731         stream->adjust (0, ACE_CDR::LONGDOUBLE_ALIGN, dummy);
00732         continue_skipping =
00733           stream->skip_bytes (ACE_CDR::LONGDOUBLE_SIZE * bounds);
00734       }
00735       break;
00736 
00737     default:
00738       while (bounds-- && continue_skipping)
00739         {
00740           int stop =
00741             TAO_Marshal_Object::perform_skip (tc2.in (), stream);
00742           if (stop == TAO::TRAVERSE_STOP)
00743             continue_skipping = false;
00744         }
00745       break;
00746     }// end of switch
00747 
00748   if (continue_skipping)
00749     return TAO::TRAVERSE_CONTINUE;
00750 
00751   // error exit
00752   if (TAO_debug_level > 0)
00753     ACE_DEBUG ((LM_DEBUG,
00754                 ACE_TEXT ("TAO_Marshal_Sequence::skip detected error\n")));
00755 
00756   throw ::CORBA::MARSHAL ();
00757 }
00758 
00759 TAO::traverse_status
00760 TAO_Marshal_Alias::skip (CORBA::TypeCode_ptr  tc, TAO_InputCDR *stream)
00761 {
00762   // Typecode of the aliased type.
00763   CORBA::TypeCode_var tc2;
00764   CORBA::Boolean continue_skipping = true;
00765 
00766   // Status of decode operation.
00767   TAO::traverse_status retval =
00768     TAO::TRAVERSE_CONTINUE;
00769 
00770   tc2 = tc->content_type ();
00771 
00772   retval = TAO_Marshal_Object::perform_skip (tc2.in (), stream);
00773 
00774   //  tc2->_decr_refcnt ();
00775   if (retval == TAO::TRAVERSE_CONTINUE
00776       && continue_skipping)
00777     return TAO::TRAVERSE_CONTINUE;
00778 
00779   if (TAO_debug_level > 0)
00780     ACE_DEBUG ((LM_DEBUG,
00781                 ACE_TEXT ("TAO_Marshal_Alias::skip detected error\n")));
00782 
00783   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00784 }
00785 
00786 // Decode exception For exceptions, the "hidden" type ID near the
00787 // front of the on-wire representation was previously unmarshaled and
00788 // mapped to the "tc" typcode we're using to traverse the memory ...
00789 // at the same time its vtable, refcount, and other state was
00790 // established.
00791 //
00792 // NOTE: This is asymmetric with respect to encoding exceptions.
00793 TAO::traverse_status
00794 TAO_Marshal_Except::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *stream)
00795 {
00796   TAO::traverse_status retval =
00797     TAO::TRAVERSE_CONTINUE;
00798   CORBA::TypeCode_var param;
00799 
00800   // skip the Repository ID
00801   if (!stream->skip_string ())
00802     return TAO::TRAVERSE_STOP;
00803 
00804   // Number of fields in the exception
00805   const CORBA::ULong member_count =
00806     tc->member_count ();
00807 
00808   for (CORBA::ULong i = 0;
00809        i < member_count && retval == TAO::TRAVERSE_CONTINUE;
00810        ++i)
00811     {
00812       param = tc->member_type (i);
00813 
00814       retval = TAO_Marshal_Object::perform_skip (param.in (), stream);
00815     }
00816 
00817   if (retval == TAO::TRAVERSE_CONTINUE)
00818     return TAO::TRAVERSE_CONTINUE;
00819 
00820   if (TAO_debug_level > 0)
00821     ACE_DEBUG ((LM_DEBUG,
00822                 ACE_TEXT ("TAO_Marshal_Except::skip detected error\n")));
00823 
00824   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00825 }
00826 
00827 // decode wstring
00828 TAO::traverse_status
00829 TAO_Marshal_WString::skip (CORBA::TypeCode_ptr, TAO_InputCDR *stream)
00830 {
00831   CORBA::Boolean continue_skipping = true;
00832 
00833   // On decode, omit the check against specified wstring bounds, and
00834   // cope with illegal "zero length" strings (all lengths on the wire
00835   // must include a NUL).
00836   //
00837   // This is on the principle of being gracious in what we accept; we
00838   // don't generate messages that fail to comply with protocol specs,
00839   // but we will accept them when it's clear how to do so.
00840 
00841   // "zero length" wstrings are legal in GIOP 1.2.
00842 
00843   continue_skipping = stream->skip_wstring ();
00844 
00845   if (continue_skipping)
00846     return TAO::TRAVERSE_CONTINUE;
00847 
00848   if (TAO_debug_level > 0)
00849     ACE_DEBUG ((LM_DEBUG,
00850                 ACE_TEXT ("TAO_Marshal_WString::skip detected error\n")));
00851   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00852 }
00853 
00854 TAO::traverse_status
00855 TAO_Marshal_Value::skip (CORBA::TypeCode_ptr tc, TAO_InputCDR *stream)
00856 {
00857   TAO::traverse_status retval = TAO::TRAVERSE_CONTINUE;
00858   CORBA::TypeCode_var param;
00859 
00860   // Use the same method to skip over our base valuetype.
00861   // To achive this we'll need to distinguish between
00862   // first-time/nested skips so that we won't attempt to
00863   // skip rep_id several times.
00864   //
00865   if (this->nested_processing_ == false)
00866     {
00867       this->nested_processing_ = true;
00868 
00869       CORBA::Long value_tag;
00870 
00871       if (!stream->read_long (value_tag))
00872         {
00873           return TAO::TRAVERSE_STOP;
00874         }
00875 
00876       TAO_ORB_Core *orb_core = stream->orb_core ();
00877       if (orb_core == 0)
00878         {
00879           orb_core = TAO_ORB_Core_instance ();
00880 
00881           if (TAO_debug_level > 0)
00882             {
00883               ACE_DEBUG ((LM_WARNING,
00884                           "TAO (%P|%t) WARNING: extracting "
00885                           "valuetype using default ORB_Core\n"));
00886             }
00887         }
00888 
00889       TAO_Valuetype_Adapter *adapter = orb_core->valuetype_adapter();
00890 
00891       if (value_tag == 0) // Null value type pointer.
00892         {
00893           // We are done.
00894           return retval;
00895         }
00896       else if (adapter->is_type_info_single(value_tag))
00897         {
00898           // Skip a single repository id which is of type string.
00899           stream->skip_string ();
00900         }
00901       else if (adapter->is_type_info_list(value_tag))
00902         {
00903           CORBA::Long num_types;
00904           if (!stream->read_long (num_types))
00905             {
00906               return TAO::TRAVERSE_STOP;
00907             }
00908           while (num_types > 0)
00909             {
00910               stream->skip_string();
00911               num_types--;
00912             }
00913         }
00914       else if (!adapter->is_type_info_implied (value_tag))
00915         {
00916           //@@ boris: VT CDR
00917           return TAO::TRAVERSE_STOP;
00918         }
00919 
00920       if (adapter->is_value_chunked (value_tag))
00921         {
00922           CORBA::Long chunk_tag = 0;
00923           while (chunk_tag != -1)
00924             {
00925               if (!stream->read_long (chunk_tag))
00926                 return TAO::TRAVERSE_STOP;
00927 
00928               if (chunk_tag > 0)
00929                 {
00930                   if (!stream->skip_bytes(chunk_tag))
00931                     return TAO::TRAVERSE_STOP;
00932                 }
00933             }
00934           return TAO::TRAVERSE_CONTINUE;
00935         }
00936 
00937     }
00938 
00939   // Handle our base valuetype if any.
00940   param = tc->concrete_base_type ();
00941 
00942   CORBA::TCKind const k = param->kind ();
00943 
00944   if (k != CORBA::tk_null)
00945     {
00946       retval = this->skip (param.in (), stream);
00947 
00948       if (retval != TAO::TRAVERSE_CONTINUE)
00949         {
00950           return retval;
00951         }
00952     }
00953 
00954   // Number of fields in the valuetype.
00955   CORBA::ULong const member_count =
00956     tc->member_count ();
00957 
00958   for (CORBA::ULong i = 0;
00959        i < member_count && retval == TAO::TRAVERSE_CONTINUE;
00960        ++i)
00961     {
00962       param = tc->member_type (i);
00963 
00964       retval = TAO_Marshal_Object::perform_skip (param.in (), stream);
00965     }
00966 
00967   if (retval == TAO::TRAVERSE_CONTINUE)
00968     return TAO::TRAVERSE_CONTINUE;
00969 
00970   if (TAO_debug_level > 0)
00971     ACE_DEBUG ((LM_DEBUG,
00972                 ACE_TEXT ("TAO_Marshal_Value::skip detected error\n")));
00973 
00974   throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
00975 }
00976 
00977 TAO_END_VERSIONED_NAMESPACE_DECL

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