common: str refactoring

renamed the prefix to be slimmer and more compact.
This commit is contained in:
Hermet Park 2025-03-06 12:04:45 +09:00
parent f98057063b
commit 96dc3d6697
15 changed files with 85 additions and 81 deletions

View file

@ -55,13 +55,13 @@ namespace tvg {
* No hexadecimal form supported
* no sequence supported after NAN
*/
float strToFloat(const char *nPtr, char **endPtr)
float toFloat(const char *str, char **end)
{
if (endPtr) *endPtr = (char *) (nPtr);
if (!nPtr) return 0.0f;
if (end) *end = (char *) (str);
if (!str) return 0.0f;
auto a = nPtr;
auto iter = nPtr;
auto a = str;
auto iter = str;
auto val = 0.0f;
unsigned long long integerPart = 0;
int minus = 1;
@ -87,7 +87,7 @@ float strToFloat(const char *nPtr, char **endPtr)
iter += 5;
else goto error;
}
if (endPtr) *endPtr = (char *) (iter);
if (end) *end = (char *) (iter);
return (minus == -1) ? -INFINITY : INFINITY;
}
@ -95,7 +95,7 @@ float strToFloat(const char *nPtr, char **endPtr)
if ((tolower(*(iter + 1)) == 'a') && (tolower(*(iter + 2)) == 'n')) iter += 3;
else goto error;
if (endPtr) *endPtr = (char *) (iter);
if (end) *end = (char *) (iter);
return (minus == -1) ? -NAN : NAN;
}
@ -164,7 +164,7 @@ float strToFloat(const char *nPtr, char **endPtr)
exponentPart = exponentPart * 10U + static_cast<unsigned int>(*iter - '0');
}
} else if (!isdigit(*(a - 1))) {
a = nPtr;
a = str;
goto success;
} else if (*iter == 0) {
goto success;
@ -190,23 +190,23 @@ float strToFloat(const char *nPtr, char **endPtr)
exponentPart--;
}
val = (minus_e == -1) ? (val / scale) : (val * scale);
} else if ((iter > nPtr) && !isdigit(*(iter - 1))) {
a = nPtr;
} else if ((iter > str) && !isdigit(*(iter - 1))) {
a = str;
goto success;
}
success:
if (endPtr) *endPtr = (char *)(a);
if (end) *end = (char *)a;
if (!std::isfinite(val)) return 0.0f;
return minus * val;
error:
if (endPtr) *endPtr = (char *)(nPtr);
if (end) *end = (char *)str;
return 0.0f;
}
char* strDuplicate(const char *str, size_t n)
char* duplicate(const char *str, size_t n)
{
auto len = strlen(str);
if (len < n) n = len;
@ -217,26 +217,26 @@ char* strDuplicate(const char *str, size_t n)
return (char*)memcpy(ret, str, n);
}
char* strAppend(char* lhs, const char* rhs, size_t n)
char* append(char* lhs, const char* rhs, size_t n)
{
if (!rhs) return lhs;
if (!lhs) return strDuplicate(rhs, n);
if (!lhs) return duplicate(rhs, n);
lhs = tvg::realloc<char*>(lhs, strlen(lhs) + n + 1);
return strncat(lhs, rhs, n);
}
char* strDirname(const char* path)
char* dirname(const char* path)
{
const char *ptr = strrchr(path, '/');
#ifdef _WIN32
if (ptr) ptr = strrchr(ptr + 1, '\\');
#endif
int len = int(ptr + 1 - path); // +1 to include '/'
return strDuplicate(path, len);
return duplicate(path, len);
}
const char* strExtension(const char* filename)
const char* fileext(const char* filename)
{
auto ext = filename;
while (ext) {

View file

@ -23,17 +23,21 @@
#ifndef _TVG_STR_H_
#define _TVG_STR_H_
#include <cstddef>
#include <stdint.h>
#include "tvgCommon.h"
namespace tvg
{
float strToFloat(const char *nPtr, char **endPtr); //convert to float
char* strDuplicate(const char *str, size_t n = SIZE_MAX); //copy the string
char* strAppend(char* lhs, const char* rhs, size_t n); //append the rhs to the lhs
char* strDirname(const char* path); //return the full directory name
const char* strExtension(const char* filename); //return the file extension name
static inline bool equal(const char* a, const char* b)
{
return !strcmp(a, b) && strlen(a) == strlen(b);
}
float toFloat(const char *str, char **end); //convert to float
char* duplicate(const char *str, size_t n = SIZE_MAX); //copy the string
char* append(char* lhs, const char* rhs, size_t n); //append the rhs to the lhs
char* dirname(const char* path); //return the full directory name
const char* fileext(const char* filename); //return the file extension name
}
#endif //_TVG_STR_H_

View file

@ -126,7 +126,7 @@ float LottieInterpolator::progress(float t)
void LottieInterpolator::set(const char* key, Point& inTangent, Point& outTangent)
{
if (key) this->key = strDuplicate(key);
if (key) this->key = duplicate(key);
this->inTangent = inTangent;
this->outTangent = outTangent;

View file

@ -138,7 +138,7 @@ bool LottieLoader::header()
p += 5;
auto e = strstr(p, ",");
if (!e) e = strstr(p, "}");
frameRate = strToFloat(p, nullptr);
frameRate = toFloat(p, nullptr);
p = e;
continue;
}
@ -148,7 +148,7 @@ bool LottieLoader::header()
p += 5;
auto e = strstr(p, ",");
if (!e) e = strstr(p, "}");
startFrame = strToFloat(p, nullptr);
startFrame = toFloat(p, nullptr);
p = e;
continue;
}
@ -158,7 +158,7 @@ bool LottieLoader::header()
p += 5;
auto e = strstr(p, ",");
if (!e) e = strstr(p, "}");
endFrame = strToFloat(p, nullptr);
endFrame = toFloat(p, nullptr);
p = e;
continue;
}
@ -168,7 +168,7 @@ bool LottieLoader::header()
p += 4;
auto e = strstr(p, ",");
if (!e) e = strstr(p, "}");
w = strToFloat(p, nullptr);
w = toFloat(p, nullptr);
p = e;
continue;
}
@ -177,7 +177,7 @@ bool LottieLoader::header()
p += 4;
auto e = strstr(p, ",");
if (!e) e = strstr(p, "}");
h = strToFloat(p, nullptr);
h = toFloat(p, nullptr);
p = e;
continue;
}
@ -209,8 +209,8 @@ bool LottieLoader::open(const char* data, uint32_t size, const char* rpath, bool
this->size = size;
this->copy = copy;
if (!rpath) this->dirName = strDuplicate(".");
else this->dirName = strDuplicate(rpath);
if (!rpath) this->dirName = duplicate(".");
else this->dirName = duplicate(rpath);
return header();
}
@ -237,7 +237,7 @@ bool LottieLoader::open(const char* path)
fclose(f);
this->dirName = strDirname(path);
this->dirName = tvg::dirname(path);
this->content = content;
this->copy = true;
@ -295,7 +295,7 @@ bool LottieLoader::override(const char* slots, bool byDefault)
//override slots
if (slots) {
//Copy the input data because the JSON parser will encode the data immediately.
auto temp = byDefault ? slots : strDuplicate(slots);
auto temp = byDefault ? slots : duplicate(slots);
//parsing slot json
LottieParser parser(temp, dirName, builder->expressions());

View file

@ -471,7 +471,7 @@ void LottieParser::registerSlot(LottieObject* obj, const char* sid)
(*p)->pairs.push({obj});
return;
}
comp->slots.push(new LottieSlot(strDuplicate(sid), obj, type));
comp->slots.push(new LottieSlot(duplicate(sid), obj, type));
}
@ -898,7 +898,7 @@ void LottieParser::parseImage(LottieImage* image, const char* data, const char*
//figure out the mimetype
auto mimeType = data + 11;
auto needle = strstr(mimeType, ";");
image->data.mimeType = strDuplicate(mimeType, needle - mimeType);
image->data.mimeType = duplicate(mimeType, needle - mimeType);
//b64 data
auto b64Data = strstr(data, ",") + 1;
size_t length = strlen(data) - (b64Data - data);

View file

@ -124,7 +124,7 @@ const char* LookaheadParserHandler::getString()
char* LookaheadParserHandler::getStringCopy()
{
auto str = getString();
if (str) return strDuplicate(str);
if (str) return duplicate(str);
return nullptr;
}

View file

@ -920,8 +920,8 @@ struct LottieBitmap : LottieProperty
} else {
//TODO: optimize here by avoiding data copy
TVGLOG("LOTTIE", "Shallow copy of the image data!");
b64Data = strDuplicate(rhs.b64Data);
mimeType = strDuplicate(rhs.mimeType);
b64Data = duplicate(rhs.b64Data);
mimeType = duplicate(rhs.mimeType);
}
size = rhs.size;
width = rhs.width;

