Write a string vector to a text wave
thomas_braun
The wave referenced in waveHandle must be created in the appropriate size prior to calling this function.
If you want a 1D textwave, the wave's size must be stringVector.size(). I used a 2D wave with stringVector.size()/2 rows and 2 columns.
<br />
int stringVectorToTextWave(std::vector<std::string> &stringVector, waveHndl &waveHandle){<br />
<br />
std::vector<long int> stringSizes;<br />
char buf[1000];<br />
int lockStateWave, ret, i;<br />
<br />
long int offset;<br />
long int totalSize=0;<br />
<br />
if(stringVector.size() == 0){<br />
return -1;<br />
}<br />
<br />
// number of 32-bit integers (aka long int) is one more compared to the number of strings<br />
const long int numEntriesPlusOne = stringVector.size()+1;<br />
<br />
std::vector<std::string>::const_iterator it;<br />
for(it = stringVector.begin(); it != stringVector.end(); it++){<br />
try{<br />
stringSizes.push_back(it->size());<br />
}<br />
catch(...){<br />
return NOMEM;<br />
}<br />
totalSize += it->size();<br />
}<br />
<br />
totalSize += numEntriesPlusOne*sizeof(long);<br />
<br />
Handle textHandle = NewHandle(totalSize);<br />
if(MemError() || textHandle == NULL){<br />
return NOMEM;<br />
}<br />
<br />
//sprintf(buf,"totalSize of strings %d",GetHandleSize(textHandle));<br />
//XOPNotice(buf);<br />
<br />
for(i=0; i < numEntriesPlusOne; i++){<br />
<br />
if(i == 0){// position of the first string<br />
offset = numEntriesPlusOne*sizeof(long);<br />
}<br />
else{ // and of all the others<br />
offset+=stringSizes[i-1];<br />
}<br />
//sprintf(buf,"offset=%d, offsetPosition=%d*sizeof(long)",offset,i);<br />
//XOPNotice(buf);<br />
<br />
// write offsets<br />
memcpy(*textHandle+i*sizeof(long),&offset,sizeof(long));<br />
<br />
if(i < stringVector.size()){<br />
<br />
//sprintf(buf,"string=%s, stringPosition=%d",stringVector[i].c_str(),offset);<br />
//XOPNotice(buf);<br />
<br />
// write strings<br />
memcpy(*textHandle+offset,stringVector[i].c_str(),stringSizes[i]);<br />
}<br />
}<br />
<br />
// mode = 2 defines the format of the handle contents to<br />
// offsetToFirstString<br />
// offsetToSecondString<br />
// ...<br />
// offsetToPositionAfterLastString<br />
// firstString<br />
//...<br />
int mode=2;<br />
<br />
// Locking is only needed on MacOS9<br />
// acquire waveHandle lock<br />
lockStateWave=MoveLockHandle(waveHandle);<br />
ret = SetTextWaveData(waveHandle,mode,textHandle);<br />
<br />
//sprintf(buf,"SetTextWaveData returned %d",ret);<br />
//XOPNotice(buf);<br />
<br />
// release waveHandle lock<br />
HSetState(waveHandle, lockStateWave);<br />
DisposeHandle(textHandle);<br />
<br />
return ret;<br />
}<br />
int stringVectorToTextWave(std::vector<std::string> &stringVector, waveHndl &waveHandle){<br />
<br />
std::vector<long int> stringSizes;<br />
char buf[1000];<br />
int lockStateWave, ret, i;<br />
<br />
long int offset;<br />
long int totalSize=0;<br />
<br />
if(stringVector.size() == 0){<br />
return -1;<br />
}<br />
<br />
// number of 32-bit integers (aka long int) is one more compared to the number of strings<br />
const long int numEntriesPlusOne = stringVector.size()+1;<br />
<br />
std::vector<std::string>::const_iterator it;<br />
for(it = stringVector.begin(); it != stringVector.end(); it++){<br />
try{<br />
stringSizes.push_back(it->size());<br />
}<br />
catch(...){<br />
return NOMEM;<br />
}<br />
totalSize += it->size();<br />
}<br />
<br />
totalSize += numEntriesPlusOne*sizeof(long);<br />
<br />
Handle textHandle = NewHandle(totalSize);<br />
if(MemError() || textHandle == NULL){<br />
return NOMEM;<br />
}<br />
<br />
//sprintf(buf,"totalSize of strings %d",GetHandleSize(textHandle));<br />
//XOPNotice(buf);<br />
<br />
for(i=0; i < numEntriesPlusOne; i++){<br />
<br />
if(i == 0){// position of the first string<br />
offset = numEntriesPlusOne*sizeof(long);<br />
}<br />
else{ // and of all the others<br />
offset+=stringSizes[i-1];<br />
}<br />
//sprintf(buf,"offset=%d, offsetPosition=%d*sizeof(long)",offset,i);<br />
//XOPNotice(buf);<br />
<br />
// write offsets<br />
memcpy(*textHandle+i*sizeof(long),&offset,sizeof(long));<br />
<br />
if(i < stringVector.size()){<br />
<br />
//sprintf(buf,"string=%s, stringPosition=%d",stringVector[i].c_str(),offset);<br />
//XOPNotice(buf);<br />
<br />
// write strings<br />
memcpy(*textHandle+offset,stringVector[i].c_str(),stringSizes[i]);<br />
}<br />
}<br />
<br />
// mode = 2 defines the format of the handle contents to<br />
// offsetToFirstString<br />
// offsetToSecondString<br />
// ...<br />
// offsetToPositionAfterLastString<br />
// firstString<br />
//...<br />
int mode=2;<br />
<br />
// Locking is only needed on MacOS9<br />
// acquire waveHandle lock<br />
lockStateWave=MoveLockHandle(waveHandle);<br />
ret = SetTextWaveData(waveHandle,mode,textHandle);<br />
<br />
//sprintf(buf,"SetTextWaveData returned %d",ret);<br />
//XOPNotice(buf);<br />
<br />
// release waveHandle lock<br />
HSetState(waveHandle, lockStateWave);<br />
DisposeHandle(textHandle);<br />
<br />
return ret;<br />
}<br />
Forum
Support
Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More
Unless you are running on OS 9, the handle locking part is obsolete and can be removed.
July 5, 2010 at 11:53 am - Permalink
In the manual it says that "SetTextWaveData can not change the number of points in the text wave. Therefore the data in textDataH must be consistent with the number of points in waveH". Shouldn't this mean that you have to check/redimension the size of the waveHandle to make sure it is the same size as the data you're just about to put in it?
July 6, 2010 at 11:50 pm - Permalink
July 9, 2010 at 12:29 am - Permalink