00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00026 #include "fibonacci.h"
00027
00028
00029 #ifdef __GNUG__
00030 # pragma implementation
00031 #endif
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00051 static unsigned long Order2FibonacciNumbers_[] = {
00052 1, 2, 3, 5,
00053 8, 13, 21, 34, 55,
00054 89, 144, 233, 377, 610,
00055 987, 1597, 2584, 4181, 6765,
00056 10946, 17711, 28657, 46368, 75025,
00057 121393, 196418, 317811, 514229, 832040,
00058 1346269, 2178309, 3524578, 5702887, 9227465,
00059 14930352, 24157817, 39088169, 63245986, 102334155,
00060 165580141, 267914296, 433494437, 701408733, 1134903170
00061 };
00062
00064 #define NUMBER_OF_ORDER2_FIBS 44
00065
00066
00075 unsigned long Fibonacci::encode(unsigned long number)
00076 {
00077 int i = NUMBER_OF_ORDER2_FIBS - 1;
00078
00079 unsigned long fn;
00080 unsigned long code;
00081
00082 code = 1;
00083
00084 while (i > -1)
00085 {
00086 fn = Order2FibonacciNumbers_[i];
00087
00088 if (fn <= number)
00089 {
00090 number -= fn;
00091
00092 code <<= 1;
00093 code |= 1;
00094 }
00095 else
00096 if (code > 1)
00097 code <<= 1;
00098
00099 i--;
00100 }
00101
00102 return code;
00103 }
00104
00105
00106
00115 unsigned long Fibonacci::decode(unsigned long code)
00116 {
00117 unsigned long number = 0;
00118 int i = 0;
00119 bool lastWasOne = false;
00120
00121 while (code)
00122 {
00123 if (code & 1)
00124 {
00125 if (!lastWasOne)
00126 {
00127 number += Order2FibonacciNumbers_[i];
00128
00129 lastWasOne = true;
00130 }
00131 else
00132
00133 return number;
00134 }
00135 else
00136 lastWasOne = false;
00137
00138 code >>= 1;
00139 i++;
00140 }
00141
00142 return number;
00143 }
00144
00145
00146
00160 size_t Fibonacci::encodeToBuffer(void *buffer, size_t itemSize, unsigned long number)
00161 {
00162 unsigned char *charBuf = (unsigned char *)buffer;
00163 unsigned char tmpChar = 0;
00164 unsigned char bits = 0;
00165 size_t charsTotal = 0;
00166 unsigned long code = encode(number);
00167
00168
00169 while (code)
00170 {
00171 tmpChar <<= 1;
00172 tmpChar |= (code & 1);
00173 bits++;
00174
00175 if (bits == SIZEOF_CHAR*8)
00176 {
00177
00178 charBuf[charsTotal] = tmpChar;
00179 charsTotal++;
00180 bits = 0;
00181 tmpChar = 0;
00182 }
00183
00184 code >>= 1;
00185 }
00186
00187 if (!bits)
00188
00189 charsTotal--;
00190 else
00191 {
00192
00193
00194 while (bits < SIZEOF_CHAR*8)
00195 {
00196 tmpChar <<= 1;
00197 bits++;
00198 }
00199 charBuf[charsTotal] = tmpChar;
00200 }
00201
00202
00203 while ((charsTotal + 1) % itemSize)
00204 {
00205
00206 charsTotal++;
00207 charBuf[charsTotal] = 0;
00208 }
00209
00210 return (charsTotal+1) / itemSize;
00211 }
00212
00213
00214
00215
00229 size_t Fibonacci::decodeFromBuffer(void *buffer, size_t itemSize, size_t *nrItems)
00230 {
00231 unsigned long code = 0;
00232 unsigned long number;
00233 unsigned char *charBuf = (unsigned char *)buffer;
00234 bool lastWasOne = false;
00235 unsigned char tmpChar = 0;
00236 size_t charsTotal = 0;
00237 unsigned char mask;
00238
00239
00240 while (true)
00241 {
00242 tmpChar = charBuf[charsTotal];
00243 charsTotal++;
00244 mask = 1 << (SIZEOF_CHAR*8-1);
00245
00246 while (mask)
00247 {
00248 if (tmpChar & mask)
00249 {
00250 if (!lastWasOne)
00251 {
00252 code <<= 1;
00253 code |= 1;
00254 lastWasOne = true;
00255 }
00256 else
00257 {
00258 number = decode(code);
00259
00260 while (charsTotal % itemSize)
00261 charsTotal++;
00262
00263 *nrItems = charsTotal / itemSize;
00264 return number;
00265 }
00266 }
00267 else
00268 {
00269 code <<= 1;
00270 lastWasOne = false;
00271 }
00272
00273 mask >>= 1;
00274 }
00275 }
00276
00277 }
00278
00279