View file

@ -72,7 +72,7 @@ static void _copyStyle(SvgStyleProperty* to, const SvgStyleProperty* from)
to->fill.paint.curColor = from->fill.paint.curColor;
if (from->fill.paint.url) {
if (to->fill.paint.url) tvg::free(to->fill.paint.url);
to->fill.paint.url = strDuplicate(from->fill.paint.url);
to->fill.paint.url = duplicate(from->fill.paint.url);
}
to->fill.flags = (to->fill.flags | SvgFillFlags::Paint);
to->flags = (to->flags | SvgStyleFlags::Fill);
@ -106,7 +106,7 @@ static void _copyStyle(SvgStyleProperty* to, const SvgStyleProperty* from)
to->stroke.paint.curColor = from->stroke.paint.curColor;
if (from->stroke.paint.url) {
if (to->stroke.paint.url) tvg::free(to->stroke.paint.url);
to->stroke.paint.url = strDuplicate(from->stroke.paint.url);
to->stroke.paint.url = duplicate(from->stroke.paint.url);
}
to->stroke.flags = (to->stroke.flags | SvgStrokeFlags::Paint);
to->flags = (to->flags | SvgStyleFlags::Stroke);
@ -197,11 +197,11 @@ void cssCopyStyleAttr(SvgNode* to, const SvgNode* from)
if (from->style->clipPath.url) {
if (to->style->clipPath.url) tvg::free(to->style->clipPath.url);
to->style->clipPath.url = strDuplicate(from->style->clipPath.url);
to->style->clipPath.url = duplicate(from->style->clipPath.url);
}
if (from->style->mask.url) {
if (to->style->mask.url) tvg::free(to->style->mask.url);
to->style->mask.url = strDuplicate(from->style->mask.url);
to->style->mask.url = duplicate(from->style->mask.url);
}
}

