We can just return a new instance of this when it's requested. This only
ever holds pointers to the existing registed caches, so it's not a large
object. Plus, this also gets rid of the need to keep around a separate
member function just to properly clear out the union.
Gets rid of one of five globals in the filesystem code.
This is the same behavior-wise as DeleteDirectoryRecursively, with the
only difference being that it doesn't delete the top level directory in
the hierarchy, so given:
root_dir/
- some_dir/
- File.txt
- OtherFile.txt
The end result is just:
root_dir/
These parameters don't need to utilize a shared lifecycle directly in
the interface. Instead, the caller should provide a regular reference
for the function to use. This also allows the type system to flag
attempts to pass nullptr and makes it more generic, since it can now be
used in contexts where a shared_ptr isn't being used (in other words, we
don't constrain the usage of the interface to a particular mode of
memory management).
While we're at it, organize the array linearly, since clang formats the
array elements quite wide length-wise with the addition of the missing
'u'.
Technically also fixes patch lookup and icon lookup with Portuguese,
though I doubt anyone has actually run into this issue.
The decision was made to name them LayeredExeFS instead of just LayeredFS to differentiate from normal RomFS-based mods. The name may be long/unweildy, but conveys the meaning well.
This will scan the <mod>/exefs dir for all files and then layer those on top of the game's exefs and use this as the new exefs. This allows for overriding of the compressed NSOs or adding new files. This does use the same dir as IPS/IPSwitch patch, but since the loader will not look for those they are ignored.
There's no real point to keeping the separate enum around, especially
given the name of the error code itself is supposed to document what the
value actually represents.
Allows resuing a common KeyManager when a large amount of NCAs are handled by the same class. Should the parameter not be provided, a new KeyManager will be constructed, as was the default behavior prior to this.
* get rid of boost::optional
* Remove optional references
* Use std::reference_wrapper for optional references
* Fix clang format
* Fix clang format part 2
* Adressed feedback
* Fix clang format and MacOS build
Returns the raw NACP bytes and the raw icon bytes into a title-provided buffer. Pulls from Registration Cache for control data, returning all zeros should it not exist.
When enabled in settings, PatchNSO will dump the unmodified NSO that it was passed to a file named <build id>.nso in the dump root for the current title ID.
When writing VFS, it initally seemed useful to include a function to in-place convert container files into directories in one homogenous directory structure, but re-evaluating it now there have been plenty of chances to use it and there has always been a better way. Removing as it is unused and likely will not be used.
The constructor alone is pretty large, the reading code should be split
into its consistuent parts to make it easier to understand it without
having to build a mental model of a 300+ line function.
The only reason the getter existed was to check whether or not the
program NCA was null. Instead, we can just provide a function to query
for the existence of it, instead of exposing it entirely.
The data retrieved in these cases are ultimately chiefly owned by either
the RegisteredCache instance itself, or the filesystem factories. Both
these should live throughout the use of their contained data. If they
don't, it should be considered an interface/design issue, and using
shared_ptr instances here would mask that, as the data would always be
prolonged after the main owner's lifetime ended.
This makes the lifetime of the data explicit and makes it harder to
accidentally create cyclic references. It also makes the interface
slightly more flexible than the previous API, as a shared_ptr can be
created from a unique_ptr, but not the other way around, so this allows
for that use-case if it ever becomes necessary in some form.
Neither of these functions require the use of shared ownership of the
returned pointer. This makes it more difficult to create reference
cycles with, and makes the interface more generic, as std::shared_ptr
instances can be created from a std::unique_ptr, but the vice-versa
isn't possible. This also alters relevant functions to take NCA
arguments by const reference rather than a const reference to a
std::shared_ptr. These functions don't alter the ownership of the memory
used by the NCA instance, so we can make the interface more generic by
not assuming anything about the type of smart pointer the NCA is
contained within and make it the caller's responsibility to ensure the
supplied NCA is valid.
We can just compare the existing std::vector instance with a constexpr
std::array containing the desired match. This is lighter resource-wise,
as we don't need to allocate on the heap.
Adds missing includes to prevent potential compilation issues in the
future. Also moves the definition of a struct into the cpp file, so that
some includes don't need to be introduced within the header.
Specifically bugs/crashes that arise when putting them in positions that are legal but not typical, such as midline, between patch data, or between patch records.
GetName() returns a std::string by value, not by reference, so after the
std::string_view is constructed, it's not well defined to actually
execute any member functions of std::string_view that attempt to access
the data, as the std::string has already been destroyed. Instead, we can
just use a std::string and erase the last four characters.
When searching for a file extension, it's generally preferable to begin
the search at the end of the string rather than the beginning, as the
whole string isn't going to be walked just to check for something at the
end of it.
If an error occurs when constructing the PartitionFilesystem instance,
the constructor would be exited early, which wouldn't initialize the
extracted data member, making it possible for other code to perform an
uninitialized read by calling the public IsExtractedType() member
function. This prevents that.
Like the other two bits of factored out code, this can also be put
within its own function. We can also modify the code so that it accepts
a const reference to a std::vector of files, this way, we can
deduplicate the file retrieval.
Now the constructor for NSP isn't a combination of multiple behaviors in
one spot. It's nice and separate.
This too, is completely separate behavior from what is in the
constructor, so we can move this to its own isolated function to keep
everything self-contained.
If any of the error paths before the NCA retrieval are taken, it'll
result in program_nca_status being left in an inconsistent state. So we
initialize it by default with a value indicating an error.