487 /* Write The value to the struct. These ARE endian safe. */ |
487 /* Write The value to the struct. These ARE endian safe. */ |
488 WriteValue(ptr, conv, x); |
488 WriteValue(ptr, conv, x); |
489 } |
489 } |
490 } |
490 } |
491 |
491 |
|
492 /** Calculate the net length of a string. This is in almost all cases |
|
493 * just strlen(), but if the string is not properly terminated, we'll |
|
494 * resort to the maximum length of the buffer. |
|
495 * @param ptr pointer to the stringbuffer |
|
496 * @param length maximum length of the string (buffer) |
|
497 * @return return the net length of the string */ |
|
498 static inline size_t SlCalcNetStringLen(const char *ptr, uint length) |
|
499 { |
|
500 return minu(strlen(ptr), length - 1); |
|
501 } |
|
502 |
|
503 /** Calculate the gross length of the string that it |
|
504 * will occupy in the savegame. This includes the real length, returned |
|
505 * by SlCalcNetStringLen and the length that the index will occupy. |
|
506 * @param ptr pointer to the stringbuffer |
|
507 * @param length maximum length of the string (buffer size, etc.) |
|
508 * @return return the gross length of the string */ |
492 static inline size_t SlCalcStringLen(const char *ptr, uint length) |
509 static inline size_t SlCalcStringLen(const char *ptr, uint length) |
493 { |
510 { |
494 DEBUG(misc, 1) ("[Sl] TODO: save/load real length"); |
511 uint len = SlCalcNetStringLen(ptr, length); |
495 return length;//(_sl.save) ? min(strlen(ptr), length - 1) : SlReadArrayLength(); |
512 return len + SlGetArrayLength(len); // also include the length of the index |
496 } |
513 } |
497 |
514 |
498 /** |
515 /** |
499 * Save/Load a string. |
516 * Save/Load a string. |
500 * @param ptr the string being manipulated |
517 * @param ptr the string being manipulated |
501 * @param the length of the string (full length) |
518 * @param the length of the string (full length) |
502 * @param conv must be SLE_FILE_STRING |
519 * @param conv must be SLE_FILE_STRING */ |
503 * @todo the full length of the string is saved, even when the buffer |
|
504 * is 512 bytes and only 10 of those are used */ |
|
505 static void SlString(void *ptr, uint length, VarType conv) |
520 static void SlString(void *ptr, uint length, VarType conv) |
506 { |
521 { |
507 uint len = SlCalcStringLen(ptr, length); |
522 uint len; |
508 assert((conv & 0xF) == SLE_FILE_STRING); |
523 assert(GetVarFileType(conv) == SLE_FILE_STRING); |
509 |
524 |
510 SlCopyBytes(ptr, len); |
525 if (_sl.save) { |
|
526 len = SlCalcNetStringLen(ptr, length); |
|
527 SlWriteArrayLength(len); |
|
528 SlCopyBytes(ptr, len); |
|
529 return; |
|
530 } |
|
531 |
|
532 len = SlReadArrayLength(); |
|
533 |
|
534 if (len >= length) { |
|
535 DEBUG(misc, 0) ("[Sl] String length in savegame is bigger than buffer, truncating"); |
|
536 SlCopyBytes(ptr, length); |
|
537 SlSkipBytes(len - length); |
|
538 len = length - 1; |
|
539 } else { |
|
540 SlCopyBytes(ptr, len); |
|
541 } |
|
542 |
|
543 ((char*)ptr)[len] = '\0'; // properly terminate the string |
511 } |
544 } |
512 |
545 |
513 /** |
546 /** |
514 * Return the size in bytes of a certain type of atomic array |
547 * Return the size in bytes of a certain type of atomic array |
515 * @param length The length of the array counted in elements |
548 * @param length The length of the array counted in elements |