Exemple #1
0
/**
 * Assign the to-be-parsed string.
 */
rsRetVal rsParsAssignString(rsParsObj *pThis, cstr_t *pCStr)
{
	rsCHECKVALIDOBJECT(pThis, OIDrsPars);
	rsCHECKVALIDOBJECT(pCStr, OIDrsCStr);
	
	pThis->pCStr = pCStr;
	pThis->iCurrPos = 0;

	return RS_RET_OK;
}
Exemple #2
0
/* Parse a quoted string ("-some-data") from the given position.
 * Leading whitespace before the first quote is skipped. During
 * parsing, escape sequences are detected and converted:
 * \\ - backslash character
 * \" - quote character
 * any other value \<somechar> is reserved for future use.
 *
 * After return, the parse pointer is paced after the trailing
 * quote.
 *
 * Output:
 * ppCStr Pointer to the parsed string - must be freed by caller and
 *        does NOT include the quotes.
 * rgerhards, 2005-09-19
 */
rsRetVal parsQuotedCStr(rsParsObj *pThis, cstr_t **ppCStr)
{
	register unsigned char *pC;
	cstr_t *pCStr;
	DEFiRet;

	rsCHECKVALIDOBJECT(pThis, OIDrsPars);

	if((iRet = parsSkipAfterChar(pThis, '"')) != RS_RET_OK)
		FINALIZE;
	pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos;

	/* OK, we most probably can obtain a value... */
	CHKiRet(rsCStrConstruct(&pCStr));

	while(pThis->iCurrPos < rsCStrLen(pThis->pCStr)) {
		if(*pC == '"') {
			break;	/* we are done! */
		} else if(*pC == '\\') {
			++pThis->iCurrPos;
			++pC;
			if(pThis->iCurrPos < rsCStrLen(pThis->pCStr)) {
				/* in this case, we copy the escaped character
				 * to the output buffer (but do not rely on this,
				 * we might later introduce other things, like \007!
				 */
				if((iRet = rsCStrAppendChar(pCStr, *pC)) != RS_RET_OK) {
					rsCStrDestruct(&pCStr);
					FINALIZE;
				}
			}
		} else { /* regular character */
			if((iRet = rsCStrAppendChar(pCStr, *pC)) != RS_RET_OK) {
				rsCStrDestruct (&pCStr);
				FINALIZE;
			}
		}
		++pThis->iCurrPos;
		++pC;
	}
	
	if(*pC == '"') {
		++pThis->iCurrPos; /* 'eat' trailing quote */
	} else {
		/* error - improperly quoted string! */
		rsCStrDestruct (&pCStr);
		ABORT_FINALIZE(RS_RET_MISSING_TRAIL_QUOTE);
	}

	/* We got the string, let's finish it...  */
	if((iRet = rsCStrFinish(pCStr)) != RS_RET_OK) {
		rsCStrDestruct (&pCStr);
		FINALIZE;
	}

	/* done! */
	*ppCStr = pCStr;
finalize_it:
	RETiRet;
}
Exemple #3
0
/* Converts the CStr object to a classical zero-terminated C string,
 * returns that string and destroys the CStr object. The returned string
 * MUST be freed by the caller. The function might return NULL if
 * no memory can be allocated.
 *
 * This is the NEW replacement for rsCStrConvSzStrAndDestruct which does
 * no longer utilize a special buffer but soley works on pBuf (and also
 * assumes that cstrFinalize had been called).
 *
 * Parameters are as follows:
 * pointer to the object, pointer to string-pointer to receive string and
 * bRetNULL: 0 - must not return NULL on empty string, return "" in that
 * case, 1 - return NULL instead of an empty string.
 * PLEASE NOTE: the caller must free the memory returned in ppSz in any case
 * (except, of course, if it is NULL).
 */
