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 00015 00021 #define MINIINI_REALLOCATE(buf, cap, size, type)\ 00022 {\ 00023 cap *= 2;\ 00024 type * tempbuf = new type[cap];\ 00025 memcpy(tempbuf, buf, size * sizeof(type));\ 00026 delete [] buf;\ 00027 buf = tempbuf;\ 00028 } 00029 00030 00032 00036 inline const c * NextLine(const c * currentchar) 00037 { 00038 register c ch; 00039 //searching for first newline 00040 for(; ; ++currentchar) 00041 { 00042 ch = *currentchar; 00043 if(ch == 13 || ch == 10) 00044 { 00045 break; 00046 } 00047 else if(ch == '\0') 00048 { 00049 return currentchar; 00050 } 00051 } 00052 //searching for first non-newline 00053 for(; ; ++currentchar) 00054 { 00055 ch = *currentchar; 00056 if(ch != 13 && ch != 10) 00057 { 00058 return currentchar; 00059 } 00060 } 00061 } 00062 00064 00068 static inline const c * GetName(const INISection * ptr) 00069 { 00070 return ptr->GetName(); 00071 } 00072 00074 00078 static inline const c * GetName(const c * ptr) 00079 { 00080 return ptr; 00081 } 00082 00084 00091 template <typename T> 00092 inline bool Insert(T * * array, const ui length, register T * elem) 00093 { 00094 //Binary search to find where to insert elem 00095 ui min = 0; 00096 ui max = length; 00097 ui mid; 00098 register c c1, c2; 00099 register const c * str1, * str2; 00100 while(min < max) 00101 { 00102 mid = (max + min) / 2; 00103 //string comparison 00104 str1 = GetName(elem); 00105 str2 = GetName(array[mid]); 00106 do 00107 { 00108 c1 = *str1++; 00109 c2 = *str2++; 00110 } 00111 while(c1 && c1 == c2); 00112 if(c1 > c2) 00113 { 00114 min = mid + 1; 00115 } 00116 else 00117 { 00118 max = mid; 00119 } 00120 } 00121 00122 //when we're finished searching, min is the index where we can put the elem. 00123 ui movesize = length - min; 00124 //this is where we insert elem 00125 register T * * ins = array + min; 00126 //memmove is slow for small blocks of data 00127 if(movesize < 28) 00128 { 00129 register T * * out = array + length; 00130 register T * * in = out - 1; 00131 for(;in >= ins; --in, --out ) 00132 { 00133 *out = *in; 00134 } 00135 } 00136 else 00137 { 00138 memmove(ins + 1, ins, movesize * sizeof(T *)); 00139 } 00140 *ins = elem; 00141 return true; 00142 } 00143 00144 #ifdef __GNUC__ 00145 template <typename T> 00146 inline i BinarySearch(const T * const * const array, const ui length, const c * name) 00147 __attribute__((always_inline)) 00148 #endif 00149 ; 00151 00159 template <typename T> 00160 inline i BinarySearch(const T * const * const array, const ui length, const c * name) 00161 { 00162 //Start, middle and end of currently searched interval 00163 i min, mid, max; 00164 min = 0; 00165 max = length - 1; 00166 //We copy characters used in string comparison here 00167 register c c1, c2; 00168 register const c * str1, * str2; 00169 while(min <= max) 00170 { 00171 mid = (max + min) / 2; 00172 str1 = name; 00173 str2 = GetName(array[mid]); 00174 do 00175 { 00176 c1 = *str1++; 00177 c2 = *str2++; 00178 } 00179 while(c1 && c1 == c2); 00180 //tag is greater than Tags[mid] 00181 if(c1 > c2) 00182 { 00183 min = mid + 1; 00184 } 00185 else if(c1 < c2) 00186 { 00187 max = mid - 1; 00188 } 00189 else 00190 { 00191 //found tag 00192 return mid; 00193 } 00194 } 00195 //tag not found 00196 return -1; 00197 } 00198 00199 } 00201 #endif