View file

@ -63,7 +63,7 @@ static char* _copyId(const char* str)
if (!str) return nullptr;
if (strlen(str) == 0) return nullptr;
return strDuplicate(str);
return duplicate(str);
}
@ -79,7 +79,7 @@ static bool _parseNumber(const char** content, const char** end, float* number)
{
const char* _end = end ? *end : nullptr;
*number = strToFloat(*content, (char**)&_end);
*number = toFloat(*content, (char**)&_end);
//If the start of string is not number
if ((*content) == _end) {
if (end) *end = _end;
@ -137,7 +137,7 @@ static void _parseAspectRatio(const char** content, AspectRatioAlign* align, Asp
// According to https://www.w3.org/TR/SVG/coords.html#Units
static float _toFloat(const SvgParser* svgParse, const char* str, SvgParserLengthType type)
{
float parsedValue = strToFloat(str, nullptr);
float parsedValue = toFloat(str, nullptr);
if (strstr(str, "cm")) parsedValue *= PX_PER_CM;
else if (strstr(str, "mm")) parsedValue *= PX_PER_MM;
@ -166,7 +166,7 @@ static float _gradientToFloat(const SvgParser* svgParse, const char* str, bool&
{
char* end = nullptr;
float parsedValue = strToFloat(str, &end);
float parsedValue = toFloat(str, &end);
isPercentage = false;
if (strstr(str, "%")) {
@ -189,7 +189,7 @@ static float _toOffset(const char* str)
char* end = nullptr;
auto strEnd = str + strlen(str);
float parsedValue = strToFloat(str, &end);
float parsedValue = toFloat(str, &end);
end = _skipSpace(end, nullptr);
auto ptr = strstr(str, "%");
@ -206,7 +206,7 @@ static float _toOffset(const char* str)
static int _toOpacity(const char* str)
{
char* end = nullptr;
float opacity = strToFloat(str, &end);
float opacity = toFloat(str, &end);
if (end) {
if (end[0] == '%' && end[1] == '\0') return lrint(opacity * 2.55f);
@ -334,7 +334,7 @@ static void _parseDashArray(SvgLoaderData* loader, const char *str, SvgDash* das
while (*str) {
str = _skipComma(str);
float parsedValue = strToFloat(str, &end);
float parsedValue = toFloat(str, &end);
if (str == end) break;
if (parsedValue <= 0.0f) break;
if (*end == '%') {
@ -371,7 +371,7 @@ static char* _idFromUrl(const char* url)
if (*id == ' ' || *id == '\'') return nullptr;
}
return strDuplicate(open, (close - open + 1));
return duplicate(open, (close - open + 1));
}
@ -379,7 +379,7 @@ static unsigned char _parseColor(const char* value, char** end)
{
float r;
r = strToFloat(value, end);
r = toFloat(value, end);
*end = _skipSpace(*end, nullptr);
if (**end == '%') {
r = 255 * r / 100;
@ -730,7 +730,7 @@ static char* _parseNumbersArray(char* str, float* points, int* ptCount, int len)
str = _skipSpace(str, nullptr);
while ((count < len) && (isdigit(*str) || *str == '-' || *str == '+' || *str == '.')) {
points[count++] = strToFloat(str, &end);
points[count++] = toFloat(str, &end);
str = end;
str = _skipSpace(str, nullptr);
if (*str == ',') ++str;
@ -932,7 +932,7 @@ static bool _attrParseSvgNode(void* data, const char* key, const char* value)
} else if (STR_AS(key, "style")) {
return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader);
#ifdef THORVG_LOG_ENABLED
} else if ((STR_AS(key, "x") || STR_AS(key, "y")) && fabsf(strToFloat(value, nullptr)) > FLOAT_EPSILON) {
} else if ((STR_AS(key, "x") || STR_AS(key, "y")) && fabsf(toFloat(value, nullptr)) > FLOAT_EPSILON) {
TVGLOG("SVG", "Unsupported attributes used [Elements type: Svg][Attribute: %s][Value: %s]", key, value);
#endif
} else {
@ -1025,7 +1025,7 @@ static void _handleStrokeLineJoinAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode*
static void _handleStrokeMiterlimitAttr(SvgLoaderData* loader, SvgNode* node, const char* value)
{
char* end = nullptr;
const float miterlimit = strToFloat(value, &end);
const float miterlimit = toFloat(value, &end);
// https://www.w3.org/TR/SVG2/painting.html#LineJoin
// - A negative value for stroke-miterlimit must be treated as an illegal value.
@ -1202,7 +1202,7 @@ static bool _parseStyleAttr(void* data, const char* key, const char* value, bool
while (size > 0 && isspace(value[size - 1])) {
size--;
}
value = strDuplicate(value, size);
value = duplicate(value, size);
importance = true;
}
if (style) {
@ -1426,7 +1426,7 @@ static void _parseGaussianBlurStdDeviation(const char** content, float* x, float
while (*str && n < 2) {
str = _skipComma(str);
auto parsedValue = strToFloat(str, &end);
auto parsedValue = toFloat(str, &end);
if (parsedValue < 0.0f) break;
deviation[n++] = parsedValue;
str = end;
@ -2009,7 +2009,7 @@ static char* _idFromHref(const char* href)
{
href = _skipSpace(href, nullptr);
if ((*href) == '#') href++;
return strDuplicate(href);
return duplicate(href);
}
@ -2231,7 +2231,7 @@ static bool _attrParseTextNode(void* data, const char* key, const char* value)
if (STR_AS(key, "font-family")) {
if (value) {
tvg::free(text->fontFamily);
text->fontFamily = strDuplicate(value);
text->fontFamily = duplicate(value);
}
} else if (STR_AS(key, "style")) {
return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader);
@ -3214,15 +3214,15 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
to->style->flags = (to->style->flags | from->style->flags);
if (from->style->clipPath.url) {
tvg::free(to->style->clipPath.url);
to->style->clipPath.url = strDuplicate(from->style->clipPath.url);
to->style->clipPath.url = duplicate(from->style->clipPath.url);
}
if (from->style->mask.url) {
tvg::free(to->style->mask.url);
to->style->mask.url = strDuplicate(from->style->mask.url);
to->style->mask.url = duplicate(from->style->mask.url);
}
if (from->style->filter.url) {
if (to->style->filter.url) tvg::free(to->style->filter.url);
to->style->filter.url = strDuplicate(from->style->filter.url);
to->style->filter.url = duplicate(from->style->filter.url);
}
//Copy node attribute
@ -3246,7 +3246,7 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
case SvgNodeType::Path: {
if (from->node.path.path) {
tvg::free(to->node.path.path);
to->node.path.path = strDuplicate(from->node.path.path);
to->node.path.path = duplicate(from->node.path.path);
}
break;
}
@ -3269,7 +3269,7 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
to->node.image.h = from->node.image.h;
if (from->node.image.href) {
tvg::free(to->node.image.href);
to->node.image.href = strDuplicate(from->node.image.href);
to->node.image.href = duplicate(from->node.image.href);
}
break;
}
@ -3289,11 +3289,11 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
to->node.text.fontSize = from->node.text.fontSize;
if (from->node.text.text) {
tvg::free(to->node.text.text);
to->node.text.text = strDuplicate(from->node.text.text);
to->node.text.text = duplicate(from->node.text.text);
}
if (from->node.text.fontFamily) {
tvg::free(to->node.text.fontFamily);
to->node.text.fontFamily = strDuplicate(from->node.text.fontFamily);
to->node.text.fontFamily = duplicate(from->node.text.fontFamily);
}
break;
}
@ -3489,7 +3489,7 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
static void _svgLoaderParserText(SvgLoaderData* loader, const char* content, unsigned int length)
{
auto text = &loader->svgParse->node->node.text;
text->text = strAppend(text->text, content, length);
text->text = append(text->text, content, length);
}

View file

@ -47,7 +47,7 @@ static char* _skipComma(const char* content)
static bool _parseNumber(char** content, float* number)
{
char* end = NULL;
*number = strToFloat(*content, &end);
*number = toFloat(*content, &end);
//If the start of string is not number
if ((*content) == end) return false;
//Skip comma if any

View file

@ -551,11 +551,11 @@ const char* simpleXmlParseCSSAttribute(const char* buf, unsigned bufLength, char
if (*p == '.') break;
}
if (p == itr) *tag = strDuplicate("all");
else *tag = strDuplicate(itr, p - itr);
if (p == itr) *tag = duplicate("all");
else *tag = duplicate(itr, p - itr);
if (p == itrEnd) *name = nullptr;
else *name = strDuplicate(p + 1, itrEnd - p - 1);
else *name = duplicate(p + 1, itrEnd - p - 1);
return (nextElement ? nextElement + 1 : nullptr);
}

View file

@ -160,7 +160,7 @@ static LoadModule* _find(FileType type)
#ifdef THORVG_FILE_IO_SUPPORT
static LoadModule* _findByPath(const char* filename)
{
auto ext = strExtension(filename);
auto ext = fileext(filename);
if (!ext) return nullptr;
if (!strcmp(ext, "svg")) return _find(FileType::Svg);
@ -277,7 +277,7 @@ LoadModule* LoaderMgr::loader(const char* filename, bool* invalid)
//TODO: svg & lottie is not sharable.
auto allowCache = true;
auto ext = strExtension(filename);
auto ext = fileext(filename);
if (ext && (!strcmp(ext, "svg") || !strcmp(ext, "json") || !strcmp(ext, "lot"))) allowCache = false;
if (allowCache) {
@ -287,7 +287,7 @@ LoadModule* LoaderMgr::loader(const char* filename, bool* invalid)
if (auto loader = _findByPath(filename)) {
if (loader->open(filename)) {
if (allowCache) {
loader->hashpath = strDuplicate(filename);
loader->hashpath = duplicate(filename);
loader->pathcache = true;
{
ScopedLock lock(key);
@ -303,7 +303,7 @@ LoadModule* LoaderMgr::loader(const char* filename, bool* invalid)
if (auto loader = _find(static_cast<FileType>(i))) {
if (loader->open(filename)) {
if (allowCache) {
loader->hashpath = strDuplicate(filename);
loader->hashpath = duplicate(filename);
loader->pathcache = true;
{
ScopedLock lock(key);
@ -436,7 +436,7 @@ LoadModule* LoaderMgr::loader(const char* name, const char* data, uint32_t size,
//function is dedicated for ttf loader (the only supported font loader)
auto loader = new TtfLoader;
if (loader->open(data, size, "", copy)) {
loader->hashpath = strDuplicate(name);
loader->hashpath = duplicate(name);
loader->pathcache = true;
ScopedLock lock(key);
_activeLoaders.back(loader);

View file

@ -80,7 +80,7 @@ static SaveModule* _find(FileType type)
static SaveModule* _find(const char* filename)
{
auto ext = strExtension(filename);
auto ext = fileext(filename);
if (ext && !strcmp(ext, "gif")) return _find(FileType::Gif);
return nullptr;
}

View file

@ -53,7 +53,7 @@ struct Text::Impl : Paint::Impl
Result text(const char* utf8)
{
tvg::free(this->utf8);
if (utf8) this->utf8 = strDuplicate(utf8);
if (utf8) this->utf8 = tvg::duplicate(utf8);
else this->utf8 = nullptr;
changed = true;
@ -156,7 +156,7 @@ struct Text::Impl : Paint::Impl
++dup->loader->sharing;
}
dup->utf8 = strDuplicate(utf8);
dup->utf8 = tvg::duplicate(utf8);
dup->italic = italic;
dup->fontSize = fontSize;

View file

@ -136,7 +136,7 @@ bool GifSaver::save(Animation* animation, Paint* bg, const char* filename, TVG_U
}
if (!filename) return false;
this->path = strDuplicate(filename);
this->path = duplicate(filename);
this->animation = animation;