rsRetVal cstrConvSzStrAndDestruct(cstr_t *pThis, uchar **ppSz, int bRetNULL)
{
	DEFiRet;
	uchar* pRetBuf;

	rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
	assert(ppSz != NULL);
	assert(bRetNULL == 0 || bRetNULL == 1);

	if(pThis->pBuf == NULL) {
		if(bRetNULL == 0) {
			CHKmalloc(pRetBuf = MALLOC(sizeof(uchar)));
			*pRetBuf = '\0';
		} else {
			pRetBuf = NULL;
		}
	} else
		pRetBuf = pThis->pBuf;
	
	*ppSz = pRetBuf;

finalize_it:
	/* We got it, now free the object ourselfs. Please note
	 * that we can NOT use the rsCStrDestruct function as it would
	 * also free the sz String buffer, which we pass on to the user.
	 */
	RSFREEOBJ(pThis);
	RETiRet;
}
Exemple #4
0
/* compare a rsCStr object with a classical sz string.  This function
 * is almost identical to rsCStrZsStrCmp(), but it also takes an offset
 * to the CStr object from where the comparison is to start.
 * I have thought quite a while if it really makes sense to more or
 * less duplicate the code. After all, if you call it with an offset of
 * zero, the functionality is exactly the same. So it looks natural to
 * just have a single function. However, supporting the offset requires
 * some (few) additional integer operations. While they are few, they
 * happen at places in the code that is run very frequently. All in all,
 * I have opted for performance and thus duplicated the code. I hope
 * this is a good, or at least acceptable, compromise.
 * rgerhards, 2005-09-26
 * This function also has an offset-pointer which allows to
 * specify *where* the compare operation should begin in
 * the CStr. If everything is to be compared, it must be set
 * to 0. If some leading bytes are to be skipped, it must be set
 * to the first index that is to be compared. It must not be
 * set higher than the string length (this is considered a
 * program bug and will lead to unpredictable results and program aborts).
 * rgerhards 2005-09-26
 */
