Made on Kubuntu
00001 // Copyright (C) 2009-2010 Ferdinand Majerech 00002 // This file is part of MiniINI 00003 // For conditions of distribution and use, see copyright notice in LICENSE.txt 00004 00005 #ifndef UTIL_H_INCLUDED 00006 #define UTIL_H_INCLUDED 00007 00008 #include "typedefs.h" 00009 00011 namespace miniini_private 00012 { 00013 00020 #define MINIINI_REALLOCATE(buf, cap, size, type)\ 00021 {\ 00022 cap *= 2;\ 00023 type * tempbuf = new type[cap];\ 00024 memcpy(tempbuf, buf, size * sizeof(type));\ 00025 delete [] buf;\ 00026 buf = tempbuf;\ 00027 } 00028 00029 00034 inline const c * NextLine(const c * currentchar) 00035 { 00036 register c ch; 00037 //searching for first newline 00038 for(; ; ++currentchar) 00039 { 00040 ch = *currentchar; 00041 if(ch == 13 || ch == 10) 00042 { 00043 break; 00044 } 00045 else if(ch == '\0') 00046 { 00047 return currentchar; 00048 } 00049 } 00050 //searching for first non-newline 00051 for(; ; ++currentchar) 00052 { 00053 ch = *currentchar; 00054 if(ch != 13 && ch != 10) 00055 { 00056 return currentchar; 00057 } 00058 } 00059 } 00060 00065 static inline const c * GetName(const INISection * ptr) 00066 { 00067 return ptr->GetName(); 00068 } 00069 00074 static inline const c * GetName(const c * ptr) 00075 { 00076 return ptr; 00077 } 00078 00086 template <typename T> 00087 inline bool Insert(T * * array, const ui length, register T * elem) 00088 { 00089 //Binary search to find where to insert elem 00090 ui min = 0; 00091 ui max = length; 00092 ui mid; 00093 register c c1, c2; 00094 register const c * str1, * str2; 00095 while(min < max) 00096 { 00097 mid = (max + min) / 2; 00098 //string comparison 00099 str1 = GetName(elem); 00100 str2 = GetName(array[mid]); 00101 do 00102 { 00103 c1 = *str1++; 00104 c2 = *str2++; 00105 } 00106 while(c1 && c1 == c2); 00107 if(c1 > c2) 00108 { 00109 min = mid + 1; 00110 } 00111 else 00112 { 00113 max = mid; 00114 } 00115 } 00116 00117 //when we're finished searching, min is the index where we can put the elem. 00118 ui movesize = length - min; 00119 //this is where we insert elem 00120 register T * * ins = array + min; 00121 //memmove is slow for small blocks of data 00122 if(movesize < 28) 00123 { 00124 register T * * out = array + length; 00125 register T * * in = out - 1; 00126 for(;in >= ins; --in, --out ) 00127 { 00128 *out = *in; 00129 } 00130 } 00131 else 00132 { 00133 memmove(ins + 1, ins, movesize * sizeof(T *)); 00134 } 00135 *ins = elem; 00136 return true; 00137 } 00138 00139 #ifdef __GNUC__ 00140 template <typename T> 00141 inline i BinarySearch(const T * const * const array, const ui length, const c * name) 00142 __attribute__((always_inline)) 00143 #endif 00144 ; 00153 template <typename T> 00154 inline i BinarySearch(const T * const * const array, const ui length, const c * name) 00155 { 00156 //Start, middle and end of currently searched interval 00157 i min, mid, max; 00158 min = 0; 00159 max = length - 1; 00160 //We copy characters used in string comparison here 00161 register c c1, c2; 00162 register const c * str1, * str2; 00163 while(min <= max) 00164 { 00165 mid = (max + min) / 2; 00166 str1 = name; 00167 str2 = GetName(array[mid]); 00168 do 00169 { 00170 c1 = *str1++; 00171 c2 = *str2++; 00172 } 00173 while(c1 && c1 == c2); 00174 //tag is greater than Tags[mid] 00175 if(c1 > c2) 00176 { 00177 min = mid + 1; 00178 } 00179 else if(c1 < c2) 00180 { 00181 max = mid - 1; 00182 } 00183 else 00184 { 00185 //found tag 00186 return mid; 00187 } 00188 } 00189 //tag not found 00190 return -1; 00191 } 00192 00193 } 00195 #endif