![]() |
pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
|
00001 /* 00002 ------------------------------------------------------------------------------- 00003 This file is part of the Plink, Plonk, Plank libraries 00004 by Martin Robinson 00005 00006 http://code.google.com/p/pl-nk/ 00007 00008 Copyright University of the West of England, Bristol 2011-14 00009 All rights reserved. 00010 00011 Redistribution and use in source and binary forms, with or without 00012 modification, are permitted provided that the following conditions are met: 00013 00014 * Redistributions of source code must retain the above copyright 00015 notice, this list of conditions and the following disclaimer. 00016 * Redistributions in binary form must reproduce the above copyright 00017 notice, this list of conditions and the following disclaimer in the 00018 documentation and/or other materials provided with the distribution. 00019 * Neither the name of University of the West of England, Bristol nor 00020 the names of its contributors may be used to endorse or promote products 00021 derived from this software without specific prior written permission. 00022 00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00024 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00025 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00026 DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 00034 This software makes use of third party libraries. For more information see: 00035 doc/license.txt included in the distribution. 00036 ------------------------------------------------------------------------------- 00037 */ 00038 00039 #ifndef PLANK_CONTAINERSMISC_H 00040 #define PLANK_CONTAINERSMISC_H 00041 00042 #include "../random/plank_RNG.h" 00043 00044 static inline PlankI pl_AlignI (const PlankI value, const PlankI alignment) 00045 { 00046 return value + (alignment - (value % alignment)) * !!(value % alignment); 00047 } 00048 00049 static inline PlankUI pl_AlignUI (const PlankUI value, const PlankUI alignment) 00050 { 00051 return value + (alignment - (value % alignment)) * !!(value % alignment); 00052 } 00053 00054 static inline PlankLL pl_AlignLL (const PlankLL value, const PlankLL alignment) 00055 { 00056 return value + (alignment - (value % alignment)) * !!(value % alignment); 00057 } 00058 00059 static inline PlankULL pl_AlignULL (const PlankULL value, const PlankULL alignment) 00060 { 00061 return value + (alignment - (value % alignment)) * !!(value % alignment); 00062 } 00063 00064 00065 static inline void pl_SwapP (PlankP* a, PlankP* b) 00066 { 00067 PlankP temp; 00068 temp = *a; 00069 *a = *b; 00070 *b = temp; 00071 } 00072 00074 typedef struct PlankUI24 00075 { 00076 PlankUC data[3]; 00077 } PlankUI24; 00078 00080 typedef struct PlankI24 00081 { 00082 PlankUC data[3]; 00083 } PlankI24; 00084 00088 typedef struct PlankF80 00089 { 00090 PlankUC data[10]; 00091 } PlankF80; 00092 00093 00095 typedef struct PlankPascalString255 00096 { 00097 PlankUC data[256]; 00098 } PlankPascalString255; 00099 00100 00103 static inline PlankUI24 pl_ConvertUIToUI24 (const PlankUI i32) 00104 { 00105 #if PLANK_LITTLEENDIAN 00106 PlankUI24 i24; 00107 i24 = *(PlankUI24*)&i32; 00108 return i24; 00109 #elif PLANK_BIGENDIAN 00110 PlankUI24 i24; 00111 unsigned char* bits; 00112 00113 bits = (unsigned char*)&i32; 00114 i24 = *(PlankUI24*)(bits + 1); 00115 return i24; 00116 #else 00117 #error Neither PLANK_BIGENDIAN or PLANK_LITTLEENDIAN are set to 1 00118 #endif 00119 } 00120 00121 00124 static inline PlankUI pl_ConvertUI24ToUI (const PlankUI24 i24) 00125 { 00126 #if PLANK_LITTLEENDIAN 00127 PlankUI i32; 00128 i32 = *(PlankUI*)&i24 & 0xffffff; 00129 return i32; 00130 #elif PLANK_BIGENDIAN 00131 PlankUI i32; 00132 i32 = (*(PlankUI*)&i24 >> 8) & 0xffffff; 00133 return i32; 00134 #else 00135 #error Neither PLANK_BIGENDIAN or PLANK_LITTLEENDIAN are set to 1 00136 #endif 00137 } 00138 00141 static inline PlankI24 pl_ConvertIToI24 (const PlankI i32) 00142 { 00143 #if PLANK_LITTLEENDIAN 00144 PlankI24 i24; 00145 i24 = *(PlankI24*)&i32; 00146 return i24; 00147 #elif PLANK_BIGENDIAN 00148 PlankI24 i24; 00149 unsigned char* bits; 00150 00151 bits = (unsigned char*)&i32; 00152 i24 = *(PlankI24*)(bits + 1); 00153 return i24; 00154 #else 00155 #error Neither PLANK_BIGENDIAN or PLANK_LITTLEENDIAN are set to 1 00156 #endif 00157 } 00158 00161 static inline PlankI pl_ConvertI24ToI (const PlankI24 i24) 00162 { 00163 #if PLANK_LITTLEENDIAN 00164 PlankI i32; 00165 i32 = *(PlankI*)&i24 & 0xffffff; 00166 00167 if (i32 & 0x00800000) 00168 return i32 | 0xff000000; 00169 else 00170 return i32; 00171 #elif PLANK_BIGENDIAN 00172 PlankI i32; 00173 i32 = (*(PlankI*)&i24 >> 8) & 0xffffff; 00174 00175 if (i32 & 0x00800000) 00176 return i32 | 0xff000000; 00177 else 00178 return i32; 00179 #else 00180 #error Neither PLANK_BIGENDIAN or PLANK_LITTLEENDIAN are set to 1 00181 #endif 00182 } 00183 00184 typedef struct PlankVec2F 00185 { 00186 float values[2]; 00187 } PlankVec2F; 00188 00189 typedef struct PlankVec3F 00190 { 00191 float values[3]; 00192 } PlankVec3F; 00193 00194 typedef struct PlankVec4F 00195 { 00196 float values[4]; 00197 } PlankVec4F; 00198 00199 typedef struct PlankVec2D 00200 { 00201 double values[2]; 00202 } PlankVec2D; 00203 00204 typedef struct PlankVec3D 00205 { 00206 double values[3]; 00207 } PlankVec3D; 00208 00209 typedef struct PlankVec4D 00210 { 00211 double values[4]; 00212 } PlankVec4D; 00213 00219 static inline PlankUC pl_CountOnesUC (PlankUC x) 00220 { 00221 x -= ((x >> 1) & 0x55); 00222 x = (((x >> 2) & 0x33) + (x & 0x33)); 00223 x = (((x >> 4) + x) & 0x0f); 00224 return x; 00225 } 00226 00227 static inline PlankUC pl_CountLeadingZerosUC (PlankUC x) 00228 { 00229 x |= (x >> 1); 00230 x |= (x >> 2); 00231 x |= (x >> 4); 00232 return 8 - pl_CountOnesUC (x); 00233 } 00234 00235 static inline PlankUC pl_CountTrailingZerosUC (PlankUC x) 00236 { 00237 return 8 - pl_CountLeadingZerosUC (~x & (x - 1)); 00238 } 00239 00240 static inline PlankUC pl_CountLeadingOnesUC (PlankUC x) 00241 { 00242 return pl_CountLeadingZerosUC (~x); 00243 } 00244 00245 static inline PlankUC pl_CountTrailingOnesUC (PlankUC x) 00246 { 00247 return 8 - pl_CountLeadingZerosUC (x & (~x - 1)); 00248 } 00249 00250 static inline PlankUC pl_NumBitsRequiredUC (PlankUC x) 00251 { 00252 return 8 - pl_CountLeadingZerosUC (x); 00253 } 00254 00255 static inline PlankUC pl_Log2CeilUC (PlankUC x) 00256 { 00257 return 8 - pl_CountLeadingZerosUC (x - 1); 00258 } 00259 00260 static inline PlankUC pl_NextPowerOf2UC (PlankUC x) 00261 { 00262 return (PlankUC)1 << pl_Log2CeilUC (x); 00263 } 00264 00265 static inline PlankB pl_IsPowerOf2UC (PlankUC x) 00266 { 00267 return (x & (x - 1)) == 0; 00268 } 00269 00270 static inline PlankUS pl_CountOnesUS (PlankUS x) 00271 { 00272 x -= ((x >> 1) & 0x5555); 00273 x = (((x >> 2) & 0x3333) + (x & 0x3333)); 00274 x = (((x >> 4) + x) & 0x0f0f); 00275 x += (x >> 8); 00276 return x & 0x001f; 00277 } 00278 00279 static inline PlankUS pl_CountLeadingZerosUS (PlankUS x) 00280 { 00281 x |= (x >> 1); 00282 x |= (x >> 2); 00283 x |= (x >> 4); 00284 x |= (x >> 8); 00285 return 16 - pl_CountOnesUS (x); 00286 } 00287 00288 static inline PlankUS pl_CountTrailingZerosUS (PlankUS x) 00289 { 00290 return 16 - pl_CountLeadingZerosUS (~x & (x - 1)); 00291 } 00292 00293 static inline PlankUS pl_CountLeadingOnesUS (PlankUS x) 00294 { 00295 return pl_CountLeadingZerosUS (~x); 00296 } 00297 00298 static inline PlankUS pl_CountTrailingOnesUS (PlankUS x) 00299 { 00300 return 16 - pl_CountLeadingZerosUS (x & (~x - 1)); 00301 } 00302 00303 static inline PlankUS pl_NumBitsRequiredUS (PlankUS x) 00304 { 00305 return 16 - pl_CountLeadingZerosUS (x); 00306 } 00307 00308 static inline PlankUS pl_Log2CeilUS (PlankUS x) 00309 { 00310 return 16 - pl_CountLeadingZerosUS (x - 1); 00311 } 00312 00313 static inline PlankUS pl_NextPowerOf2US (PlankUS x) 00314 { 00315 return 1 << pl_Log2CeilUS (x); 00316 } 00317 00318 static inline PlankB pl_IsPowerOf2US (PlankUS x) 00319 { 00320 return (x & (x - 1)) == (PlankUS)0; 00321 } 00322 00323 static inline PlankUI pl_CountOnesUI (PlankUI x) 00324 { 00325 x -= ((x >> 1) & 0x55555555); 00326 x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); 00327 x = (((x >> 4) + x) & 0x0f0f0f0f); 00328 x += (x >> 8); 00329 x += (x >> 16); 00330 return x & 0x0000003f; 00331 } 00332 00333 static inline PlankUI pl_CountLeadingZerosUI (PlankUI x) 00334 { 00335 x |= (x >> 1); 00336 x |= (x >> 2); 00337 x |= (x >> 4); 00338 x |= (x >> 8); 00339 x |= (x >> 16); 00340 return 32 - pl_CountOnesUI (x); 00341 } 00342 00343 static inline PlankUI pl_CountTrailingZerosUI (PlankUI x) 00344 { 00345 return 32 - pl_CountLeadingZerosUI (~x & (x - 1)); 00346 } 00347 00348 static inline PlankUI pl_CountLeadingOnesUI (PlankUI x) 00349 { 00350 return pl_CountLeadingZerosUI (~x); 00351 } 00352 00353 static inline PlankUI pl_CountTrailingOnesUI (PlankUI x) 00354 { 00355 return 32 - pl_CountLeadingZerosUI (x & (~x - 1)); 00356 } 00357 00358 static inline PlankUI pl_NumBitsRequiredUI (PlankUI x) 00359 { 00360 return 32 - pl_CountLeadingZerosUI (x); 00361 } 00362 00363 static inline PlankUI pl_Log2CeilUI (PlankUI x) 00364 { 00365 return 32 - pl_CountLeadingZerosUI (x - 1); 00366 } 00367 00368 static inline PlankUI pl_NextPowerOf2UI (PlankUI x) 00369 { 00370 return 1 << pl_Log2CeilUI (x); 00371 } 00372 00373 static inline PlankB pl_IsPowerOf2UI (PlankUI x) 00374 { 00375 return (x & (x - 1)) == (PlankUI)0; 00376 } 00377 00378 static inline PlankULL pl_CountOnesULL (PlankULL x) 00379 { 00380 x -= ((x >> 1) & 0x5555555555555555ULL); 00381 x = (((x >> 2) & 0x3333333333333333ULL) + (x & 0x3333333333333333ULL)); 00382 x = (((x >> 4) + x) & 0x0f0f0f0f0f0f0f0fULL); 00383 x += (x >> 8); 00384 x += (x >> 16); 00385 x += (x >> 32); 00386 return x & 0x000000000000007fULL; 00387 } 00388 00389 static inline PlankULL pl_CountLeadingZerosULL (PlankULL x) 00390 { 00391 x |= (x >> 1); 00392 x |= (x >> 2); 00393 x |= (x >> 4); 00394 x |= (x >> 8); 00395 x |= (x >> 16); 00396 x |= (x >> 32); 00397 return 64 - pl_CountOnesULL (x); 00398 } 00399 00400 static inline PlankULL pl_CountTrailingZerosULL (PlankULL x) 00401 { 00402 return 64 - pl_CountLeadingZerosULL (~x & (x - 1)); 00403 } 00404 00405 static inline PlankULL pl_CountLeadingOnesULL (PlankULL x) 00406 { 00407 return pl_CountLeadingZerosULL (~x); 00408 } 00409 00410 static inline PlankULL pl_CountTrailingOnesULL (PlankULL x) 00411 { 00412 return 64 - pl_CountLeadingZerosULL (x & (~x - 1)); 00413 } 00414 00415 static inline PlankULL pl_NumBitsRequiredULL (PlankULL x) 00416 { 00417 return 64 - pl_CountLeadingZerosULL (x); 00418 } 00419 00420 static inline PlankULL pl_Log2CeilULL (PlankULL x) 00421 { 00422 return 64 - pl_CountLeadingZerosULL (x - 1); 00423 } 00424 00425 static inline PlankULL pl_NextPowerOf2ULL (PlankULL x) 00426 { 00427 return 1ULL << pl_Log2CeilULL (x); 00428 } 00429 00430 static inline PlankB pl_IsPowerOf2ULL (PlankULL x) 00431 { 00432 return (x & (x - 1)) == (PlankULL)0; 00433 } 00434 00436 00437 00444 static inline void pl_SwapEndianUS (unsigned short *bits) 00445 { 00446 *bits = (*bits >> 8) | (*bits << 8); 00447 } 00448 00450 static inline void pl_SwapEndianUI24 (PlankUI24 *bits) 00451 { 00452 PlankUC temp = bits->data[0]; 00453 bits->data[0] = bits->data[2]; 00454 bits->data[2] = temp; 00455 } 00456 00458 static inline void pl_SwapEndianUI (unsigned int *bits) 00459 { 00460 *bits = (*bits >> 24) | ((*bits << 8) & 0x00ff0000) | ((*bits >> 8) & 0x0000ff00) | (*bits << 24); 00461 } 00462 00464 static inline void pl_SwapEndianULL (PlankULL *bits) 00465 { 00466 *bits = (*bits >> 56) | 00467 ((*bits << 40) & 0x00ff000000000000ULL) | 00468 ((*bits << 24) & 0x0000ff0000000000ULL) | 00469 ((*bits << 8) & 0x000000ff00000000ULL) | 00470 ((*bits >> 8) & 0x00000000ff000000ULL) | 00471 ((*bits >> 24) & 0x0000000000ff0000ULL) | 00472 ((*bits >> 40) & 0x000000000000ff00ULL) | 00473 (*bits << 56); 00474 } 00475 00476 static inline void pl_SwapEndianF80 (PlankF80 *bits) 00477 { 00478 PlankF80 temp = *bits; 00479 00480 bits->data[0] = temp.data[9]; 00481 bits->data[1] = temp.data[8]; 00482 bits->data[2] = temp.data[7]; 00483 bits->data[3] = temp.data[6]; 00484 bits->data[4] = temp.data[5]; 00485 bits->data[5] = temp.data[4]; 00486 bits->data[6] = temp.data[3]; 00487 bits->data[7] = temp.data[2]; 00488 bits->data[8] = temp.data[1]; 00489 bits->data[9] = temp.data[0]; 00490 } 00491 00493 static inline void pl_SwapEndianUL (PlankUL *data) 00494 { 00495 #if PLANK_32BIT 00496 pl_SwapEndianUI ((unsigned int*)data); 00497 #elif PLANK_64BIT 00498 pl_SwapEndianULL ((PlankULL*)data); 00499 #else 00500 #error Neither PLANK_32BIT or PLANK_64BIT are set to 1 00501 #endif 00502 } 00503 00505 static inline void pl_SwapEndianS (short *data) 00506 { 00507 pl_SwapEndianUS ((unsigned short*)data); 00508 } 00509 00511 static inline void pl_SwapEndianI (int *data) 00512 { 00513 pl_SwapEndianUI ((unsigned int*)data); 00514 } 00515 00517 static inline void pl_SwapEndianI24 (PlankI24 *data) 00518 { 00519 pl_SwapEndianUI24 ((PlankUI24*)data); 00520 } 00521 00523 static inline void pl_SwapEndianL (long *data) 00524 { 00525 #if PLANK_32BIT 00526 pl_SwapEndianUI ((unsigned int*)data); 00527 #elif PLANK_64BIT 00528 pl_SwapEndianULL ((PlankULL*)data); 00529 #else 00530 #error Neither PLANK_32BIT or PLANK_64BIT are set to 1 00531 #endif 00532 } 00533 00535 static inline void pl_SwapEndianLL (PlankLL *data) 00536 { 00537 pl_SwapEndianULL ((PlankULL*)data); 00538 } 00539 00541 static inline void pl_SwapEndianF (float *data) 00542 { 00543 pl_SwapEndianUI ((unsigned int*)data); 00544 } 00545 00547 static inline void pl_SwapEndianD (double *data) 00548 { 00549 pl_SwapEndianULL ((PlankULL*)data); 00550 } 00551 00553 00554 00557 static inline PlankFourCharCode pl_FourCharCode (const char* data) 00558 { 00559 PlankFourCharCode code; 00560 00561 code = (data[0] == '\0') ? 0 : *(PlankFourCharCode*)data; 00562 00563 #if PLANK_BIGENDIAN 00564 pl_SwapEndianI ((int*)code); 00565 #endif 00566 return code; 00567 } 00568 00569 #define PLANKFOURCHARCODE(data) (*(const PlankFourCharCode*)data) 00570 00571 static inline PlankFourCharCodeString pl_FourCharCode2String (const PlankFourCharCode code) 00572 { 00573 PlankFourCharCodeString string; 00574 *(PlankFourCharCode*)string.string = code; 00575 00576 #if PLANK_BIGENDIAN 00577 pl_SwapEndianI ((int*)code); 00578 #endif 00579 00580 string.string[4] = '\0'; 00581 00582 return string; 00583 } 00584 00586 static inline PlankUI pl_F802I (const PlankF80 extended) 00587 { 00588 PlankUI mantissa; 00589 PlankUI last = 0; 00590 PlankUC exp; 00591 00592 #if PLANK_LITTLEENDIAN 00593 pl_SwapEndianUI ((PlankUI*)(extended.data + 2)); 00594 #endif 00595 00596 mantissa = *(PlankUI*)(extended.data + 2); 00597 exp = 30 - *(extended.data + 1); 00598 00599 while (exp) 00600 { 00601 last = mantissa; 00602 mantissa = mantissa >> 1; 00603 --exp; 00604 } 00605 00606 if (last & 0x00000001) 00607 ++mantissa; 00608 00609 return mantissa; 00610 } 00611 00613 static inline PlankF80 pl_I2F80 (const PlankUI value) 00614 { 00615 PlankF80 extended; 00616 PlankI temp = value; 00617 PlankUI exp; 00618 PlankUC i; 00619 00620 pl_MemoryZero (&extended, sizeof (PlankF80)); 00621 00622 if (value == 0) 00623 goto exit; 00624 00625 exp = temp; 00626 exp = exp >> 1; 00627 00628 for (i = 0; i < 32; ++i) 00629 { 00630 exp = exp >> 1; 00631 00632 if (!exp) 00633 break; 00634 } 00635 00636 if (value == -1) 00637 extended.data[0] = 191; 00638 else if (value == 1) 00639 extended.data[0] = 63; 00640 // else if (value < 0) 00641 // extended.data[0] = 192; 00642 else 00643 extended.data[0] = 64; 00644 00645 extended.data[1] = i; 00646 00647 for (i = 32; i > 0; --i) 00648 { 00649 if (temp & 0x80000000) 00650 break; 00651 00652 temp <<= 1; 00653 } 00654 00655 *(PlankUI*)(extended.data + 2) = temp; 00656 00657 #if PLANK_LITTLEENDIAN 00658 pl_SwapEndianUI ((PlankUI*)(extended.data + 2)); 00659 #endif 00660 00661 exit: 00662 return extended; 00663 } 00664 00669 typedef struct PlankGUID* PlankGUIDRef; 00670 00671 typedef struct PlankGUID 00672 { 00673 PlankUI data1; 00674 PlankUS data2; 00675 PlankUS data3; 00676 PlankUC data4[8]; 00677 } PlankGUID; 00678 00679 00680 static inline void pl_GUID_InitRandom (PlankGUIDRef p) 00681 { 00682 PlankRNGRef rng; 00683 rng = pl_RNGGlobal(); 00684 00685 p->data1 = pl_RNG_NextInt (rng, 0xffffffff); 00686 p->data2 = (PlankUS)pl_RNG_NextInt (rng, 0xffff); 00687 p->data3 = (PlankUS)pl_RNG_NextInt (rng, 0x0fff) | 0x4000; 00688 *(PlankULL*)&p->data4 = (((PlankULL)pl_RNG_NextInt (rng, 0xffffffff)) << 32) | pl_RNG_NextInt (rng, 0xffffffff); 00689 p->data4[0] = ((PlankUC)(pl_RNG_NextInt (rng, 4) + 8) << 4) | (PlankUC)(pl_RNG_NextInt (rng, 0x0f)); 00690 } 00691 00692 static inline void pl_GUID_Init42244 (PlankGUIDRef p, const PlankUI data1, const PlankUS data2, const PlankUS data3, const PlankUI data4hi, const PlankUI data4lo) 00693 { 00694 p->data1 = data1; 00695 p->data2 = data2; 00696 p->data3 = data3; 00697 *(PlankULL*)&p->data4 = (((PlankULL)data4hi) << 32) | data4lo; 00698 } 00699 00700 static inline void pl_GUID_Init4228 (PlankGUIDRef p, const PlankUI data1, const PlankUS data2, const PlankUS data3, const PlankULL data4) 00701 { 00702 p->data1 = data1; 00703 p->data2 = data2; 00704 p->data3 = data3; 00705 *(PlankULL*)&p->data4 = data4; 00706 } 00707 00708 static inline void pl_GUID_Init4221x8 (PlankGUIDRef p, const PlankUI data1, const PlankUS data2, const PlankUS data3, 00709 const PlankUC data4_0, 00710 const PlankUC data4_1, 00711 const PlankUC data4_2, 00712 const PlankUC data4_3, 00713 const PlankUC data4_4, 00714 const PlankUC data4_5, 00715 const PlankUC data4_6, 00716 const PlankUC data4_7) 00717 { 00718 p->data1 = data1; 00719 p->data2 = data2; 00720 p->data3 = data3; 00721 p->data4[0] = data4_0; 00722 p->data4[1] = data4_1; 00723 p->data4[2] = data4_2; 00724 p->data4[3] = data4_3; 00725 p->data4[4] = data4_4; 00726 p->data4[5] = data4_5; 00727 p->data4[6] = data4_6; 00728 p->data4[7] = data4_7; 00729 } 00730 00731 static inline void pl_GUID_Init422p (PlankGUIDRef p, const PlankUI data1, const PlankUS data2, const PlankUS data3, const PlankUC* data4) 00732 { 00733 p->data1 = data1; 00734 p->data2 = data2; 00735 p->data3 = data3; 00736 pl_MemoryCopy (&p->data4, data4, 8); 00737 } 00738 00739 static inline const char* pl_HexDigit2CharMap() 00740 { 00741 static char map[16]; 00742 static PlankB firstTime = PLANK_TRUE; 00743 00744 if (firstTime) 00745 { 00746 pl_MemoryCopy(map, "0123456789abcdef", 16); 00747 firstTime = PLANK_FALSE; 00748 } 00749 00750 return map; 00751 } 00752 00753 static inline const char* pl_Char2HexDigitMap() 00754 { 00755 static char map[128]; 00756 static PlankB firstTime = PLANK_TRUE; 00757 int i; 00758 00759 if (firstTime) 00760 { 00761 // invalid chars 00762 for (i = 0; i < 128; ++i) 00763 map[i] = -2; 00764 00765 // valid chars >= -1 00766 map['-'] = -1; 00767 map['0'] = 0; 00768 map['1'] = 1; 00769 map['2'] = 2; 00770 map['3'] = 3; 00771 map['4'] = 4; 00772 map['5'] = 5; 00773 map['6'] = 6; 00774 map['7'] = 7; 00775 map['8'] = 8; 00776 map['9'] = 9; 00777 map['a'] = 10; 00778 map['b'] = 11; 00779 map['c'] = 12; 00780 map['d'] = 13; 00781 map['e'] = 14; 00782 map['f'] = 15; 00783 map['A'] = 10; 00784 map['B'] = 11; 00785 map['C'] = 12; 00786 map['D'] = 13; 00787 map['E'] = 14; 00788 map['F'] = 15; 00789 } 00790 00791 return map; 00792 } 00793 00794 00795 static inline PlankResult pl_GUID_InitHexString (PlankGUIDRef p, const char* string) 00796 { 00797 const char *map; 00798 PlankResult result; 00799 PlankUL i, len; 00800 00801 result = PlankResult_OK; 00802 map = pl_Char2HexDigitMap(); 00803 00804 if (string[0] == '{') 00805 string++; 00806 00807 len = strlen (string); 00808 00809 if (len < 36 || len > 37 ) 00810 { 00811 result = PlankResult_UnknownError; 00812 goto exit; 00813 } 00814 00815 if ((len == 37) && string[36] != '}') 00816 { 00817 result = PlankResult_UnknownError; 00818 goto exit; 00819 } 00820 00821 if ((string[8] != '-') || (string[13] != '-') || (string[18] != '-') || (string[23] != '-')) 00822 { 00823 result = PlankResult_UnknownError; 00824 goto exit; 00825 } 00826 00827 for (i = 0; i < 36; ++i) 00828 { 00829 if (map[string[i]] < -1) 00830 { 00831 result = PlankResult_UnknownError; 00832 goto exit; 00833 } 00834 } 00835 00836 p->data1 = (((PlankUI)map[string[ 0]]) << 28) | 00837 (((PlankUI)map[string[ 1]]) << 24) | 00838 (((PlankUI)map[string[ 2]]) << 20) | 00839 (((PlankUI)map[string[ 3]]) << 16) | 00840 (((PlankUI)map[string[ 4]]) << 12) | 00841 (((PlankUI)map[string[ 5]]) << 8) | 00842 (((PlankUI)map[string[ 6]]) << 4) | 00843 (((PlankUI)map[string[ 7]]) << 0); 00844 00845 p->data2 = (((PlankUS)map[string[ 9]]) << 12) | 00846 (((PlankUS)map[string[10]]) << 8) | 00847 (((PlankUS)map[string[11]]) << 4) | 00848 (((PlankUS)map[string[12]]) << 0); 00849 00850 p->data3 = (((PlankUS)map[string[14]]) << 12) | 00851 (((PlankUS)map[string[15]]) << 8) | 00852 (((PlankUS)map[string[16]]) << 4) | 00853 (((PlankUS)map[string[17]]) << 0); 00854 00855 p->data4[0] = (((PlankUC)map[string[19]]) << 4) | (((PlankUC)map[string[20]]) << 0); 00856 p->data4[1] = (((PlankUC)map[string[21]]) << 4) | (((PlankUC)map[string[22]]) << 0); 00857 00858 p->data4[2] = (((PlankUC)map[string[24]]) << 4) | (((PlankUC)map[string[25]]) << 0); 00859 p->data4[3] = (((PlankUC)map[string[26]]) << 4) | (((PlankUC)map[string[27]]) << 0); 00860 p->data4[4] = (((PlankUC)map[string[28]]) << 4) | (((PlankUC)map[string[29]]) << 0); 00861 p->data4[5] = (((PlankUC)map[string[30]]) << 4) | (((PlankUC)map[string[31]]) << 0); 00862 p->data4[6] = (((PlankUC)map[string[32]]) << 4) | (((PlankUC)map[string[33]]) << 0); 00863 p->data4[7] = (((PlankUC)map[string[34]]) << 4) | (((PlankUC)map[string[35]]) << 0); 00864 00865 exit: 00866 return result; 00867 } 00868 00869 static inline PlankResult pl_GUID_InitChunkString (PlankGUIDRef p, const char* string) 00870 { 00871 const char *map; 00872 char chunkID[5]; 00873 PlankResult result; 00874 PlankUL i, len; 00875 00876 result = PlankResult_OK; 00877 map = pl_Char2HexDigitMap(); 00878 00879 if (string[0] == '{') 00880 string++; 00881 00882 len = strlen (string); 00883 00884 if (len < 32 || len > 33) 00885 { 00886 result = PlankResult_UnknownError; 00887 goto exit; 00888 } 00889 00890 if ((len == 33) && string[32] != '}') 00891 { 00892 result = PlankResult_UnknownError; 00893 goto exit; 00894 } 00895 00896 if ((string[4] != '-') || (string[9] != '-') || (string[14] != '-') || (string[19] != '-')) 00897 { 00898 result = PlankResult_UnknownError; 00899 goto exit; 00900 } 00901 00902 for (i = 5; i < 32; ++i) 00903 { 00904 if (map[string[i]] < -1) 00905 { 00906 result = PlankResult_UnknownError; 00907 goto exit; 00908 } 00909 } 00910 00911 chunkID[0] = string[0]; 00912 chunkID[1] = string[1]; 00913 chunkID[2] = string[2]; 00914 chunkID[3] = string[3]; 00915 chunkID[4] = '\0'; 00916 00917 p->data1 = pl_FourCharCode (chunkID); 00918 00919 p->data2 = (((PlankUS)map[string[ 5]]) << 12) | 00920 (((PlankUS)map[string[ 6]]) << 8) | 00921 (((PlankUS)map[string[ 7]]) << 4) | 00922 (((PlankUS)map[string[ 8]]) << 0); 00923 00924 p->data3 = (((PlankUS)map[string[10]]) << 12) | 00925 (((PlankUS)map[string[11]]) << 8) | 00926 (((PlankUS)map[string[12]]) << 4) | 00927 (((PlankUS)map[string[13]]) << 0); 00928 00929 p->data4[0] = (((PlankUC)map[string[15]]) << 4) | (((PlankUC)map[string[16]]) << 0); 00930 p->data4[1] = (((PlankUC)map[string[17]]) << 4) | (((PlankUC)map[string[18]]) << 0); 00931 00932 p->data4[2] = (((PlankUC)map[string[20]]) << 4) | (((PlankUC)map[string[21]]) << 0); 00933 p->data4[3] = (((PlankUC)map[string[22]]) << 4) | (((PlankUC)map[string[23]]) << 0); 00934 p->data4[4] = (((PlankUC)map[string[24]]) << 4) | (((PlankUC)map[string[25]]) << 0); 00935 p->data4[5] = (((PlankUC)map[string[26]]) << 4) | (((PlankUC)map[string[27]]) << 0); 00936 p->data4[6] = (((PlankUC)map[string[28]]) << 4) | (((PlankUC)map[string[29]]) << 0); 00937 p->data4[7] = (((PlankUC)map[string[30]]) << 4) | (((PlankUC)map[string[31]]) << 0); 00938 00939 exit: 00940 return result; 00941 } 00942 00943 static inline PlankResult pl_GUID_InitString (PlankGUIDRef p, const char* string) 00944 { 00945 PlankUL len; 00946 00947 len = strlen (string); 00948 00949 if (len == 32 || len == 34) 00950 return pl_GUID_InitChunkString (p, string); 00951 else if (len == 36 || len == 38) 00952 return pl_GUID_InitHexString (p, string); 00953 else 00954 return PlankResult_UnknownError; 00955 } 00956 00957 static inline void pl_GUID_HexString (const PlankGUID* p, const PlankB withBraces, char* string) 00958 { 00959 const char *map; 00960 00961 map = pl_HexDigit2CharMap(); 00962 00963 if (withBraces) 00964 *string++ = '{'; 00965 00966 *string++ = map[(p->data1 >> 28) & 0x0f]; 00967 *string++ = map[(p->data1 >> 24) & 0x0f]; 00968 *string++ = map[(p->data1 >> 20) & 0x0f]; 00969 *string++ = map[(p->data1 >> 16) & 0x0f]; 00970 *string++ = map[(p->data1 >> 12) & 0x0f]; 00971 *string++ = map[(p->data1 >> 8) & 0x0f]; 00972 *string++ = map[(p->data1 >> 4) & 0x0f]; 00973 *string++ = map[(p->data1 >> 0) & 0x0f]; 00974 *string++ = '-'; 00975 *string++ = map[(p->data2 >> 12) & 0x0f]; 00976 *string++ = map[(p->data2 >> 8) & 0x0f]; 00977 *string++ = map[(p->data2 >> 4) & 0x0f]; 00978 *string++ = map[(p->data2 >> 0) & 0x0f]; 00979 *string++ = '-'; 00980 *string++ = map[(p->data3 >> 12) & 0x0f]; 00981 *string++ = map[(p->data3 >> 8) & 0x0f]; 00982 *string++ = map[(p->data3 >> 4) & 0x0f]; 00983 *string++ = map[(p->data3 >> 0) & 0x0f]; 00984 *string++ = '-'; 00985 *string++ = map[(p->data4[0] >> 4) & 0x0f]; 00986 *string++ = map[(p->data4[0] >> 0) & 0x0f]; 00987 *string++ = map[(p->data4[1] >> 4) & 0x0f]; 00988 *string++ = map[(p->data4[1] >> 0) & 0x0f]; 00989 *string++ = '-'; 00990 *string++ = map[(p->data4[2] >> 4) & 0x0f]; 00991 *string++ = map[(p->data4[2] >> 0) & 0x0f]; 00992 *string++ = map[(p->data4[3] >> 4) & 0x0f]; 00993 *string++ = map[(p->data4[3] >> 0) & 0x0f]; 00994 *string++ = map[(p->data4[4] >> 4) & 0x0f]; 00995 *string++ = map[(p->data4[4] >> 0) & 0x0f]; 00996 *string++ = map[(p->data4[5] >> 4) & 0x0f]; 00997 *string++ = map[(p->data4[5] >> 0) & 0x0f]; 00998 *string++ = map[(p->data4[6] >> 4) & 0x0f]; 00999 *string++ = map[(p->data4[6] >> 0) & 0x0f]; 01000 *string++ = map[(p->data4[7] >> 4) & 0x0f]; 01001 *string++ = map[(p->data4[7] >> 0) & 0x0f]; 01002 01003 if (withBraces) 01004 *string++ = '}'; 01005 01006 *string++ = '\0'; 01007 } 01008 01009 static inline void pl_GUID_ChunkString (const PlankGUID* p, const PlankB withBraces, char* string) 01010 { 01011 const char *map; 01012 01013 map = pl_HexDigit2CharMap(); 01014 01015 if (withBraces) 01016 *string++ = '{'; 01017 01018 #if PLANK_LITTLEENDIAN 01019 *string++ = ((char*)&p->data1)[0]; 01020 *string++ = ((char*)&p->data1)[1]; 01021 *string++ = ((char*)&p->data1)[2]; 01022 *string++ = ((char*)&p->data1)[3]; 01023 #endif 01024 #if PLANK_BIGENDIAN 01025 *string++ = ((char*)&p->data1)[3]; 01026 *string++ = ((char*)&p->data1)[2]; 01027 *string++ = ((char*)&p->data1)[1]; 01028 *string++ = ((char*)&p->data1)[0]; 01029 #endif 01030 *string++ = '-'; 01031 *string++ = map[(p->data2 >> 12) & 0x0f]; 01032 *string++ = map[(p->data2 >> 8) & 0x0f]; 01033 *string++ = map[(p->data2 >> 4) & 0x0f]; 01034 *string++ = map[(p->data2 >> 0) & 0x0f]; 01035 *string++ = '-'; 01036 *string++ = map[(p->data3 >> 12) & 0x0f]; 01037 *string++ = map[(p->data3 >> 8) & 0x0f]; 01038 *string++ = map[(p->data3 >> 4) & 0x0f]; 01039 *string++ = map[(p->data3 >> 0) & 0x0f]; 01040 *string++ = '-'; 01041 *string++ = map[(p->data4[0] >> 4) & 0x0f]; 01042 *string++ = map[(p->data4[0] >> 0) & 0x0f]; 01043 *string++ = map[(p->data4[1] >> 4) & 0x0f]; 01044 *string++ = map[(p->data4[1] >> 0) & 0x0f]; 01045 *string++ = '-'; 01046 *string++ = map[(p->data4[2] >> 4) & 0x0f]; 01047 *string++ = map[(p->data4[2] >> 0) & 0x0f]; 01048 *string++ = map[(p->data4[3] >> 4) & 0x0f]; 01049 *string++ = map[(p->data4[3] >> 0) & 0x0f]; 01050 *string++ = map[(p->data4[4] >> 4) & 0x0f]; 01051 *string++ = map[(p->data4[4] >> 0) & 0x0f]; 01052 *string++ = map[(p->data4[5] >> 4) & 0x0f]; 01053 *string++ = map[(p->data4[5] >> 0) & 0x0f]; 01054 *string++ = map[(p->data4[6] >> 4) & 0x0f]; 01055 *string++ = map[(p->data4[6] >> 0) & 0x0f]; 01056 *string++ = map[(p->data4[7] >> 4) & 0x0f]; 01057 *string++ = map[(p->data4[7] >> 0) & 0x0f]; 01058 01059 if (withBraces) 01060 *string++ = '}'; 01061 01062 *string++ = '\0'; 01063 } 01064 01065 01066 static inline PlankB pl_GUID_Equal (const PlankGUID* p, const PlankGUID* other) 01067 { 01068 return pl_MemoryCompare (p, other, sizeof (PlankGUID)); 01069 } 01070 01071 static inline PlankB pl_GUID_EqualWithString (const PlankGUID* p, const char* other) 01072 { 01073 PlankGUID guid; 01074 01075 if (pl_GUID_InitString (&guid, other) != PlankResult_OK) 01076 return PLANK_FALSE; 01077 01078 return pl_MemoryCompare (p, &guid, sizeof (PlankGUID)); 01079 } 01080 01081 01082 static inline PlankB pl_GUID_IsNull (const PlankGUID* p) 01083 { 01084 return (p->data1 == 0) && (p->data2 == 0) && (p->data3 == 0) && ((*(PlankULL*)p->data4) == 0); 01085 } 01086 01088 01089 01090 #endif // PLANK_CONTAINERSMISC_H