When I was looking for the following source code in .NET source code, I didn't find source for PadHelper
that is the method inside PadLeft
and PadRight
.
Is there something wrong with my search?
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern String PadHelper(int totalWidth, char paddingChar, bool isRightPadded);
This doesn't seem to be a well documented thing. I also don't know more details and how this works, but take a look at this thread at CodeProject. The method seems to be located in comstring.cpp.
Unfortunately the post which has been linked in this thread is not available any more. This might have been an interesting one.
Edit: Found the full source here on github.
/*==================================PadHelper===================================
**Action:
**Returns:
**Arguments:
**Exceptions:
==============================================================================*/
FCIMPL4(Object*, COMString::PadHelper, StringObject* thisRefUNSAFE, INT32 totalWidth, CLR_CHAR paddingChar, CLR_BOOL isRightPadded)
{
CONTRACTL {
DISABLED(GC_TRIGGERS);
THROWS;
MODE_COOPERATIVE;
SO_TOLERANT;
} CONTRACTL_END;
STRINGREF refRetVal = NULL;
STRINGREF thisRef = (STRINGREF) thisRefUNSAFE;
HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_RETURNOBJ, thisRef);
//-[autocvtpro]-------------------------------------------------------
WCHAR *thisChars, *padChars;
INT32 thisLength;
if (thisRef==NULL) {
COMPlusThrow(kNullReferenceException, L"NullReference_This");
}
RefInterpretGetStringValuesDangerousForGC(thisRef, &thisChars, &thisLength);
//Don't let them pass in a negative totalWidth
if (totalWidth<0) {
COMPlusThrowArgumentOutOfRange(L"totalWidth", L"ArgumentOutOfRange_NeedNonNegNum");
}
//If the string is longer than the length which they requested, give them
//back the old string.
if (totalWidth<thisLength) {
refRetVal = thisRef;
goto lExit;
}
if (isRightPadded) {
refRetVal = NewString(&(thisRef), 0, thisLength, totalWidth);
padChars = refRetVal->GetBuffer();
for (int i=thisLength; i<totalWidth; i++) {
padChars[i] = paddingChar;
}
refRetVal->SetStringLength(totalWidth);
_ASSERTE(padChars[totalWidth] == 0);
} else {
refRetVal = NewString(totalWidth);
INT32 startingPos = totalWidth-thisLength;
padChars = refRetVal->GetBuffer();
// Reget thisChars, since if NewString triggers GC, thisChars may become trash.
RefInterpretGetStringValuesDangerousForGC(thisRef, &thisChars, &thisLength);
memcpyNoGCRefs(padChars+startingPos, thisChars, thisLength * sizeof(WCHAR));
for (int i=0; i<startingPos; i++) {
padChars[i] = paddingChar;
}
}
lExit: ;
//-[autocvtepi]-------------------------------------------------------
HELPER_METHOD_FRAME_END();
return OBJECTREFToObject(refRetVal);
}
FCIMPLEND