Skip to content

Fix endianness and alignment assumptions in pnNpCommon IO code#1850

Open
dgelessus wants to merge 11 commits intoH-uru:masterfrom
dgelessus:pnNpCommon_endianness
Open

Fix endianness and alignment assumptions in pnNpCommon IO code#1850
dgelessus wants to merge 11 commits intoH-uru:masterfrom
dgelessus:pnNpCommon_endianness

Conversation

@dgelessus
Copy link
Copy Markdown
Contributor

My goal was just to remove the StrCopy calls, but while I was here, I also fixed the endianness and alignment issues in this code. Perhaps it will help @dpogue on PowerPC :)

This adds some helper functions for converting little-endian UTF-16 directly from/to ST::string, which could also be useful for other code that reads/writes UTF-16 strings manually, like file server manifests and the GameMgr.

Copy link
Copy Markdown
Member

@dpogue dpogue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definitely nicer than the hacky string copy stuff I had to do in plNglFile


#include "HeadSpin.h"

#include <string_theory/string>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use forward declarations instead?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably. I was too lazy to type out the template declaration needed for ST::char16_buffer :D

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the return type of hsSTStringToUTF16LE as suggested above would also resolve this ;)

@Hoikas Hoikas requested a review from zrax March 8, 2026 19:18
Comment on lines +62 to +63
// Can't pre-allocate anything, because we don't know the string length yet...
std::vector<char16_t> utf16Buffer;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can, however, reserve bufferSize/sizeof(char16_t) to flatten the number of actual memory allocations to 1.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, I don't think that's a good idea in the general case. For something like the file server manifests, where we have potentially hundreds of zero-terminated strings concatenated, we don't want to reserve the size of the entire manifest for each string.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good point, I wasn't considering the case where the buffer is significantly larger than the string to extract from it...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would something like 128 work as an initial size that's big enough to handle most of the strings we'd expect over the network without incurring reallocations but also not incurring a big chunk of memory?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rewrote the code so it counts the string length beforehand. This allows reusing hsSTStringFromUTF16LE, which allocates a buffer with the right size.

return ST::string::from_utf16(utf16Buffer.data(), utf16Buffer.size());
}

ST::utf16_buffer hsSTStringToUTF16LE(const ST::string& string)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swapping the endianness of the buffer implies that this is no longer a legal utf16_buffer... It may make more sense logically to return as a vector<uint16_t>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made it a std::vector<uint8_t> now, so we don't have any incorrect endianness values at all. This actually also works better for the calling code.


#include "HeadSpin.h"

#include <string_theory/string>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the return type of hsSTStringToUTF16LE as suggested above would also resolve this ;)

@dgelessus dgelessus force-pushed the pnNpCommon_endianness branch from cd6cbe1 to 2c39b17 Compare March 12, 2026 00:50
@dgelessus dgelessus force-pushed the pnNpCommon_endianness branch from 65326ec to 2bec282 Compare March 22, 2026 00:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants