[clib] Add buffer length argument to all functions returning strings

If the buffer is not long enough, the string is truncated and the return value
is the required buffer length. Otherwise, the return value is 0.
This commit is contained in:
Ray Speth 2016-10-17 23:33:49 -04:00
parent c16c15367f
commit 8a9eabeeac
7 changed files with 25 additions and 30 deletions

View file

@ -190,7 +190,12 @@ void tokenizeString(const std::string& oval,
std::vector<std::string>& v);
//! Copy the contents of a std::string into a char array of a given length
void copyString(const std::string& source, char* dest, size_t length);
/*!
* If *length* is less than the size of *source*, the string will be truncated
* and the function will return the length of the buffer required to hold
* *source*. Otherwise, returns 0.
*/
size_t copyString(const std::string& source, char* dest, size_t length);
}

View file

@ -20,11 +20,11 @@ extern "C" {
CANTERA_CAPI int xml_clear();
CANTERA_CAPI int xml_copy(int i);
CANTERA_CAPI int xml_build(int i, const char* file);
CANTERA_CAPI int xml_attrib(int i, const char* key, char* value);
CANTERA_CAPI int xml_attrib(int i, const char* key, size_t lenval, char* value);
CANTERA_CAPI int xml_addAttrib(int i, const char* key, const char* value);
CANTERA_CAPI int xml_addComment(int i, const char* comment);
CANTERA_CAPI int xml_value(int i, char* value);
CANTERA_CAPI int xml_tag(int i, char* tag);
CANTERA_CAPI int xml_value(int i, size_t lenval, char* value);
CANTERA_CAPI int xml_tag(int i, size_t lentag, char* tag);
CANTERA_CAPI int xml_child(int i, const char* loc);
CANTERA_CAPI int xml_child_bynumber(int i, int m);
CANTERA_CAPI int xml_findID(int i, const char* id);

View file

@ -366,14 +366,16 @@ void tokenizeString(const std::string& oval,
}
}
void copyString(const std::string& source, char* dest, size_t length)
size_t copyString(const std::string& source, char* dest, size_t length)
{
const char* c_src = source.c_str();
size_t N = std::min(length, source.length()+1);
size_t ret = (length >= source.length() + 1) ? 0 : source.length() + 1;
std::copy(c_src, c_src + N, dest);
if (length != 0) {
dest[length-1] = '\0';
}
return ret;
}
}

View file

@ -287,8 +287,7 @@ extern "C" {
int thermo_getName(int n, size_t lennm, char* nm)
{
try {
copyString(ThermoCabinet::item(n).name(), nm, lennm);
return 0;
return copyString(ThermoCabinet::item(n).name(), nm, lennm);
} catch (...) {
return handleAllExceptions(-1, ERR);
}
@ -307,8 +306,7 @@ extern "C" {
int thermo_getSpeciesName(int n, size_t k, size_t lennm, char* nm)
{
try {
copyString(ThermoCabinet::item(n).speciesName(k), nm, lennm);
return 0;
return copyString(ThermoCabinet::item(n).speciesName(k), nm, lennm);
} catch (...) {
return handleAllExceptions(-1, ERR);
}
@ -317,8 +315,7 @@ extern "C" {
int thermo_getElementName(int n, size_t m, size_t lennm, char* nm)
{
try {
copyString(ThermoCabinet::item(n).elementName(m), nm, lennm);
return 0;
return copyString(ThermoCabinet::item(n).elementName(m), nm, lennm);
} catch (...) {
return handleAllExceptions(-1, ERR);
}
@ -1210,8 +1207,7 @@ extern "C" {
try {
Kinetics& k = KineticsCabinet::item(n);
k.checkReactionIndex(i);
copyString(k.reactionString(i), buf, len);
return 0;
return static_cast<int>(copyString(k.reactionString(i), buf, len));
} catch (...) {
return handleAllExceptions(-1, ERR);
}

View file

@ -92,9 +92,7 @@ extern "C" {
try {
Domain1D& dom = DomainCabinet::item(i);
dom.checkComponentIndex(n);
string nm = dom.componentName(n);
copyString(nm, buf, sz);
return static_cast<int>(nm.size());
return copyString(dom.componentName(n), buf, sz);
} catch (...) {
return handleAllExceptions(-1, ERR);
}

View file

@ -100,13 +100,12 @@ extern "C" {
}
}
int xml_attrib(int i, const char* key, char* value)
int xml_attrib(int i, const char* key, size_t lenval, char* value)
{
try {
XML_Node& node = XmlCabinet::item(i);
if (node.hasAttrib(key)) {
string v = node[key];
strncpy(value, v.c_str(), 80);
return copyString(node[key], value, lenval);
} else {
throw CanteraError("xml_attrib","node "
" has no attribute '"+string(key)+"'");
@ -114,7 +113,6 @@ extern "C" {
} catch (...) {
return handleAllExceptions(-1, ERR);
}
return 0;
}
int xml_addAttrib(int i, const char* key, const char* value)
@ -137,26 +135,22 @@ extern "C" {
return 0;
}
int xml_tag(int i, char* tag)
int xml_tag(int i, size_t lentag, char* tag)
{
try {
string v = XmlCabinet::item(i).name();
strncpy(tag, v.c_str(), 80);
return copyString(XmlCabinet::item(i).name(), tag, lentag);
} catch (...) {
return handleAllExceptions(-1, ERR);
}
return 0;
}
int xml_value(int i, char* value)
int xml_value(int i, size_t lenval, char* value)
{
try {
string v = XmlCabinet::item(i).value();
strncpy(value, v.c_str(), 80);
return copyString(XmlCabinet::item(i).value(), value, lenval);
} catch (...) {
return handleAllExceptions(-1, ERR);
}
return 0;
}
int xml_child(int i, const char* loc)

View file

@ -115,11 +115,11 @@ void xmlmethods(int nlhs, mxArray* plhs[],
case 20:
// return an attribute
key = getString(prhs[3]);
iok = xml_attrib(i, key, v);
iok = xml_attrib(i, key, 80, v);
break;
case 21:
// return the value of the node
iok = xml_value(i, v);
iok = xml_value(i, 80, v);
break;
default:
mexErrMsgTxt("unknown job parameter");