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 INSERT_H_INCLUDED 00006 #define INSERT_H_INCLUDED 00007 00008 #include "typedefs.h" 00009 00011 namespace miniini_private 00012 { 00013 00015 00021 #define 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 void 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 //when we're finished searching, min is the index where we can put the elem. 00122 ui movesize = length - min; 00123 //this is where we insert elem 00124 register T * * ins = array + min; 00125 //memmove is slow for small blocks of data 00126 if(movesize < 28) 00127 { 00128 register T * * out = array + length; 00129 register T * * in = out - 1; 00130 for(;in >= ins; --in, --out ) 00131 { 00132 *out = *in; 00133 } 00134 } 00135 else 00136 { 00137 memmove(ins + 1, ins, movesize * sizeof(T *)); 00138 } 00139 *ins = elem; 00140 } 00141 00142 #ifdef __GNUC__ 00143 template <typename T> 00144 inline i BinarySearch(const T * const * const array, const ui length, const c * name) 00145 __attribute__((always_inline)) 00146 #endif 00147 ; 00149 00157 template <typename T> 00158 inline i BinarySearch(const T * const * const array, const ui length, const c * name) 00159 { 00160 //Start, middle and end of currently searched interval 00161 i min, mid, max; 00162 min = 0; 00163 max = length - 1; 00164 //We copy characters used in string comparison here 00165 register c c1, c2; 00166 register const c * str1, * str2; 00167 while(min <= max) 00168 { 00169 mid = (max + min) / 2; 00170 str1 = name; 00171 str2 = GetName(array[mid]); 00172 do 00173 { 00174 c1 = *str1++; 00175 c2 = *str2++; 00176 } 00177 while(c1 && c1 == c2); 00178 //tag is greater than Tags[mid] 00179 if(c1 > c2) 00180 { 00181 min = mid + 1; 00182 } 00183 else if(c1 < c2) 00184 { 00185 max = mid - 1; 00186 } 00187 else 00188 { 00189 //found tag 00190 return mid; 00191 } 00192 } 00193 //tag not found 00194 return -1; 00195 } 00196 00197 } 00199 #endif