2

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);
Rufus L
  • 36,127
  • 5
  • 30
  • 43
  • No, nothing wrong with your search. That's a method inside an external assembly (not part of the .net framework) and the source code is not publicly available (at least as far as I know). – Rufus L Apr 09 '19 at 22:00

1 Answers1

6

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
aYo
  • 199
  • 1
  • 7