Esempio n. 1
0
// Internal version of rf_string_find, used for byte position.
int rf_string_find_byte_pos(const struct RFstring *tstr,
                            const struct RFstring *sstr,
                            const char options)
{
#define CHECK_NOT_CHAR(s_, i_)                  \
    do{                                         \
        /* if is is not a character */          \
        switch(rf_string_data(s_)[i_])           \
        {                                       \
        case ' ':case '\t':case '\n':           \
            break;                              \
        default:                                \
            return RF_FAILURE;                  \
            break;                              \
        }                                       \
    }while(0)
    const char* found = 0;
    RF_ASSERT(tstr, "got null string in function");
    if (!sstr) {
        RF_WARNING("Provided null search string parameter");
        return RF_FAILURE;
    }
    //search matching characters
    if(!RF_BITFLAG_ON(options, RF_CASE_IGNORE))
    {
        //if it is not found
        if(!(found = strstr_nnt(rf_string_data(tstr), rf_string_length_bytes(tstr),
                               rf_string_data(sstr), rf_string_length_bytes(sstr))))
            return RF_FAILURE;

        //get the byte position
        uint32_t bytepos = found - rf_string_data(tstr);
        //if we need the exact string as it is given
        if(RF_BITFLAG_ON(options, RF_MATCH_WORD))
        {
            //check before the found string
            if(bytepos != 0)
            {
                CHECK_NOT_CHAR(tstr, bytepos - 1);
            }
            //check after the found string
            if(bytepos + rf_string_length_bytes(sstr) != rf_string_length_bytes(tstr))
            {
                //if is is not a character
                CHECK_NOT_CHAR(tstr, bytepos + rf_string_length_bytes(sstr));
            }
        }//end of the exact string option
        //else return the position in the bytes buffer
        return bytepos;
    }

    //else, case insensitive search
    uint32_t i,j;
    for(i=0; i < rf_string_length_bytes(tstr); i ++)
    {
        //if i matches the start of the substring
        for(j = 0; j < rf_string_length_bytes(sstr); j++)
        {
            //if the jth char is a big letter
            if(rf_string_data(sstr)[j] >= 0x41 && rf_string_data(sstr)[j] <= 0x5a)
            {
                //no match
                if(rf_string_data(sstr)[j] != rf_string_data(tstr)[i+j] &&
                   rf_string_data(sstr)[j]+32 != rf_string_data(tstr)[i+j])
                    break;
                //there is a match in the jth character
                if(RF_BITFLAG_ON(options, RF_MATCH_WORD))
                {
                    /*
                      if it's the first substring character and if the string
                      we search is not in it's beginning, check for EXACT 
                      string before
                    */
                    if(j == 0 && i != 0)
                    {
                        CHECK_NOT_CHAR(tstr, i - 1);
                    }
                }//exact string check if ends
            }
            //small letter
            else if(rf_string_data(sstr)[j] >= 0x61 && 
                    rf_string_data(sstr)[j] <= 0x7a)
            {
                //no match
                if(rf_string_data(sstr)[j] != rf_string_data(tstr)[i+j] &&
                   rf_string_data(sstr)[j]-32 != rf_string_data(tstr)[i+j])
                    break;
                //there is a match in the jth character
                if(RF_BITFLAG_ON(options, RF_MATCH_WORD))
                {
                    /*
                      if it's the first substring character and if the string
                      we search is not in it's beginning, check for EXACT 
                      string before
                    */
                    if(j == 0 && i != 0)
                    {
                        CHECK_NOT_CHAR(tstr, i - 1);
                    }
                }//exact string check if ends
            }
            //not a letter and no match
            else if(rf_string_data(sstr)[j] != rf_string_data(tstr)[i+j])
            {
                break;//break off the substring search loop
            }

            //we either found it or need to perform one last check for exact string
            if(j == rf_string_length_bytes(sstr) - 1)
            {
                //only if the end of the string is not right after the substring
                if(RF_BITFLAG_ON(options, RF_MATCH_WORD) &&
                   i + rf_string_length_bytes(sstr) < rf_string_length_bytes(tstr))
                {
                    CHECK_NOT_CHAR(tstr, i + rf_string_length_bytes(sstr));
                }//end of the exact string check
                //succes
                return i;
            }//end of it's the last char of the substring check
        }//substring iteration ends
    }//this string iteration ends
    return RF_FAILURE; //getting here means nothing was found

#undef CHECK_NOT_CHAR
}
Esempio n. 2
0
// Internal version of rfString_Find, used for byte position.
int32_t rfString_FindBytePos(const void* str,const void* sstrP,char options)
{
    RF_String* thisstr = (RF_String*)str;
    RF_String* sstr = (RF_String*)sstrP;

    char* found = 0;
    //if we want to match the case of the string then it's a simple search of matching characters
    if( (RF_BITFLAG_ON(options,RF_CASE_IGNORE)) == false)
    {
        //if it is not found
        if( (found = strstr(thisstr->bytes,sstr->bytes)) == 0)
            return RF_FAILURE;

        //get the byte position
        uint32_t bytepos = found-thisstr->bytes;
        //if we need the exact string as it is given
        if(RF_BITFLAG_ON(options,RF_MATCH_WORD))
        {
            //check before the found string
            if(bytepos != 0)
            {
                //if is is not a character
                switch(thisstr->bytes[bytepos-1])
                {
                    case ' ':case '\t':case '\n':
                    break;
                    default:
                        return RF_FAILURE;
                    break;
                }
            }
            //check after the found string
            if(bytepos+sstr->byteLength != thisstr->byteLength)
            {
                //if is is not a character
                switch(thisstr->bytes[bytepos+sstr->byteLength])
                {
                    case ' ':case '\t':case '\n':
                    break;
                    default:
                        return RF_FAILURE;
                    break;
                }
            }
        }//end of the exact string option
        //else return the position in the bytes buffer
        return bytepos;
    }

    //else, case insensitive search
    uint32_t i,j;
    //if(cstr[0] >= 0x41 && cstr[0] <= 0x5a)
    for(i=0;i<thisstr->byteLength; i ++)
    {
        //if i matches the start of the substring
        for(j = 0; j < sstr->byteLength; j++)
        {
            //if the jth char is a big letter
            if(sstr->bytes[j] >= 0x41 && sstr->bytes[j] <= 0x5a)
            {
                //no match
                if(sstr->bytes[j] != thisstr->bytes[i+j] && sstr->bytes[j]+32 != thisstr->bytes[i+j])
                    break;
                //there is a match in the jth character so let's perform additional checks if needed
                if(RF_BITFLAG_ON(options,RF_MATCH_WORD))
                {
                    //if it's the first substring character and if the string we search is not in it's beginning, check for EXACT string before
                    if(j == 0 && i != 0)
                    {
                        switch(thisstr->bytes[i-1])
                        {
                            case ' ':case '\t':case '\n':
                            break;
                            default:
                                return RF_FAILURE;
                            break;
                        }
                    }
                }//exact string check if ends
            }
            //small letter
            else if(sstr->bytes[j] >= 0x61 && sstr->bytes[j] <= 0x7a)
            {
                //no match
                if(sstr->bytes[j] != thisstr->bytes[i+j] && sstr->bytes[j]-32 != thisstr->bytes[i+j])
                    break;
                //there is a match in the jth character so let's perform additional checks if needed
                if(RF_BITFLAG_ON(options,RF_MATCH_WORD))
                {
                    //if it's the first substring character and if the string we search is not in it's beginning, check for EXACT string before
                    if(j == 0 && i != 0)
                    {
                        switch(thisstr->bytes[i-1])
                        {
                            case ' ':case '\t':case '\n':
                            break;
                            default:
                                return RF_FAILURE;
                            break;
                        }
                    }
                }//exact string check if ends
            }
            //not a letter and no match
            else if(sstr->bytes[j] != thisstr->bytes[i+j])
                break;//break off the substring search loop

            //if we get here and it's the last char of the substring we either found it or need to perform one last check for exact string
            if(j == sstr->byteLength-1)
            {
                //only if the end of the string is not right after the substring
                if( RF_BITFLAG_ON(options,RF_MATCH_WORD) && i+sstr->byteLength < thisstr->byteLength)
                {
                    switch(thisstr->bytes[i+sstr->byteLength])
                    {
                        case ' ':case '\t':case '\n':
                        break;
                        default:
                            return RF_FAILURE;
                        break;
                    }
                }//end of the exact string check
                //succes
                return i;
            }//end of it's the last char of the substring check
        }//substring iteration ends
    }//this string iteration ends
    return RF_FAILURE; //getting here means nothing was found
}