(linenum→info "unix/slp.c:2238")

dbus/1.0.2/dbus/dbus-marshal-byteswap.c

    1: /* -*- mode: C; c-file-style: "gnu" -*- */
    2: /* dbus-marshal-byteswap.c  Swap a block of marshaled data
    3:  *
    4:  * Copyright (C) 2005 Red Hat, Inc.
    5:  *
    6:  * Licensed under the Academic Free License version 2.1
    7:  *
    8:  * This program is free software; you can redistribute it and/or modify
    9:  * it under the terms of the GNU General Public License as published by
   10:  * the Free Software Foundation; either version 2 of the License, or
   11:  * (at your option) any later version.
   12:  *
   13:  * This program is distributed in the hope that it will be useful,
   14:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   15:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16:  * GNU General Public License for more details.
   17:  *
   18:  * You should have received a copy of the GNU General Public License
   19:  * along with this program; if not, write to the Free Software
   20:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   21:  *
   22:  */
   23: 
   24: #include "dbus-marshal-byteswap.h"
   25: #include "dbus-marshal-basic.h"
   26: #include "dbus-signature.h"
   27: 
   28: /**
   29:  * @addtogroup DBusMarshal
   30:  * @{
   31:  */
   32: 
   33: static void
   34: byteswap_body_helper (DBusTypeReader       *reader,
   35:                       dbus_bool_t           walk_reader_to_end,
   36:                       int                   old_byte_order,
   37:                       int                   new_byte_order,
   38:                       unsigned char        *p,
   39:                       unsigned char       **new_p)
   40: {
   41:   int current_type;
   42: 
   43:   while ((current_type = _dbus_type_reader_get_current_type (reader)) != DBUS_TYPE_INVALID)
   44:     {
   45:       switch (current_type)
   46:         {
   47:         case DBUS_TYPE_BYTE:
   48:           ++p;
   49:           break;
   50: 
   51:         case DBUS_TYPE_INT16:
   52:         case DBUS_TYPE_UINT16:
   53:           {
   54:             p = _DBUS_ALIGN_ADDRESS (p, 2);
   55:             *((dbus_uint16_t*)p) = DBUS_UINT16_SWAP_LE_BE (*((dbus_uint16_t*)p));
   56:             p += 2;
   57:           }
   58:           break;
   59:           
   60:         case DBUS_TYPE_BOOLEAN:
   61:         case DBUS_TYPE_INT32:
   62:         case DBUS_TYPE_UINT32:
   63:           {
   64:             p = _DBUS_ALIGN_ADDRESS (p, 4);
   65:             *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
   66:             p += 4;
   67:           }
   68:           break;
   69:           
   70:         case DBUS_TYPE_INT64:
   71:         case DBUS_TYPE_UINT64:
   72:         case DBUS_TYPE_DOUBLE:
   73:           {
   74:             p = _DBUS_ALIGN_ADDRESS (p, 8);
   75: #ifdef DBUS_HAVE_INT64
   76:             *((dbus_uint64_t*)p) = DBUS_UINT64_SWAP_LE_BE (*((dbus_uint64_t*)p));
   77: #else
   78:             _dbus_swap_array (p, 1, 8);
   79: #endif
   80:             p += 8;
   81:           }
   82:           break;
   83: 
   84:         case DBUS_TYPE_ARRAY:
   85:         case DBUS_TYPE_STRING:
   86:         case DBUS_TYPE_OBJECT_PATH:
   87:           {
   88:             dbus_uint32_t array_len;
   89:             
   90:             p = _DBUS_ALIGN_ADDRESS (p, 4);
   91: 
   92:             array_len = _dbus_unpack_uint32 (old_byte_order, p);
   93: 
   94:             *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
   95:             p += 4;
   96: 
   97:             if (current_type == DBUS_TYPE_ARRAY)
   98:               {
   99:                 int elem_type;
  100:                 int alignment;
  101: 
  102:                 elem_type = _dbus_type_reader_get_element_type (reader);
  103:                 alignment = _dbus_type_get_alignment (elem_type);
  104: 
  105:                 _dbus_assert ((array_len / alignment) < DBUS_MAXIMUM_ARRAY_LENGTH);
  106: 
  107:                 p = _DBUS_ALIGN_ADDRESS (p, alignment);
  108:                 
  109:                 if (dbus_type_is_fixed (elem_type))
  110:                   {
  111:                     if (alignment > 1)
  112:                       _dbus_swap_array (p, array_len / alignment, alignment);
  113:                     p += array_len;
  114:                   }
  115:                 else
  116:                   {
  117:                     DBusTypeReader sub;
  118:                     const unsigned char *array_end;
  119: 
  120:                     array_end = p + array_len;
  121:                     
  122:                     _dbus_type_reader_recurse (reader, &sub);
  123: 
  124:                     while (p < array_end)
  125:                       {
  126:                         byteswap_body_helper (&sub,
  127:                                               FALSE,
  128:                                               old_byte_order,
  129:                                               new_byte_order,
  130:                                               p, &p);
  131:                       }
  132:                   }
  133:               }
  134:             else
  135:               {
  136:                 _dbus_assert (current_type == DBUS_TYPE_STRING ||
  137:                               current_type == DBUS_TYPE_OBJECT_PATH);
  138:                 
  139:                 p += (array_len + 1); /* + 1 for nul */
  140:               }
  141:           }
  142:           break;
  143: 
  144:         case DBUS_TYPE_SIGNATURE:
  145:           {
  146:             dbus_uint32_t sig_len;
  147: 
  148:             sig_len = *p;
  149:             
  150:             p += (sig_len + 2); /* +2 for len and nul */
  151:           }
  152:           break;
  153: 
  154:         case DBUS_TYPE_VARIANT:
  155:           {
  156:             /* 1 byte sig len, sig typecodes, align to
  157:              * contained-type-boundary, values.
  158:              */
  159:             dbus_uint32_t sig_len;
  160:             DBusString sig;
  161:             DBusTypeReader sub;
  162:             int contained_alignment;
  163: 
  164:             sig_len = *p;
  165:             ++p;
  166: 
  167:             _dbus_string_init_const_len (&sig, p, sig_len);
  168: 
  169:             p += (sig_len + 1); /* 1 for nul */
  170: 
  171:             contained_alignment = _dbus_type_get_alignment (_dbus_first_type_in_signature (&sig, 0));
  172:             
  173:             p = _DBUS_ALIGN_ADDRESS (p, contained_alignment);
  174: 
  175:             _dbus_type_reader_init_types_only (&sub, &sig, 0);
  176: 
  177:             byteswap_body_helper (&sub, FALSE, old_byte_order, new_byte_order, p, &p);
  178:           }
  179:           break;
  180: 
  181:         case DBUS_TYPE_STRUCT:
  182:         case DBUS_TYPE_DICT_ENTRY:
  183:           {
  184:             DBusTypeReader sub;
  185: 
  186:             p = _DBUS_ALIGN_ADDRESS (p, 8);
  187:             
  188:             _dbus_type_reader_recurse (reader, &sub);
  189:             
  190:             byteswap_body_helper (&sub, TRUE, old_byte_order, new_byte_order, p, &p);
  191:           }
  192:           break;
  193: 
  194:         default:
  195:           _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
  196:           break;
  197:         }
  198: 
  199:       if (walk_reader_to_end)
  200:         _dbus_type_reader_next (reader);
  201:       else
  202:         break;
  203:     }
  204: 
  205:   if (new_p)
  206:     *new_p = p;
  207: }
  208: 
  209: /**
  210:  * Byteswaps the marshaled data in the given value_str.
  211:  *
  212:  * @param signature the types in the value_str
  213:  * @param signature_start where in signature is the signature
  214:  * @param old_byte_order the old byte order
  215:  * @param new_byte_order the new byte order
  216:  * @param value_str the string containing the body
  217:  * @param value_pos where the values start
  218:  */
  219: void
  220: _dbus_marshal_byteswap (const DBusString *signature,
  221:                         int               signature_start,
  222:                         int               old_byte_order,
  223:                         int               new_byte_order,
  224:                         DBusString       *value_str,
  225:                         int               value_pos)
  226: {
  227:   DBusTypeReader reader;
  228: 
  229:   _dbus_assert (value_pos >= 0);
  230:   _dbus_assert (value_pos <= _dbus_string_get_length (value_str));
  231: 
  232:   if (old_byte_order == new_byte_order)
  233:     return;
  234:   
  235:   _dbus_type_reader_init_types_only (&reader,
  236:                                      signature, signature_start);
  237: 
  238:   byteswap_body_helper (&reader, TRUE,
  239:                         old_byte_order, new_byte_order,
  240:                         _dbus_string_get_data_len (value_str, value_pos, 0),
  241:                         NULL);
  242: }
  243: 
  244: /** @} */
  245: 
  246: /* Tests in dbus-marshal-byteswap-util.c */
Syntax (Markdown)