tools/trace-malloc/formdata.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/trace-malloc/formdata.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,204 @@
     1.4 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     1.5 + *
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +/*
    1.11 +**  formdata.c
    1.12 +**
    1.13 +**  Play utility to parse up form get data into name value pairs.
    1.14 +*/
    1.15 +
    1.16 +#include "formdata.h"
    1.17 +
    1.18 +#include <stdlib.h>
    1.19 +#include <string.h>
    1.20 +#include <ctype.h>
    1.21 +
    1.22 +
    1.23 +static void unhexcape(char* inPlace)
    1.24 +/*
    1.25 +**  Real low tech unhexcaper....
    1.26 +**
    1.27 +**  inPlace     string to decode, in place as it were.
    1.28 +*/
    1.29 +{
    1.30 +    if(NULL != inPlace)
    1.31 +    {
    1.32 +        int index1 = 0;
    1.33 +        int index2 = 0;
    1.34 +        int theLen = strlen(inPlace);
    1.35 +        
    1.36 +        for(; index1 <= theLen; index1++)
    1.37 +        {
    1.38 +            if('%' == inPlace[index1] && '\0' != inPlace[index1 + 1] && '\0' != inPlace[index1 + 2])
    1.39 +            {
    1.40 +                int unhex = 0;
    1.41 +                
    1.42 +                if('9' >= inPlace[index1 + 1])
    1.43 +                {
    1.44 +                    unhex |= ((inPlace[index1 + 1] - '0') << 4);
    1.45 +                }
    1.46 +                else
    1.47 +                {
    1.48 +                    unhex |= ((toupper(inPlace[index1 + 1]) - 'A' + 10) << 4);
    1.49 +                }
    1.50 +                
    1.51 +                if('9' >= inPlace[index1 + 2])
    1.52 +                {
    1.53 +                    unhex |= (inPlace[index1 + 2] - '0');
    1.54 +                }
    1.55 +                else
    1.56 +                {
    1.57 +                    unhex |= (toupper(inPlace[index1 + 2]) - 'A' + 10);
    1.58 +                }
    1.59 +                
    1.60 +                index1 += 2;
    1.61 +                inPlace[index1] = unhex;
    1.62 +            }
    1.63 +            
    1.64 +            inPlace[index2++] = inPlace[index1];
    1.65 +        }
    1.66 +    }
    1.67 +}
    1.68 +
    1.69 +
    1.70 +FormData* FormData_Create(const char* inFormData)
    1.71 +{
    1.72 +    FormData* retval = NULL;
    1.73 +
    1.74 +    if(NULL != inFormData)
    1.75 +    {
    1.76 +        FormData* container = NULL;
    1.77 +
    1.78 +        /*
    1.79 +        **  Allocate form data container.
    1.80 +        */
    1.81 +        container = (FormData*)calloc(1, sizeof(FormData));
    1.82 +        if(NULL != container)
    1.83 +        {
    1.84 +            /*
    1.85 +            **  Dup the incoming form data.
    1.86 +            */
    1.87 +            container->mStorage = strdup(inFormData);
    1.88 +            if(NULL != container->mStorage)
    1.89 +            {
    1.90 +                char* traverse = NULL;
    1.91 +                unsigned nvpairs = 1;
    1.92 +                unsigned storeLen = 0;
    1.93 +
    1.94 +                /*
    1.95 +                **  Count the number of pairs we are going to have.
    1.96 +                **  We do this by counting '&' + 1.
    1.97 +                */
    1.98 +                for(traverse = container->mStorage; '\0' != *traverse; traverse++)
    1.99 +                {
   1.100 +                    if('&' == *traverse)
   1.101 +                    {
   1.102 +                        nvpairs++;
   1.103 +                    }
   1.104 +                }
   1.105 +                storeLen = (unsigned)(traverse - container->mStorage);
   1.106 +
   1.107 +                /*
   1.108 +                **  Allocate space for our names and values.
   1.109 +                */
   1.110 +                container->mNArray = (char**)calloc(nvpairs * 2, sizeof(char*));
   1.111 +                if(NULL != container->mNArray)
   1.112 +                {
   1.113 +                    char* amp = NULL;
   1.114 +                    char* equ = NULL;
   1.115 +
   1.116 +                    container->mVArray = &container->mNArray[nvpairs];
   1.117 +
   1.118 +                    /*
   1.119 +                    **  Go back over the storage.
   1.120 +                    **  Fill in the names and values as we go.
   1.121 +                    **  Terminate on dividing '=' and '&' characters.
   1.122 +                    **  Increase the count of items as we go.
   1.123 +                    */
   1.124 +                    for(traverse = container->mStorage; NULL != traverse; container->mNVCount++)
   1.125 +                    {
   1.126 +                        container->mNArray[container->mNVCount] = traverse;
   1.127 +
   1.128 +                        amp = strchr(traverse, '&');
   1.129 +                        equ = strchr(traverse, '=');
   1.130 +                        traverse = NULL;
   1.131 +
   1.132 +                        if(NULL != equ && (NULL == amp || equ < amp))
   1.133 +                        {
   1.134 +                            *equ++ = '\0';
   1.135 +
   1.136 +                            container->mVArray[container->mNVCount] = equ;
   1.137 +                        }
   1.138 +                        else
   1.139 +                        {
   1.140 +                            container->mVArray[container->mNVCount] = (container->mStorage + storeLen);
   1.141 +                        }
   1.142 +
   1.143 +                        if(NULL != amp)
   1.144 +                        {
   1.145 +                            *amp++ = '\0';
   1.146 +
   1.147 +                            traverse = amp;
   1.148 +                        }
   1.149 +
   1.150 +                        unhexcape(container->mNArray[container->mNVCount]);
   1.151 +                        unhexcape(container->mVArray[container->mNVCount]);
   1.152 +                    }
   1.153 +
   1.154 +                    retval = container;
   1.155 +                }
   1.156 +            }
   1.157 +        }
   1.158 +
   1.159 +        /*
   1.160 +        **  If we failed, cleanup.
   1.161 +        */
   1.162 +        if(NULL == retval)
   1.163 +        {
   1.164 +            FormData_Destroy(container);
   1.165 +        }
   1.166 +    }
   1.167 +
   1.168 +    return retval;
   1.169 +}
   1.170 +
   1.171 +
   1.172 +void FormData_Destroy(FormData* inDestroy)
   1.173 +{
   1.174 +    if(NULL != inDestroy)
   1.175 +    {
   1.176 +        unsigned traverse = 0;
   1.177 +
   1.178 +        for(traverse = 0; traverse < inDestroy->mNVCount; traverse++)
   1.179 +        {
   1.180 +            if(NULL != inDestroy->mNArray)
   1.181 +            {
   1.182 +                inDestroy->mNArray[traverse] = NULL;
   1.183 +            }
   1.184 +            if(NULL != inDestroy->mVArray)
   1.185 +            {
   1.186 +                inDestroy->mVArray[traverse] = NULL;
   1.187 +            }
   1.188 +        }
   1.189 +        inDestroy->mNVCount = 0;
   1.190 +
   1.191 +        if(NULL != inDestroy->mStorage)
   1.192 +        {
   1.193 +            free(inDestroy->mStorage);
   1.194 +            inDestroy->mStorage = NULL;
   1.195 +        }
   1.196 +
   1.197 +        if(NULL != inDestroy->mNArray)
   1.198 +        {
   1.199 +            free(inDestroy->mNArray);
   1.200 +            inDestroy->mNArray = NULL;
   1.201 +            inDestroy->mVArray = NULL;
   1.202 +        }
   1.203 +
   1.204 +        free(inDestroy);
   1.205 +        inDestroy = NULL;
   1.206 +    }
   1.207 +}

mercurial