diff --git a/headers/os/locale/LocaleRoster.h b/headers/os/locale/LocaleRoster.h index da1defca8c..d54760c3bc 100644 --- a/headers/os/locale/LocaleRoster.h +++ b/headers/os/locale/LocaleRoster.h @@ -6,6 +6,7 @@ #define _LOCALE_ROSTER_H_ +#include #include @@ -67,6 +68,10 @@ public: bool IsFilesystemTranslationPreferred() const; + status_t GetLocalizedFileName(entry_ref& ref, + BString& localizedFileName, + bool traverse = false); + static const char* kCatLangAttr; static const char* kCatSigAttr; static const char* kCatFingerprintAttr; diff --git a/src/kits/locale/LocaleRoster.cpp b/src/kits/locale/LocaleRoster.cpp index 3b7b0a655b..c5c361cb07 100644 --- a/src/kits/locale/LocaleRoster.cpp +++ b/src/kits/locale/LocaleRoster.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -378,3 +379,77 @@ BLocaleRoster::IsFilesystemTranslationPreferred() const return rosterData->fIsFilesystemTranslationPreferred; } + + +/*! \brief Looks up a localized filename in a catalog, using attribute data + on the entry. + \param ref An entry_ref with an attribute holding data for catalog lookup. + \param localizedFileName A pre-allocated BString object for the result + of the lookup. + \param traverse A boolean to decide if symlinks are to be traversed. + \return + - \c B_OK: success + - \c B_ENTRY_NOT_FOUND: failure. Attribute not found, entry not found + in catalog, etc + - other error codes: failure + + Attribute format: "signature:context:string" + (no colon in any of signature, context and string) + + Lookup is done for the top preferred language, only. + Lookup fails if a comment is present in the catalog entry. +*/ +status_t +BLocaleRoster::GetLocalizedFileName(entry_ref& ref, BString& localizedFileName, + bool traverse) +{ + BEntry entry(&ref, traverse); + if (!entry.Exists()) + return B_ENTRY_NOT_FOUND; + + BNode node(&entry); + status_t status = node.InitCheck(); + if (status != B_OK) + return status; + + attr_info attr; + status = node.GetAttrInfo("SYS:NAME", &attr); + if (status != B_OK) + return status; + + char attribute[attr.size + 1]; + ssize_t bytes = node.ReadAttr("SYS:NAME", B_MIME_TYPE, 0, &attribute, + attr.size); + + if (bytes < 0) + return bytes; + + if (bytes == 0 || bytes != attr.size) + return B_ENTRY_NOT_FOUND; + + attribute[bytes] = '\0'; + + char* signature = attribute; + char* context = strchr(signature, ':'); + if (context == NULL) + return B_ENTRY_NOT_FOUND; + + context[0] = '\0'; + context++; + + char* string = strchr(context, ':'); + if (string == NULL) + return B_ENTRY_NOT_FOUND; + + string[0] = '\0'; + string++; + + BCatalog catalog(signature); + + const char* temp = catalog.GetString(string, context); + if (temp == NULL) + return B_ENTRY_NOT_FOUND; + + localizedFileName = temp; + return B_OK; +}