diff --git a/include/strbuf.h b/include/strbuf.h index f25206b878..f9ac39fc62 100644 --- a/include/strbuf.h +++ b/include/strbuf.h @@ -1,51 +1,267 @@ #ifndef POKEPLATINUM_STRBUF_H #define POKEPLATINUM_STRBUF_H -typedef struct Strbuf_t Strbuf; +#include "struct_decls/struct_02023790_decl.h" + typedef u16 charcode_t; -/* +/** + * Managed string buffer. + */ +struct Strbuf { + /// Maximum allocated size of the buffer. + u16 maxSize; + + /// Size of the buffer, at present; the length of the underlying string. + u16 size; + + /// Integrity value specified at allocation time. + u32 integrity; + + /// The underlying character buffer. + /// + /// UB: This is meant to be a flexible array, but is purposefully defined + /// incorrectly in order to match the original byte-code. The correct + /// definition method would be as `data[]`. + charcode_t data[1]; +}; + +/** * Control codes for how to pad numeric strings. - * - * Ex: `1000000` being assigned to a buffer of size 20 may be: - * - Left-justified: "1000000 " - * - Right-justified, padded with spaces: " 1000000" - * - Right-justified, padded with zeroes: "00000000000001000000" */ enum PaddingMode { + /// Do not pad the string. Effectively left-justification. PADDING_MODE_NONE, + + /// Right-justify the string, padding with spaces. PADDING_MODE_SPACES, + + /// Right-justify the string, padding with zeroes. PADDING_MODE_ZEROES, }; -/* +/** * Control codes for which charset to use when formatting a string. */ enum CharsetMode { + /// Use the Japanese character set (i.e., full-width characters). CHARSET_MODE_JP, + + /// Use the English character set (i.e., half-width characters). CHARSET_MODE_EN, }; +/** + * @brief Init routine. Allocates memory for a new Strbuf, initializes it + * with an integrity-check value, and exposes its address. + * + * @param size The size of the new Strbuf to allocate from the heap. + * @param heapID ID of the heap to own the new Strbuf. + * @return Address to the new Strbuf. + */ Strbuf* Strbuf_Init(u32 size, u32 heapID); + +/** + * @brief Free routine. Destroys an existing Strbuf and returns its memory + * to the owning heap. + * + * @param strbuf Address to the Strbuf to be freed. + */ void Strbuf_Free(Strbuf *strbuf); + +/** + * @brief Clears out a string of any existing character data. The first value + * in the underlying data buffer is set to `CHAR_EOS`, and `strbuf->size` is + * set to 0. + * + * @param strbuf Address to the Strbuf to be cleared. + */ void Strbuf_Clear(Strbuf *strbuf); + +/** + * @brief Copies the contents of the data buffer in `src` to the data buffer + * in `dst`. Fails if the contents of `src` will not fit into `dst`'s + * allocated memory. + * + * @param dst Destination buffer. `dst->size` and `dst->data` will be modified. + * @param src Source buffer. `src->size` and `src->data` will be accessed. + */ void Strbuf_Copy(Strbuf *dst, const Strbuf *src); + +/** + * @brief Clones the contents of a given Strbuf into a new Strbuf and returns + * the address of the newly-created struct. + * + * This is effectively a nice wrapper around the following code: + * + * ```c + * Strbuf *dst = Strbuf_Init(src->size + 1, heapID); + * Strbuf_Copy(dst, src); + * ``` + * + * @param src Source buffer to clone. + * @param heapID ID of the heap which will own the new Strbuf. + * @return Address to the cloned Strbuf. + */ Strbuf* Strbuf_Clone(const Strbuf *src, u32 heapID); + +/** + * @brief Format a number into a destination buffer. + * + * The destination buffer must already be initialized. + * + * @param[out] dst Destination buffer. + * @param num Number to be formatted. + * @param maxDigits Maximum number of digits to format, right-justified. + * @param paddingMode Padding mode to use when formatting the number. + * @param charsetMode Charset mode to use when formatting the number. + */ void Strbuf_FormatInt(Strbuf *dst, int num, u32 maxDigits, enum PaddingMode paddingMode, enum CharsetMode charsetMode); + +/** + * @brief Format a number into a destination buffer. + * + * The destination buffer must already be initialized. + * + * @param[out] dst Destination buffer. + * @param num Number to be formatted. + * @param maxDigits Maximum number of digits to format, right-justified. + * @param paddingMode Padding mode to use when formatting the number. + * @param charsetMode Charset mode to use when formatting the number. + */ void Strbuf_FormatU64(Strbuf *dst, u64 num, u32 maxDigits, enum PaddingMode paddingMode, enum CharsetMode charsetMode); + +/** + * @brief Parses a numeric string into a number. + * + * @param src Numeric string. + * @param[out] success Flag denoting if the result string was fully processed. + * @return Parsed result. + */ u64 Strbuf_AtoI(const Strbuf *src, BOOL *success); + +/** + * @brief Compares two strings. Follows the `strcmp` standard. + * + * @param str1 First string. + * @param str2 Second string. + * @return 0 if the strings match, 1 if they do not. + */ int Strbuf_Compare(const Strbuf *str1, const Strbuf *str2); + +/** + * @brief Accessor for the length of a string. + * + * @param strbuf + * @return `strbuf->size` + */ u32 Strbuf_Length(const Strbuf *strbuf); + +/** + * @brief Counts the number of lines in a string. + * + * @param strbuf + * @return The number of lines in `strbuf`. + */ u32 Strbuf_NumLines(const Strbuf *strbuf); -void Strbuf_CopyLineNum(Strbuf *dst, const Strbuf *src, u32 linenum); + +/** + * @brief Copies a particular line number from `src` into `dst`. + * + * Lines are zero-indexed, e.g. `lineNum == 0` will copy the first line, + * `lineNum == 1` will copy the second line, etc. + * + * @param[out] dst Destination buffer. + * @param src Source buffer. + * @param lineNum Number of the line to copy, zero-indexed. + */ +void Strbuf_CopyLineNum(Strbuf *dst, const Strbuf *src, u32 lineNum); + +/** + * @brief Copies data from a raw character buffer into a managed Strbuf. + * + * @param[out] dst Destination buffer. + * @param src Raw character source buffer. + */ void Strbuf_CopyChars(Strbuf *dst, const charcode_t *src); + +/** + * @brief Copies a specific number of values from a raw character buffer into + * a managed Strbuf. + * + * @param[out] dst Destination buffer. + * @param src Raw character source buffer. + * @param num Number of values to copy. + */ void Strbuf_CopyNumChars(Strbuf *dst, const charcode_t *src, u32 num); -void Strbuf_ToChars(const Strbuf *src, charcode_t *dst, u32 dstsize); + +/** + * @brief Dumps the contents of a Strbuf into a raw character buffer. + * + * Fails if `src->size + 1 > dstSize`. + * + * @param src Source buffer. + * @param[out] dst Destination buffer. + * @param dstSize Size of `dst`. + */ +void Strbuf_ToChars(const Strbuf *src, charcode_t *dst, u32 dstSize); + +/** + * @brief Accessor for the underlying data buffer of a managed string. + * + * @param strbuf + * @return Underlying data buffer for `strbuf`. + */ const charcode_t* Strbuf_GetData(const Strbuf *strbuf); + +/** + * @brief Concatenates `src` onto the end of `dst`, if allocation permits. + * + * Fails if `dst->maxSize < dst->size + src->size + 1`. + * + * @param[out] dst Destination buffer. + * @param src Source buffer. + */ void Strbuf_Concat(Strbuf *dst, const Strbuf *src); + +/** + * @brief Appends a single character onto `dst`, if allocation permits. + * + * Fails if `dst->maxSize >= dst->size + 1`. + * + * @param[out] dst Destination buffer. + * @param c Character to append. + */ void Strbuf_AppendChar(Strbuf *dst, charcode_t c); + +/** + * @brief Checks if a given string is a trainer name. + * + * Trainer names are identified using a specific leader character which denotes + * different handling methods for their concatenation. + * + * @param strbuf + * @return TRUE if `strbuf` is a trainer name, FALSE otherwise. + */ BOOL Strbuf_IsTrainerName(Strbuf *strbuf); -void Strbuf_ConcatTrainerName(Strbuf *str1, Strbuf *str2); + +/** + * @brief Concatenates `src` onto the end of `dst`, accounting for trainer + * name compression. + * + * If `src` is not a trainer name, then this falls back to `Strbuf_Concat`. + * + * @param[out] dst Destination buffer. + * @param src Source buffer. + */ +void Strbuf_ConcatTrainerName(Strbuf *dst, Strbuf *src); + +/** + * @brief Converts a particular character to uppercase. + * + * @param strbuf + * @param i Index of the character to capitalize, zero-indexed. + */ void Strbuf_UpperChar(Strbuf *strbuf, int i); #endif // POKEPLATINUM_STRBUF_H diff --git a/include/struct_decls/struct_02023790_decl.h b/include/struct_decls/struct_02023790_decl.h index d94fd62075..011831121e 100644 --- a/include/struct_decls/struct_02023790_decl.h +++ b/include/struct_decls/struct_02023790_decl.h @@ -1,6 +1,6 @@ #ifndef POKEPLATINUM_STRUCT_02023790_DECL_H #define POKEPLATINUM_STRUCT_02023790_DECL_H -typedef struct Strbuf_t Strbuf; +typedef struct Strbuf Strbuf; #endif // POKEPLATINUM_STRUCT_02023790_DECL_H diff --git a/src/overlay056/ov56_022561C0.c b/src/overlay056/ov56_022561C0.c index 09f69cc6f6..fa0753025f 100644 --- a/src/overlay056/ov56_022561C0.c +++ b/src/overlay056/ov56_022561C0.c @@ -61,13 +61,6 @@ FS_EXTERN_OVERLAY(overlay56); -struct Strbuf_t { - u16 unk_00; - u16 unk_02; - u32 unk_04; - u16 unk_08[1]; -}; - typedef struct { u16 unk_00; u16 unk_02; diff --git a/src/strbuf.c b/src/strbuf.c index d986dbd970..ae4765ab9b 100644 --- a/src/strbuf.c +++ b/src/strbuf.c @@ -5,13 +5,6 @@ #include "heap.h" #include "strbuf.h" -struct Strbuf_t { - u16 maxSize; - u16 size; - u32 integrity; - charcode_t data[1]; -}; - #define SIZEOF_STRBUF_HEADER (sizeof(Strbuf) - sizeof(charcode_t)) #define STRBUF_MAGIC_NUMBER (0xB6F8D2EC)