📄 strptrlen.cpp
字号:
/* File: StrPtrLen.cpp Contains: Implementation of class defined in StrPtrLen.h. */#include <ctype.h>
#include <stdlib.h>#include "StrPtrLen.h"#include "OS.h"
StrPtrLen::~StrPtrLen()
{
// printf("ycb_Db %x\n", Ptr);
}
UInt8 StrPtrLen::sCaseInsensitiveMask[] ={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, //0-9 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, //10-19 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, //20-29 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, //30-39 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, //40-49 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, //50-59 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, //60-69 //stop on every character except a letter 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, //70-79 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, //80-89 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, //90-99 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, //100-109 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, //110-119 120, 121, 122, 123, 124, 125, 126, 127, 128, 129 //120-129};UInt8 StrPtrLen::sNonPrintChars[] ={ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, //0-9 // stop 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, //10-19 //'\r' & '\n' are not stop conditions 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //20-29 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, //30-39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40-49 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //50-59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //60-69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //70-79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //80-89 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //90-99 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //100-109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //110-119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //120-129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //130-139 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140-149 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150-159 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160-169 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, //170-179 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //180-189 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //190-199 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //200-209 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //210-219 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //220-229 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //230-239 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //240-249 1, 1, 1, 1, 1, 1 //250-255};char* StrPtrLen::GetAsCString() const{ // convert to a "NEW'd" zero terminated char array // caler is reponsible for the newly allocated memory char *theString = new char[Len+1]; if ( Ptr && Len > 0 ) ::memcpy( theString, Ptr, Len ); theString[Len] = 0; return theString;}Bool StrPtrLen::Equal(const StrPtrLen &compare) const{ if (NULL == compare.Ptr && NULL == Ptr ) return TRUE; if ((NULL == compare.Ptr) || (NULL == Ptr)) return FALSE; if ((compare.Len == Len) && (memcmp(compare.Ptr, Ptr, Len) == 0)) return TRUE; else return FALSE;}Bool StrPtrLen::Equal(const char* compare) const{ if (NULL == compare && NULL == Ptr ) return TRUE; if ((NULL == compare) || (NULL == Ptr)) return FALSE; if ((::strlen(compare) == Len) && (memcmp(compare, Ptr, Len) == 0)) return TRUE; else return FALSE;}Bool StrPtrLen::NumEqualIgnoreCase(const char* compare, const UInt32 len) const{ // compare thru the first "len: bytes Assert(compare != NULL); if (len <= Len) { for (UInt32 x = 0; x < len; x++) if (sCaseInsensitiveMask[Ptr[x]] != sCaseInsensitiveMask[compare[x]]) return FALSE; return TRUE; } return FALSE;}Bool StrPtrLen::EqualIgnoreCase(const char* compare, const UInt32 len) const{ Assert(compare != NULL); if (len == Len) { for (UInt32 x = 0; x < len; x++) if (sCaseInsensitiveMask[Ptr[x]] != sCaseInsensitiveMask[compare[x]]) return FALSE; return TRUE; } return FALSE;}char *StrPtrLen::FindStringCase(char *queryCharStr, StrPtrLen *resultStr, Bool caseSensitive) const{ // Be careful about exiting this method from the middle. This routine deletes allocated memory at the end. // if (resultStr) resultStr->Set(NULL,0); Assert (NULL != queryCharStr); if (NULL == queryCharStr) return NULL; if (NULL == Ptr) return NULL; if (0 == Len) return NULL; StrPtrLen queryStr(queryCharStr); char *editSource = NULL; char *resultChar = NULL; char lastSourceChar = Ptr[Len -1]; if (lastSourceChar != 0) // need to modify for termination. { editSource = new char[Len + 1]; // Ptr could be a static string so make a copy ::memcpy( editSource, Ptr, Len ); editSource[Len] = 0; // this won't work on static strings so we are modifing a new string here } char *queryString = queryCharStr; char *dupSourceString = NULL; char *dupQueryString = NULL; char *sourceString = Ptr; UInt32 foundLen = 0; if (editSource != NULL) // a copy of the source ptr and len 0 terminated sourceString = editSource; if (!caseSensitive) { dupSourceString = ::strdup(sourceString); dupQueryString = ::strdup(queryCharStr); if (dupSourceString && dupQueryString) { sourceString = StrPtrLen(dupSourceString).ToUpper(); queryString = StrPtrLen(dupQueryString).ToUpper(); resultChar = ::strstr(sourceString,queryString); ::free(dupSourceString); ::free(dupQueryString); } } else { resultChar = ::strstr(sourceString,queryString); } if (resultChar != NULL) // get the start offset { foundLen = resultChar - sourceString; resultChar = Ptr + foundLen; // return a pointer in the source buffer if (resultChar > (Ptr + Len)) // make sure it is in the buffer resultChar = NULL; } if (editSource != NULL) delete [] editSource; if (resultStr != NULL && resultChar != NULL) resultStr->Set(resultChar,queryStr.Len); #if STRPTRLENTESTING printf("StrPtrLen::FindStringCase found string=%s\n",resultChar);#endif return resultChar;}UInt32 StrPtrLen::RemoveWhitespace(){ if (Ptr == NULL || Len == 0) return 0; char *EndPtr = Ptr + Len; // one past last char char *destPtr = Ptr; char *srcPtr = Ptr; Len = 0; while (srcPtr < EndPtr) { if (*srcPtr != ' ' && *srcPtr != '\t') { if (srcPtr != destPtr) *destPtr = *srcPtr; destPtr++; Len ++; } srcPtr ++; } return Len;}UInt32 StrPtrLen::TrimLeadingWhitespace(){ if (Ptr == NULL || Len == 0) return 0; char *EndPtr = Ptr + Len; //one past last char while (Ptr < EndPtr) { if (*Ptr != ' ' && *Ptr != '\t') break; Ptr += 1; Len -= 1; } return Len;}UInt32 StrPtrLen::TrimTrailingWhitespace(){ if (Ptr == NULL || Len == 0) return 0; char *theCharPtr = Ptr + (Len - 1); // last char while (theCharPtr >= Ptr) { if (*theCharPtr != ' ' && *theCharPtr != '\t') break; theCharPtr -= 1; Len -= 1; } return Len;}void StrPtrLen::PrintStr(){ char *thestr = GetAsCString(); for (UInt32 i = 0; i < Len; i ++) { if (StrPtrLen::sNonPrintChars[Ptr[i]]) { thestr[i] = 0; break; } } if (thestr != NULL) { printf(thestr); delete[] thestr; } }void StrPtrLen::PrintStr(char *appendStr){ StrPtrLen::PrintStr(); if (appendStr != NULL) printf(appendStr);}void StrPtrLen::PrintStrEOL(char* stopStr, char *appendStr){ char *thestr = GetAsCString(); Int32 i = 0; for (; i < (Int32) Len; i ++) { if (StrPtrLen::sNonPrintChars[Ptr[i]]) { thestr[i] = 0; break; } } for (i = 0; thestr[i] != 0 ; i ++) { if (thestr[i] == '%' && thestr[i+1] != '%' ) { thestr[i] = '$'; } } Int32 stopLen = 0; if (stopStr != NULL) stopLen = ::strlen(stopStr); if (stopLen > 0 && stopLen <= i) { char* stopPtr = ::strstr(thestr, stopStr); if (stopPtr != NULL) { stopPtr += stopLen; *stopPtr = 0; i = stopPtr - thestr; } } char * theStrLine = thestr; char * nextLine = NULL; char * theChar = NULL; static char *cr="\\r"; static char *lf="\\n\n"; Int32 tempLen = i; for (i = 0; i < tempLen; i ++) { if (theStrLine[i] == '\r') { theChar = cr; theStrLine[i] = 0; nextLine = &theStrLine[i+1]; } else if (theStrLine[i] == '\n') { theChar = lf; theStrLine[i] = 0; nextLine = &theStrLine[i+1]; } if (nextLine != NULL) { printf(theStrLine); printf(theChar); theStrLine = nextLine; nextLine = NULL; tempLen -= (i+1); i = -1; } } printf(theStrLine); delete thestr; if (appendStr != NULL) printf(appendStr); }#if STRPTRLENTESTINGBool StrPtrLen::Test(){ static char* test1 = "2347.;.][';[;]abcdefghijklmnopqrstuvwxyz#%#$$#"; static char* test2 = "2347.;.][';[;]ABCDEFGHIJKLMNOPQRSTUVWXYZ#%#$$#"; static char* test3 = "Content-Type:"; static char* test4 = "cONTent-TYPe:"; static char* test5 = "cONTnnt-TYPe:"; static char* test6 = "cONTent-TY"; static char* test7 = "ontent-Type:"; static char* test8 = "ONTent-TYPe:"; static char* test9 = "-TYPe:"; static char* test10 = ":"; StrPtrLen theVictim1(test1, strlen(test1)); if (!theVictim1.EqualIgnoreCase(test2, strlen(test2))) return FALSE; if (theVictim1.EqualIgnoreCase(test3, strlen(test3))) return FALSE; if (!theVictim1.EqualIgnoreCase(test1, strlen(test1))) return FALSE; StrPtrLen theVictim2(test3, strlen(test3)); if (!theVictim2.EqualIgnoreCase(test4, strlen(test4))) return FALSE; if (theVictim2.EqualIgnoreCase(test5, strlen(test5))) return FALSE; if (theVictim2.EqualIgnoreCase(test6, strlen(test6))) return FALSE; StrPtrLen outResultStr; if (!theVictim1.FindStringIgnoreCase(test2, &outResultStr)) return FALSE; if (theVictim1.FindStringIgnoreCase(test3, &outResultStr)) return FALSE; if (!theVictim1.FindStringIgnoreCase(test1, &outResultStr)) return FALSE; if (!theVictim2.FindStringIgnoreCase(test4)) return FALSE; if (theVictim2.FindStringIgnoreCase(test5)) return FALSE; if (!theVictim2.FindStringIgnoreCase(test6)) return FALSE; if (!theVictim2.FindStringIgnoreCase(test7)) return FALSE; if (!theVictim2.FindStringIgnoreCase(test8)) return FALSE; if (!theVictim2.FindStringIgnoreCase(test9)) return FALSE; if (!theVictim2.FindStringIgnoreCase(test10)) return FALSE; if (theVictim1.FindString(test2, &outResultStr)) return FALSE; if (theVictim1.FindString(test3, &outResultStr)) return FALSE; if (!theVictim1.FindString(test1, &outResultStr)) return FALSE; if (theVictim2.FindString(test4)) return FALSE; if (theVictim2.FindString(test5)) return FALSE; if (theVictim2.FindString(test6)) return FALSE; if (!theVictim2.FindString(test7)) return FALSE; if (theVictim2.FindString(test8)) return FALSE; if (theVictim2.FindString(test9)) return FALSE; if (!theVictim2.FindString(test10)) return FALSE; StrPtrLen query; query.Set(test2); if (theVictim1.FindString(query, &outResultStr)) return FALSE; if (outResultStr.Len > 0) return FALSE; if (outResultStr.Ptr != NULL) return FALSE; query.Set(test3); if (theVictim1.FindString(query, &outResultStr)) return FALSE; if (outResultStr.Len > 0) return FALSE; if (outResultStr.Ptr != NULL) return FALSE; query.Set(test1); if (!theVictim1.FindString(query, &outResultStr)) return FALSE; if (!outResultStr.Equal(query)) return FALSE; query.Set(test4); if (query.Equal(theVictim2.FindString(query))) return FALSE; query.Set(test5); if (query.Equal(theVictim2.FindString(query))) return FALSE; query.Set(test6); if (query.Equal(theVictim2.FindString(query))) return FALSE; query.Set(test7); if (!query.Equal(theVictim2.FindString(query))) return FALSE; query.Set(test8); if (query.Equal(theVictim2.FindString(query))) return FALSE; query.Set(test9); if (query.Equal(theVictim2.FindString(query))) return FALSE; query.Set(test10); if (!query.Equal(theVictim2.FindString(query))) return FALSE; query.Set(test10); if (!query.Equal(theVictim2.FindString(query))) return FALSE; StrPtrLen partialStaticSource(test1,5); query.Set("abcd"); if (query.Equal(partialStaticSource.FindString(query))) return FALSE; query.Set("47"); if (query.Equal(partialStaticSource.FindString(query))) // success = !equal because the char str is longer than len return FALSE; if (query.FindString(partialStaticSource.FindString(query))) // success = !found because the 0 term src is not in query return FALSE; partialStaticSource.FindString(query,&outResultStr); if (!outResultStr.Equal(query)) // success =found the result Ptr and Len is the same as the query return FALSE; return TRUE;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -