Updates for consistent string handling across shared library (#182)

This commit is contained in:
David Brownell 2020-03-26 14:44:07 -07:00 коммит произвёл GitHub
Родитель 2eebd7e6a1
Коммит e99406bdf4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 20 добавлений и 30 удалений

Просмотреть файл

@ -103,7 +103,7 @@ TEST_CASE("IsValidCountry") {
TEST_CASE("GetSupportedCountries") {
ErrorInfoHandle * pErrorInfo(nullptr);
StringBuffer * pStringBuffers(nullptr);
char const * const * pStringBuffers(nullptr);
size_t numStringBuffers;
CHECK(DateTimeFeaturizer_GetSupportedCountries(nullptr, &pStringBuffers, &numStringBuffers, &pErrorInfo));
@ -112,8 +112,8 @@ TEST_CASE("GetSupportedCountries") {
REQUIRE(numStringBuffers != 0);
// Spot check a few of the values
CHECK(strcmp(pStringBuffers->pString, "Argentina") == 0);
CHECK(strcmp((pStringBuffers + numStringBuffers - 1)->pString, "Wales") == 0);
CHECK(strcmp(*pStringBuffers, "Argentina") == 0);
CHECK(strcmp(*(pStringBuffers + numStringBuffers - 1), "Wales") == 0);
CHECK(DateTimeFeaturizer_DestroyStringBuffers(pStringBuffers, numStringBuffers, &pErrorInfo));
CHECK(pErrorInfo == nullptr);

Просмотреть файл

@ -66,7 +66,7 @@ FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_IsValidCountry(/*in*/ char const
}
}
FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_GetSupportedCountries(/*in*/ char const *optionalDataRootDir, /*out*/ StringBuffer ** ppStringBuffers, /*out*/ std::size_t * pNumStringBuffers, /*out*/ ErrorInfoHandle **ppErrorInfo) {
FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_GetSupportedCountries(/*in*/ char const *optionalDataRootDir, /*out*/ char const * const ** ppStringBuffers, /*out*/ std::size_t * pNumStringBuffers, /*out*/ ErrorInfoHandle **ppErrorInfo) {
if(ppErrorInfo == nullptr)
return false;
@ -91,14 +91,14 @@ FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_GetSupportedCountries(/*in*/ char
delete [] pData;
}
static void StringBufferDeleter(StringBuffer *pData) {
delete [] pData;
}
static void StringsDeleter(char const ** pStrings) {
delete [] pStrings;
};
};
using StringUniquePtr = std::unique_ptr<char, void (*)(char *)>;
using StringUniquePtrs = std::vector<std::pair<StringUniquePtr, size_t>>;
using StringBufferUniquePtr = std::unique_ptr<StringBuffer, void (*)(StringBuffer *)>;
using StringsUniquePtr = std::unique_ptr<char const *, void (*)(char const **)>;
// ----------------------------------------------------------------------
// Create the strings
@ -115,20 +115,19 @@ FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_GetSupportedCountries(/*in*/ char
}
// Create the string buffer and assign the strings
StringBufferUniquePtr pStringBuffers(new StringBuffer[countries.size()], Internal::StringBufferDeleter);
StringBuffer * pStringBuffersPtr(pStringBuffers.get());
StringsUniquePtr pStrings(new char const *[countries.size()], Internal::StringsDeleter);
char const ** pStringsPtr(pStrings.get());
for(auto const & rawInfo : rawStringInfo) {
pStringBuffersPtr->pString = std::get<0>(rawInfo).get();
pStringBuffersPtr->cCharacters = std::get<1>(rawInfo);
++pStringBuffersPtr;
*pStringsPtr = std::get<0>(rawInfo).get();
++pStringsPtr;
}
// If here, all memory was successfully allocated and we can release all pointers
for(auto & rawInfo : rawStringInfo)
std::get<0>(rawInfo).release();
*ppStringBuffers = pStringBuffers.release();
*ppStringBuffers = pStrings.release();
*pNumStringBuffers = countries.size();
return true;
@ -139,7 +138,7 @@ FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_GetSupportedCountries(/*in*/ char
}
}
FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_DestroyStringBuffers(/*in*/ StringBuffer *pStringBuffer, /*in*/ std::size_t numStringBuffers, /*out*/ ErrorInfoHandle **ppErrorInfo) {
FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_DestroyStringBuffers(/*in*/ char const * const * pStringBuffer, /*in*/ std::size_t numStringBuffers, /*out*/ ErrorInfoHandle **ppErrorInfo) {
if(ppErrorInfo == nullptr)
return false;
@ -152,13 +151,13 @@ FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_DestroyStringBuffers(/*in*/ Strin
if(pStringBuffer == nullptr)
return true;
StringBuffer const * ptr(pStringBuffer);
StringBuffer const * const pEnd(ptr + numStringBuffers);
char const * const * ptr(pStringBuffer);
char const * const * const pEnd(ptr + numStringBuffers);
while(ptr != pEnd) {
if(ptr->pString == nullptr || ptr->cCharacters == 0) throw std::invalid_argument("Invalid string element");
if(*ptr == nullptr) throw std::invalid_argument("Invalid string element");
delete [] ptr->pString;
delete [] *ptr;
++ptr;
}

Просмотреть файл

@ -11,19 +11,10 @@ extern "C" {
/* This file exposes non-standard functionality in the DateTimeFeaturizer */
FEATURIZER_LIBRARY_API_PACK_PREFIX
struct StringBuffer {
char const * pString;
std::size_t cCharacters;
} FEATURIZER_LIBRARY_API_PACK_INLINE;
FEATURIZER_LIBRARY_API_PACK_SUFFIX
FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_CreateTransformerFromSavedDataWithDataRoot(/*in*/ unsigned char const *pBuffer, /*in*/ std::size_t cBufferSize, /*in*/ char const *dataRootDir, /*out*/ DateTimeFeaturizer_TransformerHandle **ppTransformerHandle, /*out*/ ErrorInfoHandle **ppErrorInfo);
FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_IsValidCountry(/*in*/ char const *countryName, /*in*/ char const *optionalDataRootDir, /*out*/ bool *isValid, /*out*/ ErrorInfoHandle **ppErrorInfo);
FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_GetSupportedCountries(/*in*/ char const *optionalDataRootDir, /*out*/ StringBuffer ** ppStringBuffers, /*out*/ std::size_t * pNumStringBuffers, /*out*/ ErrorInfoHandle **ppErrorInfo);
FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_DestroyStringBuffers(/*in*/ StringBuffer *pStringBuffer, /*in*/ std::size_t numStringBuffers, /*out*/ ErrorInfoHandle **ppErrorInfo);
FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_GetSupportedCountries(/*in*/ char const *optionalDataRootDir, /*out*/ char const * const ** ppStringBuffers, /*out*/ std::size_t * pNumStringBuffers, /*out*/ ErrorInfoHandle **ppErrorInfo);
FEATURIZER_LIBRARY_API bool DateTimeFeaturizer_DestroyStringBuffers(/*in*/ char const * const * pStringBuffers, /*in*/ std::size_t numStringBuffers, /*out*/ ErrorInfoHandle **ppErrorInfo);
} // extern "C"