changed streamScanfN to return number of read bytes
This commit is contained in:
@ -27,7 +27,7 @@ class BCDConverter : public StreamFormatConverter
|
|||||||
{
|
{
|
||||||
int parse (const StreamFormat&, StreamBuffer&, const char*&, bool);
|
int parse (const StreamFormat&, StreamBuffer&, const char*&, bool);
|
||||||
bool printLong(const StreamFormat&, StreamBuffer&, long);
|
bool printLong(const StreamFormat&, StreamBuffer&, long);
|
||||||
int scanLong(const StreamFormat&, const char*, long&);
|
long scanLong(const StreamFormat&, const char*, long&);
|
||||||
};
|
};
|
||||||
|
|
||||||
int BCDConverter::
|
int BCDConverter::
|
||||||
@ -39,64 +39,65 @@ parse(const StreamFormat& fmt, StreamBuffer&, const char*&, bool)
|
|||||||
bool BCDConverter::
|
bool BCDConverter::
|
||||||
printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
||||||
{
|
{
|
||||||
unsigned char bcd[6]={0,0,0,0,0,0}; // sufficient for 2^32
|
unsigned char bcd;
|
||||||
int i;
|
bool neg = false;
|
||||||
int prec = fmt.prec; // number of nibbles
|
long i;
|
||||||
if (prec == -1)
|
unsigned long prec = fmt.prec < 0 ? 2 * sizeof(value) : fmt.prec; // number of nibbles
|
||||||
{
|
unsigned long width = (prec + (fmt.flags & sign_flag ? 2 : 1)) / 2;
|
||||||
prec = 2 * sizeof (value);
|
|
||||||
}
|
|
||||||
int width = (prec + (fmt.flags & sign_flag ? 2 : 1)) / 2;
|
|
||||||
if (fmt.width > width) width = fmt.width;
|
if (fmt.width > width) width = fmt.width;
|
||||||
if (fmt.flags & sign_flag && value < 0)
|
if (fmt.flags & sign_flag && value < 0 && prec > 0)
|
||||||
{
|
{
|
||||||
// negative BCD value, I hope "F" as "-" is OK
|
neg = true;
|
||||||
bcd[5] = 0xF0;
|
|
||||||
value = -value;
|
value = -value;
|
||||||
}
|
}
|
||||||
if (prec > 10) prec = 10;
|
|
||||||
for (i = 0; i < prec; i++)
|
|
||||||
{
|
|
||||||
bcd[i/2] |= (value % 10) << (4 * (i & 1));
|
|
||||||
value /= 10;
|
|
||||||
}
|
|
||||||
if (fmt.flags & alt_flag)
|
if (fmt.flags & alt_flag)
|
||||||
{
|
{
|
||||||
// least significant byte first (little endian)
|
// least significant byte first (little endian)
|
||||||
for (i = 0; i < (prec + 1) / 2; i++)
|
while (width-- && prec)
|
||||||
{
|
{
|
||||||
output.append(bcd[i]);
|
bcd = value%10;
|
||||||
|
if (--prec)
|
||||||
|
{
|
||||||
|
--prec;
|
||||||
|
value /= 10;
|
||||||
|
bcd |= (value%10)<<4;
|
||||||
|
value /= 10;
|
||||||
|
}
|
||||||
|
output.append(bcd);
|
||||||
}
|
}
|
||||||
for (; i < width; i++)
|
if (width)
|
||||||
{
|
output.append('\0', width);
|
||||||
output.append('\0');
|
if (neg) output[-1] |= 0xf0;
|
||||||
}
|
|
||||||
output[-1] |= bcd[5];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// most significant byte first (big endian)
|
// most significant byte first (big endian)
|
||||||
int firstbyte = output.length();
|
output.append('\0', width);
|
||||||
for (i = 0; i < width - (prec + 1) / 2; i++)
|
if (neg) output[-width] |= 0xf0;
|
||||||
|
i = 0;
|
||||||
|
while (width-- && prec)
|
||||||
{
|
{
|
||||||
output.append('\0');
|
bcd = value%10;
|
||||||
|
if (--prec)
|
||||||
|
{
|
||||||
|
--prec;
|
||||||
|
value /= 10;
|
||||||
|
bcd |= (value%10)<<4;
|
||||||
|
value /= 10;
|
||||||
|
}
|
||||||
|
output[--i]=bcd;
|
||||||
}
|
}
|
||||||
for (i = (prec - 1) / 2; i >= 0; i--)
|
|
||||||
{
|
|
||||||
output.append(bcd[i]);
|
|
||||||
}
|
|
||||||
output[firstbyte] |= bcd[5];
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BCDConverter::
|
long BCDConverter::
|
||||||
scanLong(const StreamFormat& fmt, const char* input, long& value)
|
scanLong(const StreamFormat& fmt, const char* input, long& value)
|
||||||
{
|
{
|
||||||
int length = 0;
|
long length = 0;
|
||||||
int val = 0;
|
long val = 0;
|
||||||
unsigned char bcd1, bcd10;
|
unsigned char bcd1, bcd10;
|
||||||
int width = fmt.width;
|
long width = fmt.width;
|
||||||
if (width == 0) width = 1;
|
if (width == 0) width = 1;
|
||||||
if (fmt.flags & alt_flag)
|
if (fmt.flags & alt_flag)
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@ class BinaryConverter : public StreamFormatConverter
|
|||||||
{
|
{
|
||||||
int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
||||||
bool printLong(const StreamFormat&, StreamBuffer&, long);
|
bool printLong(const StreamFormat&, StreamBuffer&, long);
|
||||||
int scanLong(const StreamFormat&, const char*, long&);
|
long scanLong(const StreamFormat&, const char*, long&);
|
||||||
};
|
};
|
||||||
|
|
||||||
int BinaryConverter::
|
int BinaryConverter::
|
||||||
@ -77,7 +77,7 @@ printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
|||||||
if (x <= 0x3FFFFFFF) { prec -= 2; x <<=2; }
|
if (x <= 0x3FFFFFFF) { prec -= 2; x <<=2; }
|
||||||
if (x <= 0x7FFFFFFF) { prec -= 1; }
|
if (x <= 0x7FFFFFFF) { prec -= 1; }
|
||||||
}
|
}
|
||||||
int width = prec;
|
unsigned long width = prec;
|
||||||
if (fmt.width > width) width = fmt.width;
|
if (fmt.width > width) width = fmt.width;
|
||||||
char zero = fmt.info[0];
|
char zero = fmt.info[0];
|
||||||
char one = fmt.info[1];
|
char one = fmt.info[1];
|
||||||
@ -88,7 +88,7 @@ printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
|||||||
if (!(fmt.flags & left_flag))
|
if (!(fmt.flags & left_flag))
|
||||||
{
|
{
|
||||||
// pad left
|
// pad left
|
||||||
while (width > prec)
|
while (width > (unsigned int)prec)
|
||||||
{
|
{
|
||||||
output.append(' ');
|
output.append(' ');
|
||||||
width--;
|
width--;
|
||||||
@ -112,7 +112,7 @@ printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
|||||||
if (!(fmt.flags & left_flag))
|
if (!(fmt.flags & left_flag))
|
||||||
{
|
{
|
||||||
// pad left
|
// pad left
|
||||||
while (width > prec)
|
while (width > (unsigned int)prec)
|
||||||
{
|
{
|
||||||
output.append(fill);
|
output.append(fill);
|
||||||
width--;
|
width--;
|
||||||
@ -132,13 +132,13 @@ printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BinaryConverter::
|
long BinaryConverter::
|
||||||
scanLong(const StreamFormat& fmt, const char* input, long& value)
|
scanLong(const StreamFormat& fmt, const char* input, long& value)
|
||||||
{
|
{
|
||||||
long val = 0;
|
long val = 0;
|
||||||
int width = fmt.width;
|
long width = fmt.width;
|
||||||
if (width == 0) width = -1;
|
if (width == 0) width = -1;
|
||||||
int length = 0;
|
long length = 0;
|
||||||
char zero = fmt.info[0];
|
char zero = fmt.info[0];
|
||||||
char one = fmt.info[1];
|
char one = fmt.info[1];
|
||||||
if (!isspace(zero) && !isspace(one))
|
if (!isspace(zero) && !isspace(one))
|
||||||
|
@ -500,7 +500,7 @@ class ChecksumConverter : public StreamFormatConverter
|
|||||||
{
|
{
|
||||||
int parse (const StreamFormat&, StreamBuffer&, const char*&, bool);
|
int parse (const StreamFormat&, StreamBuffer&, const char*&, bool);
|
||||||
bool printPseudo(const StreamFormat&, StreamBuffer&);
|
bool printPseudo(const StreamFormat&, StreamBuffer&);
|
||||||
int scanPseudo(const StreamFormat&, StreamBuffer&, long& cursor);
|
long scanPseudo(const StreamFormat&, StreamBuffer&, long& cursor);
|
||||||
};
|
};
|
||||||
|
|
||||||
int ChecksumConverter::
|
int ChecksumConverter::
|
||||||
@ -535,7 +535,7 @@ parse(const StreamFormat&, StreamBuffer& info, const char*& source, bool)
|
|||||||
source+=3;
|
source+=3;
|
||||||
notflag = true;
|
notflag = true;
|
||||||
}
|
}
|
||||||
unsigned fnum;
|
unsigned char fnum;
|
||||||
int len = p-source;
|
int len = p-source;
|
||||||
unsigned int init, xorout;
|
unsigned int init, xorout;
|
||||||
for (fnum = 0; fnum < sizeof(checksumMap)/sizeof(checksum); fnum++)
|
for (fnum = 0; fnum < sizeof(checksumMap)/sizeof(checksum); fnum++)
|
||||||
@ -573,7 +573,7 @@ printPseudo(const StreamFormat& format, StreamBuffer& output)
|
|||||||
const char* info = format.info;
|
const char* info = format.info;
|
||||||
unsigned int init = extract<unsigned int>(info);
|
unsigned int init = extract<unsigned int>(info);
|
||||||
unsigned int xorout = extract<unsigned int>(info);
|
unsigned int xorout = extract<unsigned int>(info);
|
||||||
int fnum = extract<char>(info);
|
unsigned char fnum = extract<unsigned char>(info);
|
||||||
|
|
||||||
int start = format.width;
|
int start = format.width;
|
||||||
int length = output.length()-format.width;
|
int length = output.length()-format.width;
|
||||||
@ -641,7 +641,7 @@ printPseudo(const StreamFormat& format, StreamBuffer& output)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ChecksumConverter::
|
long ChecksumConverter::
|
||||||
scanPseudo(const StreamFormat& format, StreamBuffer& input, long& cursor)
|
scanPseudo(const StreamFormat& format, StreamBuffer& input, long& cursor)
|
||||||
{
|
{
|
||||||
unsigned int sum;
|
unsigned int sum;
|
||||||
@ -649,8 +649,8 @@ scanPseudo(const StreamFormat& format, StreamBuffer& input, long& cursor)
|
|||||||
unsigned int init = extract<unsigned int>(info);
|
unsigned int init = extract<unsigned int>(info);
|
||||||
unsigned int xorout = extract<unsigned int>(info);
|
unsigned int xorout = extract<unsigned int>(info);
|
||||||
int start = format.width;
|
int start = format.width;
|
||||||
int fnum = extract<char>(info);
|
unsigned char fnum = extract<unsigned char>(info);
|
||||||
int length = cursor-format.width;
|
long length = cursor-format.width;
|
||||||
|
|
||||||
if (format.prec > 0) length -= format.prec;
|
if (format.prec > 0) length -= format.prec;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class EnumConverter : public StreamFormatConverter
|
|||||||
{
|
{
|
||||||
int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
||||||
bool printLong(const StreamFormat&, StreamBuffer&, long);
|
bool printLong(const StreamFormat&, StreamBuffer&, long);
|
||||||
int scanLong(const StreamFormat&, const char*, long&);
|
long scanLong(const StreamFormat&, const char*, long&);
|
||||||
};
|
};
|
||||||
|
|
||||||
// info format: <numEnums><index><string>0<index><string>0...
|
// info format: <numEnums><index><string>0<index><string>0...
|
||||||
@ -148,7 +148,7 @@ printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EnumConverter::
|
long EnumConverter::
|
||||||
scanLong(const StreamFormat& fmt, const char* input, long& value)
|
scanLong(const StreamFormat& fmt, const char* input, long& value)
|
||||||
{
|
{
|
||||||
debug("EnumConverter::scanLong(%%%c, \"%s\")\n",
|
debug("EnumConverter::scanLong(%%%c, \"%s\")\n",
|
||||||
@ -156,7 +156,7 @@ scanLong(const StreamFormat& fmt, const char* input, long& value)
|
|||||||
const char* s = fmt.info;
|
const char* s = fmt.info;
|
||||||
long numEnums = extract<long>(s);
|
long numEnums = extract<long>(s);
|
||||||
long index;
|
long index;
|
||||||
int length;
|
long length;
|
||||||
|
|
||||||
bool match;
|
bool match;
|
||||||
while (numEnums--)
|
while (numEnums--)
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
class MantissaExponentConverter : public StreamFormatConverter
|
class MantissaExponentConverter : public StreamFormatConverter
|
||||||
{
|
{
|
||||||
virtual int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
virtual int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
||||||
virtual int scanDouble(const StreamFormat&, const char*, double&);
|
virtual long scanDouble(const StreamFormat&, const char*, double&);
|
||||||
virtual bool printDouble(const StreamFormat&, StreamBuffer&, double);
|
virtual bool printDouble(const StreamFormat&, StreamBuffer&, double);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ parse(const StreamFormat&, StreamBuffer&,
|
|||||||
return double_format;
|
return double_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MantissaExponentConverter::
|
long MantissaExponentConverter::
|
||||||
scanDouble(const StreamFormat& fmt, const char* input, double& value)
|
scanDouble(const StreamFormat& fmt, const char* input, double& value)
|
||||||
{
|
{
|
||||||
int mantissa;
|
int mantissa;
|
||||||
|
@ -27,7 +27,7 @@ class RawConverter : public StreamFormatConverter
|
|||||||
{
|
{
|
||||||
int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
||||||
bool printLong(const StreamFormat&, StreamBuffer&, long);
|
bool printLong(const StreamFormat&, StreamBuffer&, long);
|
||||||
int scanLong(const StreamFormat&, const char*, long&);
|
long scanLong(const StreamFormat&, const char*, long&);
|
||||||
};
|
};
|
||||||
|
|
||||||
int RawConverter::
|
int RawConverter::
|
||||||
@ -40,10 +40,9 @@ parse(const StreamFormat& fmt, StreamBuffer&,
|
|||||||
bool RawConverter::
|
bool RawConverter::
|
||||||
printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
||||||
{
|
{
|
||||||
int prec = fmt.prec; // number of bytes from value
|
unsigned int prec = fmt.prec < 0 ? 1 : fmt.prec; // number of bytes from value, default 1
|
||||||
if (prec == -1) prec = 1; // default: 1 byte
|
unsigned long width = prec; // number of bytes in output
|
||||||
int width = prec; // number of bytes in output
|
if (prec > sizeof(long)) prec=sizeof(long);
|
||||||
if (prec > (int)sizeof(long)) prec=sizeof(long);
|
|
||||||
if (fmt.width > width) width = fmt.width;
|
if (fmt.width > width) width = fmt.width;
|
||||||
|
|
||||||
char byte = 0;
|
char byte = 0;
|
||||||
@ -96,12 +95,12 @@ printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RawConverter::
|
long RawConverter::
|
||||||
scanLong(const StreamFormat& fmt, const char* input, long& value)
|
scanLong(const StreamFormat& fmt, const char* input, long& value)
|
||||||
{
|
{
|
||||||
long length = 0;
|
long length = 0;
|
||||||
long val = 0;
|
long val = 0;
|
||||||
int width = fmt.width;
|
unsigned long width = fmt.width;
|
||||||
if (width == 0) width = 1; // default: 1 byte
|
if (width == 0) width = 1; // default: 1 byte
|
||||||
if (fmt.flags & skip_flag)
|
if (fmt.flags & skip_flag)
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@ class RawFloatConverter : public StreamFormatConverter
|
|||||||
{
|
{
|
||||||
int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
||||||
bool printDouble(const StreamFormat&, StreamBuffer&, double);
|
bool printDouble(const StreamFormat&, StreamBuffer&, double);
|
||||||
int scanDouble(const StreamFormat&, const char*, double&);
|
long scanDouble(const StreamFormat&, const char*, double&);
|
||||||
};
|
};
|
||||||
|
|
||||||
int RawFloatConverter::
|
int RawFloatConverter::
|
||||||
@ -90,7 +90,7 @@ printDouble(const StreamFormat& format, StreamBuffer& output, double value)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RawFloatConverter::
|
long RawFloatConverter::
|
||||||
scanDouble(const StreamFormat& format, const char* input, double& value)
|
scanDouble(const StreamFormat& format, const char* input, double& value)
|
||||||
{
|
{
|
||||||
int nbOfBytes;
|
int nbOfBytes;
|
||||||
|
@ -38,8 +38,8 @@
|
|||||||
class RegexpConverter : public StreamFormatConverter
|
class RegexpConverter : public StreamFormatConverter
|
||||||
{
|
{
|
||||||
int parse (const StreamFormat& fmt, StreamBuffer&, const char*&, bool);
|
int parse (const StreamFormat& fmt, StreamBuffer&, const char*&, bool);
|
||||||
int scanString(const StreamFormat& fmt, const char*, char*, size_t);
|
long scanString(const StreamFormat& fmt, const char*, char*, unsigned long&);
|
||||||
int scanPseudo(const StreamFormat& fmt, StreamBuffer& input, long& cursor);
|
long scanPseudo(const StreamFormat& fmt, StreamBuffer& input, long& cursor);
|
||||||
bool printPseudo(const StreamFormat& fmt, StreamBuffer& output);
|
bool printPseudo(const StreamFormat& fmt, StreamBuffer& output);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ parse(const StreamFormat& fmt, StreamBuffer& info,
|
|||||||
}
|
}
|
||||||
if (fmt.prec > 9)
|
if (fmt.prec > 9)
|
||||||
{
|
{
|
||||||
error("Subexpression index %d too big (>9)\n", fmt.prec);
|
error("Subexpression index %ld too big (>9)\n", fmt.prec);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,14 +115,13 @@ parse(const StreamFormat& fmt, StreamBuffer& info,
|
|||||||
return string_format;
|
return string_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RegexpConverter::
|
long RegexpConverter::
|
||||||
scanString(const StreamFormat& fmt, const char* input,
|
scanString(const StreamFormat& fmt, const char* input,
|
||||||
char* value, size_t maxlen)
|
char* value, unsigned long& size)
|
||||||
{
|
{
|
||||||
int ovector[30];
|
int ovector[30];
|
||||||
int rc;
|
int rc;
|
||||||
unsigned int l;
|
unsigned int l;
|
||||||
|
|
||||||
const char* info = fmt.info;
|
const char* info = fmt.info;
|
||||||
pcre* code = extract<pcre*>(info);
|
pcre* code = extract<pcre*>(info);
|
||||||
int length = fmt.width > 0 ? fmt.width : strlen(input);
|
int length = fmt.width > 0 ? fmt.width : strlen(input);
|
||||||
@ -141,17 +140,18 @@ scanString(const StreamFormat& fmt, const char* input,
|
|||||||
if (fmt.flags & skip_flag) return ovector[subexpr*2+1];
|
if (fmt.flags & skip_flag) return ovector[subexpr*2+1];
|
||||||
|
|
||||||
l = ovector[subexpr*2+1] - ovector[subexpr*2];
|
l = ovector[subexpr*2+1] - ovector[subexpr*2];
|
||||||
if (l >= maxlen) {
|
if (l >= size) {
|
||||||
if (!(fmt.flags & sign_flag)) {
|
if (!(fmt.flags & sign_flag)) {
|
||||||
error("Regexp: Matching string \"%s\" too long (%d>%ld bytes). You may want to try the + flag: \"%%+/.../\"\n",
|
error("Regexp: Matching string \"%s\" too long (%d>%ld bytes). You may want to try the + flag: \"%%+/.../\"\n",
|
||||||
StreamBuffer(input + ovector[subexpr*2],l).expand()(),
|
StreamBuffer(input + ovector[subexpr*2],l).expand()(),
|
||||||
l, (long)maxlen-1);
|
l, (long)size-1);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
l = maxlen-1;
|
l = size-1;
|
||||||
}
|
}
|
||||||
memcpy(value, input + ovector[subexpr*2], l);
|
memcpy(value, input + ovector[subexpr*2], l);
|
||||||
value[l] = '\0';
|
value[l] = '\0';
|
||||||
|
size = l+1; // update number of bytes written to value
|
||||||
return ovector[1]; // consume input until end of match
|
return ovector[1]; // consume input until end of match
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,8 +159,8 @@ static void regsubst(const StreamFormat& fmt, StreamBuffer& buffer, long start)
|
|||||||
{
|
{
|
||||||
const char* subst = fmt.info;
|
const char* subst = fmt.info;
|
||||||
pcre* code = extract<pcre*>(subst);
|
pcre* code = extract<pcre*>(subst);
|
||||||
long length;
|
unsigned long length, c;
|
||||||
int rc, l, c, r, rl, n;
|
int rc, l, r, rl, n;
|
||||||
int ovector[30];
|
int ovector[30];
|
||||||
StreamBuffer s;
|
StreamBuffer s;
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ static void regsubst(const StreamFormat& fmt, StreamBuffer& buffer, long start)
|
|||||||
for (c = 0, n = 1; c < length; n++)
|
for (c = 0, n = 1; c < length; n++)
|
||||||
{
|
{
|
||||||
rc = pcre_exec(code, NULL, buffer(start+c), length-c, 0, 0, ovector, 30);
|
rc = pcre_exec(code, NULL, buffer(start+c), length-c, 0, 0, ovector, 30);
|
||||||
debug("pcre_exec match \"%.*s\" result = %d\n", (int)length-c, buffer(start+c), rc);
|
debug("pcre_exec match \"%.*s\" result = %d\n", (int)(length-c), buffer(start+c), rc);
|
||||||
if (rc < 0) // no match
|
if (rc < 0) // no match
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -229,7 +229,7 @@ static void regsubst(const StreamFormat& fmt, StreamBuffer& buffer, long start)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int RegexpConverter::
|
long RegexpConverter::
|
||||||
scanPseudo(const StreamFormat& fmt, StreamBuffer& input, long& cursor)
|
scanPseudo(const StreamFormat& fmt, StreamBuffer& input, long& cursor)
|
||||||
{
|
{
|
||||||
/* re-write input buffer */
|
/* re-write input buffer */
|
||||||
|
@ -1215,6 +1215,7 @@ normal_format:
|
|||||||
{
|
{
|
||||||
long ldummy;
|
long ldummy;
|
||||||
double ddummy;
|
double ddummy;
|
||||||
|
long unsigned size=0;
|
||||||
switch (fmt.type)
|
switch (fmt.type)
|
||||||
{
|
{
|
||||||
case unsigned_format:
|
case unsigned_format:
|
||||||
@ -1229,7 +1230,7 @@ normal_format:
|
|||||||
break;
|
break;
|
||||||
case string_format:
|
case string_format:
|
||||||
consumed = StreamFormatConverter::find(fmt.conv)->
|
consumed = StreamFormatConverter::find(fmt.conv)->
|
||||||
scanString(fmt, inputLine(consumedInput), NULL, 0);
|
scanString(fmt, inputLine(consumedInput), NULL, size);
|
||||||
break;
|
break;
|
||||||
case pseudo_format:
|
case pseudo_format:
|
||||||
// pass complete input
|
// pass complete input
|
||||||
@ -1482,7 +1483,7 @@ scanValue(const StreamFormat& fmt, long& value)
|
|||||||
}
|
}
|
||||||
else return -1;
|
else return -1;
|
||||||
}
|
}
|
||||||
if (fmt.flags & fix_width_flag && consumed != fmt.width) return -1;
|
if (fmt.flags & fix_width_flag && (unsigned long)consumed != fmt.width) return -1;
|
||||||
if (consumed > inputLine.length()-consumedInput) return -1;
|
if (consumed > inputLine.length()-consumedInput) return -1;
|
||||||
debug("StreamCore::scanValue(%s) scanned %li\n",
|
debug("StreamCore::scanValue(%s) scanned %li\n",
|
||||||
name(), value);
|
name(), value);
|
||||||
@ -1514,7 +1515,7 @@ scanValue(const StreamFormat& fmt, double& value)
|
|||||||
}
|
}
|
||||||
else return -1;
|
else return -1;
|
||||||
}
|
}
|
||||||
if (fmt.flags & fix_width_flag && (consumed != (fmt.width + fmt.prec + 1))) return -1;
|
if (fmt.flags & fix_width_flag && ((unsigned long)consumed != (fmt.width + fmt.prec + 1))) return -1;
|
||||||
if (consumed > inputLine.length()-consumedInput) return -1;
|
if (consumed > inputLine.length()-consumedInput) return -1;
|
||||||
debug("StreamCore::scanValue(%s) scanned %#g\n",
|
debug("StreamCore::scanValue(%s) scanned %#g\n",
|
||||||
name(), value);
|
name(), value);
|
||||||
@ -1523,7 +1524,7 @@ scanValue(const StreamFormat& fmt, double& value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
long StreamCore::
|
long StreamCore::
|
||||||
scanValue(const StreamFormat& fmt, char* value, long maxlen)
|
scanValue(const StreamFormat& fmt, char* value, unsigned long& size)
|
||||||
{
|
{
|
||||||
if (fmt.type != string_format)
|
if (fmt.type != string_format)
|
||||||
{
|
{
|
||||||
@ -1531,13 +1532,12 @@ scanValue(const StreamFormat& fmt, char* value, long maxlen)
|
|||||||
name(), fmt.conv);
|
name(), fmt.conv);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (maxlen < 0) maxlen = 0;
|
|
||||||
flags |= ScanTried;
|
flags |= ScanTried;
|
||||||
if (!matchSeparator()) return -1;
|
if (!matchSeparator()) return -1;
|
||||||
long consumed = StreamFormatConverter::find(fmt.conv)->
|
long consumed = StreamFormatConverter::find(fmt.conv)->
|
||||||
scanString(fmt, inputLine(consumedInput), value, maxlen);
|
scanString(fmt, inputLine(consumedInput), value, size);
|
||||||
debug("StreamCore::scanValue(%s, format=%%%c, char*, maxlen=%ld) input=\"%s\"\n",
|
debug("StreamCore::scanValue(%s, format=%%%c, char*, size=%ld) input=\"%s\"\n",
|
||||||
name(), fmt.conv, maxlen, inputLine.expand(consumedInput)());
|
name(), fmt.conv, size, inputLine.expand(consumedInput)());
|
||||||
if (consumed < 0)
|
if (consumed < 0)
|
||||||
{
|
{
|
||||||
if (fmt.flags & default_flag)
|
if (fmt.flags & default_flag)
|
||||||
@ -1547,11 +1547,11 @@ scanValue(const StreamFormat& fmt, char* value, long maxlen)
|
|||||||
}
|
}
|
||||||
else return -1;
|
else return -1;
|
||||||
}
|
}
|
||||||
if (fmt.flags & fix_width_flag && consumed != fmt.width) return -1;
|
if (fmt.flags & fix_width_flag && (unsigned long)consumed != fmt.width) return -1;
|
||||||
if (consumed > inputLine.length()-consumedInput) return -1;
|
if (consumed > inputLine.length()-consumedInput) return -1;
|
||||||
#ifndef NO_TEMPORARY
|
#ifndef NO_TEMPORARY
|
||||||
debug("StreamCore::scanValue(%s) scanned \"%s\"\n",
|
debug("StreamCore::scanValue(%s) scanned \"%s\"\n",
|
||||||
name(), StreamBuffer(value, maxlen).expand()());
|
name(), StreamBuffer(value, size).expand()());
|
||||||
#endif
|
#endif
|
||||||
flags |= GotValue;
|
flags |= GotValue;
|
||||||
return consumed;
|
return consumed;
|
||||||
|
@ -137,7 +137,7 @@ protected:
|
|||||||
bool printValue(const StreamFormat& format, char* value);
|
bool printValue(const StreamFormat& format, char* value);
|
||||||
long scanValue(const StreamFormat& format, long& value);
|
long scanValue(const StreamFormat& format, long& value);
|
||||||
long scanValue(const StreamFormat& format, double& value);
|
long scanValue(const StreamFormat& format, double& value);
|
||||||
long scanValue(const StreamFormat& format, char* value, long maxlen);
|
long scanValue(const StreamFormat& format, char* value, unsigned long& size);
|
||||||
long scanValue(const StreamFormat& format);
|
long scanValue(const StreamFormat& format);
|
||||||
|
|
||||||
StreamBuffer protocolname;
|
StreamBuffer protocolname;
|
||||||
|
@ -157,7 +157,7 @@ class Stream : protected StreamCore
|
|||||||
long initRecord(const char* filename, const char* protocol,
|
long initRecord(const char* filename, const char* protocol,
|
||||||
const char* busname, int addr, const char* busparam);
|
const char* busname, int addr, const char* busparam);
|
||||||
bool print(format_t *format, va_list ap);
|
bool print(format_t *format, va_list ap);
|
||||||
bool scan(format_t *format, void* pvalue, size_t maxStringSize);
|
long scan(format_t *format, void* pvalue, size_t maxStringSize);
|
||||||
bool process();
|
bool process();
|
||||||
|
|
||||||
// device support functions
|
// device support functions
|
||||||
@ -554,19 +554,21 @@ long streamPrintf(dbCommon *record, format_t *format, ...)
|
|||||||
long streamScanfN(dbCommon* record, format_t *format,
|
long streamScanfN(dbCommon* record, format_t *format,
|
||||||
void* value, size_t maxStringSize)
|
void* value, size_t maxStringSize)
|
||||||
{
|
{
|
||||||
|
long size;
|
||||||
debug("streamScanfN(%s,format=%%%c,maxStringSize=%ld)\n",
|
debug("streamScanfN(%s,format=%%%c,maxStringSize=%ld)\n",
|
||||||
record->name, format->priv->conv, (long)maxStringSize);
|
record->name, format->priv->conv, (long)maxStringSize);
|
||||||
Stream* pstream = (Stream*)record->dpvt;
|
Stream* pstream = (Stream*)record->dpvt;
|
||||||
if (!pstream) return ERROR;
|
if (!pstream) return ERROR;
|
||||||
if (!pstream->scan(format, value, maxStringSize))
|
size = pstream->scan(format, value, maxStringSize);
|
||||||
|
if (size == ERROR)
|
||||||
{
|
{
|
||||||
return ERROR;
|
debug("streamScanfN(%s) failed\n", record->name);
|
||||||
}
|
}
|
||||||
#ifndef NO_TEMPORARY
|
#ifndef NO_TEMPORARY
|
||||||
debug("streamScanfN(%s) success, value=\"%s\"\n",
|
debug("streamScanfN(%s) success, value=\"%s\"\n",
|
||||||
record->name, StreamBuffer((char*)value).expand()());
|
record->name, StreamBuffer((char*)value).expand()());
|
||||||
#endif
|
#endif
|
||||||
return OK;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stream methods ////////////////////////////////////////////////////////
|
// Stream methods ////////////////////////////////////////////////////////
|
||||||
@ -800,11 +802,12 @@ print(format_t *format, va_list ap)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Stream::
|
long Stream::
|
||||||
scan(format_t *format, void* value, size_t maxStringSize)
|
scan(format_t *format, void* value, size_t maxStringSize)
|
||||||
{
|
{
|
||||||
// called by streamScanfN
|
// called by streamScanfN
|
||||||
|
|
||||||
|
unsigned long size = maxStringSize;
|
||||||
// first remove old value from inputLine (if we are scanning arrays)
|
// first remove old value from inputLine (if we are scanning arrays)
|
||||||
consumedInput += currentValueLength;
|
consumedInput += currentValueLength;
|
||||||
currentValueLength = 0;
|
currentValueLength = 0;
|
||||||
@ -820,20 +823,17 @@ scan(format_t *format, void* value, size_t maxStringSize)
|
|||||||
break;
|
break;
|
||||||
case DBF_STRING:
|
case DBF_STRING:
|
||||||
currentValueLength = scanValue(*format->priv, (char*)value,
|
currentValueLength = scanValue(*format->priv, (char*)value,
|
||||||
maxStringSize);
|
size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error("INTERNAL ERROR (%s): Illegal format type\n", name());
|
error("INTERNAL ERROR (%s): Illegal format type\n", name());
|
||||||
return false;
|
return ERROR;
|
||||||
}
|
|
||||||
if (currentValueLength < 0)
|
|
||||||
{
|
|
||||||
currentValueLength = 0;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
// Don't remove scanned value from inputLine yet, because
|
// Don't remove scanned value from inputLine yet, because
|
||||||
// we might need the string in a later error message.
|
// we might need the string in a later error message.
|
||||||
return true;
|
if (currentValueLength == ERROR) return ERROR;
|
||||||
|
if (format->type == DBF_STRING) return size;
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// epicsTimerNotify virtual method ///////////////////////////////////////
|
// epicsTimerNotify virtual method ///////////////////////////////////////
|
||||||
@ -1163,6 +1163,7 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
|||||||
int status;
|
int status;
|
||||||
const char* putfunc;
|
const char* putfunc;
|
||||||
format_s fmt;
|
format_s fmt;
|
||||||
|
unsigned long stringsize = MAX_STRING_SIZE;
|
||||||
|
|
||||||
fmt.type = dbfMapping[format.type];
|
fmt.type = dbfMapping[format.type];
|
||||||
fmt.priv = &format;
|
fmt.priv = &format;
|
||||||
@ -1172,10 +1173,18 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
|||||||
// to field of this or other record.
|
// to field of this or other record.
|
||||||
StreamBuffer fieldBuffer;
|
StreamBuffer fieldBuffer;
|
||||||
DBADDR* pdbaddr = (DBADDR*)fieldaddress;
|
DBADDR* pdbaddr = (DBADDR*)fieldaddress;
|
||||||
long nord;
|
size_t size;
|
||||||
long nelem = pdbaddr->no_elements;
|
unsigned long nord;
|
||||||
size_t size = nelem * dbValueSize(fmt.type);
|
unsigned long nelem = pdbaddr->no_elements;
|
||||||
buffer = fieldBuffer.clear().reserve(size);
|
if (format.type == string_format &&
|
||||||
|
(pdbaddr->field_type == DBF_CHAR || pdbaddr->field_type == DBF_UCHAR))
|
||||||
|
{
|
||||||
|
// string to char array
|
||||||
|
size = nelem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
size = nelem * dbValueSize(fmt.type);
|
||||||
|
buffer = fieldBuffer.clear().reserve(size); // maybe write to field directly in case types match?
|
||||||
for (nord = 0; nord < nelem; nord++)
|
for (nord = 0; nord < nelem; nord++)
|
||||||
{
|
{
|
||||||
debug("Stream::matchValue(%s): buffer before: %s\n",
|
debug("Stream::matchValue(%s): buffer before: %s\n",
|
||||||
@ -1232,24 +1241,27 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
|||||||
}
|
}
|
||||||
case string_format:
|
case string_format:
|
||||||
{
|
{
|
||||||
if (pdbaddr->field_type == DBF_CHAR)
|
if (pdbaddr->field_type == DBF_CHAR ||
|
||||||
|
pdbaddr->field_type == DBF_UCHAR)
|
||||||
{
|
{
|
||||||
// string to char array
|
// string to char array
|
||||||
consumed = scanValue(format, buffer, nelem);
|
stringsize = nelem;
|
||||||
|
consumed = scanValue(format, buffer, stringsize);
|
||||||
debug("Stream::matchValue(%s): %s.%s = \"%.*s\"\n",
|
debug("Stream::matchValue(%s): %s.%s = \"%.*s\"\n",
|
||||||
name(), pdbaddr->precord->name,
|
name(), pdbaddr->precord->name,
|
||||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||||
(int)consumed, buffer);
|
(int)consumed, buffer);
|
||||||
nord = nelem;
|
nord = nelem; // this shortcuts the loop
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
stringsize = MAX_STRING_SIZE;
|
||||||
consumed = scanValue(format,
|
consumed = scanValue(format,
|
||||||
buffer+MAX_STRING_SIZE*nord, MAX_STRING_SIZE);
|
buffer+MAX_STRING_SIZE*nord, stringsize);
|
||||||
debug("Stream::matchValue(%s): %s.%s[%li] = \"%.*s\"\n",
|
debug("Stream::matchValue(%s): %s.%s[%li] = \"%.*s\"\n",
|
||||||
name(), pdbaddr->precord->name,
|
name(), pdbaddr->precord->name,
|
||||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||||
nord, MAX_STRING_SIZE, buffer+MAX_STRING_SIZE*nord);
|
nord, (int)stringsize, buffer+MAX_STRING_SIZE*nord);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1290,7 +1302,7 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
|||||||
/* convert from Unix epoch (1 Jan 1970) to EPICS epoch (1 Jan 1990) */
|
/* convert from Unix epoch (1 Jan 1970) to EPICS epoch (1 Jan 1990) */
|
||||||
dval = dval-631152000u;
|
dval = dval-631152000u;
|
||||||
pdbaddr->precord->time.secPastEpoch = (long)dval;
|
pdbaddr->precord->time.secPastEpoch = (long)dval;
|
||||||
// rouding: we don't have 9 digits precision
|
// rounding: we don't have 9 digits precision
|
||||||
// in a double of today's number of seconds
|
// in a double of today's number of seconds
|
||||||
pdbaddr->precord->time.nsec = (long)((dval-(long)dval)*1e6)*1000;
|
pdbaddr->precord->time.nsec = (long)((dval-(long)dval)*1e6)*1000;
|
||||||
debug("Stream::matchValue(%s): writing %i.%i to %s.TIME field\n",
|
debug("Stream::matchValue(%s): writing %i.%i to %s.TIME field\n",
|
||||||
@ -1307,10 +1319,11 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (format.type == string_format &&
|
if (format.type == string_format &&
|
||||||
(pdbaddr->field_type == DBF_CHAR || pdbaddr->field_type == DBF_UCHAR))
|
(pdbaddr->field_type == DBF_CHAR ||
|
||||||
|
pdbaddr->field_type == DBF_UCHAR))
|
||||||
{
|
{
|
||||||
/* write strings to [U]CHAR arrays */
|
/* write strings to [U]CHAR arrays */
|
||||||
nord = consumed;
|
nord = stringsize;
|
||||||
fmt.type = DBF_CHAR;
|
fmt.type = DBF_CHAR;
|
||||||
}
|
}
|
||||||
if (pdbaddr->precord == record || INIT_RUN)
|
if (pdbaddr->precord == record || INIT_RUN)
|
||||||
@ -1349,25 +1362,26 @@ matchValue(const StreamFormat& format, const void* fieldaddress)
|
|||||||
case DBF_ULONG:
|
case DBF_ULONG:
|
||||||
case DBF_LONG:
|
case DBF_LONG:
|
||||||
case DBF_ENUM:
|
case DBF_ENUM:
|
||||||
error("%s: %s(%s.%s, %s, %li) failed\n",
|
error("%s: %s(%s.%s, %s, %li, %lu) failed\n",
|
||||||
name(), putfunc, pdbaddr->precord->name,
|
name(), putfunc, pdbaddr->precord->name,
|
||||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||||
pamapdbfType[fmt.type].strvalue,
|
pamapdbfType[fmt.type].strvalue,
|
||||||
lval);
|
lval, nord);
|
||||||
return false;
|
return false;
|
||||||
case DBF_DOUBLE:
|
case DBF_DOUBLE:
|
||||||
error("%s: %s(%s.%s, %s, %#g) failed\n",
|
error("%s: %s(%s.%s, %s, %#g, %lu) failed\n",
|
||||||
name(), putfunc, pdbaddr->precord->name,
|
name(), putfunc, pdbaddr->precord->name,
|
||||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||||
pamapdbfType[fmt.type].strvalue,
|
pamapdbfType[fmt.type].strvalue,
|
||||||
dval);
|
dval, nord);
|
||||||
return false;
|
return false;
|
||||||
case DBF_STRING:
|
case DBF_STRING:
|
||||||
error("%s: %s(%s.%s, %s, \"%.*s\") failed\n",
|
case DBF_CHAR:
|
||||||
|
error("%s: %s(%s.%s, %s, \"%.*s\", %lu) failed\n",
|
||||||
name(), putfunc, pdbaddr->precord->name,
|
name(), putfunc, pdbaddr->precord->name,
|
||||||
((dbFldDes*)pdbaddr->pfldDes)->name,
|
((dbFldDes*)pdbaddr->pfldDes)->name,
|
||||||
pamapdbfType[fmt.type].strvalue,
|
pamapdbfType[fmt.type].strvalue,
|
||||||
(int)consumed, buffer);
|
(int)consumed, buffer, nord);
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -50,9 +50,9 @@ typedef struct StreamFormat
|
|||||||
char conv;
|
char conv;
|
||||||
StreamFormatType type;
|
StreamFormatType type;
|
||||||
unsigned short flags;
|
unsigned short flags;
|
||||||
short prec;
|
long prec;
|
||||||
unsigned short width;
|
unsigned long width;
|
||||||
unsigned short infolen;
|
unsigned long infolen;
|
||||||
const char* info;
|
const char* info;
|
||||||
} StreamFormat;
|
} StreamFormat;
|
||||||
|
|
||||||
|
@ -113,12 +113,12 @@ parseFormat(const char*& source, FormatType formatType, StreamFormat& streamForm
|
|||||||
char* p;
|
char* p;
|
||||||
val = strtoul (source, &p, 10);
|
val = strtoul (source, &p, 10);
|
||||||
source = p;
|
source = p;
|
||||||
if (val > 0xFFFF)
|
if (val > LONG_MAX)
|
||||||
{
|
{
|
||||||
error("Field width %ld out of range\n", val);
|
error("Field width %ld out of range\n", val);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
streamFormat.width = (unsigned short)val;
|
streamFormat.width = val;
|
||||||
// look for prec
|
// look for prec
|
||||||
streamFormat.prec = -1;
|
streamFormat.prec = -1;
|
||||||
if (*source == '.')
|
if (*source == '.')
|
||||||
@ -132,7 +132,7 @@ parseFormat(const char*& source, FormatType formatType, StreamFormat& streamForm
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
source = p;
|
source = p;
|
||||||
if (val > 0x7FFF)
|
if (val > SHRT_MAX)
|
||||||
{
|
{
|
||||||
error("Precision %ld out of range\n", val);
|
error("Precision %ld out of range\n", val);
|
||||||
return false;
|
return false;
|
||||||
@ -205,7 +205,7 @@ printPseudo(const StreamFormat& fmt, StreamBuffer&)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StreamFormatConverter::
|
long StreamFormatConverter::
|
||||||
scanLong(const StreamFormat& fmt, const char*, long&)
|
scanLong(const StreamFormat& fmt, const char*, long&)
|
||||||
{
|
{
|
||||||
error("Unimplemented scanLong method for %%%c format\n",
|
error("Unimplemented scanLong method for %%%c format\n",
|
||||||
@ -213,7 +213,7 @@ scanLong(const StreamFormat& fmt, const char*, long&)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StreamFormatConverter::
|
long StreamFormatConverter::
|
||||||
scanDouble(const StreamFormat& fmt, const char*, double&)
|
scanDouble(const StreamFormat& fmt, const char*, double&)
|
||||||
{
|
{
|
||||||
error("Unimplemented scanDouble method for %%%c format\n",
|
error("Unimplemented scanDouble method for %%%c format\n",
|
||||||
@ -221,15 +221,15 @@ scanDouble(const StreamFormat& fmt, const char*, double&)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StreamFormatConverter::
|
long StreamFormatConverter::
|
||||||
scanString(const StreamFormat& fmt, const char*, char*, size_t)
|
scanString(const StreamFormat& fmt, const char*, char*, unsigned long&)
|
||||||
{
|
{
|
||||||
error("Unimplemented scanString method for %%%c format\n",
|
error("Unimplemented scanString method for %%%c format\n",
|
||||||
fmt.conv);
|
fmt.conv);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StreamFormatConverter::
|
long StreamFormatConverter::
|
||||||
scanPseudo(const StreamFormat& fmt, StreamBuffer&, long&)
|
scanPseudo(const StreamFormat& fmt, StreamBuffer&, long&)
|
||||||
{
|
{
|
||||||
error("Unimplemented scanPseudo method for %%%c format\n",
|
error("Unimplemented scanPseudo method for %%%c format\n",
|
||||||
@ -255,11 +255,11 @@ static void copyFormatString(StreamBuffer& info, const char* source)
|
|||||||
|
|
||||||
// Standard Long Converter for 'diouxX'
|
// Standard Long Converter for 'diouxX'
|
||||||
|
|
||||||
static int prepareval(const StreamFormat& fmt, const char*& input, bool& neg)
|
static long prepareval(const StreamFormat& fmt, const char*& input, bool& neg)
|
||||||
{
|
{
|
||||||
int length = 0;
|
long consumed = 0;
|
||||||
neg = false;
|
neg = false;
|
||||||
while (isspace(*input)) { input++; length++; }
|
while (isspace(*input)) { input++; consumed++; }
|
||||||
if (fmt.width)
|
if (fmt.width)
|
||||||
{
|
{
|
||||||
// take local copy because strto* don't have width parameter
|
// take local copy because strto* don't have width parameter
|
||||||
@ -268,7 +268,7 @@ static int prepareval(const StreamFormat& fmt, const char*& input, bool& neg)
|
|||||||
{
|
{
|
||||||
// normally whitespace does not count to width
|
// normally whitespace does not count to width
|
||||||
// but do so if space flag is present
|
// but do so if space flag is present
|
||||||
width -= length;
|
width -= consumed;
|
||||||
}
|
}
|
||||||
strncpy((char*)fmt.info, input, width);
|
strncpy((char*)fmt.info, input, width);
|
||||||
((char*)fmt.info)[width] = 0;
|
((char*)fmt.info)[width] = 0;
|
||||||
@ -283,21 +283,21 @@ static int prepareval(const StreamFormat& fmt, const char*& input, bool& neg)
|
|||||||
neg = true;
|
neg = true;
|
||||||
skipsign:
|
skipsign:
|
||||||
input++;
|
input++;
|
||||||
length++;
|
consumed++;
|
||||||
}
|
}
|
||||||
if (isspace(*input))
|
if (isspace(*input))
|
||||||
{
|
{
|
||||||
// allow space after sign only if # flag is set
|
// allow space after sign only if # flag is set
|
||||||
if (!(fmt.flags & alt_flag)) return -1;
|
if (!(fmt.flags & alt_flag)) return -1;
|
||||||
}
|
}
|
||||||
return length;
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
class StdLongConverter : public StreamFormatConverter
|
class StdLongConverter : public StreamFormatConverter
|
||||||
{
|
{
|
||||||
int parse(const StreamFormat& fmt, StreamBuffer& output, const char*& value, bool scanFormat);
|
int parse(const StreamFormat& fmt, StreamBuffer& output, const char*& value, bool scanFormat);
|
||||||
bool printLong(const StreamFormat& fmt, StreamBuffer& output, long value);
|
bool printLong(const StreamFormat& fmt, StreamBuffer& output, long value);
|
||||||
int scanLong(const StreamFormat& fmt, const char* input, long& value);
|
long scanLong(const StreamFormat& fmt, const char* input, long& value);
|
||||||
};
|
};
|
||||||
|
|
||||||
int StdLongConverter::
|
int StdLongConverter::
|
||||||
@ -306,7 +306,7 @@ parse(const StreamFormat& fmt, StreamBuffer& info,
|
|||||||
{
|
{
|
||||||
if (scanFormat && fmt.prec >= 0)
|
if (scanFormat && fmt.prec >= 0)
|
||||||
{
|
{
|
||||||
error("Use of precision field '.%d' not allowed with %%%c input conversion\n",
|
error("Use of precision field '.%ld' not allowed with %%%c input conversion\n",
|
||||||
fmt.prec, fmt.conv);
|
fmt.prec, fmt.conv);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -334,17 +334,17 @@ printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StdLongConverter::
|
long StdLongConverter::
|
||||||
scanLong(const StreamFormat& fmt, const char* input, long& value)
|
scanLong(const StreamFormat& fmt, const char* input, long& value)
|
||||||
{
|
{
|
||||||
char* end;
|
char* end;
|
||||||
int length;
|
long consumed;
|
||||||
bool neg;
|
bool neg;
|
||||||
int base;
|
int base;
|
||||||
long v;
|
long v;
|
||||||
|
|
||||||
length = prepareval(fmt, input, neg);
|
consumed = prepareval(fmt, input, neg);
|
||||||
if (length < 0) return -1;
|
if (consumed < 0) return -1;
|
||||||
switch (fmt.conv)
|
switch (fmt.conv)
|
||||||
{
|
{
|
||||||
case 'd':
|
case 'd':
|
||||||
@ -366,9 +366,9 @@ scanLong(const StreamFormat& fmt, const char* input, long& value)
|
|||||||
}
|
}
|
||||||
v = strtoul(input, &end, base);
|
v = strtoul(input, &end, base);
|
||||||
if (end == input) return -1;
|
if (end == input) return -1;
|
||||||
length += end-input;
|
consumed += end-input;
|
||||||
value = neg ? -v : v;
|
value = neg ? -v : v;
|
||||||
return length;
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterConverter (StdLongConverter, "diouxX");
|
RegisterConverter (StdLongConverter, "diouxX");
|
||||||
@ -379,7 +379,7 @@ class StdDoubleConverter : public StreamFormatConverter
|
|||||||
{
|
{
|
||||||
virtual int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
virtual int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
||||||
virtual bool printDouble(const StreamFormat&, StreamBuffer&, double);
|
virtual bool printDouble(const StreamFormat&, StreamBuffer&, double);
|
||||||
virtual int scanDouble(const StreamFormat&, const char*, double&);
|
virtual long scanDouble(const StreamFormat&, const char*, double&);
|
||||||
};
|
};
|
||||||
|
|
||||||
int StdDoubleConverter::
|
int StdDoubleConverter::
|
||||||
@ -388,7 +388,7 @@ parse(const StreamFormat& fmt, StreamBuffer& info,
|
|||||||
{
|
{
|
||||||
if (scanFormat && fmt.prec >= 0)
|
if (scanFormat && fmt.prec >= 0)
|
||||||
{
|
{
|
||||||
error("Use of precision field '.%d' not allowed with %%%c input conversion\n",
|
error("Use of precision field '.%ld' not allowed with %%%c input conversion\n",
|
||||||
fmt.prec, fmt.conv);
|
fmt.prec, fmt.conv);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -411,20 +411,20 @@ printDouble(const StreamFormat& fmt, StreamBuffer& output, double value)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StdDoubleConverter::
|
long StdDoubleConverter::
|
||||||
scanDouble(const StreamFormat& fmt, const char* input, double& value)
|
scanDouble(const StreamFormat& fmt, const char* input, double& value)
|
||||||
{
|
{
|
||||||
char* end;
|
char* end;
|
||||||
int length;
|
long consumed;
|
||||||
bool neg;
|
bool neg;
|
||||||
|
|
||||||
length = prepareval(fmt, input, neg);
|
consumed = prepareval(fmt, input, neg);
|
||||||
if (length < 0) return -1;
|
if (consumed < 0) return -1;
|
||||||
value = strtod(input, &end);
|
value = strtod(input, &end);
|
||||||
if (neg) value = -value;
|
if (neg) value = -value;
|
||||||
if (end == input) return -1;
|
if (end == input) return -1;
|
||||||
length += end-input;
|
consumed += end-input;
|
||||||
return length;
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterConverter (StdDoubleConverter, "feEgG");
|
RegisterConverter (StdDoubleConverter, "feEgG");
|
||||||
@ -435,7 +435,7 @@ class StdStringConverter : public StreamFormatConverter
|
|||||||
{
|
{
|
||||||
virtual int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
virtual int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
||||||
virtual bool printString(const StreamFormat&, StreamBuffer&, const char*);
|
virtual bool printString(const StreamFormat&, StreamBuffer&, const char*);
|
||||||
virtual int scanString(const StreamFormat&, const char*, char*, size_t);
|
virtual long scanString(const StreamFormat&, const char*, char*, unsigned long&);
|
||||||
};
|
};
|
||||||
|
|
||||||
int StdStringConverter::
|
int StdStringConverter::
|
||||||
@ -451,7 +451,7 @@ parse(const StreamFormat& fmt, StreamBuffer& info,
|
|||||||
}
|
}
|
||||||
if (scanFormat && fmt.prec >= 0)
|
if (scanFormat && fmt.prec >= 0)
|
||||||
{
|
{
|
||||||
error("Use of precision field '.%d' not allowed with %%%c input conversion\n",
|
error("Use of precision field '.%ld' not allowed with %%%c input conversion\n",
|
||||||
fmt.prec, fmt.conv);
|
fmt.prec, fmt.conv);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -483,17 +483,17 @@ printString(const StreamFormat& fmt, StreamBuffer& output, const char* value)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StdStringConverter::
|
long StdStringConverter::
|
||||||
scanString(const StreamFormat& fmt, const char* input,
|
scanString(const StreamFormat& fmt, const char* input,
|
||||||
char* value, size_t maxlen)
|
char* value, unsigned long &size)
|
||||||
{
|
{
|
||||||
int length = 0;
|
long consumed = 0;
|
||||||
|
long space_left = size;
|
||||||
int width = fmt.width;
|
int width = fmt.width;
|
||||||
|
|
||||||
if ((fmt.flags & skip_flag) || value == NULL) maxlen = 0;
|
if ((fmt.flags & skip_flag) || value == NULL) space_left = 0;
|
||||||
|
|
||||||
// if user does not specify width assume "ininity" (-1)
|
// if user does not specify width assume "infinity" (-1)
|
||||||
if (width == 0)
|
if (width == 0)
|
||||||
{
|
{
|
||||||
if (fmt.conv == 'c') width = 1;
|
if (fmt.conv == 'c') width = 1;
|
||||||
@ -506,14 +506,14 @@ scanString(const StreamFormat& fmt, const char* input,
|
|||||||
// but do so if space flag is present
|
// but do so if space flag is present
|
||||||
if (fmt.flags & space_flag)
|
if (fmt.flags & space_flag)
|
||||||
{
|
{
|
||||||
if (maxlen > 1)
|
if (space_left > 1) // keep space for terminal null byte
|
||||||
{
|
{
|
||||||
*value++ = *input;
|
*value++ = *input;
|
||||||
maxlen--;
|
space_left--;
|
||||||
}
|
}
|
||||||
width--;
|
width--;
|
||||||
}
|
}
|
||||||
length++;
|
consumed++;
|
||||||
input++;
|
input++;
|
||||||
}
|
}
|
||||||
while (*input && width)
|
while (*input && width)
|
||||||
@ -521,20 +521,22 @@ scanString(const StreamFormat& fmt, const char* input,
|
|||||||
// normally whitespace ends string
|
// normally whitespace ends string
|
||||||
// but don't end if # flag is present
|
// but don't end if # flag is present
|
||||||
if (!(fmt.flags & alt_flag) && isspace(*input)) break;
|
if (!(fmt.flags & alt_flag) && isspace(*input)) break;
|
||||||
if (maxlen > 1)
|
if (space_left > 1)
|
||||||
{
|
{
|
||||||
*value++ = *input;
|
*value++ = *input;
|
||||||
maxlen--;
|
space_left--;
|
||||||
}
|
}
|
||||||
length++;
|
consumed++;
|
||||||
width--;
|
width--;
|
||||||
input++;
|
input++;
|
||||||
}
|
}
|
||||||
if (maxlen > 0)
|
if (space_left)
|
||||||
{
|
{
|
||||||
*value = '\0';
|
*value = '\0';
|
||||||
|
space_left--;
|
||||||
|
size -= space_left; // update number of bytes copied to value
|
||||||
}
|
}
|
||||||
return length;
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterConverter (StdStringConverter, "s");
|
RegisterConverter (StdStringConverter, "s");
|
||||||
@ -545,7 +547,7 @@ class StdCharsConverter : public StreamFormatConverter
|
|||||||
{
|
{
|
||||||
virtual int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
virtual int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
||||||
virtual bool printLong(const StreamFormat&, StreamBuffer&, long);
|
virtual bool printLong(const StreamFormat&, StreamBuffer&, long);
|
||||||
virtual int scanString(const StreamFormat&, const char*, char*, size_t);
|
virtual long scanString(const StreamFormat&, const char*, char*, unsigned long&);
|
||||||
};
|
};
|
||||||
|
|
||||||
int StdCharsConverter::
|
int StdCharsConverter::
|
||||||
@ -560,7 +562,7 @@ parse(const StreamFormat& fmt, StreamBuffer& info,
|
|||||||
}
|
}
|
||||||
if (scanFormat && fmt.prec >= 0)
|
if (scanFormat && fmt.prec >= 0)
|
||||||
{
|
{
|
||||||
error("Use of precision field '.%d' not allowed with %%%c input conversion\n",
|
error("Use of precision field '.%ld' not allowed with %%%c input conversion\n",
|
||||||
fmt.prec, fmt.conv);
|
fmt.prec, fmt.conv);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -581,35 +583,37 @@ printLong(const StreamFormat& fmt, StreamBuffer& output, long value)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StdCharsConverter::
|
long StdCharsConverter::
|
||||||
scanString(const StreamFormat& fmt, const char* input,
|
scanString(const StreamFormat& fmt, const char* input,
|
||||||
char* value, size_t maxlen)
|
char* value, unsigned long& size)
|
||||||
{
|
{
|
||||||
int length = 0;
|
long consumed = 0;
|
||||||
|
long width = fmt.width;
|
||||||
|
long space_left = size;
|
||||||
|
|
||||||
int width = fmt.width;
|
if ((fmt.flags & skip_flag) || value == NULL) space_left = 0;
|
||||||
|
|
||||||
if ((fmt.flags & skip_flag) || value == NULL) maxlen = 0;
|
|
||||||
|
|
||||||
// if user does not specify width assume 1
|
// if user does not specify width assume 1
|
||||||
if (width == 0) width = 1;
|
if (width == 0) width = 1;
|
||||||
|
|
||||||
while (*input && width)
|
while (*input && width)
|
||||||
{
|
{
|
||||||
if (maxlen > 1)
|
if (space_left > 1) // keep space for terminal null byte
|
||||||
{
|
{
|
||||||
*value++ = *input;
|
*value++ = *input;
|
||||||
maxlen--;
|
space_left--;
|
||||||
}
|
}
|
||||||
length++;
|
consumed++;
|
||||||
width--;
|
width--;
|
||||||
input++;
|
input++;
|
||||||
}
|
}
|
||||||
if (maxlen > 0)
|
if (space_left)
|
||||||
{
|
{
|
||||||
*value = '\0';
|
*value = '\0';
|
||||||
|
space_left--;
|
||||||
|
size -= space_left; // update number of bytes written to value
|
||||||
}
|
}
|
||||||
return length;
|
return consumed; // return number of bytes consumed from input
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterConverter (StdCharsConverter, "c");
|
RegisterConverter (StdCharsConverter, "c");
|
||||||
@ -619,7 +623,7 @@ RegisterConverter (StdCharsConverter, "c");
|
|||||||
class StdCharsetConverter : public StreamFormatConverter
|
class StdCharsetConverter : public StreamFormatConverter
|
||||||
{
|
{
|
||||||
virtual int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
virtual int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
||||||
virtual int scanString(const StreamFormat&, const char*, char*, size_t);
|
virtual long scanString(const StreamFormat&, const char*, char*, unsigned long&);
|
||||||
// no print method, %[ is readonly
|
// no print method, %[ is readonly
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -651,7 +655,7 @@ parse(const StreamFormat& fmt, StreamBuffer& info,
|
|||||||
}
|
}
|
||||||
if (scanFormat && fmt.prec >= 0)
|
if (scanFormat && fmt.prec >= 0)
|
||||||
{
|
{
|
||||||
error("Use of precision field '.%d' not allowed with %%%c input conversion\n",
|
error("Use of precision field '.%ld' not allowed with %%%c input conversion\n",
|
||||||
fmt.prec, fmt.conv);
|
fmt.prec, fmt.conv);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -698,35 +702,38 @@ parse(const StreamFormat& fmt, StreamBuffer& info,
|
|||||||
return string_format;
|
return string_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StdCharsetConverter::
|
long StdCharsetConverter::
|
||||||
scanString(const StreamFormat& fmt, const char* input,
|
scanString(const StreamFormat& fmt, const char* input,
|
||||||
char* value, size_t maxlen)
|
char* value, unsigned long& size)
|
||||||
{
|
{
|
||||||
int length = 0;
|
long consumed = 0;
|
||||||
int width = fmt.width;
|
long width = fmt.width;
|
||||||
|
long space_left = size;
|
||||||
|
|
||||||
if ((fmt.flags & skip_flag) || value == NULL) maxlen = 0;
|
if ((fmt.flags & skip_flag) || value == NULL) space_left = 0;
|
||||||
|
|
||||||
// if user does not specify width assume "ininity" (-1)
|
// if user does not specify width assume "infinity" (-1)
|
||||||
if (width == 0) width = -1;
|
if (width == 0) width = -1;
|
||||||
|
|
||||||
while (*input && width)
|
while (*input && width)
|
||||||
{
|
{
|
||||||
if (fmt.info[*input>>3] & 1<<(*input&7)) break;
|
if (fmt.info[*input>>3] & 1<<(*input&7)) break;
|
||||||
if (maxlen > 1)
|
if (space_left > 1) // keep space for terminal null byte
|
||||||
{
|
{
|
||||||
*value++ = *input;
|
*value++ = *input;
|
||||||
maxlen--;
|
space_left--;
|
||||||
}
|
}
|
||||||
length++;
|
consumed++;
|
||||||
width--;
|
width--;
|
||||||
input++;
|
input++;
|
||||||
}
|
}
|
||||||
if (maxlen > 0)
|
if (space_left)
|
||||||
{
|
{
|
||||||
*value = '\0';
|
*value = '\0';
|
||||||
|
space_left--;
|
||||||
|
size -= space_left; // update number of bytes written to value
|
||||||
}
|
}
|
||||||
return length;
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegisterConverter (StdCharsetConverter, "[");
|
RegisterConverter (StdCharsetConverter, "[");
|
||||||
|
@ -56,13 +56,13 @@ public:
|
|||||||
StreamBuffer& output, const char* value);
|
StreamBuffer& output, const char* value);
|
||||||
virtual bool printPseudo(const StreamFormat& fmt,
|
virtual bool printPseudo(const StreamFormat& fmt,
|
||||||
StreamBuffer& output);
|
StreamBuffer& output);
|
||||||
virtual int scanLong(const StreamFormat& fmt,
|
virtual long scanLong(const StreamFormat& fmt,
|
||||||
const char* input, long& value);
|
const char* input, long& value);
|
||||||
virtual int scanDouble(const StreamFormat& fmt,
|
virtual long scanDouble(const StreamFormat& fmt,
|
||||||
const char* input, double& value);
|
const char* input, double& value);
|
||||||
virtual int scanString(const StreamFormat& fmt,
|
virtual long scanString(const StreamFormat& fmt,
|
||||||
const char* input, char* value, size_t maxlen);
|
const char* input, char* value, unsigned long& size);
|
||||||
virtual int scanPseudo(const StreamFormat& fmt,
|
virtual long scanPseudo(const StreamFormat& fmt,
|
||||||
StreamBuffer& inputLine, long& cursor);
|
StreamBuffer& inputLine, long& cursor);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -130,8 +130,8 @@ void* ref_##converter = ®istrar_##converter\
|
|||||||
* You only need to implement the flavour of print and/or scan suitable for
|
* You only need to implement the flavour of print and/or scan suitable for
|
||||||
* the datatype returned by parse().
|
* the datatype returned by parse().
|
||||||
*
|
*
|
||||||
* Now, fmt.type contains the value returned by parse(). With fmt.info()
|
* Now, fmt.type contains the value returned by parse(). With fmt.info() you
|
||||||
* you will get the string you have written to info in parse() (null terminated).
|
* will get the string you have written to info in parse() (null terminated).
|
||||||
* The length of the info string can be found in fmt.infolen.
|
* The length of the info string can be found in fmt.infolen.
|
||||||
*
|
*
|
||||||
* In print*(), append the converted value to output. Do not modify what is
|
* In print*(), append the converted value to output. Do not modify what is
|
||||||
@ -139,9 +139,14 @@ void* ref_##converter = ®istrar_##converter\
|
|||||||
* Return true on success, false on failure.
|
* Return true on success, false on failure.
|
||||||
*
|
*
|
||||||
* In scan*(), read the value from input and return the number of consumed
|
* In scan*(), read the value from input and return the number of consumed
|
||||||
* bytes. In the string version, don't write more bytes than maxlen! If the
|
* bytes.
|
||||||
* skip_flag is set, you don't need to write to value, since the value will be
|
* In the string version, don't write more bytes than size including a
|
||||||
* discarded anyway. Return -1 on failure.
|
* mandatory terminating null byte. Update size with the number of bytes
|
||||||
|
* written into the value, wich may differ from the number of bytes consumed
|
||||||
|
* from the input (e.g. due to leading space). If the skip_flag is set, the
|
||||||
|
* input will be discarded. Thus, don't write to value. You also don't need
|
||||||
|
* to update size.
|
||||||
|
* Return -1 on failure.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Register your class
|
* Register your class
|
||||||
|
@ -1484,7 +1484,7 @@ compileFormat(StreamBuffer& buffer, const char*& formatstr,
|
|||||||
buffer.append(infoString);
|
buffer.append(infoString);
|
||||||
|
|
||||||
debug("StreamProtocolParser::Protocol::compileFormat: format.type=%s, "
|
debug("StreamProtocolParser::Protocol::compileFormat: format.type=%s, "
|
||||||
"infolen=%d infostring=\"%s\"\n",
|
"infolen=%ld infostring=\"%s\"\n",
|
||||||
StreamFormatTypeStr[streamFormat.type],
|
StreamFormatTypeStr[streamFormat.type],
|
||||||
streamFormat.infolen, infoString.expand()());
|
streamFormat.infolen, infoString.expand()());
|
||||||
formatstr = source; // move pointer after parsed format
|
formatstr = source; // move pointer after parsed format
|
||||||
|
@ -75,7 +75,7 @@ class TimestampConverter : public StreamFormatConverter
|
|||||||
{
|
{
|
||||||
int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
int parse(const StreamFormat&, StreamBuffer&, const char*&, bool);
|
||||||
bool printDouble(const StreamFormat&, StreamBuffer&, double);
|
bool printDouble(const StreamFormat&, StreamBuffer&, double);
|
||||||
int scanDouble(const StreamFormat&, const char*, double&);
|
long scanDouble(const StreamFormat&, const char*, double&);
|
||||||
};
|
};
|
||||||
|
|
||||||
int TimestampConverter::
|
int TimestampConverter::
|
||||||
@ -516,9 +516,7 @@ startover:
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long TimestampConverter::
|
||||||
|
|
||||||
int TimestampConverter::
|
|
||||||
scanDouble(const StreamFormat& format, const char* input, double& value)
|
scanDouble(const StreamFormat& format, const char* input, double& value)
|
||||||
{
|
{
|
||||||
struct tm brokenDownTime;
|
struct tm brokenDownTime;
|
||||||
|
@ -114,18 +114,23 @@ static long readData(dbCommon *record, format_t *format)
|
|||||||
break;
|
break;
|
||||||
case DBF_CHAR:
|
case DBF_CHAR:
|
||||||
case DBF_UCHAR:
|
case DBF_UCHAR:
|
||||||
memset(aai->bptr, 0, aai->nelm);
|
|
||||||
aai->nord = 0;
|
aai->nord = 0;
|
||||||
if (streamScanfN(record, format,
|
if ((lval = streamScanfN(record, format,
|
||||||
(char *)aai->bptr, aai->nelm) == ERROR)
|
(char *)aai->bptr, aai->nelm)) == ERROR)
|
||||||
{
|
{
|
||||||
|
memset(aai->bptr, 0, aai->nelm);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
((char*)aai->bptr)[aai->nelm-1] = 0;
|
if ((size_t)lval < aai->nelm)
|
||||||
for (lval = aai->nelm-2;
|
{
|
||||||
lval >= 0 && ((char*)aai->bptr)[lval] == 0;
|
memset(((char*)aai->bptr)+lval , 0, aai->nelm-lval);
|
||||||
lval--);
|
lval++;
|
||||||
aai->nord = lval+1;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
((char*)aai->bptr)[aai->nelm-1] = 0;
|
||||||
|
}
|
||||||
|
aai->nord = lval;
|
||||||
return OK;
|
return OK;
|
||||||
default:
|
default:
|
||||||
errlogSevPrintf(errlogFatal,
|
errlogSevPrintf(errlogFatal,
|
||||||
|
@ -114,18 +114,23 @@ static long readData(dbCommon *record, format_t *format)
|
|||||||
break;
|
break;
|
||||||
case DBF_CHAR:
|
case DBF_CHAR:
|
||||||
case DBF_UCHAR:
|
case DBF_UCHAR:
|
||||||
memset(aao->bptr, 0, aao->nelm);
|
|
||||||
aao->nord = 0;
|
aao->nord = 0;
|
||||||
if (streamScanfN(record, format,
|
if ((lval = streamScanfN(record, format,
|
||||||
(char *)aao->bptr, aao->nelm) == ERROR)
|
(char *)aao->bptr, aao->nelm)) == ERROR)
|
||||||
{
|
{
|
||||||
|
memset(aao->bptr, 0, aao->nelm);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
((char*)aao->bptr)[aao->nelm-1] = 0;
|
if ((size_t)lval < aao->nelm)
|
||||||
for (lval = aao->nelm-2;
|
{
|
||||||
lval >= 0 && ((char*)aao->bptr)[lval] == 0;
|
memset(((char*)aao->bptr)+lval , 0, aao->nelm-lval);
|
||||||
lval--);
|
lval++;
|
||||||
aao->nord = lval+1;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
((char*)aao->bptr)[aao->nelm-1] = 0;
|
||||||
|
}
|
||||||
|
aao->nord = lval;
|
||||||
return OK;
|
return OK;
|
||||||
default:
|
default:
|
||||||
errlogSevPrintf(errlogFatal,
|
errlogSevPrintf(errlogFatal,
|
||||||
|
@ -114,18 +114,23 @@ static long readData(dbCommon *record, format_t *format)
|
|||||||
break;
|
break;
|
||||||
case DBF_CHAR:
|
case DBF_CHAR:
|
||||||
case DBF_UCHAR:
|
case DBF_UCHAR:
|
||||||
memset(wf->bptr, 0, wf->nelm);
|
|
||||||
wf->nord = 0;
|
wf->nord = 0;
|
||||||
if (streamScanfN(record, format,
|
if ((lval = streamScanfN(record, format,
|
||||||
(char *)wf->bptr, wf->nelm) == ERROR)
|
(char *)wf->bptr, wf->nelm)) == ERROR)
|
||||||
{
|
{
|
||||||
|
memset(wf->bptr, 0, wf->nelm);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
((char*)wf->bptr)[wf->nelm-1] = 0;
|
if ((size_t)lval < wf->nelm)
|
||||||
for (lval = wf->nelm-2;
|
{
|
||||||
lval >= 0 && ((char*)wf->bptr)[lval] == 0;
|
memset(((char*)wf->bptr)+lval , 0, wf->nelm-lval);
|
||||||
lval--);
|
lval++;
|
||||||
wf->nord = lval+1;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
((char*)wf->bptr)[wf->nelm-1] = 0;
|
||||||
|
}
|
||||||
|
wf->nord = lval;
|
||||||
return OK;
|
return OK;
|
||||||
default:
|
default:
|
||||||
errlogSevPrintf(errlogFatal,
|
errlogSevPrintf(errlogFatal,
|
||||||
|
Reference in New Issue
Block a user