#include <errno.h>
#include <String/rfc_string.h>
#include <rf_utils.h>
#include "string_private.h"
#include "../IO/io_private.h"
#include <String/rfc_stringx.h>
#include <math.h>
#include <rf_localmem.h>
#ifndef RF_OPTION_DEFAULT_ARGUMENTS
RF_String* rfString_Create(const char* s,...)
#else
RF_String* i_rfString_Create(const char* s,...)
#endif
{
READ_VSNPRINTF_ARGS(s,s,0)
uint32_t byteLength;
if( rfUTF8_VerifySequence(buff,&byteLength) == RF_FAILURE)
{
LOG_ERROR("Error at String Allocation due to invalid UTF-8 byte sequence",RE_STRING_INIT_FAILURE);
if(buffAllocated == true)
free(buff);
return 0;
}
RF_String* ret;
RF_MALLOC(ret,sizeof(RF_String));
ret->byteLength = byteLength;
RF_MALLOC(ret->bytes,ret->byteLength+1);
memcpy(ret->bytes,buff,ret->byteLength+1);
if(buffAllocated==true)
free(buff);
return ret;
}
#ifdef RF_OPTION_DEFAULT_ARGUMENTS
RF_String* i_NVrfString_Create(const char* s)
{
uint32_t byteLength;
if( rfUTF8_VerifySequence(s,&byteLength) == RF_FAILURE)
{
LOG_ERROR("Error at String Allocation due to invalid UTF-8 byte sequence",RE_STRING_INIT_FAILURE);
return 0;
}
RF_String* ret;
RF_MALLOC(ret,sizeof(RF_String));
ret->byteLength = byteLength;
RF_MALLOC(ret->bytes,ret->byteLength+1);
memcpy(ret->bytes,s,ret->byteLength+1);
return ret;
}
#endif
RF_String* i_rfString_CreateLocal1(const char* s,...)
{
#if RF_OPTION_SOURCE_ENCODING != RF_UTF8
uint32_t characterLength,*codepoints,i=0,j;
#endif
rfLMS_MacroEvalPtr(RF_LMS);
READ_VSNPRINTF_ARGS(s,s,0)
#if (RF_OPTION_SOURCE_ENCODING == RF_UTF16_LE) || (RF_OPTION_SOURCE_ENCODING == RF_UTF16_BE)
while(buff[i] != '\0' && buff[i+1]!= '\0')
i++;
i+=2;
RF_MALLOC(codepoints,i/2)
#elif (RF_OPTION_SOURCE_ENCODING == RF_UTF32_LE) || (RF_OPTION_SOURCE_ENCODING == RF_UTF32_BE)
while(buff[i] != '\0' && buff[i+1]!= '\0' && buff[i+2]!= '\0' && buff[i+3]!= '\0')
i++;
i+=4;
RF_MALLOC(codepoints,i)
#endif
#if (RF_OPTION_SOURCE_ENCODING == RF_UTF16_LE)
if(rfUTILS_Endianess() == RF_LITTLE_ENDIAN)
if(rfUTF16_Decode(buff,&characterLength,codepoints) == false)
goto cleanup;
else
if(rfUTF16_Decode_swap(buff,&characterLength,codepoints)==false)
goto cleanup;
#elif RF_OPTION_SOURCE_ENCODING == RF_UTF16_BE
if(rfUTILS_Endianess() == RF_LITTLE_ENDIAN)
if(rfUTF16_Decode_swap(buff,&characterLength,codepoints) == false)
goto cleanup;
else
if(rfUTF16_Decode(buff,&characterLength,codepoints)==false)
goto cleanup;
#elif RF_OPTION_SOURCE_ENCODING == RF_UTF32_LE
memcpy(codepoints,buff,i);
if(rfUTILS_Endianess != RF_LITTLE_ENDIAN)
{
for(j=0;j<i;j+=4)
{
rfUTILS_SwapEndianUI((uint32_t*)(codepoints+j))
}
}
#elif RF_OPTION_SOURCE_ENCODING == RF_UTF32_BE
memcpy(codepoints,buff,i);
if(rfUTILS_Endianess !RF_BIG_ENDIAN RF_LITTLE_ENDIAN)
{
for(j=0;j<i;j+=4)
{
rfUTILS_SwapEndianUI((uint32_t*)(codepoints+j))
}
}
#endif
#if RF_OPTION_SOURCE_ENCODING != RF_UTF8
if(buffAllocated == true)
free(buff);
buffAllocated = true;
if((buff = rfUTF8_Encode(codepoints,characterLength,&byteLength)) == 0)
{
LOG_ERROR("While attempting to create a temporary RF_String the given byte sequence could not be properly encoded into UTF-8",RE_UTF8_ENCODING);
free(codepoints);
return 0;
}
free(codepoints);
#endif
uint32_t byteLength;
if( rfUTF8_VerifySequence(buff,&byteLength) == RF_FAILURE)
{
LOG_ERROR("Error at String Allocation due to invalid UTF-8 byte sequence",RE_STRING_INIT_FAILURE);
if(buffAllocated == true)
free(buff);
return 0;
}
RF_String* ret;
ret = rfLMS_Push(RF_LMS,sizeof(RF_String));
if(ret == 0)
{
LOG_ERROR("Memory allocation from the Local Memory Stack failed. Insufficient local memory stack space. Consider compiling the library with bigger stack space. Quitting proccess...",
RE_LOCALMEMSTACK_INSUFFICIENT);
exit(RE_LOCALMEMSTACK_INSUFFICIENT);
}
ret->byteLength = byteLength;
ret->bytes = rfLMS_Push(RF_LMS,ret->byteLength+1);
if(ret->bytes == 0)
{
LOG_ERROR("Memory allocation from the Local Memory Stack failed. Insufficient local memory stack space. Consider compiling the library with bigger stack space. Quitting proccess...",
RE_LOCALMEMSTACK_INSUFFICIENT);
exit(RE_LOCALMEMSTACK_INSUFFICIENT);
}
memcpy(ret->bytes,buff,ret->byteLength+1);
if(buffAllocated == true)
free(buff);
return ret;
#if (RF_OPTION_SOURCE_ENCODING == RF_UTF16_LE) || (RF_OPTION_SOURCE_ENCODING == RF_UTF16_BE)
cleanup:
#if RF_OPTION_SOURCE_ENCODING == RF_UTF16_LE
LOG_ERROR("Temporary RF_String creation from a UTF-16 Little Endian buffer failed due to UTF-16 decoding failure",RE_UTF16_INVALID_SEQUENCE);
#elif RF_OPTION_SOURCE_ENCODING == RF_UTF16_BE
LOG_ERROR("Temporary RF_String creation from a UTF-16 Big Endian buffer failed due to UTF-16 decoding failure",RE_UTF16_INVALID_SEQUENCE);
#endif
free(codepoints);
if(buffAllocated == true)
free(buff);
return 0;
#endif
}
RF_String* i_NVrfString_CreateLocal(const char* s)
{
#if RF_OPTION_SOURCE_ENCODING != RF_UTF8
uint32_t characterLength,*codepoints,i=0,j;
char* buff;
#endif
rfLMS_MacroEvalPtr(RF_LMS);
#if (RF_OPTION_SOURCE_ENCODING == RF_UTF16_LE) || (RF_OPTION_SOURCE_ENCODING == RF_UTF16_BE)
while(s[i] != '\0' &&s[i+1]!= '\0')
i++;
i+=2;
RF_MALLOC(codepoints,i/2)
#elif (RF_OPTION_SOURCE_ENCODING == RF_UTF32_LE) || (RF_OPTION_SOURCE_ENCODING == RF_UTF32_BE)
while(s[i] != '\0' && s[i+1]!= '\0' && s[i+2]!= '\0' && s[i+3]!= '\0')
i++;
i+=4;
RF_MALLOC(codepoints,i)
#endif
#if (RF_OPTION_SOURCE_ENCODING == RF_UTF16_LE)
if(rfUTILS_Endianess() == RF_LITTLE_ENDIAN)
if(rfUTF16_Decode(s,&characterLength,codepoints) == false)
goto cleanup;
else
if(rfUTF16_Decode_swap(s,&characterLength,codepoints)==false)
goto cleanup;
#elif RF_OPTION_SOURCE_ENCODING == RF_UTF16_BE
if(rfUTILS_Endianess() == RF_LITTLE_ENDIAN)
if(rfUTF16_Decode_swap(s,&characterLength,codepoints) == false)
goto cleanup;
else
if(rfUTF16_Decode(s,&characterLength,codepoints)==false)
goto cleanup;
#elif RF_OPTION_SOURCE_ENCODING == RF_UTF32_LE
memcpy(codepoints,s,i);
if(rfUTILS_Endianess != RF_LITTLE_ENDIAN)
{
for(j=0;j<i;j+=4)
{
rfUTILS_SwapEndianUI((uint32_t*)(codepoints+j))
}
}
#elif RF_OPTION_SOURCE_ENCODING == RF_UTF32_BE
memcpy(codepoints,s,i);
if(rfUTILS_Endianess !RF_BIG_ENDIAN RF_LITTLE_ENDIAN)
{
for(j=0;j<i;j+=4)
{
rfUTILS_SwapEndianUI((uint32_t*)(codepoints+j))
}
}
#endif
#if RF_OPTION_SOURCE_ENCODING != RF_UTF8
if((buff = rfUTF8_Encode(codepoints,characterLength,&byteLength)) == 0)
{
LOG_ERROR("While attempting to create a temporary RF_String the given byte sequence could not be properly encoded into UTF-8",RE_UTF8_ENCODING);
free(codepoints);
return 0;
}
free(codepoints);
#endif
uint32_t byteLength;
#if RF_OPTION_SOURCE_ENCODING == RF_UTF8
if( rfUTF8_VerifySequence(s,&byteLength) == RF_FAILURE)
#else
if( rfUTF8_VerifySequence(buff,&byteLength) == RF_FAILURE)
#endif
{
LOG_ERROR("Error at String Allocation due to invalid UTF-8 byte sequence",RE_STRING_INIT_FAILURE);
return 0;
}
RF_String* ret;
ret = rfLMS_Push(RF_LMS,sizeof(RF_String));
if(ret == 0)
{
LOG_ERROR("Memory allocation from the Local Memory Stack failed during string allocation. Insufficient local memory stack space. Consider compiling the library with bigger stack space. Quitting proccess...",
RE_LOCALMEMSTACK_INSUFFICIENT);
exit(RE_LOCALMEMSTACK_INSUFFICIENT);
}
ret->byteLength = byteLength;
ret->bytes = rfLMS_Push(RF_LMS,ret->byteLength+1);
if(ret->bytes == 0)
{
LOG_ERROR("Memory allocation from the Local Memory Stack failed during string allocation. Insufficient local memory stack space. Consider compiling the library with bigger stack space. Quitting proccess...",
RE_LOCALMEMSTACK_INSUFFICIENT);
exit(RE_LOCALMEMSTACK_INSUFFICIENT);
}
#if RF_OPTION_SOURCE_ENCODING == RF_UTF8
memcpy(ret->bytes,s,ret->byteLength+1);
#else
memcpy(ret->bytes,buff,ret->byteLength+1);
#endif
return ret;
#if (RF_OPTION_SOURCE_ENCODING == RF_UTF16_LE) || (RF_OPTION_SOURCE_ENCODING == RF_UTF16_BE)
cleanup:
#if RF_OPTION_SOURCE_ENCODING == RF_UTF16_LE
LOG_ERROR("Temporary RF_String creation from a UTF-16 Little Endian buffer failed due to UTF-16 decoding failure",RE_UTF16_INVALID_SEQUENCE);
#elif RF_OPTION_SOURCE_ENCODING == RF_UTF16_BE
LOG_ERROR("Temporary RF_String creation from a UTF-16 Big Endian buffer failed due to UTF-16 decoding failure",RE_UTF16_INVALID_SEQUENCE);
#endif
free(codepoints);
return 0;
#endif
}
#ifndef RF_OPTION_DEFAULT_ARGUMENTS
char rfString_Init(RF_String* str,const char* s,...)
#else
char i_rfString_Init(RF_String* str,const char* s,...)
#endif
{
READ_VSNPRINTF_ARGS(s,s,false)
uint32_t byteLength;
if( rfUTF8_VerifySequence(buff,&byteLength) == RF_FAILURE)
{
LOG_ERROR("Error at String Initialization due to invalid UTF-8 byte sequence",RE_STRING_INIT_FAILURE);
if(buffAllocated==true)
free(buff);
return false;
}
str->byteLength = byteLength;
RF_MALLOC(str->bytes,str->byteLength+1);
memcpy(str->bytes,buff,str->byteLength+1);
if(buffAllocated == true)
free(buff);
return true;
}
#ifdef RF_OPTION_DEFAULT_ARGUMENTS
char i_NVrfString_Init(RF_String* str,const char* s)
{
uint32_t byteLength;
if( rfUTF8_VerifySequence(s,&byteLength) == RF_FAILURE)
{
LOG_ERROR("Error at String Initialization due to invalid UTF-8 byte sequence",RE_STRING_INIT_FAILURE);
return false;
}
str->byteLength = byteLength;
RF_MALLOC(str->bytes,str->byteLength+1);
memcpy(str->bytes,s,str->byteLength+1);
return true;
}
#endif
RF_String* rfString_Create_cp(uint32_t codepoint)
{
RF_String* ret;
RF_MALLOC(ret,sizeof(RF_String));
if(rfString_Init_cp(ret,codepoint) == true)
{
return ret;
}
free(ret);
return 0;
}
char rfString_Init_cp(RF_String* str, uint32_t codepoint)
{
RF_MALLOC(str->bytes,5)
if(RF_HEXLE_UI(codepoint,0x007f))
{
str->bytes[0] = codepoint;
str->bytes[1] = '\0';
str->byteLength = 1;
}
else if( RF_HEXGE_UI(codepoint,0x0080) && RF_HEXLE_UI(codepoint,0x07ff))
{
str->bytes[1] = (codepoint & 0x3F)|(0x02<<6);
str->bytes[0] = ((codepoint & 0x7C0) >> 6) | (0x6<<5);
str->bytes[2] = '\0';
str->byteLength = 2;
}
else if( RF_HEXGE_UI(codepoint,0x0800) && RF_HEXLE_UI(codepoint,0x0ffff))
{
str->bytes[2] = (codepoint & 0x3F)|(0x02<<6);
str->bytes[1] = ((codepoint & 0xFC0) >> 6) | (0x02<<6);
str->bytes[0] = (((codepoint & 0xF000))>>12) | (0xE<<4);
str->bytes[3] = '\0';
str->byteLength = 3;
}
else if( RF_HEXGE_UI(codepoint,0x10000) && RF_HEXLE_UI(codepoint,0x10ffff))
{
str->bytes[3] = (codepoint & 0x3F)|(0x02<<6);
str->bytes[2] = ((codepoint & 0xFC0) >> 6) | (0x02<<6);
str->bytes[1] = (((codepoint & 0x3F000))>>12) | (0x02<<6);
str->bytes[0] = (((codepoint & 0x1C0000))>>18) | (0x1E<<3);
str->bytes[4] = '\0';
str->byteLength = 4;
}
else
{
LOG_ERROR("Attempted to encode an invalid unicode code point into a string",RE_UTF8_INVALID_CODE_POINT);
free(str->bytes);
return false;
}
return true;
}
RF_String* rfString_Create_i(int32_t i)
{
int32_t numLen;
char buff[12]; sprintf(buff,"%d",i);
numLen = strlen(buff);
RF_String* ret;
RF_MALLOC(ret,sizeof(RF_String));
ret->byteLength = numLen;
RF_MALLOC(ret->bytes,numLen+1);
strcpy(ret->bytes,buff);
return ret;
}
char rfString_Init_i(RF_String* str, int32_t i)
{
int32_t numLen;
char buff[12]; sprintf(buff,"%d",i);
numLen = strlen(buff);
str->byteLength = numLen;
RF_MALLOC(str->bytes,numLen+1);
strcpy(str->bytes,buff);
return true;
}
RF_String* rfString_Create_f(float f)
{
char* buff;
RF_MALLOC(buff,128);
sprintf(buff,"%f",f);
uint32_t len = strlen(buff);
RF_String* ret;
RF_MALLOC(ret,sizeof(RF_String));
ret->byteLength = len;
RF_MALLOC(ret->bytes,len+1);
strcpy(ret->bytes,buff);
free(buff);
return ret;
}
char rfString_Init_f(RF_String* str,float f)
{
char* buff;
RF_MALLOC(buff,128);
sprintf(buff,"%f",f);
uint32_t len = strlen(buff);
str->byteLength = len;
RF_MALLOC(str->bytes,len+1);
strcpy(str->bytes,buff);
free(buff);
return true;
}
RF_String* rfString_Create_UTF16(const char* s,char endianess)
{
RF_String* ret;
RF_MALLOC(ret,sizeof(RF_String));
if(rfString_Init_UTF16(ret,s,endianess)==false)
{
free(ret);
return 0;
}
return ret;
}
char rfString_Init_UTF16(RF_String* str,const char* s,char endianess)
{
uint32_t* codepoints;
uint32_t byteLength,characterLength,utf8ByteLength;
char* utf8;
byteLength = 0;
while(s[byteLength]!= 0 || s[byteLength+1]!=0)
{
byteLength++;
}
byteLength+=3; RF_MALLOC(codepoints,byteLength*2) switch(endianess)
{
case RF_LITTLE_ENDIAN:
case RF_BIG_ENDIAN:
if(rfUTILS_Endianess() == endianess) {
if(rfUTF16_Decode(s,&characterLength,codepoints) == false)
{
free(codepoints);
LOG_ERROR("String initialization failed due to invalide UTF-16 sequence",RE_STRING_INIT_FAILURE);
return false;
}
}
else {
if(rfUTF16_Decode_swap(s,&characterLength,codepoints) == false)
{
free(codepoints);
LOG_ERROR("String initialization failed due to invalide UTF-16 sequence",RE_STRING_INIT_FAILURE);
return false;
}
}
break;
default:
LOG_ERROR("Illegal endianess value provided",RE_INPUT);
free(codepoints);
return false;
break;
} if( (utf8 = rfUTF8_Encode(codepoints,characterLength,&utf8ByteLength))==0)
{
free(codepoints);
return false;
}
free(codepoints);
str->bytes = utf8;
str->byteLength = utf8ByteLength;
return true;
}
RF_String* rfString_Create_UTF32(const char* s)
{
RF_String* ret;
RF_MALLOC(ret,sizeof(RF_String));
if(rfString_Init_UTF32(ret,s)==false)
{
free(ret);
return 0;
}
return ret;
}
char rfString_Init_UTF32(RF_String* str,const char* s)
{
char swapE = false;
uint32_t off = 0;
int32_t i = 0;
uint32_t* codeBuffer = (uint32_t*)(s+off);
if(RF_HEXEQ_UI(codeBuffer[0],0xFEFF)) {
if(rfUTILS_Endianess()==RF_LITTLE_ENDIAN)
swapE = true;
}
if(RF_HEXEQ_UI(codeBuffer[0],0xFFFE0000)) {
if(rfUTILS_Endianess()==RF_BIG_ENDIAN)
swapE = true;
}
else {
if(rfUTILS_Endianess() == RF_LITTLE_ENDIAN)
swapE = true;
}
if(swapE==true)
{
while(codeBuffer[i] != 0)
{
rfUTILS_SwapEndianUI(codeBuffer+i);
i++;
}
}
uint32_t length;
rfUTF32_Length(codeBuffer,length);
char* utf8;uint32_t utf8ByteLength;
if((utf8=rfUTF8_Encode(codeBuffer,length,&utf8ByteLength)) == 0)
{
return false; }
if(codeBuffer != 0)
{
str->bytes = (char*)codeBuffer;
str->byteLength = utf8ByteLength;
return true;
}
return false;
}
void i_rfString_Assign(RF_String* dest,void* sourceP)
{
RF_String* source = (RF_String*)sourceP;
if(source->byteLength > dest->byteLength)
{
RF_REALLOC(dest->bytes,char,source->byteLength+1);
}
memcpy(dest->bytes,source->bytes,source->byteLength+1);
dest->byteLength = source->byteLength;
}
char rfString_Assign_char(RF_String* str,uint32_t codepoint)
{
if(str->byteLength <5)
{
RF_REALLOC(str->bytes,char,5);
}
if(RF_HEXLE_UI(codepoint,0x007f))
{
str->bytes[0] = codepoint;
str->bytes[1] = '\0';
str->byteLength = 1;
}
else if( RF_HEXGE_UI(codepoint,0x0080) && RF_HEXLE_UI(codepoint,0x07ff))
{
str->bytes[1] = (codepoint & 0x3F)|(0x02<<6);
str->bytes[0] = ((codepoint & 0x7C0) >> 6) | (0x6<<5);
str->bytes[2] = '\0';
str->byteLength = 2;
}
else if( RF_HEXGE_UI(codepoint,0x0800) && RF_HEXLE_UI(codepoint,0x0ffff))
{
str->bytes[2] = (codepoint & 0x3F)|(0x02<<6);
str->bytes[1] = ((codepoint & 0xFC0) >> 6) | (0x02<<6);
str->bytes[0] = (((codepoint & 0xF000))>>12) | (0xE<<4);
str->bytes[3] = '\0';
str->byteLength = 3;
}
else if( RF_HEXGE_UI(codepoint,0x10000) && RF_HEXLE_UI(codepoint,0x10ffff))
{
str->bytes[3] = (codepoint & 0x3F)|(0x02<<6);
str->bytes[2] = ((codepoint & 0xFC0) >> 6) | (0x02<<6);
str->bytes[1] = (((codepoint & 0x3F000))>>12) | (0x02<<6);
str->bytes[0] = (((codepoint & 0x1C0000))>>18) | (0x1E<<3);
str->bytes[4] = '\0';
str->byteLength = 4;
}
else
{
LOG_ERROR("Attempted to encode an invalid unicode code point into a string",RE_UTF8_INVALID_CODE_POINT);
return false;
}
return true;
}
#ifndef RF_OPTION_DEFAULT_ARGUMENTS
RF_String* rfString_Create_nc(const char* s,...)
#else
RF_String* i_rfString_Create_nc(const char* s,...)
#endif
{
RF_String* ret;
RF_MALLOC(ret,sizeof(RF_String));
READ_VSNPRINTF_ARGS(s,s,0);
ret->byteLength = bytesWritten;
RF_MALLOC(ret->bytes,ret->byteLength+1);
memcpy(ret->bytes,buff,ret->byteLength+1);
if(buffAllocated)
free(buff);
return ret;
}
#ifdef RF_OPTION_DEFAULT_ARGUMENTS
RF_String* i_NVrfString_Create_nc(const char* s)
{
RF_String* ret;
RF_MALLOC(ret,sizeof(RF_String));
ret->byteLength = strlen(s);
RF_MALLOC(ret->bytes,ret->byteLength+1);
memcpy(ret->bytes,s,ret->byteLength+1);
return ret;
}
#endif
#ifndef RF_OPTION_DEFAULT_ARGUMENTS
char rfString_Init_nc(struct RF_String* str,const char* s,...)
#else
char i_rfString_Init_nc(struct RF_String* str,const char* s,...)
#endif
{
READ_VSNPRINTF_ARGS(s,s,false)
str->byteLength = bytesWritten;
RF_MALLOC(str->bytes,str->byteLength+1);
memcpy(str->bytes,buff,str->byteLength+1);
if(buffAllocated == true)
free(buff);
return true;
}
#ifdef RF_OPTION_DEFAULT_ARGUMENTS
char i_NVrfString_Init_nc(struct RF_String* str,const char* s)
{
str->byteLength = strlen(s);
RF_MALLOC(str->bytes,str->byteLength+1);
memcpy(str->bytes,s,str->byteLength+1);
return true;
}
#endif
void rfString_Destroy(RF_String* s)
{
free(s->bytes);
free(s);
}
void rfString_Deinit(RF_String* s)
{
free(s->bytes);
}
uint16_t* rfString_ToUTF16(RF_String* s,uint32_t* length)
{
uint32_t* codepoints,charsN;
codepoints = rfUTF8_Decode(s->bytes,s->byteLength,&charsN);
return rfUTF16_Encode(codepoints,charsN,length);
}
uint32_t* rfString_ToUTF32(RF_String* s,uint32_t* length)
{
return rfUTF8_Decode(s->bytes,s->byteLength,length);
}
uint32_t rfString_Length(void* str)
{
RF_String* s = (RF_String*)str;
uint32_t length,i;
RF_STRING_ITERATE_START(s,length,i)
RF_STRING_ITERATE_END(length,i);
return length;
}
uint32_t rfString_GetChar(void* str,uint32_t c)
{
RF_String* thisstr = (RF_String*)str;
uint32_t length,i;
uint32_t codePoint = RF_STRING_INDEX_OUT_OF_BOUNDS;
RF_STRING_ITERATE_START(thisstr,length,i)
if(length == c)
{
codePoint = rfString_BytePosToCodePoint(thisstr,i);
break;
}
RF_STRING_ITERATE_END(length,i)
return codePoint;
}
uint32_t rfString_BytePosToCodePoint(void* str,uint32_t i)
{
uint32_t codePoint=0;
RF_String* thisstr = (RF_String*)str;
if( ((thisstr->bytes[i] & 0x80)>>7) == 0 )
{
codePoint = thisstr->bytes[i];
}
else if ( RF_HEXEQ_C( ( (~(thisstr->bytes[i] ^ 0xC0))>>5),0x7) )
{
codePoint =0;
codePoint = (thisstr->bytes[i+1] & 0x3F) ;
codePoint |= ((thisstr->bytes[i] & 0x1F) << 6);
}
else if( RF_HEXEQ_C( ( (~(thisstr->bytes[i] ^ 0xE0))>>4),0xF) )
{
codePoint = 0;
codePoint = (thisstr->bytes[i+2] & 0x3F) ;
codePoint |= ((thisstr->bytes[i+1] & 0x3F) << 6);
codePoint |= ((thisstr->bytes[i] & 0xF) << 12);
}
else if( RF_HEXEQ_C( ( (~(thisstr->bytes[i] ^ 0xF0))>>3), 0x1F))
{
codePoint = 0;
codePoint = (thisstr->bytes[i+3] & 0x3F) ;
codePoint |= ((thisstr->bytes[i+2] & 0x3F) << 6);
codePoint |= ((thisstr->bytes[i+1] & 0x3F) << 12);
codePoint |= ((thisstr->bytes[i] & 0x7) << 18);
}
return codePoint;
}
uint32_t rfString_BytePosToCharPos(void* thisstrP,uint32_t bytepos,char before)
{
RF_String* thisstr = (RF_String*)thisstrP;
uint32_t charPos = 0;
uint32_t byteI = 0;
if(rfUTF8_IsContinuationByte(thisstr->bytes[bytepos])==false)
{
RF_STRING_ITERATE_START(thisstr,charPos,byteI)
if(byteI == bytepos)
return charPos;
RF_STRING_ITERATE_END(charPos,byteI)
}
RF_STRING_ITERATE_START(thisstr,charPos,byteI)
if(byteI > bytepos)
break;
RF_STRING_ITERATE_END(charPos,byteI)
if(before == true)
return charPos-1;
return charPos;
}
char i_rfString_Equal(void* s1P,void* s2P)
{
RF_String* s1 = (RF_String*)s1P;
RF_String* s2 = (RF_String*)s2P;
if( strcmp(s1->bytes,s2->bytes)==0)
{
return true;
}
return false;
}
int32_t i_rfString_Find(const void* str,const void* sstrP,const char* optionsP)
{
RF_String* thisstr = (RF_String*)str;
RF_String* sstr = (RF_String*)sstrP;
char options = *optionsP;
char* found = 0;
if( (RF_BITFLAG_ON( options,RF_CASE_IGNORE)) == false)
{
if( (found = strstr(thisstr->bytes,sstr->bytes)) == 0)
{
return RF_FAILURE;
}
uint32_t bytepos = found-thisstr->bytes;
if(RF_BITFLAG_ON( options,RF_MATCH_WORD))
{
if(bytepos != 0)
{
switch(thisstr->bytes[bytepos-1])
{
case ' ':case '\t':case '\n':
break;
default:
return RF_FAILURE;
break;
}
}
if(bytepos+sstr->byteLength != thisstr->byteLength)
{
switch(thisstr->bytes[bytepos+sstr->byteLength])
{
case ' ':case '\t':case '\n':
break;
default:
return RF_FAILURE;
break;
}
}
} return rfString_BytePosToCharPos(thisstr,bytepos,false);
}
uint32_t i,j;
for(i=0;i<thisstr->byteLength; i ++)
{
for(j = 0; j < sstr->byteLength; j++)
{
if(sstr->bytes[j] >= 0x41 && sstr->bytes[j] <= 0x5a)
{
if(sstr->bytes[j] != thisstr->bytes[i+j] && sstr->bytes[j]+32 != thisstr->bytes[i+j])
break;
if(RF_BITFLAG_ON( options,RF_MATCH_WORD))
{
if(j == 0 && i != 0)
{
switch(thisstr->bytes[i-1])
{
case ' ':case '\t':case '\n':
break;
default:
return RF_FAILURE;
break;
}
}
} }
else if(sstr->bytes[j] >= 0x61 && sstr->bytes[j] <= 0x7a)
{
if(sstr->bytes[j] != thisstr->bytes[i+j] && sstr->bytes[j]-32 != thisstr->bytes[i+j])
break;
if(RF_BITFLAG_ON(options,RF_MATCH_WORD))
{
if(j == 0 && i != 0)
{
switch(thisstr->bytes[i-1])
{
case ' ':case '\t':case '\n':
break;
default:
return RF_FAILURE;
break;
}
}
} }
else if(sstr->bytes[j] != thisstr->bytes[i+j])
break;
if(j == sstr->byteLength-1)
{
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;
}
} return rfString_BytePosToCharPos(thisstr,i,false);
} } } return RF_FAILURE;
}
char rfString_ToInt(void* str,int32_t* v)
{
RF_String* thisstr = (RF_String*)str;
char* end;
*v = strtol ( thisstr->bytes, &end,10);
if(end[0] == '\0')
return true;
return false;
}
int rfString_ToDouble(void* thisstrP,double* f)
{
RF_String* str = (RF_String*)thisstrP;
*f = strtod(str->bytes,NULL);
if(*f == 0.0)
{
if(rfString_Equal(str,RFS_("0")) || rfString_Equal(str,RFS_("0.0")))
return RF_SUCCESS;
if(errno == ERANGE)
return RE_STRING_TOFLOAT_UNDERFLOW;
return RE_STRING_TOFLOAT;
}
if(*f == HUGE_VAL && errno == ERANGE)
return RE_STRING_TOFLOAT_RANGE;
return RF_SUCCESS;
}
const char* rfString_ToCstr(const void* str)
{
RF_String* thisstr = (RF_String*)str;
return thisstr->bytes;
}
RF_String* rfString_Copy_OUT(void* srcP)
{
RF_String* src = (RF_String*)srcP;
RF_String* ret;
RF_MALLOC(ret,sizeof(RF_String));
ret->byteLength = src->byteLength;
RF_MALLOC(ret->bytes,ret->byteLength+1);
memcpy(ret->bytes,src->bytes,ret->byteLength+1);
return ret;
}
void rfString_Copy_IN(RF_String* dst,void* srcP)
{
RF_String* src = (RF_String*)srcP;
dst->byteLength = src->byteLength;
RF_MALLOC(dst->bytes,src->byteLength+1);
memcpy(dst->bytes,src->bytes,dst->byteLength+1);
return;
}
void rfString_Copy_chars(RF_String* dst,void* srcP,uint32_t charsN)
{
uint32_t i = 0,bytePos;
RF_String* src = (RF_String*)srcP;
RF_STRING_ITERATE_START(src,i,bytePos)
if(i == charsN)
break;
RF_STRING_ITERATE_END(i,bytePos)
dst->byteLength = bytePos;
RF_MALLOC(dst->bytes,dst->byteLength+1);
memcpy(dst->bytes,src->bytes,dst->byteLength+1);
dst->bytes[dst->byteLength] = '\0';}
char i_rfString_ScanfAfter(void* str,void* afterstrP,const char* format,void* var)
{
RF_String* thisstr = (RF_String*)str;
RF_String* afterstr = (RF_String*)afterstrP;
char* found,*s;
if( (found = strstr(thisstr->bytes,afterstr->bytes)) ==0 )
{
return false;
}
s = thisstr->bytes + (found-thisstr->bytes+afterstr->byteLength);
if(sscanf(s,format,var) <=0)
{
return false;
}
return true;
}
int32_t i_rfString_Count(void* str,void* sstr2,const char* optionsP)
{
RF_String* thisstr = (RF_String*)str;
RF_String* sstr = (RF_String*)sstr2;
char options = *optionsP;
int32_t index = 0;
int32_t move;
int32_t n = 0;
while ((move = rfString_FindBytePos(thisstr,sstr,options)) != RF_FAILURE)
{
move+= sstr->byteLength;
n++;
thisstr->bytes+=move;
index +=move;
thisstr->byteLength -=move;
}
thisstr->bytes-=index;
thisstr->byteLength += index;
return n;
}
i_DECLIMEX_ char rfString_Tokenize(void* str,char* sep,uint32_t* tokensN,RF_String** tokens)
{
RF_String* thisstr = (RF_String*)str;
uint32_t i;
*tokensN = rfString_Count(thisstr,RFS_(sep),0)+1;
if(*tokensN == 0)
return false;
RF_MALLOC(*tokens,sizeof(RF_String) *(*tokensN));
uint32_t sepLen = strlen(sep);
char* s,*e;
s = thisstr->bytes;
for(i = 0; i < (*tokensN)-1; i ++)
{
e = strstr(s,sep);
(*tokens)[i].byteLength = e-s;
RF_MALLOC((*tokens)[i].bytes,(*tokens)[i].byteLength+1);
strncpy((*tokens)[i].bytes,s,(*tokens)[i].byteLength);
(*tokens)[i].bytes[(*tokens)[i].byteLength] = '\0';
s = e+sepLen;
}
(*tokens)[i].byteLength = strlen(s);
RF_MALLOC((*tokens)[i].bytes,(*tokens)[i].byteLength+1);
strncpy((*tokens)[i].bytes,s,(*tokens)[i].byteLength);
(*tokens)[i].bytes[(*tokens)[i].byteLength] = '\0';
return true;
}
char i_rfString_Between(void* thisstrP,void* lstrP,void* rstrP,RF_String* result,const char* optionsP)
{
int32_t start,end;
RF_String* thisstr = (RF_String*)thisstrP;
RF_String* lstr = (RF_String*)lstrP;
RF_String* rstr = (RF_String*)rstrP;
char options = *optionsP;
RF_String temp;
if( (start = rfString_FindBytePos(thisstr,lstr,options))== RF_FAILURE)
{
return false;
}
rfString_After(thisstr,lstr,&temp,options);
if( (end = rfString_FindBytePos(&temp,rstr,options))== RF_FAILURE)
{
return false;
}
rfString_Deinit(&temp);
result->byteLength = end;
RF_MALLOC(result->bytes,result->byteLength+1);
memcpy(result->bytes,thisstr->bytes+start+lstr->byteLength,result->byteLength+1);
result->bytes[end]= '\0';
return true;
}
#ifndef RF_OPTION_DEFAULT_ARGUMENTS
char rfString_Beforev(void* thisstrP,RF_String* result,const char* optionsP,const unsigned char* parNP, ...)
#else
char i_rfString_Beforev(void* thisstrP,RF_String* result,const char* optionsP,const unsigned char* parNP, ...)
#endif
{
RF_String* thisstr = (RF_String*)thisstrP;
RF_String* s;
char options = *optionsP;
unsigned char parN = *parNP;
int32_t i,minPos,thisPos;
va_list argList;
va_start(argList,parNP);
minPos = 9999999;
for(i = 0; i < parN; i++)
{
s = (RF_String*) va_arg(argList,RF_String*);
if( (thisPos= rfString_FindBytePos(thisstr,s,options))!= RF_FAILURE)
{
if(thisPos < minPos)
minPos = thisPos;
}
}
va_end(argList);
if(minPos == 9999999)
{
return false;
}
result->byteLength = minPos;
RF_MALLOC(result->bytes,minPos+1);
memcpy(result->bytes,thisstr->bytes,minPos);
result->bytes[minPos] = '\0';
return true;
}
char i_rfString_Before(void* thisstrP,void* sstrP,RF_String* result,const char* optionsP)
{
RF_String* thisstr = (RF_String*)thisstrP;
RF_String* sstr = (RF_String*) sstrP;
char options = *optionsP;
int32_t ret;
if( (ret = rfString_FindBytePos(thisstr,sstr,options)) == RF_FAILURE)
{
return false;
}
result->byteLength = ret;
RF_MALLOC(result->bytes,result->byteLength+1);
memcpy(result->bytes,thisstr->bytes,result->byteLength);
result->bytes[result->byteLength] = '\0';
return true;
}
char i_rfString_After(void* thisstrP,void* afterP,RF_String* out,const char* optionsP)
{
RF_String* thisstr = (RF_String*)thisstrP;
RF_String* after = (RF_String*)afterP;
char options = *optionsP;
int32_t bytePos;
if( (bytePos = rfString_FindBytePos(thisstr,after,options)) == RF_FAILURE)
{
return false;
}
rfString_Init_nc(out,thisstr->bytes+bytePos+after->byteLength);
return true;
}
#ifndef RF_OPTION_DEFAULT_ARGUMENTS
char rfString_Afterv(void* thisstrP,RF_String* result,const char* optionsP,const unsigned char* parNP,...)
#else
char i_rfString_Afterv(void* thisstrP,RF_String* result,const char* optionsP,const unsigned char* parNP,...)
#endif
{
RF_String* thisstr = (RF_String*)thisstrP;
RF_String* s;
char options = *optionsP;
unsigned char parN = *parNP;
int32_t i,minPos,thisPos;
uint32_t minPosLength;
va_list argList;
va_start(argList,parNP);
minPos = 9999999;
for(i = 0; i < parN; i++)
{
s = (RF_String*) va_arg(argList,RF_String*);
if( (thisPos= rfString_FindBytePos(thisstr,s,options))!= RF_FAILURE)
{
if(thisPos < minPos)
{
minPos = thisPos;
minPosLength = s->byteLength;
}
}
}
va_end(argList);
if(minPos == 9999999)
{
return false;
}
minPos += minPosLength; result->byteLength = thisstr->byteLength-minPos;
RF_MALLOC(result->bytes,result->byteLength);
memcpy(result->bytes,thisstr->bytes+minPos,result->byteLength);
result->bytes[result->byteLength] = '\0';
return true;
}
void i_rfString_Append(RF_String* thisstr,void* otherP)
{
RF_String* other = (RF_String*)otherP;
thisstr->byteLength +=other->byteLength;
RF_REALLOC(thisstr->bytes,char,thisstr->byteLength+1);
strncat(thisstr->bytes,other->bytes,other->byteLength);
}
void rfString_Append_i(RF_String* thisstr,const int32_t i)
{
char* buff;
RF_MALLOC(buff,thisstr->byteLength+15); sprintf(buff,"%s%i",thisstr->bytes,i);
free(thisstr->bytes);
thisstr->bytes = buff;
thisstr->byteLength = strlen(thisstr->bytes);
}
void rfString_Append_f(RF_String* thisstr,const float f)
{
char* buff;
RF_MALLOC(buff,thisstr->byteLength+64);
sprintf(buff,"%s%f",thisstr->bytes,f);
free(thisstr->bytes);
thisstr->bytes = buff;
thisstr->byteLength = strlen(thisstr->bytes);
}
void i_rfString_Prepend(RF_String* thisstr,void* otherP)
{
RF_String* other = (RF_String*)otherP;
uint32_t size;
int32_t i; size = thisstr->byteLength;
thisstr->byteLength += other->byteLength;
RF_REALLOC(thisstr->bytes,char,thisstr->byteLength+1);
for(i =size; i >=0 ; i--)
thisstr->bytes[i+other->byteLength] = thisstr->bytes[i];
memcpy(thisstr->bytes,other->bytes,other->byteLength);
}
char i_rfString_Remove(void* thisstrP,void* rstrP,uint32_t* numberP,const char* optionsP)
{
RF_String* thisstr = (RF_String*)thisstrP;
RF_String* rstr = (RF_String*)rstrP;
char options = *optionsP;
uint32_t number = *numberP;
uint32_t i,count,occurences=0;
int32_t bytePos;
char found = false;
do
{ if( (bytePos = rfString_FindBytePos(thisstr,rstr,options)) == RF_FAILURE)
{
if(found == false)
{
return false;
}
else break;
}
found = true;
count = 0;
for(i = bytePos; i <=thisstr->byteLength; i ++)
{
thisstr->bytes[i] = thisstr->bytes[i+rstr->byteLength];
count++;
}
thisstr->byteLength -= rstr->byteLength;
occurences++;
if(occurences == number)
break;
}while(bytePos != RF_FAILURE);
return true;
}
void i_rfString_KeepOnly(void* thisstrP,void* keepstrP)
{
uint32_t keepLength,i,j,charValue,temp;
uint32_t *keepChars;
RF_String* thisstr = (RF_String*)thisstrP;
RF_String* keepstr = (RF_String*)keepstrP;
char exists,charBLength;
i=0;
keepLength = rfString_Length(keepstr);
RF_MALLOC(keepChars,4*keepLength);
rfString_Iterate_Start(keepstr,i,charValue)
keepChars[i] = charValue;
rfString_Iterate_End(i)
i=0;
rfString_Iterate_Start(thisstr,i,charValue)
exists = false;
for(j=0;j<keepLength; j++)
{
if(keepChars[j] == charValue)
exists = true;
}
if(exists == false)
{
charBLength = rfUTF8_FromCodepoint(charValue,&temp);
memmove(thisstr->bytes+byteIndex_,thisstr->bytes+byteIndex_+charBLength,thisstr->byteLength-byteIndex_+charBLength);
thisstr->byteLength-=charBLength;
continue; }
rfString_Iterate_End(i)
free(keepChars);
}
char rfString_PruneStart(void* thisstrP,uint32_t n)
{
RF_String* thisstr = (RF_String*)thisstrP;
uint32_t i;
uint32_t length = 0;
unsigned nBytePos = 0;
char found = false;
RF_STRING_ITERATE_START(thisstr,length,i);
if(length == n)
{
nBytePos = i;
found = true;
break;
}
RF_STRING_ITERATE_END(length,i)
if(found == false)
{
thisstr->bytes[0] = '\0';
thisstr->byteLength = 0;
return false;
}
for(i =0; i < thisstr->byteLength-nBytePos+1;i++ )
thisstr->bytes[i] = thisstr->bytes[i+nBytePos];
thisstr->byteLength -= nBytePos;
return true;
}
char rfString_PruneEnd(void* thisstrP,uint32_t n)
{
RF_String* thisstr = (RF_String*)thisstrP;
int32_t nBytePos = -1;
uint32_t length,i;
RF_STRING_ITERATEB_START(thisstr,length,i)
if(length == n)
{
nBytePos = i;
break;
}
RF_STRING_ITERATEB_END(length,i)
if(nBytePos == -1)
{
thisstr->bytes[0] = '\0';
return false;
}
thisstr->bytes[nBytePos] = '\0';
thisstr->byteLength -= (thisstr->byteLength - nBytePos);
return true;
}
char rfString_PruneMiddleB(void* thisstrP,uint32_t p,uint32_t n)
{
RF_String* thisstr = (RF_String*)thisstrP;
if(n>p+1)
return false;
uint32_t j,i,length;
int32_t pBytePos,nBytePos;
pBytePos = nBytePos = -1;
RF_STRING_ITERATE_START(thisstr,length,i)
if(length == p+1)
{
pBytePos = i;
break;
}
if(length == p-n+1) nBytePos = i;
RF_STRING_ITERATE_END(length,i)
if(pBytePos == -1 || nBytePos == -1)
return false;
for(i=nBytePos,j=0;j<= thisstr->byteLength-pBytePos+1; i ++,j++) {
thisstr->bytes[i] = thisstr->bytes[pBytePos+j];
}
thisstr->byteLength -= (nBytePos - pBytePos);
return true;
}
char rfString_PruneMiddleF(void* thisstrP,uint32_t p,uint32_t n)
{
RF_String* thisstr = (RF_String*)thisstrP;
uint32_t j,i,length;
int32_t pBytePos,nBytePos;
pBytePos = nBytePos = -1;
RF_STRING_ITERATE_START(thisstr,length,i)
if(length == p)
pBytePos = i;
if(length == p+n)
{
nBytePos = i;
break; }
RF_STRING_ITERATE_END(length,i)
if(pBytePos == -1 )
return false;
if(nBytePos == -1)
{
thisstr->bytes[pBytePos] = '\0';
thisstr->byteLength -= (thisstr->byteLength-pBytePos);
return true;
}
for(i=pBytePos,j=0;j<= thisstr->byteLength-nBytePos+1; i ++,j++) {
thisstr->bytes[i] = thisstr->bytes[nBytePos+j];
}
thisstr->byteLength -= (nBytePos - pBytePos);
return true;
}
char i_rfString_Replace(RF_String* thisstr,void* sstrP,void* rstrP,const uint32_t* numP,const char* optionsP)
{
RF_String* sstr = (RF_String*)sstrP;
RF_String* rstr = (RF_String*)rstrP;
char options = *optionsP;
uint32_t num = *numP;
RF_StringX temp; uint32_t foundN = 0;
uint32_t number = num;
uint32_t diff,i,j;
if(rfString_FindBytePos(thisstr,sstr,options) == RF_FAILURE)
{
return false;
}
uint32_t bSize = 50;
int32_t * bytePositions;
RF_MALLOC(bytePositions,bSize*sizeof(int32_t));
if(number == 0)
number = 999999;
rfStringX_FromString_IN(&temp,thisstr);
while( (bytePositions[foundN] = rfString_FindBytePos(&temp,sstr,options)) != RF_FAILURE)
{
int32_t move = bytePositions[foundN] + sstr->byteLength;
bytePositions[foundN] = bytePositions[foundN]+temp.bIndex;
temp.bIndex += move;
temp.bytes += move;
temp.byteLength -= move;
foundN++;
if(foundN > bSize)
{
bSize *=2;
RF_REALLOC(bytePositions,int32_t,bSize);
}
if(foundN >= number)
break;
}
rfStringX_Deinit(&temp);
if(number > foundN)
number = foundN;
if(rstr->byteLength > sstr->byteLength) {
int32_t orSize,nSize;
diff = rstr->byteLength - sstr->byteLength;
orSize = thisstr->byteLength +1;
nSize= orSize + number*diff;
RF_REALLOC(thisstr->bytes,char,nSize)
for(i = 0; i < number; i ++)
{
for(j =orSize+diff-1; j > bytePositions[i]+sstr->byteLength; j -- )
thisstr->bytes[j] = thisstr->bytes[j-diff];
strncpy(thisstr->bytes+bytePositions[i],rstr->bytes,rstr->byteLength);
orSize += diff;
for(j = i+1; j < number; j ++)
bytePositions[j] = bytePositions[j]+diff;
}
thisstr->byteLength = nSize-1;
}
else if( rstr->byteLength < sstr->byteLength) {
diff = sstr->byteLength-rstr->byteLength;
for(i =0; i < number; i ++)
{
strncpy(thisstr->bytes+bytePositions[i],rstr->bytes,rstr->byteLength);
for(j =bytePositions[i]+rstr->byteLength; j < thisstr->byteLength; j ++ )
thisstr->bytes[j] = thisstr->bytes[j+diff];
for(j = i+1; j < number; j ++)
bytePositions[j] = bytePositions[j]-diff;
}
thisstr->byteLength -= diff*number;
}
else {
for(i = 0; i < number; i ++)
strncpy(thisstr->bytes+bytePositions[i],rstr->bytes,rstr->byteLength);
}
free(bytePositions);
return true;
}
char i_rfString_StripStart(void* thisstrP,void* subP)
{
RF_String* thisstr = (RF_String*) thisstrP;
RF_String*sub = (RF_String*) subP;
char ret = false,noMatch;
uint32_t charValue,i = 0,*subValues,j,subLength,bytePos;
subLength = rfString_Length(sub);
RF_MALLOC(subValues,4*subLength)
rfString_Iterate_Start(sub,i,charValue)
subValues[i] = charValue;
rfString_Iterate_End(i)
i = 0;
RF_STRING_ITERATE_START(thisstr,i,bytePos)
noMatch = true;
for(j = 0;j < subLength; j++)
{
if(rfString_BytePosToCodePoint(thisstr,bytePos) == subValues[j])
{
ret = true;
noMatch = false;
break;
}
}
if(noMatch)
break;
RF_STRING_ITERATE_END(i,bytePos)
if(ret == true)
{
for(i =0; i < thisstr->byteLength-bytePos+1;i++ )
thisstr->bytes[i] = thisstr->bytes[i+bytePos];
thisstr->byteLength -= bytePos;
}
free(subValues);
return ret;
}
char i_rfString_StripEnd(void* thisstrP,void* subP)
{
RF_String* thisstr = (RF_String*) thisstrP;
RF_String*sub = (RF_String*) subP;
char ret = false,noMatch;
uint32_t charValue,i = 0,*subValues,j,subLength,bytePos,lastBytePos,testity;
subLength = rfString_Length(sub);
RF_MALLOC(subValues,4*subLength)
rfString_Iterate_Start(sub,i,charValue)
subValues[i] = charValue;
rfString_Iterate_End(i)
i = 0;
RF_STRING_ITERATEB_START(thisstr,i,bytePos)
noMatch = true;
for(j = 0;j < subLength; j++)
{
if((testity=rfString_BytePosToCodePoint(thisstr,bytePos)) == subValues[j])
{
ret = true;
noMatch = false;
lastBytePos = bytePos;
break;
}
}
if(noMatch)
break;
RF_STRING_ITERATEB_END(i,bytePos)
if(ret == true)
{
thisstr->bytes[lastBytePos] = '\0';
thisstr->byteLength -= (thisstr->byteLength - lastBytePos);
}
free(subValues);
return ret;
}
char i_rfString_Strip(void* thisstrP,void* subP)
{
char res1 = rfString_StripStart(thisstrP,subP);
char res2 = rfString_StripEnd(thisstrP,subP);
return res1|res2;
}
RF_String* rfString_Create_fUTF8(FILE* f, char* eof)
{
RF_String* ret;
RF_MALLOC(ret,sizeof(RF_String));
if(rfString_Init_fUTF8(ret,f,eof) < 0)
{
free(ret);
return 0;
}
return ret;
}
int32_t rfString_Init_fUTF8(RF_String* str,FILE* f,char* eof)
{
int32_t bytesN;
uint32_t bufferSize; if((bytesN=rfFReadLine_UTF8(f,&str->bytes,&str->byteLength,&bufferSize,eof)) < 0)
{
LOG_ERROR("Failed to initialize String from a UTF-8 file",bytesN);
return bytesN;
}
return bytesN;
}
int32_t rfString_Assign_fUTF8(RF_String* str,FILE*f,char* eof)
{
int32_t bytesN;
uint32_t utf8ByteLength,utf8BufferSize; char* utf8 = 0;
if((bytesN=rfFReadLine_UTF8(f,&utf8,&utf8ByteLength,&utf8BufferSize,eof)) < 0)
{
LOG_ERROR("Failed to assign the contents of a UTF-8 file to a String",bytesN);
return bytesN;
}
if(str->byteLength <= utf8ByteLength)
{
RF_REALLOC(str->bytes,char,utf8ByteLength+1);
}
memcpy(str->bytes,utf8,utf8ByteLength+1);
str->byteLength = utf8ByteLength;
free(utf8);
return bytesN;
}
int32_t rfString_Append_fUTF8(RF_String* str,FILE*f,char* eof)
{
int32_t bytesN;
uint32_t utf8ByteLength,utf8BufferSize; char* utf8 = 0;
if((bytesN=rfFReadLine_UTF8(f,&utf8,&utf8ByteLength,&utf8BufferSize,eof)) < 0)
{
LOG_ERROR("Failed to assign the contents of a UTF-8 file to a String",bytesN);
return bytesN;
}
rfString_Append(str,RFS_(utf8));
free(utf8);
return bytesN;
}
RF_String* rfString_Create_fUTF16(FILE* f,char endianess,char* eof)
{
RF_String* ret;
RF_MALLOC(ret,sizeof(RF_String));
if(rfString_Init_fUTF16(ret,f,endianess,eof) < 0)
return 0;
return ret;
}
int32_t rfString_Init_fUTF16(RF_String* str,FILE* f, char endianess,char* eof)
{
int32_t bytesN;
if(endianess == RF_LITTLE_ENDIAN)
{
if((bytesN=rfFReadLine_UTF16LE(f,&str->bytes,&str->byteLength,eof)) < 0)
{
LOG_ERROR("Failure to initialize a String from reading a UTF-16 file",bytesN);
return bytesN;
}
} else {
if((bytesN=rfFReadLine_UTF16BE(f,&str->bytes,&str->byteLength,eof)) < 0)
{
LOG_ERROR("Failure to initialize a String from reading a UTF-16 file",bytesN);
return bytesN;
}
} return bytesN;
}
int32_t rfString_Assign_fUTF16(RF_String* str,FILE* f, char endianess,char* eof)
{
uint32_t utf8ByteLength;
int32_t bytesN;
char* utf8 = 0;
if(endianess == RF_LITTLE_ENDIAN)
{
if((bytesN=rfFReadLine_UTF16LE(f,&utf8,&utf8ByteLength,eof)) < 0)
{
LOG_ERROR("Failure to assign the contents of a Little Endian UTF-16 file to a String",bytesN);
return bytesN;
}
} else {
if((bytesN=rfFReadLine_UTF16BE(f,&utf8,&utf8ByteLength,eof)) < 0)
{
LOG_ERROR("Failure to assign the contents of a Big Endian UTF-16 file to a String",bytesN);
return bytesN;
}
} if(str->byteLength <= utf8ByteLength)
{
RF_REALLOC(str->bytes,char,utf8ByteLength+1);
}
memcpy(str->bytes,utf8,utf8ByteLength+1);
str->byteLength = utf8ByteLength;
free(utf8);
return bytesN;
}
int32_t rfString_Append_fUTF16(RF_String* str,FILE* f, char endianess,char* eof)
{
char*utf8;
uint32_t utf8ByteLength;
int32_t bytesN;
if(endianess == RF_LITTLE_ENDIAN)
{
if((bytesN=rfFReadLine_UTF16LE(f,&utf8,&utf8ByteLength,eof)) < 0)
{
LOG_ERROR("Failure to append the contents of a Little Endian UTF-16 file to a String",bytesN);
return bytesN;
}
} else {
if((bytesN=rfFReadLine_UTF16BE(f,&utf8,&utf8ByteLength,eof)) < 0)
{
LOG_ERROR("Failure to append the contents of a Big Endian UTF-16 file to a String",bytesN);
return bytesN;
}
} rfString_Append(str,RFS_(utf8));
free(utf8);
return bytesN;
}
RF_String* rfString_Create_fUTF32(FILE* f,char endianess,char* eof)
{
RF_String* ret;
RF_MALLOC(ret,sizeof(RF_String));
if(rfString_Init_fUTF32(ret,f,endianess,eof) < 0)
{
free(ret);
return 0;
}
return ret;
}
int32_t rfString_Init_fUTF32(RF_String* str,FILE* f,char endianess,char* eof)
{
int32_t bytesN;
if(endianess == RF_LITTLE_ENDIAN)
{
if((bytesN=rfFReadLine_UTF32LE(f,&str->bytes,&str->byteLength,eof)) <0)
{
LOG_ERROR("Failure to initialize a String from reading a Little Endian UTF-32 file",bytesN);
return bytesN;
}
} else {
if((bytesN=rfFReadLine_UTF16BE(f,&str->bytes,&str->byteLength,eof)) < 0)
{
LOG_ERROR("Failure to initialize a String from reading a Big Endian UTF-32 file",bytesN);
return bytesN;
}
} return bytesN;
}
int32_t rfString_Assign_fUTF32(RF_String* str,FILE* f,char endianess, char* eof)
{
int32_t bytesN;
char*utf8;
uint32_t utf8ByteLength;
if(endianess == RF_LITTLE_ENDIAN)
{
if((bytesN=rfFReadLine_UTF32LE(f,&utf8,&utf8ByteLength,eof)) < 0)
{
LOG_ERROR("Failure to assign to a String from reading a Little Endian UTF-32 file",bytesN);
return bytesN;
}
} else {
if((bytesN=rfFReadLine_UTF16BE(f,&utf8,&utf8ByteLength,eof)) < 0)
{
LOG_ERROR("Failure to assign to a String from reading a Big Endian UTF-32 file",bytesN);
return bytesN;
}
} if(str->byteLength <= utf8ByteLength)
{
RF_REALLOC(str->bytes,char,utf8ByteLength+1);
}
memcpy(str->bytes,utf8,utf8ByteLength+1);
str->byteLength = utf8ByteLength;
free(utf8);
return bytesN;
}
int32_t rfString_Append_fUTF32(RF_String* str,FILE* f,char endianess, char* eof)
{
int32_t bytesN;
char*utf8;
uint32_t utf8ByteLength;
if(endianess == RF_LITTLE_ENDIAN)
{
if((bytesN=rfFReadLine_UTF32LE(f,&utf8,&utf8ByteLength,eof)) < 0)
{
LOG_ERROR("Failure to append to a String from reading a Little Endian UTF-32 file",bytesN);
return bytesN;
}
} else {
if((bytesN=rfFReadLine_UTF16BE(f,&utf8,&utf8ByteLength,eof)) < 0)
{
LOG_ERROR("Failure to append to a String from reading a Big Endian UTF-32 file",bytesN);
return bytesN;
}
} rfString_Append(str,RFS_(utf8));
free(utf8);
return bytesN;
}
int32_t i_rfString_Fwrite(void* sP,FILE* f,char* encodingP)
{
uint32_t *utf32,length,i;
uint16_t* utf16;
RF_String* s = (RF_String*)sP;
char encoding = *encodingP;
switch(encoding)
{
case RF_UTF8:
if(fwrite(s->bytes,1,s->byteLength,f) != s->byteLength)
break; return RF_SUCCESS;
break;
case RF_UTF16_LE:
utf16 = rfString_ToUTF16(s,&length);
if(rfUTILS_Endianess() != RF_LITTLE_ENDIAN)
{
for(i=0;i<length;i++)
{
rfUTILS_SwapEndianUS(&utf16[i]);
}
}
if(fwrite(utf16,2,length,f) != length)
{
free(utf16);
break; }
free(utf16);
return RF_SUCCESS;
break;
case RF_UTF16_BE:
utf16 = rfString_ToUTF16(s,&length);
if(rfUTILS_Endianess() != RF_BIG_ENDIAN)
{
for(i=0;i<length;i++)
{
rfUTILS_SwapEndianUS(&utf16[i]);
}
}
if(fwrite(utf16,2,length,f) != length)
{
free(utf16);
break; }
free(utf16);
return RF_SUCCESS;
break;
case RF_UTF32_LE:
utf32 = rfString_ToUTF32(s,&length);
if(rfUTILS_Endianess() != RF_LITTLE_ENDIAN)
{
for(i=0;i<length;i++)
{
rfUTILS_SwapEndianUI(&utf32[i]);
}
}
if(fwrite(utf32,4,length,f) != length)
{
free(utf32);
break; }
free(utf32);
return RF_SUCCESS;
break;
case RF_UTF32_BE:
utf32 = rfString_ToUTF32(s,&length);
if(rfUTILS_Endianess() != RF_BIG_ENDIAN)
{
for(i=0;i<length;i++)
{
rfUTILS_SwapEndianUI(&utf32[i]);
}
}
if(fwrite(utf32,4,length,f) != length)
{
free(utf32);
break; }
free(utf32);
return RF_SUCCESS;
break;
}
i_WRITE_CHECK(f,"Writting a string to a file")
return RE_FILE_WRITE;
}