/*============================================================================== Copyright (c) 2016-2018, The Linux Foundation. Copyright (c) 2018-2020, Laurence Lundblade. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of The Linux Foundation nor the names of its contributors, nor the name "Laurence Lundblade" may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================*/ #include "UsefulBuf.h" /* Basic exercise... Call all the main public functions. Binary compare the result to the expected. There is nothing adversarial in this test */ const char * UOBTest_NonAdversarial() { const char *szReturn = NULL; UsefulBuf_MAKE_STACK_UB(outbuf,50); UsefulOutBuf UOB; UsefulOutBuf_Init(&UOB, outbuf); if(!UsefulOutBuf_AtStart(&UOB)) { szReturn = "Not at start"; goto Done; } // Put 7 bytes at beginning of buf UsefulOutBuf_AppendData(&UOB, "bluster", 7); if(UsefulOutBuf_AtStart(&UOB)) { szReturn = "At start"; goto Done; } // add a space to end UsefulOutBuf_AppendByte(&UOB, ' '); // Add 5 bytes to the end UsefulBufC UBC = {"hunny", 5}; UsefulOutBuf_AppendUsefulBuf(&UOB, UBC); // Insert 9 bytes at the beginning, slide the previous stuff right UsefulOutBuf_InsertData(&UOB, "heffalump", 9, 0); UsefulOutBuf_InsertByte(&UOB, ' ', 9); // Put 9 bytes in at position 10 -- just after "heffalump " UsefulBufC UBC2 = {"unbounce ", 9}; UsefulOutBuf_InsertUsefulBuf(&UOB, UBC2, 10); const UsefulBufC Expected = UsefulBuf_FROM_SZ_LITERAL("heffalump unbounce bluster hunny"); UsefulBufC U = UsefulOutBuf_OutUBuf(&UOB); if(UsefulBuf_IsNULLC(U) || UsefulBuf_Compare(Expected, U) || UsefulOutBuf_GetError(&UOB)) { szReturn = "OutUBuf"; } UsefulBuf_MAKE_STACK_UB(buf, 50); UsefulBufC Out = UsefulOutBuf_CopyOut(&UOB, buf); if(UsefulBuf_IsNULLC(Out) || UsefulBuf_Compare(Expected, Out)) { szReturn = "CopyOut"; } Done: return szReturn; } /* Append test utility. pUOB is the buffer to append too num is the amount to append expected is the expected return code, 0 or 1 returns 0 if test passed */ static int AppendTest(UsefulOutBuf *pUOB, size_t num, int expected) { //reset UsefulOutBuf_Reset(pUOB); // check status first if(UsefulOutBuf_GetError(pUOB)) return 1; // append the bytes UsefulOutBuf_AppendData(pUOB, (const uint8_t *)"bluster", num); // check error status after if(UsefulOutBuf_GetError(pUOB) != expected) return 1; return 0; } /* Same as append, but takes a position param too */ static int InsertTest(UsefulOutBuf *pUOB, size_t num, size_t pos, int expected) { // reset UsefulOutBuf_Reset(pUOB); // check if(UsefulOutBuf_GetError(pUOB)) return 1; UsefulOutBuf_InsertData(pUOB, (const uint8_t *)"bluster", num, pos); if(UsefulOutBuf_GetError(pUOB) != expected) return 1; return 0; } /* Boundary conditions to test - around 0 - around the buffer size - around MAX size_t Test these for the buffer size and the cursor, the insert amount, the append amount and the insert position */ const char *UOBTest_BoundaryConditionsTest() { UsefulBuf_MAKE_STACK_UB(outbuf,2); UsefulOutBuf UOB; UsefulOutBuf_Init(&UOB, outbuf); // append 0 byte to a 2 byte buffer --> success if(AppendTest(&UOB, 0, 0)) return "Append 0 bytes failed"; // append 1 byte to a 2 byte buffer --> success if(AppendTest(&UOB, 1, 0)) return "Append of 1 byte failed"; // append 2 byte to a 2 byte buffer --> success if(AppendTest(&UOB, 2, 0)) return "Append to fill buffer failed"; // append 3 bytes to a 2 byte buffer --> failure if(AppendTest(&UOB, 3, 1)) return "Overflow of buffer not caught"; // append max size_t to a 2 byte buffer --> failure if(AppendTest(&UOB, SIZE_MAX, 1)) return "Append of SIZE_MAX error not caught"; if(InsertTest(&UOB, 1, 0, 0)) return "Insert 1 byte at start failed"; if(InsertTest(&UOB, 2, 0, 0)) return "Insert 2 bytes at start failed"; if(InsertTest(&UOB, 3, 0, 1)) return "Insert overflow not caught"; if(InsertTest(&UOB, 1, 1, 1)) return "Bad insertion point not caught"; UsefulBuf_MAKE_STACK_UB(outBuf2,10); UsefulOutBuf_Init(&UOB, outBuf2); UsefulOutBuf_Reset(&UOB); // put data in the buffer UsefulOutBuf_AppendString(&UOB, "abc123"); UsefulOutBuf_InsertString(&UOB, "xyz*&^", 0); if(!UsefulOutBuf_GetError(&UOB)) { return "insert with data should have failed"; } UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5}); UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -6); if(UsefulOutBuf_GetError(&UOB)) { return "insert in huge should have succeeded"; } UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5}); UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX -5); if(UsefulOutBuf_GetError(&UOB)) { return "insert in huge should have succeeded"; } UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, SIZE_MAX - 5}); UsefulOutBuf_AppendData(&UOB, "123456789", SIZE_MAX - 4); if(!UsefulOutBuf_GetError(&UOB)) { return "lengths near max size"; } UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, 100}); if(!UsefulOutBuf_IsBufferNULL(&UOB)) { return "NULL check failed"; } return NULL; } // Test function to get size and magic number check const char *TestBasicSanity() { UsefulBuf_MAKE_STACK_UB(outbuf,10); UsefulOutBuf UOB; // First -- make sure that the room left function returns the right amount UsefulOutBuf_Init(&UOB, outbuf); if(UsefulOutBuf_RoomLeft(&UOB) != 10) return "room left failed"; if(!UsefulOutBuf_WillItFit(&UOB, 9)) { return "it did not fit"; } if(UsefulOutBuf_WillItFit(&UOB, 11)) { return "it should have not fit"; } // Next -- make sure that the magic number checking is working right UOB.magic = 8888; // make magic bogus UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7); if(!UsefulOutBuf_GetError(&UOB)) return "magic corruption check failed"; // Next make sure that the valid data length check is working right UsefulOutBuf_Init(&UOB, outbuf); UOB.data_len = UOB.UB.len+1; // make size bogus UsefulOutBuf_AppendData(&UOB, (const uint8_t *)"bluster", 7); if(!UsefulOutBuf_GetError(&UOB)) return "valid data check failed"; return NULL; } const char *UBMacroConversionsTest() { char *szFoo = "foo"; UsefulBufC Foo = UsefulBuf_FromSZ(szFoo); if(Foo.len != 3 || strncmp(Foo.ptr, szFoo, 3)) return "SZToUsefulBufC failed"; UsefulBufC Too = UsefulBuf_FROM_SZ_LITERAL("Toooo"); if(Too.len != 5 || strncmp(Too.ptr, "Toooo", 5)) return "UsefulBuf_FROM_SZ_LITERAL failed"; uint8_t pB[] = {0x42, 0x6f, 0x6f}; UsefulBufC Boo = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pB); if(Boo.len != 3 || strncmp(Boo.ptr, "Boo", 3)) return "UsefulBuf_FROM_BYTE_ARRAY_LITERAL failed"; UsefulBuf B = (UsefulBuf){(void *)Too.ptr, Too.len}; UsefulBufC BC = UsefulBuf_Const(B); if(BC.len != Too.len || BC.ptr != Too.ptr) return "UsefulBufConst failed"; return NULL; } const char *UBUtilTests() { UsefulBuf UB = NULLUsefulBuf; if(!UsefulBuf_IsNULL(UB)){ return "IsNull failed"; } if(!UsefulBuf_IsEmpty(UB)){ return "IsEmpty failed"; } if(!UsefulBuf_IsNULLOrEmpty(UB)) { return "IsNULLOrEmpty failed"; } const UsefulBufC UBC = UsefulBuf_Const(UB); if(!UsefulBuf_IsNULLC(UBC)){ return "IsNull const failed"; } if(!UsefulBuf_IsEmptyC(UBC)){ return "IsEmptyC failed"; } if(!UsefulBuf_IsNULLOrEmptyC(UBC)){ return "IsNULLOrEmptyC failed"; } const UsefulBuf UB2 = UsefulBuf_Unconst(UBC); if(!UsefulBuf_IsEmpty(UB2)) { return "Back to UB is Empty failed"; } UB.ptr = "x"; // just some valid pointer if(UsefulBuf_IsNULL(UB)){ return "IsNull failed"; } if(!UsefulBuf_IsEmptyC(UBC)){ return "IsEmpty failed"; } // test the Unconst. if(UsefulBuf_Unconst(UBC).ptr != NULL) { return "Unconst failed"; } // Set 100 bytes of '+'; validated a few tests later UsefulBuf_MAKE_STACK_UB(Temp, 100); const UsefulBufC TempC = UsefulBuf_Set(Temp, '+'); // Try to copy into a buf that is too small and see failure UsefulBuf_MAKE_STACK_UB(Temp2, 99); if(!UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp2, TempC))) { return "Copy should have failed"; } if(UsefulBuf_IsNULLC(UsefulBuf_CopyPtr(Temp2, "xx", 2))) { return "CopyPtr failed"; } UsefulBufC xxyy = UsefulBuf_CopyOffset(Temp2, 2, UsefulBuf_FROM_SZ_LITERAL("yy")); if(UsefulBuf_IsNULLC(xxyy)) { return "CopyOffset Failed"; } if(UsefulBuf_Compare(UsefulBuf_Head(xxyy, 3), UsefulBuf_FROM_SZ_LITERAL("xxy"))) { return "head failed"; } if(UsefulBuf_Compare(UsefulBuf_Tail(xxyy, 1), UsefulBuf_FROM_SZ_LITERAL("xyy"))) { return "tail failed"; } if(!UsefulBuf_IsNULLC(UsefulBuf_Head(xxyy, 5))) { return "head should have failed"; } if(!UsefulBuf_IsNULLC(UsefulBuf_Tail(xxyy, 5))) { return "tail should have failed"; } if(!UsefulBuf_IsNULLC(UsefulBuf_Tail(NULLUsefulBufC, 0))) { return "tail of NULLUsefulBufC is not NULLUsefulBufC"; } const UsefulBufC TailResult = UsefulBuf_Tail((UsefulBufC){NULL, 100}, 99); if(TailResult.ptr != NULL || TailResult.len != 1) { return "tail of NULL and length incorrect"; } if(!UsefulBuf_IsNULLC(UsefulBuf_CopyOffset(Temp2, 100, UsefulBuf_FROM_SZ_LITERAL("yy")))) { return "Copy Offset should have failed"; } // Try to copy into a NULL/empty buf and see failure const UsefulBuf UBNull = NULLUsefulBuf; if(!UsefulBuf_IsNULLC(UsefulBuf_Copy(UBNull, TempC))) { return "Copy to NULL should have failed"; } // Try to set a NULL/empty buf; nothing should happen UsefulBuf_Set(UBNull, '+'); // This will crash on failure // Copy successfully to a buffer UsefulBuf_MAKE_STACK_UB(Temp3, 101); if(UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp3, TempC))) { return "Copy should not have failed"; } static const uint8_t pExpected[] = { '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', }; UsefulBufC Expected = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpected); // This validates comparison for equality and the UsefulBuf_Set if(UsefulBuf_Compare(Expected, TempC)) { return "Set / Copy / Compare failed"; } // Compare two empties and expect success if(UsefulBuf_Compare(NULLUsefulBufC, NULLUsefulBufC)){ return "Compare Empties failed"; } // Compare with empty and expect the first to be larger if(UsefulBuf_Compare(Expected, NULLUsefulBufC) <= 0){ return "Compare with empty failed"; } static const uint8_t pExpectedBigger[] = { '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', ',', }; const UsefulBufC ExpectedBigger = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedBigger); // Expect -1 when the first arg is smaller if(UsefulBuf_Compare(Expected, ExpectedBigger) >= 0){ return "Compare with bigger"; } static const uint8_t pExpectedSmaller[] = { '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '*', }; const UsefulBufC ExpectedSmaller = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedSmaller); // Expect +1 when the first arg is larger if(UsefulBuf_Compare(Expected, ExpectedSmaller) <= 0){ return "Compare with smaller"; } static const uint8_t pExpectedLonger[] = { '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+' }; const UsefulBufC ExpectedLonger = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedLonger); // Expect -1 when the first arg is smaller if(UsefulBuf_Compare(Expected, ExpectedLonger) >= 0){ return "Compare with longer"; } static const uint8_t pExpectedShorter[] = { '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', '+', }; const UsefulBufC ExpectedShorter = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedShorter); // Expect +1 with the first arg is larger if(UsefulBuf_Compare(Expected, ExpectedShorter) <= 0){ return "Compare with shorter"; } if(UsefulBuf_IsNULLC(UsefulBuf_Copy(Temp, NULLUsefulBufC))) { return "Copy null/empty failed"; } if(UsefulBuf_IsValue(ExpectedShorter, '+') != SIZE_MAX) { return "IsValue failed to match all"; } if(UsefulBuf_IsValue(ExpectedShorter, '-') != 0) { return "IsValue should have failed right away"; } if(UsefulBuf_IsValue(NULLUsefulBufC, 0x00) != 0) { return "IsValue failed on NULLUsefulBufC"; } if(UsefulBuf_IsValue((UsefulBufC){(uint8_t[]){0x00}, 1}, 0x00) != SIZE_MAX) { return "IsValue failed finding 0 in one byte of 0"; } if(UsefulBuf_IsValue((UsefulBufC){(uint8_t[]){0x00}, 1}, 0x01) != 0) { return "IsValue failed not finding 1 in one byte of 0"; } if(UsefulBuf_IsValue(ExpectedSmaller, '+') != ExpectedSmaller.len -1) { return "IsValue failed to find final *"; } // Look for +++++... in +++++... and find it at the beginning if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedShorter)){ return "Failed to find"; } // look for ++* in ....++* and find it at the end static const uint8_t pToFind[] = {'+', '+', '*'}; const UsefulBufC ToBeFound = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pToFind); if(97 != UsefulBuf_FindBytes(ExpectedSmaller, ToBeFound)){ return "Failed to find 2"; } // look for ++* in ....++, and find it near the end if(SIZE_MAX != UsefulBuf_FindBytes(ExpectedBigger, ToBeFound)){ return "Failed to not find"; } // Look for the whole buffer in itself and succeed. if(0 != UsefulBuf_FindBytes(ExpectedLonger, ExpectedLonger)){ return "Failed to find 3"; } return NULL; } const char * UIBTest_IntegerFormat() { UsefulOutBuf_MakeOnStack(UOB,100); const uint32_t u32 = 0x0A0B0C0D; // from https://en.wikipedia.org/wiki/Endianness const uint64_t u64 = 1984738472938472; const uint16_t u16 = 40000; const uint8_t u8 = 9; const float f = (float)314.15; const double d = 2.1e10; UsefulOutBuf_AppendUint32(&UOB, u32); // Also tests UsefulOutBuf_InsertUint64 and UsefulOutBuf_GetEndPosition UsefulOutBuf_AppendUint64(&UOB, u64); // Also tests UsefulOutBuf_InsertUint32 UsefulOutBuf_AppendUint16(&UOB, u16); // Also tests UsefulOutBuf_InsertUint16 UsefulOutBuf_AppendByte(&UOB, u8); UsefulOutBuf_AppendFloat(&UOB, f); // Also tests UsefulOutBuf_InsertFloat UsefulOutBuf_AppendDouble(&UOB, d); // Also tests UsefulOutBuf_InsertDouble const UsefulBufC O = UsefulOutBuf_OutUBuf(&UOB); if(UsefulBuf_IsNULLC(O)) return "Couldn't output integers"; // from https://en.wikipedia.org/wiki/Endianness const uint8_t pExpectedNetworkOrder[4] = {0x0A, 0x0B, 0x0C, 0x0D}; if(memcmp(O.ptr, pExpectedNetworkOrder, 4)) { return "not in network order"; } UsefulInputBuf UIB; UsefulInputBuf_Init(&UIB, O); if(UsefulInputBuf_Tell(&UIB) != 0) { return "UsefulInputBuf_Tell failed"; } if(UsefulInputBuf_GetUint32(&UIB) != u32) { return "u32 out then in failed"; } if(UsefulInputBuf_GetUint64(&UIB) != u64) { return "u64 out then in failed"; } if(UsefulInputBuf_GetUint16(&UIB) != u16) { return "u16 out then in failed"; } if(UsefulInputBuf_GetByte(&UIB) != u8) { return "u8 out then in failed"; } if(UsefulInputBuf_GetFloat(&UIB) != f) { return "float out then in failed"; } if(UsefulInputBuf_GetDouble(&UIB) != d) { return "double out then in failed"; } // Reset and go again for a few more tests UsefulInputBuf_Init(&UIB, O); const UsefulBufC Four = UsefulInputBuf_GetUsefulBuf(&UIB, 4); if(UsefulBuf_IsNULLC(Four)) { return "Four is NULL"; } if(UsefulBuf_Compare(Four, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pExpectedNetworkOrder))) { return "Four compare failed"; } if(UsefulInputBuf_BytesUnconsumed(&UIB) != 23){ return "Wrong number of unconsumed bytes"; } if(!UsefulInputBuf_BytesAvailable(&UIB, 23)){ return "Wrong number of bytes available I"; } if(UsefulInputBuf_BytesAvailable(&UIB, 24)){ return "Wrong number of bytes available II"; } UsefulInputBuf_Seek(&UIB, 0); if(UsefulInputBuf_GetError(&UIB)) { return "unexpected error after seek"; } const uint8_t *pGetBytes = (const uint8_t *)UsefulInputBuf_GetBytes(&UIB, 4); if(pGetBytes == NULL) { return "GetBytes returns NULL"; } if(memcmp(pGetBytes, pExpectedNetworkOrder, 4)) { return "Got wrong bytes"; } UsefulInputBuf_Seek(&UIB, 28); if(!UsefulInputBuf_GetError(&UIB)) { return "expected error after seek"; } return NULL; } const char *UBUTest_CopyUtil() { if(UsefulBufUtil_CopyFloatToUint32(65536.0F) != 0x47800000) { return "CopyFloatToUint32 failed"; } #if !defined(__ICCARM__) || (__SUBNORMAL_FLOATING_POINTS__ == 1) if(UsefulBufUtil_CopyDoubleToUint64(4e-40F) != 0X37C16C2800000000ULL) { return "CopyDoubleToUint64 failed"; } if(UsefulBufUtil_CopyUint64ToDouble(0X37C16C2800000000ULL) != 4e-40F) { return "CopyUint64ToDouble failed"; } #endif if(UsefulBufUtil_CopyUint32ToFloat(0x47800000) != 65536.0F) { return "CopyUint32ToFloat failed"; } return NULL; }