00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00047 #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_BYTE_FORMAT_FUNCTIONS
00048 #define STLSOFT_INCL_STLSOFT_CONVERSION_HPP_BYTE_FORMAT_FUNCTIONS
00049
00050 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00051 # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_BYTE_FORMAT_FUNCTIONS_MAJOR 1
00052 # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_BYTE_FORMAT_FUNCTIONS_MINOR 0
00053 # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_BYTE_FORMAT_FUNCTIONS_REVISION 8
00054 # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_BYTE_FORMAT_FUNCTIONS_EDIT 15
00055 #endif
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00066 # include <stlsoft/stlsoft.h>
00067 #endif
00068 #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_SAP_CAST
00069 # include <stlsoft/conversion/sap_cast.hpp>
00070 #endif
00071
00072 #ifndef STLSOFT_INCL_H_STRING
00073 # define STLSOFT_INCL_H_STRING
00074 # include <string.h>
00075 # endif
00076
00077 #if defined(STLSOFT_COMPILER_IS_BORLAND)
00078 # ifndef STLSOFT_INCL_H_MEMORY
00079 # include <memory.h>
00080 # endif
00081 #endif
00082
00083
00084
00085 #ifdef STLSOFT_CONVERSION_BYTE_FORMAT_FUNCTIONS_USE_SPRINTF
00086 # ifndef STLSOFT_INCL_H_STDIO
00087 # define STLSOFT_INCL_H_STDIO
00088 # include <stdio.h>
00089 # endif
00090 #endif
00091
00092
00093
00094
00095
00096 #ifndef _STLSOFT_NO_NAMESPACE
00097 namespace stlsoft
00098 {
00099 #endif
00100
00101
00102
00103
00104
00105 #ifndef _STLSOFT_NO_NAMESPACE
00106 namespace conversion
00107 {
00108 namespace format
00109 {
00110 namespace impl
00111 {
00112 #endif
00113
00114 inline char const* format_hex_chars(bool requestUppercaseAlpha)
00115 {
00116 static const char s_lower[] = "0123456789abcdef";
00117 static const char s_upper[] = "0123456789ABCDEF";
00118
00119 return requestUppercaseAlpha ? s_upper : s_lower;
00120 }
00121
00122 inline void format_hex_uint8(char buff[2], ss_byte_t const* py, bool requestUppercaseAlpha)
00123 {
00124 STLSOFT_ASSERT(NULL != py);
00125
00126 const char* bytes = format_hex_chars(requestUppercaseAlpha);
00127 const ss_uint8_t byte0 = py[0];
00128
00129 buff[1] = bytes[(byte0 >> 0) & 0x0f];
00130 buff[0] = bytes[(byte0 >> 4) & 0x0f];
00131 }
00132
00133 inline void format_hex_uint16(char buff[4], ss_byte_t const* py, bool requestUppercaseAlpha, bool highByteFirst)
00134 {
00135 const char* bytes = format_hex_chars(requestUppercaseAlpha);
00136 const ss_uint8_t byte0 = py[highByteFirst ? 1 : 0];
00137 const ss_uint8_t byte1 = py[highByteFirst ? 0 : 1];
00138
00139 buff[1] = bytes[(byte1 >> 0) & 0x0f];
00140 buff[0] = bytes[(byte1 >> 4) & 0x0f];
00141
00142 buff[3] = bytes[(byte0 >> 0) & 0x0f];
00143 buff[2] = bytes[(byte0 >> 4) & 0x0f];
00144 }
00145
00146 inline void format_hex_uint32(char buff[8], ss_byte_t const* py, bool requestUppercaseAlpha, bool highByteFirst)
00147 {
00148 const char* bytes = format_hex_chars(requestUppercaseAlpha);
00149 const ss_uint8_t byte0 = py[highByteFirst ? 3 : 0];
00150 const ss_uint8_t byte1 = py[highByteFirst ? 2 : 1];
00151 const ss_uint8_t byte2 = py[highByteFirst ? 1 : 2];
00152 const ss_uint8_t byte3 = py[highByteFirst ? 0 : 3];
00153
00154 buff[1] = bytes[(byte3 >> 0) & 0x0f];
00155 buff[0] = bytes[(byte3 >> 4) & 0x0f];
00156
00157 buff[3] = bytes[(byte2 >> 0) & 0x0f];
00158 buff[2] = bytes[(byte2 >> 4) & 0x0f];
00159
00160 buff[5] = bytes[(byte1 >> 0) & 0x0f];
00161 buff[4] = bytes[(byte1 >> 4) & 0x0f];
00162
00163 buff[7] = bytes[(byte0 >> 0) & 0x0f];
00164 buff[6] = bytes[(byte0 >> 4) & 0x0f];
00165 }
00166
00167 inline void format_hex_uint64(char buff[16], ss_byte_t const* py, bool requestUppercaseAlpha, bool highByteFirst)
00168 {
00169 #if 0
00170 format_hex_uint32(buff + (highByteFirst ? 8 : 0), py + (highByteFirst ? 0 : 4), requestUppercaseAlpha, highByteFirst);
00171 format_hex_uint32(buff + (highByteFirst ? 0 : 8), py + (highByteFirst ? 4 : 0), requestUppercaseAlpha, highByteFirst);
00172 #else
00173 const char* bytes = format_hex_chars(requestUppercaseAlpha);
00174 const ss_uint8_t byte0 = py[highByteFirst ? 7 : 0];
00175 const ss_uint8_t byte1 = py[highByteFirst ? 6 : 1];
00176 const ss_uint8_t byte2 = py[highByteFirst ? 5 : 2];
00177 const ss_uint8_t byte3 = py[highByteFirst ? 4 : 3];
00178 const ss_uint8_t byte4 = py[highByteFirst ? 3 : 4];
00179 const ss_uint8_t byte5 = py[highByteFirst ? 2 : 5];
00180 const ss_uint8_t byte6 = py[highByteFirst ? 1 : 6];
00181 const ss_uint8_t byte7 = py[highByteFirst ? 0 : 7];
00182
00183 buff[1] = bytes[(byte7 >> 0) & 0x0f];
00184 buff[0] = bytes[(byte7 >> 4) & 0x0f];
00185
00186 buff[3] = bytes[(byte6 >> 0) & 0x0f];
00187 buff[2] = bytes[(byte6 >> 4) & 0x0f];
00188
00189 buff[5] = bytes[(byte5 >> 0) & 0x0f];
00190 buff[4] = bytes[(byte5 >> 4) & 0x0f];
00191
00192 buff[7] = bytes[(byte4 >> 0) & 0x0f];
00193 buff[6] = bytes[(byte4 >> 4) & 0x0f];
00194
00195 buff[9] = bytes[(byte3 >> 0) & 0x0f];
00196 buff[8] = bytes[(byte3 >> 4) & 0x0f];
00197
00198 buff[11] = bytes[(byte2 >> 0) & 0x0f];
00199 buff[10] = bytes[(byte2 >> 4) & 0x0f];
00200
00201 buff[13] = bytes[(byte1 >> 0) & 0x0f];
00202 buff[12] = bytes[(byte1 >> 4) & 0x0f];
00203
00204 buff[15] = bytes[(byte0 >> 0) & 0x0f];
00205 buff[14] = bytes[(byte0 >> 4) & 0x0f];
00206 #endif
00207 }
00208
00209 inline void format_hex_uint128(char buff[16], ss_byte_t const* py, bool requestUppercaseAlpha, bool highByteFirst)
00210 {
00211 format_hex_uint64(buff + (highByteFirst ? 16 : 0), py + (highByteFirst ? 0 : 8), requestUppercaseAlpha, highByteFirst);
00212 format_hex_uint64(buff + (highByteFirst ? 0 : 16), py + (highByteFirst ? 8 : 0), requestUppercaseAlpha, highByteFirst);
00213 }
00214
00215 inline void format_hex_uint256(char buff[16], ss_byte_t const* py, bool requestUppercaseAlpha, bool highByteFirst)
00216 {
00217 format_hex_uint128(buff + (highByteFirst ? 32 : 0), py + (highByteFirst ? 0 : 16), requestUppercaseAlpha, highByteFirst);
00218 format_hex_uint128(buff + (highByteFirst ? 0 : 32), py + (highByteFirst ? 16 : 0), requestUppercaseAlpha, highByteFirst);
00219 }
00220
00221
00222 #ifndef _STLSOFT_NO_NAMESPACE
00223 }
00224 }
00225 }
00226 #endif
00227
00246 inline ss_size_t format_bytes( void const* pv
00247 , ss_size_t cb
00248 , char* buff
00249 , ss_size_t cchBuff
00250 , ss_size_t byteGrouping
00251 , char const* groupSeparator
00252 , int groupsPerLine = -1
00253 , char const* lineSeparator = "\n") stlsoft_throw_0()
00254
00255
00256 {
00257 STLSOFT_ASSERT( 0 == byteGrouping
00258 || 1 == byteGrouping
00259 || 2 == byteGrouping
00260 || 4 == byteGrouping
00261 || 8 == byteGrouping
00262 || 16 == byteGrouping
00263 || 32 == byteGrouping);
00264
00265 #ifdef _DEBUG
00266 ::memset(buff, '~', cchBuff);
00267 #endif
00268
00269 if(0 == cb)
00270 {
00271 return 0;
00272 }
00273 else
00274 {
00275 if(0 == byteGrouping)
00276 {
00277 byteGrouping = sizeof(int);
00278 }
00279
00280 const ss_size_t cchSeparator = (NULL == groupSeparator) ? (groupSeparator = "", 0) : ::strlen(groupSeparator);
00281 const ss_size_t cchLineSeparator = (NULL == lineSeparator) ? 0 : ::strlen(lineSeparator);
00282 const ss_size_t numGroups = (cb + (byteGrouping - 1)) / byteGrouping;
00283 const ss_size_t numLines = (groupsPerLine < 1) ? 1 : (numGroups + (groupsPerLine - 1)) / groupsPerLine;
00284 const ss_size_t numLineSeparators = numLines - 1;
00285 ss_size_t size = (numGroups * (cchSeparator + (2 * byteGrouping))) + (numLineSeparators * cchLineSeparator) - (numLines * cchSeparator);
00286
00287 if(size <= cchBuff)
00288 {
00289 byte_t const* py = static_cast<byte_t const*>(pv);
00290 ss_size_t lineIndex;
00291 ss_size_t groupIndex;
00292
00293 for(lineIndex = 0, groupIndex = 0; 0 != cb; py += byteGrouping)
00294 {
00295 byte_t remaining[32];
00296 #ifdef STLSOFT_CONVERSION_BYTE_FORMAT_FUNCTIONS_USE_SPRINTF
00297 int cch;
00298 #endif
00299
00300 if(cb < byteGrouping)
00301 {
00302 ::memcpy(&remaining[0], py, cb);
00303 ::memset(&remaining[0] + cb, 0x00, STLSOFT_NUM_ELEMENTS(remaining) - cb);
00304
00305 py = &remaining[0];
00306 cb = byteGrouping;
00307 }
00308
00309 #if defined(STLSOFT_COMPILER_IS_GCC)
00310 typedef unsigned int8x_t;
00311 #else
00312 typedef uint32_t int8x_t;
00313 #endif
00314
00315 #ifndef _STLSOFT_NO_NAMESPACE
00316 using ::stlsoft::conversion::format::impl::format_hex_uint8;
00317 using ::stlsoft::conversion::format::impl::format_hex_uint16;
00318 using ::stlsoft::conversion::format::impl::format_hex_uint32;
00319 using ::stlsoft::conversion::format::impl::format_hex_uint64;
00320 using ::stlsoft::conversion::format::impl::format_hex_uint128;
00321 using ::stlsoft::conversion::format::impl::format_hex_uint256;
00322 #endif
00323
00324 const bool requestUppercaseAlpha = false;
00325 const bool highByteFirst = false;
00326
00327 switch(byteGrouping)
00328 {
00329 default:
00330 STLSOFT_MESSAGE_ASSERT(0, "invalid byte grouping");
00331 cb = 0;
00332 break;
00333 case 1:
00334 #ifdef STLSOFT_CONVERSION_BYTE_FORMAT_FUNCTIONS_USE_SPRINTF
00335 cch = ::sprintf( buff, "%02x"
00336 , *sap_cast<uint8_t const*>(py));
00337 buff += cch;
00338 #else
00339 format_hex_uint8(buff, py, requestUppercaseAlpha);
00340 buff += 2;
00341 #endif
00342 cb -= 1;
00343 break;
00344 case 2:
00345 #ifdef STLSOFT_CONVERSION_BYTE_FORMAT_FUNCTIONS_USE_SPRINTF
00346 cch = ::sprintf( buff, "%04x"
00347 , *sap_cast<uint16_t const*>(py));
00348 buff += cch;
00349 #else
00350 format_hex_uint16(buff, py, requestUppercaseAlpha, highByteFirst);
00351 buff += 4;
00352 #endif
00353 cb -= 2;
00354 break;
00355 case 4:
00356 #ifdef STLSOFT_CONVERSION_BYTE_FORMAT_FUNCTIONS_USE_SPRINTF
00357 cch = ::sprintf( buff, "%08x"
00358 , *sap_cast<int8x_t const*>(py));
00359 buff += cch;
00360 #else
00361 format_hex_uint32(buff, py, requestUppercaseAlpha, highByteFirst);
00362 buff += 8;
00363 #endif
00364 cb -= 4;
00365 break;
00366 case 8:
00367 #ifdef STLSOFT_CONVERSION_BYTE_FORMAT_FUNCTIONS_USE_SPRINTF
00368 cch = ::sprintf( buff, "%08x%08x"
00369 , *(sap_cast<int8x_t const*>(py) + 1)
00370 , *sap_cast<int8x_t const*>(py));
00371 buff += cch;
00372 #else
00373 format_hex_uint64(buff, py, requestUppercaseAlpha, highByteFirst);
00374 buff += 16;
00375 #endif
00376 cb -= 8;
00377 break;
00378 case 16:
00379 #ifdef STLSOFT_CONVERSION_BYTE_FORMAT_FUNCTIONS_USE_SPRINTF
00380 cch = ::sprintf( buff, "%08x%08x%08x%08x"
00381 , *(sap_cast<int8x_t const*>(py) + 3)
00382 , *(sap_cast<int8x_t const*>(py) + 2)
00383 , *(sap_cast<int8x_t const*>(py) + 1)
00384 , *sap_cast<int8x_t const*>(py));
00385 buff += cch;
00386 #else
00387 format_hex_uint128(buff, py, requestUppercaseAlpha, highByteFirst);
00388 buff += 32;
00389 #endif
00390 cb -= 16;
00391 break;
00392 case 32:
00393 #ifdef STLSOFT_CONVERSION_BYTE_FORMAT_FUNCTIONS_USE_SPRINTF
00394 cch = ::sprintf( buff, "%08x%08x%08x%08x%08x%08x%08x%08x"
00395 , *(sap_cast<int8x_t const*>(py) + 7)
00396 , *(sap_cast<int8x_t const*>(py) + 6)
00397 , *(sap_cast<int8x_t const*>(py) + 5)
00398 , *(sap_cast<int8x_t const*>(py) + 4)
00399 , *(sap_cast<int8x_t const*>(py) + 3)
00400 , *(sap_cast<int8x_t const*>(py) + 2)
00401 , *(sap_cast<int8x_t const*>(py) + 1)
00402 , *sap_cast<int8x_t const*>(py));
00403 buff += cch;
00404 #else
00405 format_hex_uint256(buff, py, requestUppercaseAlpha, highByteFirst);
00406 buff += 64;
00407 #endif
00408 cb -= 32;
00409 break;
00410 }
00411
00412 if(static_cast<ss_size_t>(groupsPerLine) == ++groupIndex)
00413 {
00414 if(++lineIndex < numLines)
00415 {
00416 ::memcpy(buff, lineSeparator, cchLineSeparator * sizeof(char));
00417 buff += cchLineSeparator;
00418 }
00419 groupIndex = 0;
00420 }
00421 else if(0 != cb)
00422 {
00423 ::memcpy(buff, groupSeparator, cchSeparator * sizeof(char));
00424 buff += cchSeparator;
00425 }
00426 }
00427
00428 if(size < cchBuff)
00429 {
00430 0[buff] = '\0';
00431 }
00432 }
00433
00434 return size;
00435 }
00436 }
00437
00439
00440
00441 #ifdef STLSOFT_UNITTEST
00442 # include "./unittest/byte_format_unittest_.h"
00443 #endif
00444
00445
00446
00447 #ifndef _STLSOFT_NO_NAMESPACE
00448 }
00449 #endif
00450
00451
00452
00453 #endif
00454
00455