int rsCStrOffsetSzStrCmp(cstr_t *pCS1, size_t iOffset, uchar *psz, size_t iLenSz)
{
	BEGINfunc
	rsCHECKVALIDOBJECT(pCS1, OIDrsCStr);
	assert(iOffset < pCS1->iStrLen);
	assert(psz != NULL);
	assert(iLenSz == strlen((char*)psz)); /* just make sure during debugging! */
	if((pCS1->iStrLen - iOffset) == iLenSz) {
		/* we are using iLenSz below, because the lengths
		 * are equal and iLenSz is faster to access
		 */
		if(iLenSz == 0) {
			return 0; /* zero-sized strings are equal ;) */
			ENDfunc
		} else {  /* we now have two non-empty strings of equal
			 * length, so we need to actually check if they
			 * are equal.
			 */
			register size_t i;
			for(i = 0 ; i < iLenSz ; ++i) {
				if(pCS1->pBuf[i+iOffset] != psz[i])
					return pCS1->pBuf[i+iOffset] - psz[i];
			}
			/* if we arrive here, the strings are equal */
			return 0;
			ENDfunc
		}
	}
Exemple #5
0
/* peek at the character at the parse pointer
 * the caller must ensure that the parse pointer is not
 * at the end of the parse buffer (e.g. by first calling
 * parsIsAtEndOfParseString).
 * rgerhards, 2005-09-27
 */
char parsPeekAtCharAtParsPtr(rsParsObj *pThis)
{
	rsCHECKVALIDOBJECT(pThis, OIDrsPars);
	assert(pThis->iCurrPos < rsCStrLen(pThis->pCStr));
	
	return(*(pThis->pCStr->pBuf + pThis->iCurrPos));
}
Exemple #6
0
/* Converts the CStr object to a classical zero-terminated C string
 * and returns that string. The caller must not free it and must not
 * destroy the CStr object as long as the ascii string is used.
 * This function may return NULL, if the string is currently NULL. This
 * is a feature, not a bug. If you need non-NULL in any case, use
 * rsCStrGetSzStrNoNULL() instead.
 * rgerhards, 2005-09-15
 */
uchar*  rsCStrGetSzStr(cstr_t *pThis)
{
	size_t i;

	rsCHECKVALIDOBJECT(pThis, OIDrsCStr);

	if(pThis->pBuf != NULL)
		if(pThis->pszBuf == NULL) {
			/* we do not yet have a usable sz version - so create it... */
			if((pThis->pszBuf = MALLOC((pThis->iStrLen + 1) * sizeof(uchar))) == NULL) {
				/* TODO: think about what to do - so far, I have no bright
				 *       idea... rgerhards 2005-09-07
				 */
			}
			else { /* we can create the sz String */
				/* now copy it while doing a sanity check. The string might contain a
				 * \0 byte. There is no way how a sz string can handle this. For
				 * the time being, we simply replace it with space - something that
				 * could definitely be improved (TODO).
				 * 2005-09-15 rgerhards
				 */
				for(i = 0 ; i < pThis->iStrLen ; ++i) {
					if(pThis->pBuf[i] == '\0')
						pThis->pszBuf[i] = ' ';
					else
						pThis->pszBuf[i] = pThis->pBuf[i];
				}
				/* write terminator... */
				pThis->pszBuf[i] = '\0';
			}
		}

	return(pThis->pszBuf);
}
Exemple #7
0
/* Sets the string object to the classigal sz-string provided.
 * Any previously stored vlaue is discarded. If a NULL pointer
 * the the new value (pszNew) is provided, an empty string is
 * created (this is NOT an error!).
 * rgerhards, 2005-10-18
 */
rsRetVal rsCStrSetSzStr(cstr_t *pThis, uchar *pszNew)
{
	rsCHECKVALIDOBJECT(pThis, OIDrsCStr);

	free(pThis->pBuf);
	free(pThis->pszBuf);
	if(pszNew == NULL) {
		pThis->iStrLen = 0;
		pThis->iBufSize = 0;
		pThis->pBuf = NULL;
		pThis->pszBuf = NULL;
	} else {
		pThis->iStrLen = strlen((char*)pszNew);
		pThis->iBufSize = pThis->iStrLen;
		pThis->pszBuf = NULL;

		/* now save the new value */
		if((pThis->pBuf = (uchar*) MALLOC(sizeof(uchar) * pThis->iStrLen)) == NULL) {
			RSFREEOBJ(pThis);
			return RS_RET_OUT_OF_MEMORY;
		}

		/* we do NOT need to copy the \0! */
		memcpy(pThis->pBuf, pszNew, pThis->iStrLen);
	}

	return RS_RET_OK;
}
Exemple #8
0
/* check if a sz-type string starts with a CStr object. This function
 * is initially written to support the "startswith" property-filter
 * comparison operation. Maybe it also has other needs.
 * This functions is modelled after the strcmp() series, thus a
 * return value of 0 indicates that the string starts with the
 * sequence while -1 indicates it does not!
 * rgerhards 2005-10-19
 */
int rsCStrSzStrStartsWithCStr(cstr_t *pCS1, uchar *psz, size_t iLenSz)
{
	register int i;
	int iMax;

	rsCHECKVALIDOBJECT(pCS1, OIDrsCStr);
	assert(psz != NULL);
	assert(iLenSz == strlen((char*)psz)); /* just make sure during debugging! */
	if(iLenSz >= pCS1->iStrLen) {
		/* we need to checkusing pCS1->iStrLen charactes at maximum, thus
		 * we move it to iMax.
		 */
		iMax = pCS1->iStrLen;
		if(iMax == 0)
			return 0; /* yes, it starts with a zero-sized string ;) */
		else {  /* we now have something to compare, so let's do it... */
			for(i = 0 ; i < iMax ; ++i) {
				if(psz[i] != pCS1->pBuf[i])
					return psz[i] - pCS1->pBuf[i];
			}
			/* if we arrive here, the string actually starts with pCS1 */
			return 0;
		}
	}
	else
		return -1; /* pCS1 is less then psz */
}
Exemple #9
0
/* The same as rsCStrStartsWithSzStr(), but does a case-insensitive
 * comparison. TODO: consolidate the two.
 * rgerhards 2008-02-28
 */
int rsCStrCaseInsensitveStartsWithSzStr(cstr_t *pCS1, uchar *psz, size_t iLenSz)
{
	register size_t i;

	rsCHECKVALIDOBJECT(pCS1, OIDrsCStr);
	assert(psz != NULL);
	assert(iLenSz == strlen((char*)psz)); /* just make sure during debugging! */
	if(pCS1->iStrLen >= iLenSz) {
		/* we are using iLenSz below, because we need to check
		 * iLenSz characters at maximum (start with!)
		 */
		if(iLenSz == 0)
			return 0; /* yes, it starts with a zero-sized string ;) */
		else {  /* we now have something to compare, so let's do it... */
			for(i = 0 ; i < iLenSz ; ++i) {
				if(tolower(pCS1->pBuf[i]) != tolower(psz[i]))
					return tolower(pCS1->pBuf[i]) - tolower(psz[i]);
			}
			/* if we arrive here, the string actually starts with psz */
			return 0;
		}
	}
	else
		return -1; /* pCS1 is less then psz */
}
Exemple #10
0
/* Skip everything up to a specified character.
 * Returns with ParsePointer set BEHIND this character.
 * Returns RS_RET_OK if found, RS_RET_NOT_FOUND if not
 * found. In that case, the ParsePointer is moved to the
 * last character of the string.
 * 2005-09-19 rgerhards
 */
rsRetVal parsSkipAfterChar(rsParsObj *pThis, char c)
{
	register unsigned char *pC;
	DEFiRet;

	rsCHECKVALIDOBJECT(pThis, OIDrsPars);

	pC = rsCStrGetBufBeg(pThis->pCStr);

	while(pThis->iCurrPos < rsCStrLen(pThis->pCStr)) {
		if(pC[pThis->iCurrPos] == c)
			break;
		++pThis->iCurrPos;
	}

	/* delimiter found? */
	if(pC[pThis->iCurrPos] == c) {
		if(pThis->iCurrPos+1 < rsCStrLen(pThis->pCStr)) {
			iRet = RS_RET_OK;
			pThis->iCurrPos++; /* 'eat' delimiter */
		} else {
			iRet = RS_RET_FOUND_AT_STRING_END;
		}
	} else {
		iRet = RS_RET_NOT_FOUND;
	}

	RETiRet;
}
Exemple #11
0
/* parse an integer. The parse pointer is advanced to the
 * position directly after the last digit. If no digit is
 * found at all, an error is returned and the parse pointer
 * is NOT advanced.
 * PORTABILITY WARNING: this function depends on the
 * continues representation of digits inside the character
 * set (as in ASCII).
 * rgerhards 2005-09-27
 */
rsRetVal parsInt(rsParsObj *pThis, int* pInt)
{
	unsigned char *pC;
	int iVal;

	rsCHECKVALIDOBJECT(pThis, OIDrsPars);
	assert(pInt != NULL);

	iVal = 0;
	pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos;

	/* order of checks is important, else we might do
	 * mis-addressing! (off by one)
	 */
	if(pThis->iCurrPos >= rsCStrLen(pThis->pCStr))
		return RS_RET_NO_MORE_DATA;
	if(!isdigit((int)*pC))
		return RS_RET_NO_DIGIT;

	while(pThis->iCurrPos < rsCStrLen(pThis->pCStr) && isdigit((int)*pC)) {
		iVal = iVal * 10 + *pC - '0';
		++pThis->iCurrPos;
		++pC;
	}

	*pInt = iVal;

	return RS_RET_OK;
}
Exemple #12
0
/* Converts the CStr object to a classical sz string and returns that.
 * Same restrictions as in rsCStrGetSzStr() applies (see there!). This
 * function here guarantees that a valid string is returned, even if
 * the CStr object currently holds a NULL pointer string buffer. If so,
 * "" is returned.
 * rgerhards 2005-10-19
 * WARNING: The returned pointer MUST NOT be freed, as it may be
 *          obtained from that constant memory pool (in case of NULL!)
 */
uchar*  rsCStrGetSzStrNoNULL(cstr_t *pThis)
{
	rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
	if(pThis->pBuf == NULL)
		return (uchar*) "";
	else
		return rsCStrGetSzStr(pThis);
}
Exemple #13
0
/* return the position of the parse pointer
 */
int rsParsGetParsePointer(rsParsObj *pThis)
{
	rsCHECKVALIDOBJECT(pThis, OIDrsPars);

	if(pThis->iCurrPos < rsCStrLen(pThis->pCStr))
		return pThis->iCurrPos;
	else
		return rsCStrLen(pThis->pCStr) - 1;
}
Exemple #14
0
/**
 * Destruct a rsPars object and its associated string.
 * rgerhards, 2005-09-26
 */
rsRetVal rsParsDestruct(rsParsObj *pThis)
{
	rsCHECKVALIDOBJECT(pThis, OIDrsPars);

	if(pThis->pCStr != NULL)
		rsCStrDestruct(&pThis->pCStr);
	RSFREEOBJ(pThis);
	return RS_RET_OK;
}
Exemple #15
0
rsRetVal rsCStrAppendInt(cstr_t *pThis, long i)
{
	DEFiRet;
	uchar szBuf[32];

	rsCHECKVALIDOBJECT(pThis, OIDrsCStr);

	CHKiRet(srUtilItoA((char*) szBuf, sizeof(szBuf), i));

	iRet = rsCStrAppendStr(pThis, szBuf);
finalize_it:
	RETiRet;
}
Exemple #16
0
/* compare two string objects - works like strcmp(), but operates
 * on CStr objects. Please note that this version here is
 * faster in the majority of cases, simply because it can
 * rely on StrLen.
 * rgerhards 2005-09-19
 * fixed bug, in which only the last byte was actually compared
 * in equal-size strings.
 * rgerhards, 2005-09-26
 */
int rsCStrCStrCmp(cstr_t *pCS1, cstr_t *pCS2)
{
	rsCHECKVALIDOBJECT(pCS1, OIDrsCStr);
	rsCHECKVALIDOBJECT(pCS2, OIDrsCStr);
	if(pCS1->iStrLen == pCS2->iStrLen)
		if(pCS1->iStrLen == 0)
			return 0; /* zero-sized string are equal ;) */
		else {  /* we now have two non-empty strings of equal
			 * length, so we need to actually check if they
			 * are equal.
			 */
			register size_t i;
			for(i = 0 ; i < pCS1->iStrLen ; ++i) {
				if(pCS1->pBuf[i] != pCS2->pBuf[i])
					return pCS1->pBuf[i] - pCS2->pBuf[i];
			}
			/* if we arrive here, the strings are equal */
			return 0;
		}
	else
		return pCS1->iStrLen - pCS2->iStrLen;
}
Exemple #17
0
/* Parse string up to a delimiter.
 *
 * Input:
 * cDelim - the delimiter
 *   The following two are for whitespace stripping,
 *   0 means "no", 1 "yes"
 *   - bTrimLeading
 *   - bTrimTrailing
 * 
 * Output:
 * ppCStr Pointer to the parsed string - must be freed by caller!
 */
rsRetVal parsDelimCStr(rsParsObj *pThis, cstr_t **ppCStr, char cDelim, int bTrimLeading, int bTrimTrailing)
{
	DEFiRet;
	register unsigned char *pC;
	cstr_t *pCStr;

	rsCHECKVALIDOBJECT(pThis, OIDrsPars);

	CHKiRet(rsCStrConstruct(&pCStr));

	if(bTrimLeading)
		parsSkipWhitespace(pThis);

	pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos;

	while(pThis->iCurrPos < rsCStrLen(pThis->pCStr)
	      && *pC != cDelim) {
		if((iRet = rsCStrAppendChar(pCStr, *pC)) != RS_RET_OK) {
			rsCStrDestruct(&pCStr);
			FINALIZE;
		}
		++pThis->iCurrPos;
		++pC;
	}
	
	if(*pC == cDelim) {
		++pThis->iCurrPos; /* eat delimiter */
	}

	/* We got the string, now take it and see if we need to
	 * remove anything at its end.
	 */
	if((iRet = rsCStrFinish(pCStr)) != RS_RET_OK) {
		rsCStrDestruct (&pCStr);
		FINALIZE;
	}

	if(bTrimTrailing) {
		if((iRet = rsCStrTrimTrailingWhiteSpace(pCStr)) 
		   != RS_RET_OK) {
			rsCStrDestruct (&pCStr);
			FINALIZE;
		}
	}

	/* done! */
	*ppCStr = pCStr;
finalize_it:
	RETiRet;
}
Exemple #18
0
/* Skip whitespace. Often used to trim parsable entries.
 * Returns with ParsePointer set to first non-whitespace
 * character (or at end of string).
 */
rsRetVal parsSkipWhitespace(rsParsObj *pThis)
{
	register unsigned char *pC;

	rsCHECKVALIDOBJECT(pThis, OIDrsPars);

	pC = rsCStrGetBufBeg(pThis->pCStr);

	while(pThis->iCurrPos < rsCStrLen(pThis->pCStr)) {
		if(!isspace((int)*(pC+pThis->iCurrPos)))
			break;
		++pThis->iCurrPos;
	}

	return RS_RET_OK;
}
Exemple #19
0
/* Trim trailing whitespace from a given string
 */
rsRetVal rsCStrTrimTrailingWhiteSpace(cstr_t *pThis)
{
	register int i;
	register uchar *pC;
	rsCHECKVALIDOBJECT(pThis, OIDrsCStr);

	i = pThis->iStrLen;
	pC = pThis->pBuf + i - 1;
	while(i > 0 && isspace((int)*pC)) {
		--pC;
		--i;
	}
	/* i now is the new string length! */
	pThis->iStrLen = i;

	return RS_RET_OK;
}
Exemple #20
0
/* Parse string up to a delimiter.
 *
 * Input:
 * cDelim - the delimiter. Note that SP within a value always is a delimiter,
 * so cDelim is actually an *additional* delimiter.
 *   The following two are for whitespace stripping,
 *   0 means "no", 1 "yes"
 *   - bTrimLeading
 *   - bTrimTrailing
 *   - bConvLower - convert string to lower case?
 * 
 * Output:
 * ppCStr Pointer to the parsed string - must be freed by caller!
 */
rsRetVal parsDelimCStr(rsParsObj *pThis, cstr_t **ppCStr, char cDelim, int bTrimLeading, int bTrimTrailing, int bConvLower)
{
	DEFiRet;
	register unsigned char *pC;
	cstr_t *pCStr = NULL;

	rsCHECKVALIDOBJECT(pThis, OIDrsPars);

	CHKiRet(rsCStrConstruct(&pCStr));

	if(bTrimLeading)
		parsSkipWhitespace(pThis);

	pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos;

	while(pThis->iCurrPos < rsCStrLen(pThis->pCStr) && *pC != cDelim) {
		CHKiRet(cstrAppendChar(pCStr, bConvLower ? tolower(*pC) : *pC));
		++pThis->iCurrPos;
		++pC;
	}
	
	if(pThis->iCurrPos < cstrLen(pThis->pCStr)) { //BUGFIX!!
		++pThis->iCurrPos; /* eat delimiter */
	}

	/* We got the string, now take it and see if we need to
	 * remove anything at its end.
	 */
	CHKiRet(cstrFinalize(pCStr));

	if(bTrimTrailing) {
		CHKiRet(cstrTrimTrailingWhiteSpace(pCStr));
	}

	/* done! */
	*ppCStr = pCStr;

finalize_it:
	if(iRet != RS_RET_OK) {
		if(pCStr != NULL)
			rsCStrDestruct(&pCStr);
	}

	RETiRet;
}
Exemple #21
0
/* append a string of known length. In this case, we make sure we do at most
 * one additional memory allocation.
 * I optimized this function to use memcpy(), among others. Consider it a
 * rewrite (which may be good to know in case of bugs) -- rgerhards, 2008-01-07
 */
rsRetVal rsCStrAppendStrWithLen(cstr_t *pThis, uchar* psz, size_t iStrLen)
{
	DEFiRet;

	rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
	assert(psz != NULL);

	/* does the string fit? */
	if(pThis->iStrLen + iStrLen > pThis->iBufSize) {  
		CHKiRet(rsCStrExtendBuf(pThis, iStrLen)); /* need more memory! */
	}

	/* ok, now we always have sufficient continues memory to do a memcpy() */
	memcpy(pThis->pBuf + pThis->iStrLen, psz, iStrLen);
	pThis->iStrLen += iStrLen;

finalize_it:
	RETiRet;
}
Exemple #22
0
/* Trim trailing whitespace from a given string
 */
rsRetVal cstrTrimTrailingWhiteSpace(cstr_t *pThis)
{
	register int i;
	register uchar *pC;
	rsCHECKVALIDOBJECT(pThis, OIDrsCStr);

	if(pThis->iStrLen == 0)
		goto done; /* empty string -> nothing to trim ;) */
	i = pThis->iStrLen;
	pC = pThis->pBuf + i - 1;
	while(i > 0 && isspace((int)*pC)) {
		--pC;
		--i;
	}
	/* i now is the new string length! */
	pThis->iStrLen = i;
	pThis->pBuf[pThis->iStrLen] = '0'; /* we always have this space */

done:	return RS_RET_OK;
}
Exemple #23
0
/* Truncate characters from the end of the string.
 * rgerhards 2005-09-15
 */
rsRetVal rsCStrTruncate(cstr_t *pThis, size_t nTrunc)
{
	rsCHECKVALIDOBJECT(pThis, OIDrsCStr);

	if(pThis->iStrLen < nTrunc)
		return RS_TRUNCAT_TOO_LARGE;
	
	pThis->iStrLen -= nTrunc;

	if(pThis->pszBuf != NULL) {
		/* in this case, we adjust the psz representation
		 * by writing a new \0 terminator - this is by far
		 * the fastest way and outweights the additional memory
		 * required. 2005-9-19 rgerhards.
		 */
		 pThis->pszBuf[pThis->iStrLen] = '\0';
	}

	return RS_RET_OK;
}
Exemple #24
0
/* Skip whitespace. Often used to trim parsable entries.
 * Returns with ParsePointer set to first non-whitespace
 * character (or at end of string).
 * If bRequireOne is set to true, at least one whitespace
 * must exist, else an error is returned.
 */
rsRetVal parsSkipWhitespace(rsParsObj *pThis)
{
	register unsigned char *pC;
	int numSkipped;
	DEFiRet;


	rsCHECKVALIDOBJECT(pThis, OIDrsPars);

	pC = rsCStrGetBufBeg(pThis->pCStr);

	numSkipped = 0;
	while(pThis->iCurrPos < rsCStrLen(pThis->pCStr)) {
		if(!isspace((int)*(pC+pThis->iCurrPos)))
			break;
		++pThis->iCurrPos;
		++numSkipped;
	}

	RETiRet;
}
Exemple #25
0
/* construct from CStr object. only the counted string is
 * copied, not the szString.
 * rgerhards 2005-10-18
 */
rsRetVal rsCStrConstructFromCStr(cstr_t **ppThis, cstr_t *pFrom)
{
	DEFiRet;
	cstr_t *pThis;

	assert(ppThis != NULL);
	rsCHECKVALIDOBJECT(pFrom, OIDrsCStr);

	CHKiRet(rsCStrConstruct(&pThis));

	pThis->iBufSize = pThis->iStrLen = pFrom->iStrLen;
	if((pThis->pBuf = (uchar*) MALLOC(sizeof(uchar) * pThis->iStrLen)) == NULL) {
		RSFREEOBJ(pThis);
		ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
	}

	/* copy properties */
	memcpy(pThis->pBuf, pFrom->pBuf, pThis->iStrLen);

	*ppThis = pThis;
finalize_it:
	RETiRet;
}
Exemple #26
0
rsRetVal parsAddrWithBits(rsParsObj *pThis, struct NetAddr **pIP, int *pBits)
{
	register uchar *pC;
	uchar *pszIP;
	uchar *pszTmp;
	struct addrinfo hints, *res = NULL;
	cstr_t *pCStr;
	DEFiRet;

	rsCHECKVALIDOBJECT(pThis, OIDrsPars);
	assert(pIP != NULL);
	assert(pBits != NULL);

	CHKiRet(cstrConstruct(&pCStr));

	parsSkipWhitespace(pThis);
	pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos;

	/* we parse everything until either '/', ',' or
	 * whitespace. Validity will be checked down below.
	 */
	while(pThis->iCurrPos < rsCStrLen(pThis->pCStr)
	      && *pC != '/' && *pC != ',' && !isspace((int)*pC)) {
		if((iRet = cstrAppendChar(pCStr, *pC)) != RS_RET_OK) {
			cstrDestruct (&pCStr);
			FINALIZE;
		}
		++pThis->iCurrPos;
		++pC;
	}
	
	/* We got the string, let's finish it...  */
	if((iRet = cstrFinalize(pCStr)) != RS_RET_OK) {
		cstrDestruct(&pCStr);
		FINALIZE;
	}

	/* now we have the string and must check/convert it to
	 * an NetAddr structure.
	 */	
  	CHKiRet(cstrConvSzStrAndDestruct(pCStr, &pszIP, 0));

	*pIP = calloc(1, sizeof(struct NetAddr));
	
	if (*((char*)pszIP) == '[') {
		pszTmp = (uchar*)strchr ((char*)pszIP, ']');
		if (pszTmp == NULL) {
			free (pszIP);
			ABORT_FINALIZE(RS_RET_INVALID_IP);
		}
		*pszTmp = '\0';

		memset (&hints, 0, sizeof (struct addrinfo));
		hints.ai_family = AF_INET6;
#		ifdef AI_ADDRCONFIG
			hints.ai_flags  = AI_ADDRCONFIG | AI_NUMERICHOST;
#		else
			hints.ai_flags  = AI_NUMERICHOST;
#		endif
		
		switch(getaddrinfo ((char*)pszIP+1, NULL, &hints, &res)) {
		case 0: 
			(*pIP)->addr.NetAddr = MALLOC (res->ai_addrlen);
			memcpy ((*pIP)->addr.NetAddr, res->ai_addr, res->ai_addrlen);
			freeaddrinfo (res);
			break;
		case EAI_NONAME:
			F_SET((*pIP)->flags, ADDR_NAME|ADDR_PRI6);
			(*pIP)->addr.HostWildcard = strdup ((const char*)pszIP+1);
			break;
		default:
			free (pszIP);
			free (*pIP);
			ABORT_FINALIZE(RS_RET_ERR);
		}
		
		if(*pC == '/') {
			/* mask bits follow, let's parse them! */
			++pThis->iCurrPos; /* eat slash */
			if((iRet = parsInt(pThis, pBits)) != RS_RET_OK) {
				free (pszIP);
				free (*pIP);
				FINALIZE;
			}
			/* we need to refresh pointer (changed by parsInt()) */
			pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos;
		} else {
			/* no slash, so we assume a single host (/128) */
			*pBits = 128;
		}
	} else { /* now parse IPv4 */
		memset (&hints, 0, sizeof (struct addrinfo));
		hints.ai_family = AF_INET;
#		ifdef AI_ADDRCONFIG
			hints.ai_flags  = AI_ADDRCONFIG | AI_NUMERICHOST;
#		else
			hints.ai_flags  = AI_NUMERICHOST;
#		endif
		
		switch(getaddrinfo ((char*)pszIP, NULL, &hints, &res)) {
		case 0: 
			(*pIP)->addr.NetAddr = MALLOC (res->ai_addrlen);
			memcpy ((*pIP)->addr.NetAddr, res->ai_addr, res->ai_addrlen);
			freeaddrinfo (res);
			break;
		case EAI_NONAME:
			F_SET((*pIP)->flags, ADDR_NAME);
			(*pIP)->addr.HostWildcard = strdup ((const char*)pszIP);
			break;
		default:
			free (pszIP);
			free (*pIP);
			ABORT_FINALIZE(RS_RET_ERR);
		}
			
		if(*pC == '/') {
			/* mask bits follow, let's parse them! */
			++pThis->iCurrPos; /* eat slash */
			if((iRet = parsInt(pThis, pBits)) != RS_RET_OK) {
				free (pszIP);
				free (*pIP);
				FINALIZE;
			}
			/* we need to refresh pointer (changed by parsInt()) */
			pC = rsCStrGetBufBeg(pThis->pCStr) + pThis->iCurrPos;
		} else {
			/* no slash, so we assume a single host (/32) */
			*pBits = 32;
		}
	}
	free(pszIP); /* no longer needed */

	/* skip to next processable character */
	while(pThis->iCurrPos < rsCStrLen(pThis->pCStr)
	      && (*pC == ',' || isspace((int)*pC))) {
		++pThis->iCurrPos;
		++pC;
	}

	iRet = RS_RET_OK;

finalize_it:
	RETiRet;
}
Exemple #27
0
/* tell if the parsepointer is at the end of the
 * to-be-parsed string. Returns 1, if so, 0
 * otherwise. rgerhards, 2005-09-27
 */
int parsIsAtEndOfParseString(rsParsObj *pThis)
{
	rsCHECKVALIDOBJECT(pThis, OIDrsPars);

	return (pThis->iCurrPos < rsCStrLen(pThis->pCStr)) ? 0 : 1;
}
Exemple #28
0
int cstrLen(cstr_t *pThis)
{
	rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
	return(pThis->iStrLen);
}