DWORD WINAPI UndecorateSymbolNameUnicode( LPCWSTR name, LPWSTR outputString, DWORD maxStringLength, DWORD flags ) { LPSTR AnsiName; LPSTR AnsiOutputString; int AnsiNameLength; DWORD rc; AnsiNameLength = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_SEPCHARS, name, -1, NULL, 0, NULL, NULL ); if (!AnsiNameLength) return 0; AnsiName = (char *)AllocIt( AnsiNameLength ); if (!AnsiName) { SetLastError( ERROR_NOT_ENOUGH_MEMORY ); return 0; } ZeroMemory( AnsiName, AnsiNameLength ); if (!WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_SEPCHARS, name, -1, AnsiName, AnsiNameLength, NULL, NULL )) { FreeIt( AnsiName ); return 0; } AnsiOutputString = (LPSTR)AllocIt( maxStringLength + 1 ); if (!AnsiOutputString) { FreeIt( AnsiName ); SetLastError( ERROR_NOT_ENOUGH_MEMORY ); return 0; } *AnsiOutputString = '\0'; rc = UndecorateSymbolName( AnsiName, AnsiOutputString, maxStringLength, flags ); MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, AnsiOutputString, -1, outputString, maxStringLength ); FreeIt( AnsiName ); FreeIt( AnsiOutputString ); return rc; }
int main() { RTR3InitExeNoArguments(0); RTPrintf("tstMemAutoPtr: TESTING...\n"); #define CHECK_EXPR(expr) \ do { bool const f = !!(expr); if (!f) { RTPrintf("tstMemAutoPtr(%d): %s!\n", __LINE__, #expr); g_cErrors++; } } while (0) /* * Some simple stuff. */ { RTCMemAutoPtr<char> NilObj; CHECK_EXPR(!NilObj); CHECK_EXPR(NilObj.get() == NULL); CHECK_EXPR(NilObj.release() == NULL); NilObj.reset(); } { RTCMemAutoPtr<char> Alloc(10); CHECK_EXPR(Alloc.get() != NULL); char *pch = Alloc.release(); CHECK_EXPR(pch != NULL); CHECK_EXPR(Alloc.get() == NULL); RTCMemAutoPtr<char> Manage(pch); CHECK_EXPR(Manage.get() == pch); CHECK_EXPR(&Manage[0] == pch); CHECK_EXPR(&Manage[1] == &pch[1]); CHECK_EXPR(&Manage[9] == &pch[9]); } /* * Use the electric fence memory API to check alternative template * arguments and also check some subscript / reference limit thing. */ { RTCMemAutoPtr<char, RTCMemEfAutoFree<char>, RTMemEfReallocNP> Electric(10); CHECK_EXPR(Electric.get() != NULL); Electric[0] = '0'; CHECK_EXPR(Electric[0] == '0'); CHECK_EXPR(*Electric == '0'); //CHECK_EXPR(Electric == '0'); Electric[9] = '1'; CHECK_EXPR(Electric[9] == '1'); /* Electric[10] = '2'; - this will crash (of course) */ } /* * Check that memory is actually free when it should be and isn't when it shouldn't. * Use the electric heap to get some extra checks. */ g_cFrees = 0; { RTCMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt(128); FreeIt[127] = '0'; } CHECK_EXPR(g_cFrees == 1); g_cFrees = 0; { RTCMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt2(128); FreeIt2[127] = '1'; FreeIt2.reset(); FreeIt2.alloc(128); FreeIt2[127] = '2'; FreeIt2.reset(FreeIt2.get()); /* this one is weird, but it's how things works... */ } CHECK_EXPR(g_cFrees == 2); g_cFrees = 0; { RTCMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> DontFreeIt(256); DontFreeIt[255] = '0'; RTMemEfFreeNP(DontFreeIt.release()); } CHECK_EXPR(g_cFrees == 0); g_cFrees = 0; { RTCMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt3(128); FreeIt3[127] = '0'; CHECK_EXPR(FreeIt3.realloc(128)); FreeIt3[127] = '0'; CHECK_EXPR(FreeIt3.realloc(256)); FreeIt3[255] = '0'; CHECK_EXPR(FreeIt3.realloc(64)); FreeIt3[63] = '0'; CHECK_EXPR(FreeIt3.realloc(32)); FreeIt3[31] = '0'; } CHECK_EXPR(g_cFrees == 1); g_cFrees = 0; { RTCMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt4; CHECK_EXPR(FreeIt4.alloc(123)); CHECK_EXPR(FreeIt4.realloc(543)); FreeIt4 = (char *)NULL; CHECK_EXPR(FreeIt4.get() == NULL); } CHECK_EXPR(g_cFrees == 1); /* * Check the ->, [] and * (unary) operators with some useful struct. */ { RTCMemAutoPtr<TSTMEMAUTOPTRSTRUCT> Struct1(1); Struct1->a = 0x11223344; Struct1->b = 0x55667788; Struct1->c = 0x99aabbcc; CHECK_EXPR(Struct1->a == 0x11223344); CHECK_EXPR(Struct1->b == 0x55667788); CHECK_EXPR(Struct1->c == 0x99aabbcc); Struct1[0].a = 0x11223344; Struct1[0].b = 0x55667788; Struct1[0].c = 0x99aabbcc; CHECK_EXPR(Struct1[0].a == 0x11223344); CHECK_EXPR(Struct1[0].b == 0x55667788); CHECK_EXPR(Struct1[0].c == 0x99aabbcc); (*Struct1).a = 0x11223344; (*Struct1).b = 0x55667788; (*Struct1).c = 0x99aabbcc; CHECK_EXPR((*Struct1).a == 0x11223344); CHECK_EXPR((*Struct1).b == 0x55667788); CHECK_EXPR((*Struct1).c == 0x99aabbcc); /* since at it... */ Struct1.get()->a = 0x11223344; Struct1.get()->b = 0x55667788; Struct1.get()->c = 0x99aabbcc; CHECK_EXPR(Struct1.get()->a == 0x11223344); CHECK_EXPR(Struct1.get()->b == 0x55667788); CHECK_EXPR(Struct1.get()->c == 0x99aabbcc); } /* * Check the zeroing of memory. */ { RTCMemAutoPtr<uint64_t, RTCMemAutoDestructor<uint64_t>, tstMemAutoPtrAllocatorNoZero> Zeroed1(1, true); CHECK_EXPR(*Zeroed1 == 0); } { RTCMemAutoPtr<uint64_t, RTCMemAutoDestructor<uint64_t>, tstMemAutoPtrAllocatorNoZero> Zeroed2; Zeroed2.alloc(5, true); CHECK_EXPR(Zeroed2[0] == 0); CHECK_EXPR(Zeroed2[1] == 0); CHECK_EXPR(Zeroed2[2] == 0); CHECK_EXPR(Zeroed2[3] == 0); CHECK_EXPR(Zeroed2[4] == 0); } /* * Summary. */ if (!g_cErrors) RTPrintf("tstMemAutoPtr: SUCCESS\n"); else RTPrintf("tstMemAutoPtr: FAILED - %d errors\n", g_cErrors); return !!g_cErrors; }