Skip to content

Commit

Permalink
fix calibration file & S parameter file corruption on some locales
Browse files Browse the repository at this point in the history
* always use "." decimal separator when serializing calibration and
touchstone files
  • Loading branch information
nanovna committed Apr 21, 2020
1 parent 5ae5c58 commit cb89150
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 30 deletions.
15 changes: 10 additions & 5 deletions vna_qt/mainwindow.C
Original file line number Diff line number Diff line change
Expand Up @@ -403,22 +403,23 @@ void MainWindow::updatePortExtension() {

static string calFileVer = "calFileVersion 1";
string MainWindow::serializeCalibration(const CalibrationInfo &cal) {
scopedCLocale _locale; // use standard number formatting
string tmp;
tmp.append(calFileVer);
tmp += '\n';
tmp.append(cal.calName + "\n");
tmp.append(to_string(cal.nPoints)+" "+to_string(cal.startFreqHz)+" "+to_string(cal.stepFreqHz));
tmp.append(" "+to_string(cal.attenuation1)+" "+to_string(cal.attenuation2));
saprintf(tmp, "%d %f %f ", cal.nPoints, cal.startFreqHz, cal.stepFreqHz);
saprintf(tmp, "%d %d", cal.attenuation1, cal.attenuation2);
tmp += '\n';
for(auto& calstd:cal.measurements) {
if(calstd.first.length() == 0)
continue;
tmp.append(calstd.first);
tmp += '\n';
for(const VNARawValue& val:calstd.second) {
int sz=val.rows()*val.cols();
for(int i=0;i<sz;i++) {
tmp.append(to_string(val(i).real()) + " ");
tmp.append(to_string(val(i).imag()));
tmp += ' ';
saprintf(tmp, "%f %f ", val(i).real(), val(i).imag());
}
tmp += '\n';
}
Expand All @@ -427,6 +428,7 @@ string MainWindow::serializeCalibration(const CalibrationInfo &cal) {
}

CalibrationInfo MainWindow::deserializeCalibration(QTextStream &inp) {
scopedCLocale _locale; // use standard number formatting
CalibrationInfo ret;
string versionStr = inp.readLine().toStdString();
if(versionStr != calFileVer) {
Expand All @@ -453,6 +455,9 @@ CalibrationInfo MainWindow::deserializeCalibration(QTextStream &inp) {
}
values.push_back(value);
}
// discard the rest of the line
inp.readLine();

ret.measurements[calstd.toStdString()] = values;
fprintf(stderr, "found cal standard %s\n", calstd.toUtf8().data());
fflush(stderr);
Expand Down
28 changes: 3 additions & 25 deletions vna_qt/touchstone.C
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,10 @@

using namespace std;

#if __cplusplus < 201103L
#error This library needs at least a C++11 compliant compiler
#endif

// append to dst
int saprintf(string& dst, const char* fmt, ...) {
int bytesToAllocate=32;
int originalLen=dst.length();
while(true) {
dst.resize(originalLen+bytesToAllocate);
va_list args;
va_start(args, fmt);
// ONLY WORKS WITH C++11!!!!!!!!
// .data() does not guarantee enough space for the null byte before c++11
int len = vsnprintf((char*)dst.data()+originalLen, bytesToAllocate+1, fmt, args);
va_end(args);
if(len>=0 && len <= bytesToAllocate) {
dst.resize(originalLen+len);
return len;
}
if(len<=0) bytesToAllocate*=2;
else bytesToAllocate = len;
}
}



string serializeTouchstone(vector<complex<double> > data, double startFreqHz, double stepFreqHz) {
scopedCLocale _locale; // use standard number formatting
string res;
res += "# MHz S MA R 50\n";
saprintf(res,"! freq S11 \n");
Expand All @@ -52,6 +28,7 @@ string serializeTouchstone(vector<complex<double> > data, double startFreqHz, do
}

string serializeTouchstone(vector<Matrix2cd> data, double startFreqHz, double stepFreqHz) {
scopedCLocale _locale; // use standard number formatting
string res;
res += "# MHz S MA R 50\n";
saprintf(res,"! freq S11 S21 S12 S22 \n");
Expand All @@ -72,6 +49,7 @@ string serializeTouchstone(vector<Matrix2cd> data, double startFreqHz, double st


void parseTouchstone(string data, int& nPorts, map<double, MatrixXcd> &results) {
scopedCLocale _locale; // use standard number formatting
istringstream iss(data);
string line;

Expand Down
44 changes: 44 additions & 0 deletions vna_qt/utility.H
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,31 @@
#include <sstream>
#include <QString>
#include <time.h>
#include <locale.h>


#if __cplusplus < 201103L
#error This library needs at least a C++11 compliant compiler
#endif

using namespace std;

// when this class is instantiated, the program locale is set to C
class scopedCLocale {
public:
bool _shouldRevert = true;
scopedCLocale() {
if(strcmp("C", setlocale(LC_ALL, NULL)) == 0)
_shouldRevert = false;
setlocale(LC_ALL, "C");
}
~scopedCLocale() {
if(_shouldRevert)
setlocale(LC_ALL, "");
}
};


inline QString qs(const string& s) {
return QString::fromStdString(s);
}
Expand Down Expand Up @@ -74,6 +96,28 @@ inline string ssprintf(int maxLen, const char* fmt, ...) {
tmp.resize(len);
return tmp;
}

// append to dst
inline int saprintf(string& dst, const char* fmt, ...) {
int bytesToAllocate=32;
int originalLen=dst.length();
while(true) {
dst.resize(originalLen+bytesToAllocate);
va_list args;
va_start(args, fmt);
// ONLY WORKS WITH C++11!!!!!!!!
// .data() does not guarantee enough space for the null byte before c++11
int len = vsnprintf((char*)dst.data()+originalLen, bytesToAllocate+1, fmt, args);
va_end(args);
if(len>=0 && len <= bytesToAllocate) {
dst.resize(originalLen+len);
return len;
}
if(len<=0) bytesToAllocate*=2;
else bytesToAllocate = len;
}
}

inline string sstrftime(const char *format, const struct tm &tm) {
char buf[256] = {0};
strftime(buf, 256, format, &tm);
Expand Down

0 comments on commit cb89150

Please sign in to comment.