LCOV - code coverage report
Current view: directory - xpcom/typelib/xpt/src - xpt_struct.c (source / functions) Found Hit Coverage
Test: app.info Lines: 436 161 36.9 %
Date: 2012-06-02 Functions: 12 8 66.7 %

       1                 : /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : /* Implementation of XDR routines for typelib structures. */
      39                 : 
      40                 : #include "xpt_xdr.h"
      41                 : #include "xpt_struct.h"
      42                 : #include <string.h>
      43                 : #include <stdio.h>
      44                 : 
      45                 : /***************************************************************************/
      46                 : /* Forward declarations. */
      47                 : 
      48                 : static PRUint32
      49                 : SizeOfTypeDescriptor(XPTTypeDescriptor *td, XPTInterfaceDescriptor *id);
      50                 : 
      51                 : static PRUint32
      52                 : SizeOfMethodDescriptor(XPTMethodDescriptor *md, XPTInterfaceDescriptor *id);
      53                 : 
      54                 : static PRUint32
      55                 : SizeOfConstDescriptor(XPTConstDescriptor *cd, XPTInterfaceDescriptor *id);
      56                 : 
      57                 : static PRUint32
      58                 : SizeOfInterfaceDescriptor(XPTInterfaceDescriptor *id);
      59                 : 
      60                 : static PRBool
      61                 : DoInterfaceDirectoryEntry(XPTArena *arena, XPTCursor *cursor,
      62                 :                           XPTInterfaceDirectoryEntry *ide, PRUint16 entry_index);
      63                 : 
      64                 : static PRBool
      65                 : DoConstDescriptor(XPTArena *arena, XPTCursor *cursor, XPTConstDescriptor *cd,
      66                 :                   XPTInterfaceDescriptor *id);
      67                 : 
      68                 : static PRBool
      69                 : DoMethodDescriptor(XPTArena *arena, XPTCursor *cursor, XPTMethodDescriptor *md, 
      70                 :                    XPTInterfaceDescriptor *id);
      71                 : 
      72                 : static PRBool
      73                 : DoAnnotation(XPTArena *arena, XPTCursor *cursor, XPTAnnotation **annp);
      74                 : 
      75                 : static PRBool
      76                 : DoInterfaceDescriptor(XPTArena *arena, XPTCursor *outer, XPTInterfaceDescriptor **idp);
      77                 : 
      78                 : static PRBool
      79                 : DoTypeDescriptorPrefix(XPTArena *arena, XPTCursor *cursor, XPTTypeDescriptorPrefix *tdp);
      80                 : 
      81                 : static PRBool
      82                 : DoTypeDescriptor(XPTArena *arena, XPTCursor *cursor, XPTTypeDescriptor *td,
      83                 :                  XPTInterfaceDescriptor *id);
      84                 : 
      85                 : static PRBool
      86                 : DoParamDescriptor(XPTArena *arena, XPTCursor *cursor, XPTParamDescriptor *pd,
      87                 :                   XPTInterfaceDescriptor *id);
      88                 : 
      89                 : /***************************************************************************/
      90                 : 
      91                 : XPT_PUBLIC_API(PRUint32)
      92                 : XPT_SizeOfHeader(XPTHeader *header)
      93                 : {
      94                 :     XPTAnnotation *ann, *last;
      95               0 :     PRUint32 size = 16 /* magic */ +
      96                 :         1 /* major */ + 1 /* minor */ +
      97                 :         2 /* num_interfaces */ + 4 /* file_length */ +
      98                 :         4 /* interface_directory */ + 4 /* data_pool */;
      99                 : 
     100               0 :     ann = header->annotations;
     101                 :     do {
     102               0 :         size += 1; /* Annotation prefix */
     103               0 :         if (XPT_ANN_IS_PRIVATE(ann->flags))
     104               0 :             size += 2 + ann->creator->length + 2 + ann->private_data->length;
     105               0 :         last = ann;
     106               0 :         ann = ann->next;
     107               0 :     } while (!XPT_ANN_IS_LAST(last->flags));
     108                 :         
     109               0 :     return size;
     110                 : }
     111                 : 
     112                 : XPT_PUBLIC_API(PRUint32)
     113                 : XPT_SizeOfHeaderBlock(XPTHeader *header)
     114                 : {
     115               0 :     PRUint32 ide_size = 16 /* IID */ + 4 /* name */ +
     116                 :         4 /* namespace */ + 4 /* descriptor */;
     117                 : 
     118               0 :     return XPT_SizeOfHeader(header) + header->num_interfaces * ide_size;
     119                 : }
     120                 : 
     121                 : XPT_PUBLIC_API(XPTHeader *)
     122                 : XPT_NewHeader(XPTArena *arena, PRUint16 num_interfaces, PRUint8 major_version, PRUint8 minor_version)
     123                 : {
     124               0 :     XPTHeader *header = XPT_NEWZAP(arena, XPTHeader);
     125               0 :     if (!header)
     126               0 :         return NULL;
     127               0 :     memcpy(header->magic, XPT_MAGIC, 16);
     128               0 :     header->major_version = major_version;
     129               0 :     header->minor_version = minor_version;
     130               0 :     header->num_interfaces = num_interfaces;
     131               0 :     if (num_interfaces) {
     132               0 :         header->interface_directory = 
     133               0 :             XPT_CALLOC(arena, 
     134                 :                        num_interfaces * sizeof(XPTInterfaceDirectoryEntry));
     135               0 :         if (!header->interface_directory) {
     136               0 :             XPT_DELETE(arena, header);
     137               0 :             return NULL;
     138                 :         }
     139                 :     }
     140               0 :     header->data_pool = 0;      /* XXX do we even need this struct any more? */
     141                 :     
     142               0 :     return header;
     143                 : }
     144                 : 
     145                 : XPT_PUBLIC_API(void)
     146                 : XPT_FreeHeader(XPTArena *arena, XPTHeader* aHeader)
     147                 : {
     148               0 :     if (aHeader) {
     149                 :         XPTAnnotation* ann;
     150               0 :         XPTInterfaceDirectoryEntry* entry = aHeader->interface_directory;
     151               0 :         XPTInterfaceDirectoryEntry* end = entry + aHeader->num_interfaces;
     152               0 :         for (; entry < end; entry++) {
     153               0 :             XPT_DestroyInterfaceDirectoryEntry(arena, entry);
     154                 :         }
     155                 : 
     156               0 :         ann = aHeader->annotations;
     157               0 :         while (ann) {
     158               0 :             XPTAnnotation* next = ann->next;
     159               0 :             if (XPT_ANN_IS_PRIVATE(ann->flags)) {
     160               0 :                 XPT_FREEIF(arena, ann->creator);
     161               0 :                 XPT_FREEIF(arena, ann->private_data);
     162                 :             }
     163               0 :             XPT_DELETE(arena, ann);
     164               0 :             ann = next;
     165                 :         }
     166                 : 
     167               0 :         XPT_FREEIF(arena, aHeader->interface_directory);
     168               0 :         XPT_DELETE(arena, aHeader);
     169                 :     }
     170               0 : }
     171                 : 
     172                 : XPT_PUBLIC_API(PRBool)
     173                 : XPT_DoHeaderPrologue(XPTArena *arena, XPTCursor *cursor, XPTHeader **headerp, PRUint32 * ide_offset)
     174                 : {
     175          218497 :     XPTMode mode = cursor->state->mode;
     176                 :     unsigned int i;
     177                 :     XPTHeader * header;
     178                 : 
     179          218497 :     if (mode == XPT_DECODE) {
     180          218497 :         header = XPT_NEWZAP(arena, XPTHeader);
     181          218497 :         if (!header)
     182               0 :             return PR_FALSE;
     183          218497 :         *headerp = header;
     184                 :     } else {
     185               0 :         header = *headerp;
     186                 :     }
     187                 : 
     188          218497 :     if (mode == XPT_ENCODE) {
     189                 :         /* IDEs appear after header, including annotations */
     190               0 :         if (ide_offset != NULL)
     191                 :         {
     192               0 :             *ide_offset = XPT_SizeOfHeader(*headerp) + 1; /* one-based offset */
     193                 :         }
     194               0 :         header->data_pool = XPT_SizeOfHeaderBlock(*headerp);
     195               0 :         XPT_SetDataOffset(cursor->state, header->data_pool);
     196                 :     }
     197                 : 
     198         3714449 :     for (i = 0; i < sizeof(header->magic); i++) {
     199         3495952 :         if (!XPT_Do8(cursor, &header->magic[i]))
     200               0 :             goto error;
     201                 :     }
     202                 : 
     203          436994 :     if (mode == XPT_DECODE && 
     204          218497 :         strncmp((const char*)header->magic, XPT_MAGIC, 16) != 0)
     205                 :     {
     206                 :         /* Require that the header contain the proper magic */
     207               0 :         fprintf(stderr,
     208                 :                 "libxpt: bad magic header in input file; "
     209                 :                 "found '%s', expected '%s'\n",
     210                 :                 header->magic, XPT_MAGIC_STRING);
     211               0 :         goto error;
     212                 :     }
     213                 :     
     214          436994 :     if (!XPT_Do8(cursor, &header->major_version) ||
     215          218497 :         !XPT_Do8(cursor, &header->minor_version)) {
     216                 :         goto error;
     217                 :     }
     218                 : 
     219          436994 :     if (mode == XPT_DECODE &&
     220          218497 :         header->major_version >= XPT_MAJOR_INCOMPATIBLE_VERSION) {
     221                 :         /* This file is newer than we are and set to an incompatible version
     222                 :          * number. We must set the header state thusly and return.
     223                 :          */
     224               0 :         header->num_interfaces = 0;
     225               0 :         header->file_length = 0;
     226               0 :         return PR_TRUE;
     227                 :     }
     228                 : 
     229          436994 :     if (!XPT_Do16(cursor, &header->num_interfaces) ||
     230          436994 :         !XPT_Do32(cursor, &header->file_length) ||
     231          218497 :         (ide_offset != NULL && !XPT_Do32(cursor, ide_offset))) {
     232                 :         goto error;
     233                 :     }
     234          218497 :     return PR_TRUE;
     235                 :     /* XXX need to free child data sometimes! */
     236               0 :     XPT_ERROR_HANDLE(arena, header);    
     237                 : }
     238                 : 
     239                 : XPT_PUBLIC_API(PRBool)
     240                 : XPT_DoHeader(XPTArena *arena, XPTCursor *cursor, XPTHeader **headerp)
     241                 : {
     242          218497 :     const int HEADER_SIZE = 24;
     243          218497 :     XPTMode mode = cursor->state->mode;
     244                 :     XPTHeader * header;
     245                 :     PRUint32 ide_offset;
     246                 :     int i;
     247                 :     XPTAnnotation *ann, *next, **annp;
     248                 : 
     249          218497 :     if (!XPT_DoHeaderPrologue(arena, cursor, headerp, &ide_offset))
     250               0 :         return PR_FALSE;
     251          218497 :     header = *headerp;
     252                 :     /* 
     253                 :      * Make sure the file length reported in the header is the same size as
     254                 :      * as our buffer unless it is zero (not set) 
     255                 :      */
     256          436994 :     if (mode == XPT_DECODE && (header->file_length != 0 && 
     257          218497 :         cursor->state->pool->allocated < header->file_length)) {
     258               0 :         fputs("libxpt: File length in header does not match actual length. File may be corrupt\n",
     259                 :             stderr);
     260               0 :         goto error;
     261                 :     }
     262                 : 
     263          218497 :     if (mode == XPT_ENCODE)
     264               0 :         XPT_DataOffset(cursor->state, &header->data_pool);
     265          218497 :     if (!XPT_Do32(cursor, &header->data_pool))
     266               0 :         goto error;
     267          218497 :     if (mode == XPT_DECODE)
     268          218497 :         XPT_DataOffset(cursor->state, &header->data_pool);
     269                 : 
     270          218497 :     if (mode == XPT_DECODE && header->num_interfaces) {
     271          218497 :         header->interface_directory = 
     272          218497 :             XPT_CALLOC(arena, header->num_interfaces * 
     273                 :                        sizeof(XPTInterfaceDirectoryEntry));
     274          218497 :         if (!header->interface_directory)
     275               0 :             goto error;
     276                 :     }
     277                 : 
     278                 :     /*
     279                 :      * Iterate through the annotations rather than recurring, to avoid blowing
     280                 :      * the stack on large xpt files.
     281                 :      */
     282          218497 :     ann = next = header->annotations;
     283          218497 :     annp = &header->annotations;
     284                 :     do {
     285          218497 :         ann = next;
     286          218497 :         if (!DoAnnotation(arena, cursor, &ann))
     287               0 :             goto error;
     288          218497 :         if (mode == XPT_DECODE) {
     289                 :             /*
     290                 :              * Make sure that we store the address of the newly allocated
     291                 :              * annotation in the previous annotation's ``next'' slot, or
     292                 :              * header->annotations for the first one.
     293                 :              */
     294          218497 :             *annp = ann;
     295          218497 :             annp = &ann->next;
     296                 :         }
     297          218497 :         next = ann->next;
     298          218497 :     } while (!XPT_ANN_IS_LAST(ann->flags));
     299                 : 
     300                 :     /* shouldn't be necessary now, but maybe later */
     301          218497 :     XPT_SeekTo(cursor, ide_offset); 
     302                 : 
     303         3616498 :     for (i = 0; i < header->num_interfaces; i++) {
     304        10194003 :         if (!DoInterfaceDirectoryEntry(arena, cursor, 
     305         6796002 :                                        &header->interface_directory[i],
     306         3398001 :                                        (PRUint16)(i + 1)))
     307               0 :             goto error;
     308                 :     }
     309                 :     
     310          218497 :     return PR_TRUE;
     311                 : 
     312                 :     /* XXX need to free child data sometimes! */
     313               0 :     XPT_ERROR_HANDLE(arena, header);    
     314                 : }   
     315                 : 
     316                 : XPT_PUBLIC_API(PRBool)
     317                 : XPT_FillInterfaceDirectoryEntry(XPTArena *arena,
     318                 :                                 XPTInterfaceDirectoryEntry *ide,
     319                 :                                 nsID *iid, char *name, char *name_space,
     320                 :                                 XPTInterfaceDescriptor *descriptor)
     321                 : {
     322               0 :     XPT_COPY_IID(ide->iid, *iid);
     323               0 :     ide->name = name ? XPT_STRDUP(arena, name) : NULL; /* what good is it w/o a name? */
     324               0 :     ide->name_space = name_space ? XPT_STRDUP(arena, name_space) : NULL;
     325               0 :     ide->interface_descriptor = descriptor;
     326               0 :     return PR_TRUE;
     327                 : }
     328                 : 
     329                 : XPT_PUBLIC_API(void)
     330                 : XPT_DestroyInterfaceDirectoryEntry(XPTArena *arena,
     331                 :                                    XPTInterfaceDirectoryEntry* ide)
     332                 : {
     333               0 :     if (ide) {
     334               0 :         if (ide->name) XPT_FREE(arena, ide->name);
     335               0 :         if (ide->name_space) XPT_FREE(arena, ide->name_space);
     336               0 :         XPT_FreeInterfaceDescriptor(arena, ide->interface_descriptor);
     337                 :     }
     338               0 : }
     339                 : 
     340                 : /* InterfaceDirectoryEntry records go in the header */
     341                 : PRBool
     342         3398001 : DoInterfaceDirectoryEntry(XPTArena *arena, XPTCursor *cursor,
     343                 :                           XPTInterfaceDirectoryEntry *ide, PRUint16 entry_index)
     344                 : {
     345         3398001 :     XPTMode mode = cursor->state->mode;
     346                 :     
     347                 :     /* write the IID in our cursor space */
     348         6796002 :     if (!XPT_DoIID(cursor, &(ide->iid)) ||
     349                 :         
     350                 :         /* write the name string in the data pool, and the offset in our
     351                 :            cursor space */
     352         6796002 :         !XPT_DoCString(arena, cursor, &(ide->name)) ||
     353                 :         
     354                 :         /* write the name_space string in the data pool, and the offset in our
     355                 :            cursor space */
     356         6796002 :         !XPT_DoCString(arena, cursor, &(ide->name_space)) ||
     357                 :         
     358                 :         /* do InterfaceDescriptors -- later, only on encode (see below) */
     359         3398001 :         !DoInterfaceDescriptor(arena, cursor, &ide->interface_descriptor)) {
     360                 :         goto error;
     361                 :     }
     362                 :     
     363         3398001 :     if (mode == XPT_DECODE)
     364         3398001 :         XPT_SetOffsetForAddr(cursor, ide, entry_index);
     365                 : 
     366         3398001 :     return PR_TRUE;
     367                 : 
     368               0 :     XPT_ERROR_HANDLE(arena, ide);    
     369                 : }
     370                 : 
     371                 : XPT_PUBLIC_API(XPTInterfaceDescriptor *)
     372                 : XPT_NewInterfaceDescriptor(XPTArena *arena, 
     373                 :                            PRUint16 parent_interface, PRUint16 num_methods,
     374                 :                            PRUint16 num_constants, PRUint8 flags)
     375                 : {
     376                 : 
     377               0 :     XPTInterfaceDescriptor *id = XPT_NEWZAP(arena, XPTInterfaceDescriptor);
     378               0 :     if (!id)
     379               0 :         return NULL;
     380                 : 
     381               0 :     if (num_methods) {
     382               0 :         id->method_descriptors = XPT_CALLOC(arena, num_methods *
     383                 :                                             sizeof(XPTMethodDescriptor));
     384               0 :         if (!id->method_descriptors)
     385               0 :             goto free_id;
     386               0 :         id->num_methods = num_methods;
     387                 :     }
     388                 : 
     389               0 :     if (num_constants) {
     390               0 :         id->const_descriptors = XPT_CALLOC(arena, num_constants *
     391                 :                                            sizeof(XPTConstDescriptor));
     392               0 :         if (!id->const_descriptors)
     393               0 :             goto free_meth;
     394               0 :         id->num_constants = num_constants;
     395                 :     }
     396                 : 
     397               0 :     if (parent_interface) {
     398               0 :         id->parent_interface = parent_interface;
     399                 :     } else {
     400               0 :         id->parent_interface = 0;
     401                 :     }
     402                 : 
     403               0 :     id->flags = flags;
     404                 : 
     405               0 :     return id;
     406                 : 
     407                 :  free_meth:
     408               0 :     XPT_FREEIF(arena, id->method_descriptors);
     409                 :  free_id:
     410               0 :     XPT_DELETE(arena, id);
     411               0 :     return NULL;
     412                 : }
     413                 : 
     414                 : XPT_PUBLIC_API(void)
     415                 : XPT_FreeInterfaceDescriptor(XPTArena *arena, XPTInterfaceDescriptor* id)
     416                 : {
     417               0 :     if (id) {
     418                 :         XPTMethodDescriptor *md, *mdend;
     419                 :         XPTConstDescriptor *cd, *cdend;
     420                 : 
     421                 :         /* Free up method descriptors */
     422               0 :         md = id->method_descriptors;
     423               0 :         mdend = md + id->num_methods;
     424               0 :         for (; md < mdend; md++) {
     425               0 :             XPT_FREEIF(arena, md->name);
     426               0 :             XPT_FREEIF(arena, md->params);
     427               0 :             XPT_FREEIF(arena, md->result);
     428                 :         }
     429               0 :         XPT_FREEIF(arena, id->method_descriptors);
     430                 : 
     431                 :         /* Free up const descriptors */
     432               0 :         cd = id->const_descriptors;
     433               0 :         cdend = cd + id->num_constants;
     434               0 :         for (; cd < cdend; cd++) {
     435               0 :             XPT_FREEIF(arena, cd->name);
     436                 :         }
     437               0 :         XPT_FREEIF(arena, id->const_descriptors);
     438                 : 
     439                 :         /* Free up type descriptors */
     440               0 :         XPT_FREEIF(arena, id->additional_types);
     441                 : 
     442               0 :         XPT_DELETE(arena, id);
     443                 :     }
     444               0 : }
     445                 : 
     446                 : XPT_PUBLIC_API(PRBool)
     447                 : XPT_InterfaceDescriptorAddTypes(XPTArena *arena, XPTInterfaceDescriptor *id, 
     448                 :                                 PRUint16 num)
     449                 : {
     450          252654 :     XPTTypeDescriptor *old = id->additional_types;
     451                 :     XPTTypeDescriptor *new;
     452          252654 :     size_t old_size = id->num_additional_types * sizeof(XPTTypeDescriptor);
     453          252654 :     size_t new_size = (num * sizeof(XPTTypeDescriptor)) + old_size;
     454                 : 
     455                 :     /* XXX should grow in chunks to minimize alloc overhead */
     456          252654 :     new = XPT_CALLOC(arena, new_size);
     457          252654 :     if (!new)
     458               0 :         return PR_FALSE;
     459          252654 :     if (old) {
     460          119264 :         if (old_size)
     461          119264 :             memcpy(new, old, old_size);
     462          119264 :         XPT_FREE(arena, old);
     463                 :     }
     464          252654 :     id->additional_types = new;
     465          252654 :     id->num_additional_types += num;
     466          252654 :     return PR_TRUE;
     467                 : }
     468                 : 
     469                 : XPT_PUBLIC_API(PRBool)
     470                 : XPT_InterfaceDescriptorAddMethods(XPTArena *arena, XPTInterfaceDescriptor *id, 
     471                 :                                   PRUint16 num)
     472                 : {
     473               0 :     XPTMethodDescriptor *old = id->method_descriptors;
     474                 :     XPTMethodDescriptor *new;
     475               0 :     size_t old_size = id->num_methods * sizeof(XPTMethodDescriptor);
     476               0 :     size_t new_size = (num * sizeof(XPTMethodDescriptor)) + old_size;
     477                 : 
     478                 :     /* XXX should grow in chunks to minimize alloc overhead */
     479               0 :     new = XPT_CALLOC(arena, new_size);
     480               0 :     if (!new)
     481               0 :         return PR_FALSE;
     482               0 :     if (old) {
     483               0 :         if (old_size)
     484               0 :             memcpy(new, old, old_size);
     485               0 :         XPT_FREE(arena, old);
     486                 :     }
     487               0 :     id->method_descriptors = new;
     488               0 :     id->num_methods += num;
     489               0 :     return PR_TRUE;
     490                 : }
     491                 : 
     492                 : XPT_PUBLIC_API(PRBool)
     493                 : XPT_InterfaceDescriptorAddConsts(XPTArena *arena, XPTInterfaceDescriptor *id, 
     494                 :                                  PRUint16 num)
     495                 : {
     496               0 :     XPTConstDescriptor *old = id->const_descriptors;
     497                 :     XPTConstDescriptor *new;
     498               0 :     size_t old_size = id->num_constants * sizeof(XPTConstDescriptor);
     499               0 :     size_t new_size = (num * sizeof(XPTConstDescriptor)) + old_size;
     500                 : 
     501                 :     /* XXX should grow in chunks to minimize alloc overhead */
     502               0 :     new = XPT_CALLOC(arena, new_size);
     503               0 :     if (!new)
     504               0 :         return PR_FALSE;
     505               0 :     if (old) {
     506               0 :         if (old_size)
     507               0 :             memcpy(new, old, old_size);
     508               0 :         XPT_FREE(arena, old);
     509                 :     }
     510               0 :     id->const_descriptors = new;
     511               0 :     id->num_constants += num;
     512               0 :     return PR_TRUE;
     513                 : }
     514                 : 
     515                 : PRUint32
     516               0 : SizeOfTypeDescriptor(XPTTypeDescriptor *td, XPTInterfaceDescriptor *id)
     517                 : {
     518               0 :     PRUint32 size = 1; /* prefix */
     519                 : 
     520               0 :     switch (XPT_TDP_TAG(td->prefix)) {
     521                 :       case TD_INTERFACE_TYPE:
     522               0 :         size += 2; /* interface_index */
     523               0 :         break;
     524                 :       case TD_INTERFACE_IS_TYPE:
     525               0 :         size += 1; /* argnum */
     526               0 :         break;
     527                 :       case TD_ARRAY:
     528               0 :         size += 2 + SizeOfTypeDescriptor(
     529               0 :                         &id->additional_types[td->type.additional_type], id);
     530               0 :         break;
     531                 :       case TD_PSTRING_SIZE_IS:
     532               0 :         size += 2; /* argnum + argnum2 */
     533               0 :         break;
     534                 :       case TD_PWSTRING_SIZE_IS:
     535               0 :         size += 2; /* argnum + argnum2 */
     536               0 :         break;
     537                 :       default:
     538                 :         /* nothing special */
     539               0 :         break;
     540                 :     }
     541               0 :     return size;
     542                 : }
     543                 : 
     544                 : PRUint32
     545               0 : SizeOfMethodDescriptor(XPTMethodDescriptor *md, XPTInterfaceDescriptor *id)
     546                 : {
     547               0 :     PRUint32 i, size =  1 /* flags */ + 4 /* name */ + 1 /* num_args */;
     548                 : 
     549               0 :     for (i = 0; i < md->num_args; i++) 
     550               0 :         size += 1 + SizeOfTypeDescriptor(&md->params[i].type, id);
     551                 : 
     552               0 :     size += 1 + SizeOfTypeDescriptor(&md->result->type, id);
     553               0 :     return size;
     554                 : }
     555                 : 
     556                 : PRUint32
     557               0 : SizeOfConstDescriptor(XPTConstDescriptor *cd, XPTInterfaceDescriptor *id)
     558                 : {
     559               0 :     PRUint32 size = 4 /* name */ + SizeOfTypeDescriptor(&cd->type, id);
     560                 : 
     561               0 :     switch (XPT_TDP_TAG(cd->type.prefix)) {
     562                 :       case TD_INT8:
     563                 :       case TD_UINT8:
     564                 :       case TD_CHAR:
     565               0 :         size ++;
     566               0 :         break;
     567                 :       case TD_INT16:
     568                 :       case TD_UINT16:
     569                 :       case TD_WCHAR:
     570               0 :         size += 2;
     571               0 :         break;
     572                 :       case TD_INT32:
     573                 :       case TD_UINT32:
     574                 :       case TD_PSTRING:
     575               0 :         size += 4;
     576               0 :         break;
     577                 :       case TD_INT64:
     578                 :       case TD_UINT64:
     579               0 :         size += 8;
     580               0 :         break;
     581                 :       default:
     582               0 :         fprintf(stderr, "libxpt: illegal type in ConstDescriptor: 0x%02x\n",
     583               0 :                 XPT_TDP_TAG(cd->type.prefix));
     584               0 :         return 0;
     585                 :     }
     586                 : 
     587               0 :     return size;
     588                 : }
     589                 : 
     590                 : PRUint32
     591               0 : SizeOfInterfaceDescriptor(XPTInterfaceDescriptor *id)
     592                 : {
     593               0 :     PRUint32 size = 2 /* parent interface */ + 2 /* num_methods */
     594                 :         + 2 /* num_constants */ + 1 /* flags */, i;
     595               0 :     for (i = 0; i < id->num_methods; i++)
     596               0 :         size += SizeOfMethodDescriptor(&id->method_descriptors[i], id);
     597               0 :     for (i = 0; i < id->num_constants; i++)
     598               0 :         size += SizeOfConstDescriptor(&id->const_descriptors[i], id);
     599               0 :     return size;
     600                 : }
     601                 : 
     602                 : PRBool
     603         3398001 : DoInterfaceDescriptor(XPTArena *arena, XPTCursor *outer, 
     604                 :                       XPTInterfaceDescriptor **idp)
     605                 : {
     606         3398001 :     XPTMode mode = outer->state->mode;
     607                 :     XPTInterfaceDescriptor *id;
     608         3398001 :     XPTCursor curs, *cursor = &curs;
     609         3398001 :     PRUint32 i, id_sz = 0;
     610                 : 
     611         3398001 :     if (mode == XPT_DECODE) {
     612         3398001 :         id = XPT_NEWZAP(arena, XPTInterfaceDescriptor);
     613         3398001 :         if (!id)
     614               0 :             return PR_FALSE;
     615         3398001 :         *idp = id;
     616                 :     } else {
     617               0 :         id = *idp;
     618               0 :         if (!id) {
     619               0 :             id_sz = 0;
     620               0 :             return XPT_Do32(outer, &id_sz);
     621                 :         }
     622               0 :         id_sz = SizeOfInterfaceDescriptor(id);
     623                 :     }
     624                 : 
     625         3398001 :     if (!XPT_MakeCursor(outer->state, XPT_DATA, id_sz, cursor))
     626               0 :         goto error;
     627                 : 
     628         3398001 :     if (!XPT_Do32(outer, &cursor->offset))
     629               0 :         goto error;
     630         3398001 :     if (mode == XPT_DECODE && !cursor->offset) {
     631         1229947 :         XPT_DELETE(arena, *idp);
     632         1229947 :         return PR_TRUE;
     633                 :     }
     634         4336108 :     if(!XPT_Do16(cursor, &id->parent_interface) ||
     635         2168054 :        !XPT_Do16(cursor, &id->num_methods)) {
     636                 :         goto error;
     637                 :     }
     638                 : 
     639         2168054 :     if (mode == XPT_DECODE && id->num_methods) {
     640         2064467 :         id->method_descriptors = XPT_CALLOC(arena, id->num_methods *
     641                 :                                             sizeof(XPTMethodDescriptor));
     642         2064467 :         if (!id->method_descriptors)
     643               0 :             goto error;
     644                 :     }
     645                 :     
     646        17455141 :     for (i = 0; i < id->num_methods; i++) {
     647        15287087 :         if (!DoMethodDescriptor(arena, cursor, &id->method_descriptors[i], id))
     648               0 :             goto error;   
     649                 :     }
     650                 :     
     651         2168054 :     if (!XPT_Do16(cursor, &id->num_constants)) {
     652               0 :         goto error;
     653                 :     }
     654                 :     
     655         2168054 :     if (mode == XPT_DECODE && id->num_constants) {
     656          401577 :         id->const_descriptors = XPT_CALLOC(arena, id->num_constants * 
     657                 :                                            sizeof(XPTConstDescriptor));
     658          401577 :         if (!id->const_descriptors)
     659               0 :             goto error;
     660                 :     }
     661                 :     
     662         6037667 :     for (i = 0; i < id->num_constants; i++) {
     663         3869613 :         if (!DoConstDescriptor(arena, cursor, &id->const_descriptors[i], id)) {
     664               0 :             goto error;
     665                 :         }
     666                 :     }
     667                 : 
     668         2168054 :     if (!XPT_Do8(cursor, &id->flags)) {
     669               0 :         goto error;
     670                 :     }
     671                 :     
     672         2168054 :     return PR_TRUE;
     673                 : 
     674               0 :     XPT_ERROR_HANDLE(arena, id);    
     675                 : }
     676                 : 
     677                 : PRBool
     678         3869613 : DoConstDescriptor(XPTArena *arena, XPTCursor *cursor, XPTConstDescriptor *cd,
     679                 :                   XPTInterfaceDescriptor *id)
     680                 : {
     681         3869613 :     PRBool ok = PR_FALSE;
     682                 : 
     683         7739226 :     if (!XPT_DoCString(arena, cursor, &cd->name) ||
     684         3869613 :         !DoTypeDescriptor(arena, cursor, &cd->type, id)) {
     685                 : 
     686               0 :         return PR_FALSE;
     687                 :     }
     688                 : 
     689         3869613 :     switch(XPT_TDP_TAG(cd->type.prefix)) {
     690                 :       case TD_INT8:
     691               0 :         ok = XPT_Do8(cursor, (PRUint8*) &cd->value.i8);
     692               0 :         break;
     693                 :       case TD_INT16:
     694          272448 :         ok = XPT_Do16(cursor, (PRUint16*) &cd->value.i16);
     695          272448 :         break;
     696                 :       case TD_INT32:
     697          625779 :         ok = XPT_Do32(cursor, (PRUint32*) &cd->value.i32);
     698          625779 :         break;
     699                 :       case TD_INT64:
     700               0 :         ok = XPT_Do64(cursor, &cd->value.i64);
     701               0 :         break;
     702                 :       case TD_UINT8:
     703               0 :         ok = XPT_Do8(cursor, &cd->value.ui8);
     704               0 :         break;
     705                 :       case TD_UINT16:
     706          683958 :         ok = XPT_Do16(cursor, &cd->value.ui16);
     707          683958 :         break;
     708                 :       case TD_UINT32:
     709         2287428 :         ok = XPT_Do32(cursor, &cd->value.ui32);
     710         2287428 :         break;
     711                 :       case TD_UINT64:
     712               0 :         ok = XPT_Do64(cursor, (PRInt64 *)&cd->value.ui64);
     713               0 :         break;
     714                 :       case TD_CHAR:
     715               0 :         ok = XPT_Do8(cursor, (PRUint8*) &cd->value.ch);
     716               0 :         break;
     717                 :       case TD_WCHAR:
     718               0 :         ok = XPT_Do16(cursor, &cd->value.wch);
     719               0 :         break;
     720                 :         /* fall-through */
     721                 :       default:
     722               0 :         fprintf(stderr, "illegal type!\n");
     723               0 :         break;
     724                 :     }
     725                 : 
     726         3869613 :     return ok;
     727                 : 
     728                 : }
     729                 : 
     730                 : XPT_PUBLIC_API(PRBool)
     731                 : XPT_FillMethodDescriptor(XPTArena *arena, XPTMethodDescriptor *meth, 
     732                 :                          PRUint8 flags, char *name, PRUint8 num_args)
     733                 : {
     734               0 :     meth->flags = flags & XPT_MD_FLAGMASK;
     735               0 :     meth->name = XPT_STRDUP(arena, name);
     736               0 :     if (!meth->name)
     737               0 :         return PR_FALSE;
     738               0 :     meth->num_args = num_args;
     739               0 :     if (num_args) {
     740               0 :         meth->params = XPT_CALLOC(arena, num_args * sizeof(XPTParamDescriptor));
     741               0 :         if (!meth->params)
     742               0 :             goto free_name;
     743                 :     } else {
     744               0 :         meth->params = NULL;
     745                 :     }
     746               0 :     meth->result = XPT_NEWZAP(arena, XPTParamDescriptor);
     747               0 :     if (!meth->result)
     748               0 :         goto free_params;
     749               0 :     return PR_TRUE;
     750                 : 
     751                 :  free_params:
     752               0 :     XPT_DELETE(arena, meth->params);
     753                 :  free_name:
     754               0 :     XPT_DELETE(arena, meth->name);
     755               0 :     return PR_FALSE;
     756                 : }
     757                 : 
     758                 : PRBool
     759        15287087 : DoMethodDescriptor(XPTArena *arena, XPTCursor *cursor, XPTMethodDescriptor *md,
     760                 :                    XPTInterfaceDescriptor *id)
     761                 : {
     762        15287087 :     XPTMode mode = cursor->state->mode;
     763                 :     int i;
     764                 : 
     765        30574174 :     if (!XPT_Do8(cursor, &md->flags) ||
     766        30574174 :         !XPT_DoCString(arena, cursor, &md->name) ||
     767        15287087 :         !XPT_Do8(cursor, &md->num_args))
     768               0 :         return PR_FALSE;
     769                 : 
     770        15287087 :     if (mode == XPT_DECODE && md->num_args) {
     771        14427305 :         md->params = XPT_CALLOC(arena, md->num_args * sizeof(XPTParamDescriptor));
     772        14427305 :         if (!md->params)
     773               0 :             return PR_FALSE;
     774                 :     }
     775                 : 
     776        38151054 :     for(i = 0; i < md->num_args; i++) {
     777        22863967 :         if (!DoParamDescriptor(arena, cursor, &md->params[i], id))
     778               0 :             goto error;
     779                 :     }
     780                 :     
     781        15287087 :     if (mode == XPT_DECODE) {
     782        15287087 :         md->result = XPT_NEWZAP(arena, XPTParamDescriptor);
     783        15287087 :         if (!md->result)
     784               0 :             return PR_FALSE;
     785                 :     }
     786                 : 
     787        30574174 :     if (!md->result ||
     788        15287087 :         !DoParamDescriptor(arena, cursor, md->result, id))
     789                 :         goto error;
     790                 :     
     791        15287087 :     return PR_TRUE;
     792                 :     
     793               0 :     XPT_ERROR_HANDLE(arena, md->params);    
     794                 : }
     795                 : 
     796                 : XPT_PUBLIC_API(PRBool)
     797                 : XPT_FillParamDescriptor(XPTArena *arena, XPTParamDescriptor *pd, PRUint8 flags,
     798                 :                         XPTTypeDescriptor *type)
     799                 : {
     800               0 :     pd->flags = flags & XPT_PD_FLAGMASK;
     801               0 :     XPT_COPY_TYPE(pd->type, *type);
     802               0 :     return PR_TRUE;
     803                 : }
     804                 : 
     805                 : PRBool
     806        38151054 : DoParamDescriptor(XPTArena *arena, XPTCursor *cursor, XPTParamDescriptor *pd, 
     807                 :                   XPTInterfaceDescriptor *id)
     808                 : {
     809        76302108 :     if (!XPT_Do8(cursor, &pd->flags) ||
     810        38151054 :         !DoTypeDescriptor(arena, cursor, &pd->type, id))
     811               0 :         return PR_FALSE;
     812                 :         
     813        38151054 :     return PR_TRUE;
     814                 : }
     815                 : 
     816                 : PRBool
     817        42273321 : DoTypeDescriptorPrefix(XPTArena *arena, XPTCursor *cursor, XPTTypeDescriptorPrefix *tdp)
     818                 : {
     819        42273321 :     return XPT_Do8(cursor, &tdp->flags);
     820                 : }
     821                 : 
     822                 : PRBool
     823        42273321 : DoTypeDescriptor(XPTArena *arena, XPTCursor *cursor, XPTTypeDescriptor *td,
     824                 :                  XPTInterfaceDescriptor *id)
     825                 : {
     826        42273321 :     if (!DoTypeDescriptorPrefix(arena, cursor, &td->prefix)) {
     827               0 :         goto error;
     828                 :     }
     829                 :     
     830        42273321 :     switch (XPT_TDP_TAG(td->prefix)) {
     831                 :       case TD_INTERFACE_TYPE:
     832         6403497 :         if (!XPT_Do16(cursor, &td->type.iface))
     833               0 :             goto error;
     834         6403497 :         break;
     835                 :       case TD_INTERFACE_IS_TYPE:
     836           44013 :         if (!XPT_Do8(cursor, &td->argnum))
     837               0 :             goto error;
     838           44013 :         break;
     839                 :       case TD_ARRAY:
     840          505308 :         if (!XPT_Do8(cursor, &td->argnum) ||
     841          252654 :             !XPT_Do8(cursor, &td->argnum2))
     842                 :             goto error;
     843                 : 
     844          252654 :         if (cursor->state->mode == XPT_DECODE) {
     845          252654 :             if(!XPT_InterfaceDescriptorAddTypes(arena, id, 1))
     846               0 :                 goto error;
     847          252654 :             td->type.additional_type = id->num_additional_types - 1;
     848                 :         }
     849                 : 
     850          505308 :         if (!DoTypeDescriptor(arena, cursor, 
     851          505308 :                               &id->additional_types[td->type.additional_type], 
     852                 :                               id))
     853               0 :             goto error;
     854          252654 :         break;
     855                 :       case TD_PSTRING_SIZE_IS:
     856                 :       case TD_PWSTRING_SIZE_IS:
     857           42618 :         if (!XPT_Do8(cursor, &td->argnum) ||
     858           21309 :             !XPT_Do8(cursor, &td->argnum2))
     859                 :             goto error;
     860           21309 :         break;
     861                 : 
     862                 :       default:
     863                 :         /* nothing special */
     864        35551848 :         break;
     865                 :     }
     866        42273321 :     return PR_TRUE;
     867                 :     
     868               0 :     XPT_ERROR_HANDLE(arena, td);    
     869                 : }
     870                 : 
     871                 : XPT_PUBLIC_API(XPTAnnotation *)
     872                 : XPT_NewAnnotation(XPTArena *arena, PRUint8 flags, XPTString *creator, 
     873                 :                   XPTString *private_data)
     874                 : {
     875               0 :     XPTAnnotation *ann = XPT_NEWZAP(arena, XPTAnnotation);
     876               0 :     if (!ann)
     877               0 :         return NULL;
     878               0 :     ann->flags = flags;
     879               0 :     if (XPT_ANN_IS_PRIVATE(flags)) {
     880               0 :         ann->creator = creator;
     881               0 :         ann->private_data = private_data;
     882                 :     }
     883               0 :     return ann;
     884                 : }
     885                 : 
     886                 : PRBool
     887          218497 : DoAnnotation(XPTArena *arena, XPTCursor *cursor, XPTAnnotation **annp)
     888                 : {
     889          218497 :     XPTMode mode = cursor->state->mode;
     890                 :     XPTAnnotation *ann;
     891                 :     
     892          218497 :     if (mode == XPT_DECODE) {
     893          218497 :         ann = XPT_NEWZAP(arena, XPTAnnotation);
     894          218497 :         if (!ann)
     895               0 :             return PR_FALSE;
     896          218497 :         *annp = ann;
     897                 :     } else {
     898               0 :         ann = *annp;
     899                 :     }
     900                 :     
     901          218497 :     if (!XPT_Do8(cursor, &ann->flags))
     902               0 :         goto error;
     903                 : 
     904          218497 :     if (XPT_ANN_IS_PRIVATE(ann->flags)) {
     905               0 :         if (!XPT_DoStringInline(arena, cursor, &ann->creator) ||
     906               0 :             !XPT_DoStringInline(arena, cursor, &ann->private_data))
     907                 :             goto error_2;
     908                 :     }
     909                 : 
     910          218497 :     return PR_TRUE;
     911                 :     
     912                 :  error_2:
     913               0 :     if (ann && XPT_ANN_IS_PRIVATE(ann->flags)) {
     914               0 :         XPT_FREEIF(arena, ann->creator);
     915               0 :         XPT_FREEIF(arena, ann->private_data);
     916                 :     }
     917               0 :     XPT_ERROR_HANDLE(arena, ann);
     918                 : }
     919                 : 
     920                 : PRBool
     921                 : XPT_GetInterfaceIndexByName(XPTInterfaceDirectoryEntry *ide_block,
     922                 :                             PRUint16 num_interfaces, char *name, 
     923                 :                             PRUint16 *indexp) 
     924                 : {
     925                 :     int i;
     926                 :     
     927               0 :     for (i=1; i<=num_interfaces; i++) {
     928               0 :         fprintf(stderr, "%s == %s ?\n", ide_block[i].name, name);
     929               0 :         if (strcmp(ide_block[i].name, name) == 0) {
     930               0 :             *indexp = i;
     931               0 :             return PR_TRUE;
     932                 :         }
     933                 :     }
     934               0 :     indexp = 0;
     935               0 :     return PR_FALSE;
     936                 : }
     937                 : 
     938                 : static XPT_TYPELIB_VERSIONS_STRUCT versions[] = XPT_TYPELIB_VERSIONS;
     939                 : #define XPT_TYPELIB_VERSIONS_COUNT (sizeof(versions) / sizeof(versions[0]))
     940                 : 
     941                 : XPT_PUBLIC_API(PRUint16)
     942                 : XPT_ParseVersionString(const char* str, PRUint8* major, PRUint8* minor)
     943                 : {
     944                 :     unsigned int i;
     945               0 :     for (i = 0; i < XPT_TYPELIB_VERSIONS_COUNT; i++) {
     946               0 :         if (!strcmp(versions[i].str, str)) {
     947               0 :             *major = versions[i].major;
     948               0 :             *minor = versions[i].minor;
     949               0 :             return versions[i].code;
     950                 :         }
     951                 :     }
     952               0 :     return XPT_VERSION_UNKNOWN;
     953                 : }
     954                 : 
     955                 : 

Generated by: LCOV version 1.7