00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef HAVE_CONFIG_H
00023 # include <config.h>
00024 #endif
00025
00026 #ifndef ALPHA_LINUX_CXX
00027 #include <fstream>
00028 #include <cstring>
00029 #include <iomanip>
00030 #include <iostream>
00031 #include <cstdlib>
00032 #include <cstdio>
00033 #endif
00034
00035 #include "useval.h"
00036 #include "utils.h"
00037
00038 #ifndef UNDER_CE
00039 using std::cout;
00040 using std::endl;
00041 using std::dec;
00042 using std::hex;
00043 using std::memcpy;
00044 using std::ostream;
00045 using std::setfill;
00046 using std::setw;
00047 using std::strcmp;
00048 using std::strlen;
00049 #endif
00050
00051
00052
00053
00054
00055
00056
00057 int Usecode_value::count_array
00058 (
00059 const Usecode_value& val
00060 )
00061 {
00062 int i;
00063 for (i = 0; val.value.array[i].type != end_of_array_type; i++)
00064 ;
00065 return (i);
00066 }
00067
00068
00069
00070
00071
00072
00073 Usecode_value::~Usecode_value()
00074 {
00075 if (type == array_type)
00076 delete [] value.array;
00077 else if (type == string_type)
00078 delete [] value.str;
00079 }
00080
00081
00082
00083
00084
00085 Usecode_value& Usecode_value::operator=
00086 (
00087 const Usecode_value& v2
00088 )
00089 {
00090 if (&v2 == this)
00091 return *this;
00092 if (type == array_type)
00093 delete [] value.array;
00094 else if (type == string_type)
00095 delete [] value.str;
00096 type = v2.type;
00097 if (type == int_type)
00098 value.intval = v2.value.intval;
00099 else if (type == pointer_type)
00100 value.ptr = v2.value.ptr;
00101 else if (type == string_type)
00102 value.str = v2.value.str ? newstrdup(v2.value.str) : 0;
00103 else if (type == array_type)
00104 {
00105 int tempsize = 1+count_array(v2);
00106 value.array = new Usecode_value[tempsize];
00107 int i = 0;
00108 do
00109 value.array[i] = v2.value.array[i];
00110 while (value.array[i++].type != end_of_array_type);
00111 }
00112
00113 undefined = v2.undefined;
00114
00115 return *this;
00116 }
00117
00118
00119
00120
00121
00122
00123 Usecode_value& Usecode_value::operator=
00124 (
00125 const char *str
00126 )
00127 {
00128 if (type == array_type)
00129 delete [] value.array;
00130 else if (type == string_type)
00131 delete [] value.str;
00132 type = string_type;
00133 value.str = str ? newstrdup(str) : 0;
00134 return *this;
00135 }
00136
00137
00138
00139
00140
00141 Usecode_value::Usecode_value
00142 (
00143 const char *s
00144 ) : type(string_type), undefined(false)
00145 {
00146 value.str = s ? newstrdup(s) : 0;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156 int Usecode_value::resize
00157 (
00158 int new_size
00159 )
00160 {
00161 if (type != array_type)
00162 {
00163 Usecode_value elem(*this);
00164 *this = Usecode_value(new_size, &elem);
00165 return (1);
00166 }
00167 int size = count_array(*this);
00168 if (new_size == size)
00169 return (1);
00170 Usecode_value *newvals = new Usecode_value[new_size + 1];
00171 newvals[new_size].type = end_of_array_type;
00172
00173 int cnt = new_size < size ? new_size : size;
00174 for (int i = 0; i < cnt; i++)
00175 newvals[i] = value.array[i];
00176 delete [] value.array;
00177 value.array = newvals;
00178 return (1);
00179 }
00180
00181 void Usecode_value::push_back(int i)
00182 {
00183 resize(count_array(*this)+1);
00184 value.array[count_array(*this)-1]=Usecode_value(i);
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 bool Usecode_value::operator==
00194 (
00195 const Usecode_value& v2
00196 ) const
00197 {
00198 if (&v2 == this)
00199 return true;
00200 if (type == int_type)
00201 return (v2.type == int_type || v2.type == pointer_type) ?
00202 (value.intval == v2.value.intval)
00203
00204 : v2.type == array_type &&
00205 !value.intval && !v2.get_array_size();
00206 else if (type == pointer_type)
00207 {
00208 if (v2.type == pointer_type || v2.type == int_type)
00209 return (value.ptr == v2.value.ptr);
00210 else if (v2.type == array_type && v2.get_array_size())
00211 {
00212 const Usecode_value& val2 = v2.value.array[0];
00213 return (value.ptr == val2.value.ptr);
00214 }
00215 else
00216 return false;
00217 }
00218 else if (type == array_type)
00219 {
00220 if (v2.type == int_type)
00221 return !get_array_size() && !v2.get_int_value();
00222 else if (v2.type == pointer_type && get_array_size())
00223 {
00224 Usecode_value& v = get_elem(0);
00225 return v2.value.ptr == v.value.ptr;
00226 }
00227 if (v2.type != array_type)
00228 return false;
00229 int cnt = get_array_size();
00230 if (cnt != v2.get_array_size())
00231 return false;
00232 for (int i = 0; i < cnt; i++)
00233 {
00234 Usecode_value& e1 = get_elem(i);
00235 const Usecode_value& e2 = v2.get_elem(i);
00236 if (!(e1 == e2))
00237 return false;
00238 }
00239 return true;
00240 }
00241 else if (type == string_type)
00242 return (v2.type == string_type &&
00243 strcmp(value.str, v2.value.str) == 0);
00244 else
00245 return false;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254 int Usecode_value::find_elem
00255 (
00256 const Usecode_value& val
00257 )
00258 {
00259 if (type != array_type)
00260 return (-1);
00261 int i;
00262 for (i = 0; value.array[i].type != end_of_array_type; i++)
00263 if (value.array[i] == val)
00264 return (i);
00265 return (-1);
00266 }
00267
00268
00269
00270
00271
00272
00273
00274 Usecode_value& Usecode_value::concat
00275 (
00276 Usecode_value& val2
00277 )
00278 {
00279 int size;
00280 if (type != array_type)
00281 {
00282 Usecode_value tmp(1, this);
00283 *this = tmp;
00284 size = 1;
00285 }
00286 else
00287 size = get_array_size();
00288 if (val2.type != array_type)
00289 {
00290 resize(size + 1);
00291 put_elem(size, val2);
00292 }
00293 else
00294 {
00295 int size2 = val2.get_array_size();
00296 resize(size + size2);
00297 for (int i = 0; i < size2; i++)
00298 put_elem(size + i, val2.get_elem(i));
00299 }
00300 return (*this);
00301 }
00302
00303
00304
00305
00306
00307 void Usecode_value::append
00308 (
00309 int *vals,
00310 int cnt
00311 )
00312 {
00313 assert(type == array_type);
00314 int sz = get_array_size();
00315 resize(sz + cnt);
00316 for (int i = 0; i < cnt; i++)
00317 value.array[sz + i].value.intval = vals[i];
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327 int Usecode_value::add_values
00328 (
00329 int index,
00330 Usecode_value& val2
00331 )
00332 {
00333 int size = get_array_size();
00334 if (!val2.is_array())
00335 {
00336 if (index >= size)
00337 resize(index + 1);
00338 put_elem(index, val2);
00339 return (1);
00340 }
00341
00342 int size2 = val2.get_array_size();
00343 if (index + size2 > size)
00344 resize(index + size2);
00345 for (int i = 0; i < size2; i++)
00346 put_elem(index++, val2.get_elem(i));
00347 return (size2);
00348 }
00349
00350
00351
00352
00353
00354 void Usecode_value::print
00355 (
00356 ostream& out, bool shortformat
00357 )
00358 {
00359 switch ((Val_type) type)
00360 {
00361 case int_type:
00362 out << hex << setfill((char)0x30) << setw(4);
00363 out << (value.intval&0xffff);
00364 out << dec;
00365 break;
00366 case pointer_type:
00367 out << hex << setfill((char)0x30) << setw(8);
00368 out << (long)value.ptr;
00369 out << dec;
00370 break;
00371 case string_type:
00372 out << '"' << value.str << '"'; break;
00373 case array_type:
00374 {
00375 out << "[ ";
00376 int i;
00377 for (i = 0; value.array[i].type != end_of_array_type; i++) {
00378 if (!shortformat || i < 2) {
00379 if (i)
00380 out << ", ";
00381
00382 value.array[i].print(out);
00383 }
00384 }
00385 if (shortformat && i > 2)
00386 out << ", ... (size " << i << ")";
00387 out << " ]";
00388 }
00389 break;
00390 default:
00391 break;
00392 }
00393 }
00394
00395 Usecode_value Usecode_value::operator+(const Usecode_value& v2)
00396 {
00397 char buf[300];
00398 Usecode_value& v1 = *this;
00399 Usecode_value sum(0);
00400
00401 if (v1.is_undefined())
00402 {
00403 sum = v2;
00404 }
00405 else if (v2.is_undefined())
00406 {
00407 sum = v1;
00408 }
00409 else if (v1.get_type() == Usecode_value::int_type)
00410 {
00411 if (v2.get_type() == Usecode_value::int_type) {
00412 sum = Usecode_value(v1.get_int_value()
00413 + v2.get_int_value());
00414 } else if (v2.get_type() == Usecode_value::string_type) {
00415 snprintf(buf, 300, "%ld%s",
00416 v1.get_int_value(),
00417 v2.get_str_value());
00418 sum = Usecode_value(buf);
00419 } else {
00420 sum = v1;
00421 }
00422 }
00423 else if (v1.get_type() == Usecode_value::string_type)
00424 {
00425 if (v2.get_type() == Usecode_value::int_type) {
00426 snprintf(buf, 300, "%s%ld",
00427 v1.get_str_value(),
00428 v2.get_int_value());
00429 sum = Usecode_value(buf);
00430 } else if (v2.get_type() == Usecode_value::string_type) {
00431 snprintf(buf, 300, "%s%s",
00432 v1.get_str_value(),
00433 v2.get_str_value());
00434 sum = Usecode_value(buf);
00435 } else {
00436 sum = v1;
00437 }
00438 }
00439 return sum;
00440 }
00441
00442
00443
00444
00445
00446
00447
00448 int Usecode_value::save
00449 (
00450 unsigned char *buf,
00451 int buflen
00452 )
00453 {
00454 uint8 *ptr = buf;
00455 switch ((Val_type) type)
00456 {
00457 case int_type:
00458 if (buflen < 5)
00459 return -1;
00460 *ptr++ = type;
00461 Write4(ptr, value.intval);
00462 break;
00463 case pointer_type:
00464 if (buflen < 5)
00465 return -1;
00466 *ptr++ = type;
00467 Write4(ptr, (int)value.ptr);
00468 break;
00469 case string_type:
00470 {
00471 int len = std::strlen(value.str);
00472 if (buflen < len + 3)
00473 return -1;
00474 *ptr++ = type;
00475 Write2(ptr, len);
00476 std::memcpy(ptr, value.str, len);
00477 ptr += len;
00478 break;
00479 }
00480 case array_type:
00481 {
00482 if (buflen < 3)
00483 return -1;
00484 *ptr++ = type;
00485 int len = count_array(*this);
00486 Write2(ptr, len);
00487 int remaining = buflen - 3;
00488 for (int i=0; i < len; i++) {
00489 int retval = value.array[i].save(ptr, remaining);
00490 if (retval == -1)
00491 return -1;
00492
00493 ptr += retval;
00494 remaining -= retval;
00495 }
00496 break;
00497 }
00498 default:
00499 return -1;
00500 }
00501 return (ptr - buf);
00502 }
00503
00504
00505
00506
00507
00508
00509
00510 bool Usecode_value::restore
00511 (
00512 unsigned char *& ptr,
00513 int buflen
00514 )
00515 {
00516 undefined = false;
00517 type = (Val_type) *ptr++;
00518 switch (type)
00519 {
00520 case int_type:
00521 if (buflen < 5)
00522 return false;
00523 value.intval = Read4(ptr);
00524 return true;
00525 case pointer_type:
00526 if (buflen < 5)
00527 return false;
00528 value.ptr = (Game_object*)Read4(ptr);
00529
00530 return true;
00531 case string_type:
00532 {
00533 int len = Read2(ptr);
00534 if (buflen < len + 3)
00535 return false;
00536 value.str = new char[len + 1];
00537 std::memcpy(value.str, ptr, len);
00538 value.str[len] = 0;
00539 ptr += len;
00540 return true;
00541 }
00542 case array_type:
00543 {
00544 if (buflen < 3)
00545 return false;
00546 int len = Read2(ptr);
00547 int remaining = buflen - 3;
00548 *this = Usecode_value(len, 0);
00549 for (int i=0; i < len; i++) {
00550 uint8* t = ptr;
00551 bool retval = value.array[i].restore(ptr, remaining);
00552 remaining -= (ptr - t);
00553 if (!retval)
00554 return false;
00555 }
00556 return true;
00557 }
00558 default:
00559 return false;
00560 }
00561 }
00562
00563
00564 ostream& operator<<(ostream& out, Usecode_value& val)
00565 {
00566 val.print(out, true);
00567 return out;
00568 }