MF_API MFString MFString_GetStats() { size_t overhead = stringPool.GetTotalMemory() + stringPool.GetOverheadMemory() + stringHeap.GetOverheadMemory(); size_t waste = 0, averageSize = 0; // calculate waste int numStrings = stringPool.GetNumAllocated(); for(int a=0; a<numStrings; ++a) { MFStringData *pString = (MFStringData*)stringPool.GetItem(a); size_t allocated = pString->allocated; if(allocated) { size_t bytes = pString->bytes+1; averageSize += bytes; waste += allocated - bytes; } } if(numStrings) averageSize /= numStrings; MFString desc; desc.Reserve(1024); desc = MFStr("String heap memory: " MFFMT_SIZE_T " allocated/" MFFMT_SIZE_T " reserved + " MFFMT_SIZE_T " overhead Waste: " MFFMT_SIZE_T " Average length: " MFFMT_SIZE_T "\n\tPool: %d/%d", stringHeap.GetAllocatedMemory(), stringHeap.GetTotalMemory(), overhead, waste, averageSize, stringPool.GetNumAllocated(), stringPool.GetNumReserved()); int numGroups = stringHeap.GetNumPools(); for(int a=0; a<numGroups; ++a) { MFObjectPool *pPool = stringHeap.GetPool(a); desc += MFStr("\n\t\t" MFFMT_SIZE_T " byte: %d/%d", pPool->GetObjectSize(), pPool->GetNumAllocated(), pPool->GetNumReserved()); } return desc; }
MFString MFString::SubStr(int offset, int count) const { if(!pData) return *this; // limit within the strings range int maxChars = (int)pData->bytes - offset; if(count < 0 || count > maxChars) count = maxChars; // bail if we don't need to do anything if(count == (int)pData->bytes) return *this; // allocate a new string MFString t; t.Reserve(count + 1); t.pData->bytes = count; // copy sub string MFString_CopyN(t.pData->pMemory, pData->pMemory + offset, count); t.pData->pMemory[count] = 0; return t; }
MFString MFString::Lower() const { if(!pData) return *this; // allocate a new string MFString t; t.Reserve(pData->bytes + 1); t.pData->bytes = pData->bytes; // copy lower case string for(size_t a=0; a<pData->bytes + 1; ++a) t.pData->pMemory[a] = (char)MFToLower(pData->pMemory[a]); return t; }
MFString MFString::operator+(const MFString &string) const { if(string.IsEmpty()) return *this; if(IsEmpty()) return string; size_t bytes = pData->bytes + string.pData->bytes; MFString t; t.Reserve(bytes + 1); MFString_CopyCat(t.pData->pMemory, pData->pMemory, string.pData->pMemory); t.pData->bytes = bytes; return t; }
MFString MFString::operator+(const char *pString) const { if(!pString || *pString == 0) return *this; if(IsEmpty()) return MFString(pString); size_t bytes = pData->bytes + MFString_Length(pString); MFString t; t.Reserve(bytes + 1); MFString_CopyCat(t.pData->pMemory, pData->pMemory, pString); t.pData->bytes = bytes; return t; }