Professional Software Consulting

getLocationMB()

The getLocationMB function.

Example Usage
char *cpRv;
char *cpLine = "Now&&is&& the&& time&&";
char *cpDelim = "&&";
int iLenField;
int iErrVal;

cpRv = getLocationMB(cpLine, strlen(cpLine), cpDelim, strlen(cpDelim), 3, &iLenField, &iErrVal);

/*
* iErrVal will be GF_SUCCESS
* cpRv will be the address of the space just before "the" in cpLine
* iLenField will be 4
*/


Source Code
/**
* Copyright (c) 2008, Corey's Consulting LLC.  All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
*   this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
*   notice, this list of conditions and the following disclaimer in the
*   documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/******************************************************************************

 getLocationMB()

 Whereas the getField() class of functions are designed to copy data from
 a delimited buffer into another buffer defined by the caller, the
 getLocation() class of functions are designed to find the beginning of
 a particular position in the delimited buffer.

 Parameters:
    cpLine      - i:line containing fields, needn't be null terminated
    iLenLine    - i:length of cpLine
    cpDelim     - i:field delimiter to use
    iLenDelim   - i:length of cpDelim
    iDesiredFld - i:field number to get, starting at 1
    ipLenField  - o:length of the extract field if location is detected
    ipErrVal    - o:where errors are placed, is always filled with a GF_xxxx
       

 Returns:
    addr: location of required field
    NULL: field not found or error, check *ipErrVal

****/
char *
getLocationMB(char *cpLine, int iLenLine, char *cpDelim, int iLenDelim,
        int iDesiredFld, int *ipLenField, int *ipErrVal)
{
int     iCurField;
int     iValidBytes;
int     iByteCounter;
char    *cpField;
char    *cpStartOfField;    // points to first byte of data in field
char    *cpEndOfField;        // points to one past last byte of data in field


    for(;;) /* enables single exit point */
    {
        /**********
        check parms
        **********/

        if (ipErrVal == NULL)
            break;        // can't set anything...



        if ((cpLine == NULL)
        || (cpDelim == NULL)
        || (ipLenField == NULL))
        {
            *ipErrVal = GF_NULL_PARAM;
            break;
        }

//printf("lenDelim=%d, lenLine=%d, desiredFld=%d\n", iLenDelim, iLenLine, iDesiredFld);

        if (iLenDelim < 1 || iLenLine < 1 || iDesiredFld < 1)
        {
            *ipErrVal = GF_INVALID_PARMS;
            break;
        }



        /**************************
        find start of desired field
        **************************/

        cpField = cpLine;
        *ipErrVal = GF_SUCCESS;
        iByteCounter = 0;
        iCurField = 1;

        if (iDesiredFld != 1)        /* first field starts at offset 0 */
        {
            while (iCurField < iDesiredFld)
            {
                // break if we're so close to the end there can't be a delim
                // and it still hasn't been found yet
                if (iLenLine - iByteCounter < iLenDelim)
                {
                    *ipErrVal = GF_FIELD_NOT_FOUND;
                    break;
                }

                if (iLenDelim == 1)
                {
                    // this saves on a call to memcmp if the length of
                    // delimiters is 1... it's not truly multi-byte.

                    if (*(cpLine+iByteCounter) == *cpDelim)
                    {
                        // delimiter found, locate first byte of field

                        cpField = cpLine + iByteCounter + iLenDelim;

                        iCurField++;        // note new field was found
                        iByteCounter += iLenDelim;    // jump past delimiter
                    }
                    else
                    {
                        iByteCounter++;
                    }
                }
                else
                {
                    if (memcmp(cpLine+iByteCounter, cpDelim, iLenDelim) == 0)
                    {
                        // delimiter found, locate first byte of field

                        cpField = cpLine + iByteCounter + iLenDelim;

                        iCurField++;        // note new field was found
                        iByteCounter += iLenDelim;    // jump past delimiter
                    }
                    else
                    {
                        iByteCounter++;
                    }
                }
            }
        }

        if (*ipErrVal != GF_SUCCESS)
            break;

        cpStartOfField = cpField;


// At this point: 
//
// 1. The start of the proper field is being pointed to by cpStartOfField
// 2. iByteCounter is equal to exactly the number of bytes already examined
// 3. (iLenLine - iByteCounter) is equal to the number of bytes left to process
//


        /************************
        find end of desired field
        ************************/
        // not endless because SOMETHING below will eventually match
        for (iValidBytes = 0;; cpField++, iValidBytes++, iByteCounter++)
        {
            if (iLenDelim < iLenLine - iByteCounter + 1)
            {
                if (iLenDelim == 1)
                {
                    // this will be slightly faster than the memcmp below...

                    if (*cpField == *cpDelim)
                    {
                        // next delimiter encountered; end of field

                        break;
                    }
                }
                else
                {
                    if (memcmp(cpField, cpDelim, iLenDelim) == 0)
                    {
                        // next delimiter encountered; end of field

                        break;
                    }
                }
            }

            // bail if we run out of input data
            if (iByteCounter >= iLenLine)
            {
                // iByteCounter must be one past end of buffer, must have
                // just finished copying the last field

                break;
            }
        }


        // end of field is defined to be the first byte which doesn't
        // count towards the number of valid bytes.

        cpEndOfField = cpField;

        *ipLenField = (int)(cpEndOfField - cpStartOfField);

        if (1==1)
            break;
    }   /* end single exit point "for" */


    if (ipErrVal)
        if (*ipErrVal != GF_SUCCESS)
            cpStartOfField = NULL;


    return(cpStartOfField);
}    // end getLocationMB()

     Contact Us     

Something wrong with this page or this site? Let the webmaster know by clicking HERE
This website designed, implemented, and maintained by Corey Dulecki
© 2009-2012, Corey's Consulting LLC