mirror of https://github.com/KLayout/klayout.git
Refactoring, some enhancements to tl::Variant
- Split binary and regular streams - Binary serialization of tl::Variant - Fixing tl::Variant parsable string representation for byte arrays and char (Format is '...'b for byte arrays and '.'c for chars). - tl::to_quoted_string now allows 0 characters in the string (escapes to '\000')
This commit is contained in:
parent
7f6071db31
commit
1de28f2d6b
|
|
@ -36,7 +36,7 @@
|
|||
#include "dbTrans.h"
|
||||
#include "dbText.h"
|
||||
|
||||
#include "tlStream.h"
|
||||
#include "tlBinaryStream.h"
|
||||
#include "tlException.h"
|
||||
|
||||
namespace db
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ static gsi::Methods properties_support_methods ()
|
|||
"convenient than using the layout object and the properties ID to retrieve the property value. "
|
||||
) +
|
||||
gsi::method ("to_s", (std::string (T::*) () const) &T::to_string,
|
||||
"@brief Returns a string representing the polygon\n"
|
||||
"@brief Returns a string representing the object\n"
|
||||
) +
|
||||
gsi::method_ext ("properties", &get_properties_meth_impl<T>,
|
||||
"@brief Gets the user properties\n"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ FORMS =
|
|||
SOURCES = \
|
||||
tlAssert.cc \
|
||||
tlBase64.cc \
|
||||
tlBinaryStream.cc \
|
||||
tlColor.cc \
|
||||
tlClassRegistry.cc \
|
||||
tlCopyOnWrite.cc \
|
||||
|
|
@ -62,6 +63,7 @@ HEADERS = \
|
|||
tlAlgorithm.h \
|
||||
tlAssert.h \
|
||||
tlBase64.h \
|
||||
tlBinaryStream.h \
|
||||
tlColor.h \
|
||||
tlClassRegistry.h \
|
||||
tlCopyOnWrite.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,691 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2026 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "tlBinaryStream.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Type codes for Variant serialization
|
||||
// These type codes are intentionally separated from tl::Variant's
|
||||
// type codes to allow a backward-compatible serialization scheme.
|
||||
|
||||
enum VariantTypeCode
|
||||
{
|
||||
var_type_nil = 0,
|
||||
var_type_bool = 1,
|
||||
var_type_char = 2,
|
||||
var_type_schar = 3,
|
||||
var_type_uchar = 4,
|
||||
var_type_short = 5,
|
||||
var_type_ushort = 6,
|
||||
var_type_int = 7,
|
||||
var_type_uint = 8,
|
||||
var_type_long = 9,
|
||||
var_type_ulong = 10,
|
||||
var_type_longlong = 11,
|
||||
var_type_ulonglong = 12,
|
||||
var_type_id = 13,
|
||||
var_type_float = 14,
|
||||
var_type_double = 15,
|
||||
var_type_string = 16,
|
||||
var_type_bytes = 17,
|
||||
var_type_list = 18,
|
||||
var_type_array = 19,
|
||||
|
||||
var_type_other = -1
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
class UnexpectedEndOfFileException
|
||||
: public tl::Exception
|
||||
{
|
||||
public:
|
||||
UnexpectedEndOfFileException (const std::string &f)
|
||||
: tl::Exception (tl::to_string (tr ("Unexpected end of file in: %s")), f)
|
||||
{ }
|
||||
};
|
||||
|
||||
class InvalidVariantTypeCode
|
||||
: public tl::Exception
|
||||
{
|
||||
public:
|
||||
InvalidVariantTypeCode (const std::string &f, int tc)
|
||||
: tl::Exception (tl::to_string (tr ("Invalid variant type code %d in file: %s - maybe file is too new for this build?")), tc, f)
|
||||
{ }
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
BinaryInputStream::BinaryInputStream (InputStream &stream)
|
||||
: m_stream (stream)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
BinaryInputStream::reset ()
|
||||
{
|
||||
m_stream.reset ();
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (std::string &v)
|
||||
{
|
||||
uint64_t l = 0;
|
||||
*this >> l;
|
||||
|
||||
v.clear ();
|
||||
v.reserve (l);
|
||||
|
||||
size_t chunk_size = 1024, n = l;
|
||||
while (n > 0) {
|
||||
size_t chunk_len = std::min (n, chunk_size);
|
||||
const char *chunk_data = m_stream.get (chunk_len);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
v.append (chunk_data, chunk_len);
|
||||
n -= chunk_len;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (std::vector<char> &v)
|
||||
{
|
||||
uint64_t l = 0;
|
||||
*this >> l;
|
||||
|
||||
v.clear ();
|
||||
v.reserve (l);
|
||||
|
||||
size_t chunk_size = 1024, n = l;
|
||||
while (n > 0) {
|
||||
size_t chunk_len = std::min (n, chunk_size);
|
||||
const char *chunk_data = m_stream.get (chunk_len);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
v.insert (v.end (), chunk_data, chunk_data + chunk_len);
|
||||
n -= chunk_len;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (double &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (8);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const double *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (float &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (4);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const float *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (bool &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (1);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
v = *chunk_data != 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (uint8_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (1);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
v = (uint8_t) *chunk_data;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (int8_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (1);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
v = (int8_t) *chunk_data;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (uint16_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (2);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const uint16_t *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (int16_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (2);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const int16_t *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (uint32_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (4);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const uint32_t *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (int32_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (4);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const int32_t *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (uint64_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (8);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const uint64_t *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (int64_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (8);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const int64_t *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (tl::Variant &v)
|
||||
{
|
||||
int16_t var_type = -1;
|
||||
*this >> var_type;
|
||||
|
||||
switch (var_type) {
|
||||
case VariantTypeCode::var_type_nil:
|
||||
v = tl::Variant ();
|
||||
break;
|
||||
case VariantTypeCode::var_type_bool:
|
||||
{
|
||||
bool f = false;
|
||||
*this >> f;
|
||||
v = tl::Variant (f);
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_char:
|
||||
{
|
||||
uint8_t vv = 0;
|
||||
*this >> vv;
|
||||
v = tl::Variant ((char) vv);
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_schar:
|
||||
{
|
||||
int8_t vv = 0;
|
||||
*this >> vv;
|
||||
v = tl::Variant ((signed char) vv);
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_uchar:
|
||||
{
|
||||
uint8_t vv = 0;
|
||||
*this >> vv;
|
||||
v = tl::Variant ((unsigned char) vv);
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_short:
|
||||
{
|
||||
int16_t vv = 0;
|
||||
*this >> vv;
|
||||
v = tl::Variant ((short) vv);
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_ushort:
|
||||
{
|
||||
uint16_t vv = 0;
|
||||
*this >> vv;
|
||||
v = tl::Variant ((unsigned short) vv);
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_int:
|
||||
{
|
||||
int32_t vv = 0;
|
||||
*this >> vv;
|
||||
v = tl::Variant ((int) vv);
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_uint:
|
||||
{
|
||||
uint32_t vv = 0;
|
||||
*this >> vv;
|
||||
v = tl::Variant ((unsigned int) vv);
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_long:
|
||||
{
|
||||
int64_t vv = 0;
|
||||
*this >> vv;
|
||||
if (vv >= (int64_t) std::numeric_limits<long>::min () && vv <= (int64_t) std::numeric_limits<long>::max ()) {
|
||||
v = tl::Variant ((long) vv);
|
||||
} else {
|
||||
// Linux to Windows migration
|
||||
v = tl::Variant ((long long) vv);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_ulong:
|
||||
{
|
||||
uint64_t vv = 0;
|
||||
*this >> vv;
|
||||
if (vv >= (uint64_t) std::numeric_limits<unsigned long>::min () && vv <= (uint64_t) std::numeric_limits<unsigned long>::max ()) {
|
||||
v = tl::Variant ((unsigned long) vv);
|
||||
} else {
|
||||
// Linux to Windows migration
|
||||
v = tl::Variant ((unsigned long long) vv);
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case VariantTypeCode::var_type_longlong:
|
||||
{
|
||||
int64_t vv = 0;
|
||||
*this >> vv;
|
||||
v = tl::Variant ((long long) vv);
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_ulonglong:
|
||||
{
|
||||
uint64_t vv = 0;
|
||||
*this >> vv;
|
||||
v = tl::Variant ((unsigned long long) vv);
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_id:
|
||||
{
|
||||
uint64_t vv = 0;
|
||||
*this >> vv;
|
||||
v = tl::Variant ((size_t) vv, true /*as id*/);
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_float:
|
||||
{
|
||||
float vv = 0;
|
||||
*this >> vv;
|
||||
v = tl::Variant (vv);
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_double:
|
||||
{
|
||||
double vv = 0;
|
||||
*this >> vv;
|
||||
v = tl::Variant (vv);
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_string:
|
||||
{
|
||||
std::string vv;
|
||||
*this >> vv;
|
||||
v = tl::Variant (std::move (vv));
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_bytes:
|
||||
{
|
||||
std::vector<char> vv;
|
||||
*this >> vv;
|
||||
v = tl::Variant (std::move (vv));
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_list:
|
||||
{
|
||||
uint64_t n = 0;
|
||||
*this >> n;
|
||||
v = tl::Variant::empty_list ();
|
||||
v.reserve (n);
|
||||
while (n-- > 0) {
|
||||
tl::Variant vv;
|
||||
*this >> vv;
|
||||
v.push (std::move (vv));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_array:
|
||||
{
|
||||
uint64_t n = 0;
|
||||
*this >> n;
|
||||
v = tl::Variant::empty_array ();
|
||||
while (n-- > 0) {
|
||||
tl::Variant vk, vv;
|
||||
*this >> vk;
|
||||
*this >> vv;
|
||||
v.insert (std::move (vk), std::move (vv));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VariantTypeCode::var_type_other:
|
||||
{
|
||||
std::string s;
|
||||
*this >> s;
|
||||
tl::Extractor ex (s.c_str ());
|
||||
v = tl::Variant ();
|
||||
ex.read (v);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw InvalidVariantTypeCode (source (), int (var_type));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// BinaryOutputStream implementation
|
||||
|
||||
BinaryOutputStream::BinaryOutputStream (OutputStreamBase &delegate)
|
||||
: OutputStream (delegate, false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
BinaryOutputStream::BinaryOutputStream (OutputStreamBase *delegate)
|
||||
: OutputStream (delegate, false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
BinaryOutputStream::BinaryOutputStream (const std::string &abstract_path, OutputStreamMode om, int keep_backups)
|
||||
: OutputStream (abstract_path, om, false, keep_backups)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (const char *s, size_t n)
|
||||
{
|
||||
// the native format for a string is a length field (uint64_t) and the bytes
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
uint64_t len = uint64_t (n);
|
||||
put_raw ((const char *) &len, 8);
|
||||
put_raw (s, n);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (const std::string &s)
|
||||
{
|
||||
// the native format for a string is a length field (uint64_t) and the bytes
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
uint64_t len = uint64_t (s.size ());
|
||||
put_raw ((const char *) &len, 8);
|
||||
put_raw (s.c_str (), s.size ());
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (double v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 8);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (float v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 4);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (bool v)
|
||||
{
|
||||
char c = v ? 1 : 0;
|
||||
put_raw (&c, 1);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (uint8_t v)
|
||||
{
|
||||
put_raw ((const char *) &v, 1);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (int8_t v)
|
||||
{
|
||||
put_raw ((const char *) &v, 1);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (uint16_t v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 2);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (int16_t v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 2);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (uint32_t v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 4);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (int32_t v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 4);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (uint64_t v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 8);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (int64_t v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 8);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (const tl::Variant &v)
|
||||
{
|
||||
switch (v.type_code ()) {
|
||||
case tl::Variant::t_nil:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_nil);
|
||||
break;
|
||||
case tl::Variant::t_bool:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_bool);
|
||||
put_native (v.to_bool ());
|
||||
break;
|
||||
case tl::Variant::t_char:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_char);
|
||||
put_native ((uint8_t) v.to_char ());
|
||||
break;
|
||||
case tl::Variant::t_schar:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_schar);
|
||||
put_native ((int8_t) v.to_schar ());
|
||||
break;
|
||||
case tl::Variant::t_uchar:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_uchar);
|
||||
put_native ((uint8_t) v.to_uchar ());
|
||||
break;
|
||||
case tl::Variant::t_short:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_short);
|
||||
put_native ((int16_t) v.to_short ());
|
||||
break;
|
||||
case tl::Variant::t_ushort:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_ushort);
|
||||
put_native ((uint16_t) v.to_ushort ());
|
||||
break;
|
||||
case tl::Variant::t_int:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_int);
|
||||
put_native ((int32_t) v.to_int ());
|
||||
break;
|
||||
case tl::Variant::t_uint:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_uint);
|
||||
put_native ((uint32_t) v.to_uint ());
|
||||
break;
|
||||
case tl::Variant::t_long:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_long);
|
||||
// NOTE: "long" is always encoded as 64 bit for compatibility of Windows + Linux
|
||||
put_native ((int64_t) v.to_long ());
|
||||
break;
|
||||
case tl::Variant::t_ulong:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_ulong);
|
||||
// NOTE: "ulong" is always encoded as 64 bit for compatibility of Windows + Linux
|
||||
put_native ((uint64_t) v.to_ulong ());
|
||||
break;
|
||||
case tl::Variant::t_longlong:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_longlong);
|
||||
put_native ((int64_t) v.to_longlong ());
|
||||
break;
|
||||
case tl::Variant::t_ulonglong:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_ulonglong);
|
||||
put_native ((uint64_t) v.to_ulonglong ());
|
||||
break;
|
||||
case tl::Variant::t_id:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_id);
|
||||
// NOTE: "id" is always encoded as 64 bit
|
||||
put_native ((uint64_t) v.to_id ());
|
||||
break;
|
||||
case tl::Variant::t_float:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_float);
|
||||
put_native (v.to_float ());
|
||||
break;
|
||||
case tl::Variant::t_double:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_double);
|
||||
put_native (v.to_double ());
|
||||
break;
|
||||
case tl::Variant::t_string:
|
||||
case tl::Variant::t_stdstring:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_string);
|
||||
put_native (v.to_stdstring ());
|
||||
break;
|
||||
case tl::Variant::t_bytearray:
|
||||
#if defined(HAVE_QT)
|
||||
case tl::Variant::t_qstring:
|
||||
case tl::Variant::t_qbytearray:
|
||||
#endif
|
||||
{
|
||||
put_native ((int16_t) VariantTypeCode::var_type_bytes);
|
||||
std::vector<char> bytes = v.to_bytearray ();
|
||||
put_native (bytes.begin ().operator-> (), bytes.size ());
|
||||
}
|
||||
break;
|
||||
case tl::Variant::t_list:
|
||||
{
|
||||
put_native ((int16_t) VariantTypeCode::var_type_list);
|
||||
put_native ((uint64_t) v.size ());
|
||||
for (auto i = v.begin (); i != v.end (); ++i) {
|
||||
put_native (*i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case tl::Variant::t_array:
|
||||
{
|
||||
put_native ((int16_t) VariantTypeCode::var_type_array);
|
||||
put_native ((uint64_t) v.array_size ());
|
||||
for (auto i = v.begin_array (); i != v.end_array (); ++i) {
|
||||
put_native (i->first);
|
||||
put_native (i->second);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
put_native ((int16_t) VariantTypeCode::var_type_other);
|
||||
put_native (v.to_parsable_string ());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2026 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_tlBinaryStream
|
||||
#define HDR_tlBinaryStream
|
||||
|
||||
#include "tlCommon.h"
|
||||
#include "tlStream.h"
|
||||
#include "tlVariant.h"
|
||||
|
||||
namespace tl
|
||||
{
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief An output stream specialized on binary representation
|
||||
*/
|
||||
|
||||
class TL_PUBLIC BinaryOutputStream
|
||||
: public OutputStream
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*
|
||||
* This constructor takes a delegate object.
|
||||
*/
|
||||
BinaryOutputStream (OutputStreamBase &delegate);
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*
|
||||
* This constructor takes a delegate object. The stream will own the delegate.
|
||||
*/
|
||||
BinaryOutputStream (OutputStreamBase *delegate);
|
||||
|
||||
/**
|
||||
* @brief Open an output stream with the given path and stream mode
|
||||
*
|
||||
* This will automatically create a delegate object and delete it later.
|
||||
*/
|
||||
BinaryOutputStream (const std::string &abstract_path, OutputStreamMode om = OM_Auto, int keep_backups = 0);
|
||||
|
||||
/**
|
||||
* @brief << operator: inserts character
|
||||
*/
|
||||
OutputStream &operator<< (char s)
|
||||
{
|
||||
put (&s, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief << operator: inserts a character
|
||||
*/
|
||||
OutputStream &operator<< (unsigned char s)
|
||||
{
|
||||
put ((const char *) &s, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief << operator: inserts a string
|
||||
*
|
||||
* In binary mode, the string is inserted as a length/data
|
||||
* combination. That matches the extraction in BinaryInputStream.
|
||||
*/
|
||||
BinaryOutputStream &operator<< (const char *s)
|
||||
{
|
||||
put_native (s, strlen (s));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief << operator: inserts a string
|
||||
*
|
||||
* In binary mode, the string is inserted as a length/data
|
||||
* combination. That matches the extraction in BinaryInputStream.
|
||||
*/
|
||||
BinaryOutputStream &operator<< (const std::string &s)
|
||||
{
|
||||
put_native (s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief << operator: inserts an object supported by "put_native".
|
||||
*/
|
||||
template <class T>
|
||||
BinaryOutputStream &operator<< (const T &t)
|
||||
{
|
||||
put_native (t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
void put_native (const std::string &s);
|
||||
void put_native (const char *s, size_t n);
|
||||
void put_native (double v);
|
||||
void put_native (float v);
|
||||
void put_native (bool v);
|
||||
void put_native (uint8_t v);
|
||||
void put_native (int8_t v);
|
||||
void put_native (uint16_t v);
|
||||
void put_native (int16_t v);
|
||||
void put_native (uint32_t v);
|
||||
void put_native (int32_t v);
|
||||
void put_native (uint64_t v);
|
||||
void put_native (int64_t v);
|
||||
void put_native (const tl::Variant &v);
|
||||
|
||||
void set_as_text (bool f);
|
||||
|
||||
// No copying currently
|
||||
BinaryOutputStream (const BinaryOutputStream &);
|
||||
BinaryOutputStream &operator= (const BinaryOutputStream &);
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief A binary input stream
|
||||
*
|
||||
* This class is put in front of a InputStream to retrieve binary primitives from the stream.
|
||||
* The binary format corresponds to binary mode of OutputStream.
|
||||
*/
|
||||
class TL_PUBLIC BinaryInputStream
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*
|
||||
* This constructor takes a delegate object.
|
||||
*/
|
||||
BinaryInputStream (InputStream &stream);
|
||||
|
||||
/**
|
||||
* @brief Gets the raw stream
|
||||
*/
|
||||
InputStream &raw_stream ()
|
||||
{
|
||||
return m_stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the source specification
|
||||
*/
|
||||
std::string source () const
|
||||
{
|
||||
return m_stream.source ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a value of a specific type
|
||||
*/
|
||||
BinaryInputStream &operator>> (std::string &v);
|
||||
BinaryInputStream &operator>> (std::vector<char> &v);
|
||||
BinaryInputStream &operator>> (double &v);
|
||||
BinaryInputStream &operator>> (float &v);
|
||||
BinaryInputStream &operator>> (bool &v);
|
||||
BinaryInputStream &operator>> (uint8_t &v);
|
||||
BinaryInputStream &operator>> (int8_t &v);
|
||||
BinaryInputStream &operator>> (uint16_t &v);
|
||||
BinaryInputStream &operator>> (int16_t &v);
|
||||
BinaryInputStream &operator>> (uint32_t &v);
|
||||
BinaryInputStream &operator>> (int32_t &v);
|
||||
BinaryInputStream &operator>> (uint64_t &v);
|
||||
BinaryInputStream &operator>> (int64_t &v);
|
||||
BinaryInputStream &operator>> (tl::Variant &v);
|
||||
|
||||
/**
|
||||
* @brief Resets to the initial position
|
||||
*/
|
||||
void reset ();
|
||||
|
||||
private:
|
||||
InputStream &m_stream;
|
||||
|
||||
// no copying
|
||||
BinaryInputStream (const BinaryInputStream &);
|
||||
BinaryInputStream &operator= (const BinaryInputStream &);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -20,8 +20,6 @@
|
|||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
|
|
@ -133,15 +131,6 @@ public:
|
|||
{ }
|
||||
};
|
||||
|
||||
class UnexpectedEndOfFileException
|
||||
: public tl::Exception
|
||||
{
|
||||
public:
|
||||
UnexpectedEndOfFileException (const std::string &f)
|
||||
: tl::Exception (tl::to_string (tr ("Unexpected end of file: %s")), f)
|
||||
{ }
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
class ZLibFilePrivate
|
||||
|
|
@ -929,183 +918,6 @@ TextInputStream::reset ()
|
|||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
BinaryInputStream::BinaryInputStream (InputStream &stream)
|
||||
: m_stream (stream)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
BinaryInputStream::reset ()
|
||||
{
|
||||
m_stream.reset ();
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (std::string &v)
|
||||
{
|
||||
uint64_t l = 0;
|
||||
*this >> l;
|
||||
|
||||
v.clear ();
|
||||
v.reserve (l);
|
||||
|
||||
size_t chunk_size = 1024, n = l;
|
||||
while (n > 0) {
|
||||
size_t chunk_len = std::min (n, chunk_size);
|
||||
const char *chunk_data = m_stream.get (chunk_len);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
v.append (chunk_data, chunk_len);
|
||||
n -= chunk_len;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (double &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (8);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const double *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (float &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (4);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const float *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (bool &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (1);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
v = *chunk_data != 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (uint8_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (1);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
v = (uint8_t) *chunk_data;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (int8_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (1);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
v = (int8_t) *chunk_data;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (uint16_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (2);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const uint16_t *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (int16_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (2);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const int16_t *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (uint32_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (4);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const uint32_t *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (int32_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (4);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const int32_t *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (uint64_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (8);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const uint64_t *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BinaryInputStream &
|
||||
BinaryInputStream::operator>> (int64_t &v)
|
||||
{
|
||||
const char *chunk_data = m_stream.get (8);
|
||||
if (! chunk_data) {
|
||||
throw UnexpectedEndOfFileException (source ());
|
||||
}
|
||||
// TODO: for now, we assume that file and memory layout are identical on all platforms
|
||||
v = *reinterpret_cast<const int64_t *> (chunk_data);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// InputFile implementation
|
||||
|
||||
|
|
@ -1479,122 +1291,6 @@ OutputStream::seek (size_t pos)
|
|||
m_pos = pos;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// BinaryOutputStream implementation
|
||||
|
||||
BinaryOutputStream::BinaryOutputStream (OutputStreamBase &delegate)
|
||||
: OutputStream (delegate, false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
BinaryOutputStream::BinaryOutputStream (OutputStreamBase *delegate)
|
||||
: OutputStream (delegate, false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
BinaryOutputStream::BinaryOutputStream (const std::string &abstract_path, OutputStreamMode om, int keep_backups)
|
||||
: OutputStream (abstract_path, om, false, keep_backups)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (const char *s, size_t n)
|
||||
{
|
||||
// the native format for a string is a length field (uint64_t) and the bytes
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
uint64_t len = uint64_t (n);
|
||||
put_raw ((const char *) &len, 8);
|
||||
put_raw (s, n);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (const std::string &s)
|
||||
{
|
||||
// the native format for a string is a length field (uint64_t) and the bytes
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
uint64_t len = uint64_t (s.size ());
|
||||
put_raw ((const char *) &len, 8);
|
||||
put_raw (s.c_str (), s.size ());
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (double v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 8);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (float v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 4);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (bool v)
|
||||
{
|
||||
char c = v ? 1 : 0;
|
||||
put_raw (&c, 1);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (uint8_t v)
|
||||
{
|
||||
put_raw ((const char *) &v, 1);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (int8_t v)
|
||||
{
|
||||
put_raw ((const char *) &v, 1);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (uint16_t v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 2);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (int16_t v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 2);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (uint32_t v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 4);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (int32_t v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 4);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (uint64_t v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 8);
|
||||
}
|
||||
|
||||
void
|
||||
BinaryOutputStream::put_native (int64_t v)
|
||||
{
|
||||
// TODO: for now we assume that the memory layout is the same for all platforms
|
||||
put_raw ((const char *) &v, 8);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// OutputFileBase implementation
|
||||
|
||||
|
|
|
|||
|
|
@ -805,69 +805,6 @@ private:
|
|||
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief A binary input stream
|
||||
*
|
||||
* This class is put in front of a InputStream to retrieve binary primitives from the stream.
|
||||
* The binary format corresponds to binary mode of OutputStream.
|
||||
*/
|
||||
class TL_PUBLIC BinaryInputStream
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*
|
||||
* This constructor takes a delegate object.
|
||||
*/
|
||||
BinaryInputStream (InputStream &stream);
|
||||
|
||||
/**
|
||||
* @brief Gets the raw stream
|
||||
*/
|
||||
InputStream &raw_stream ()
|
||||
{
|
||||
return m_stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the source specification
|
||||
*/
|
||||
std::string source () const
|
||||
{
|
||||
return m_stream.source ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a value of a specific type
|
||||
*/
|
||||
BinaryInputStream &operator>> (std::string &v);
|
||||
BinaryInputStream &operator>> (double &v);
|
||||
BinaryInputStream &operator>> (float &v);
|
||||
BinaryInputStream &operator>> (bool &v);
|
||||
BinaryInputStream &operator>> (uint8_t &v);
|
||||
BinaryInputStream &operator>> (int8_t &v);
|
||||
BinaryInputStream &operator>> (uint16_t &v);
|
||||
BinaryInputStream &operator>> (int16_t &v);
|
||||
BinaryInputStream &operator>> (uint32_t &v);
|
||||
BinaryInputStream &operator>> (int32_t &v);
|
||||
BinaryInputStream &operator>> (uint64_t &v);
|
||||
BinaryInputStream &operator>> (int64_t &v);
|
||||
|
||||
/**
|
||||
* @brief Resets to the initial position
|
||||
*/
|
||||
void reset ();
|
||||
|
||||
private:
|
||||
InputStream &m_stream;
|
||||
|
||||
// no copying
|
||||
BinaryInputStream (const BinaryInputStream &);
|
||||
BinaryInputStream &operator= (const BinaryInputStream &);
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief The output stream delegate base class
|
||||
*
|
||||
|
|
@ -1537,111 +1474,6 @@ private:
|
|||
OutputStream &operator= (const OutputStream &);
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief An output stream specialized on binary representation
|
||||
*/
|
||||
|
||||
class TL_PUBLIC BinaryOutputStream
|
||||
: public OutputStream
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*
|
||||
* This constructor takes a delegate object.
|
||||
*/
|
||||
BinaryOutputStream (OutputStreamBase &delegate);
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*
|
||||
* This constructor takes a delegate object. The stream will own the delegate.
|
||||
*/
|
||||
BinaryOutputStream (OutputStreamBase *delegate);
|
||||
|
||||
/**
|
||||
* @brief Open an output stream with the given path and stream mode
|
||||
*
|
||||
* This will automatically create a delegate object and delete it later.
|
||||
*/
|
||||
BinaryOutputStream (const std::string &abstract_path, OutputStreamMode om = OM_Auto, int keep_backups = 0);
|
||||
|
||||
/**
|
||||
* @brief << operator: inserts character
|
||||
*/
|
||||
OutputStream &operator<< (char s)
|
||||
{
|
||||
put (&s, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief << operator: inserts a character
|
||||
*/
|
||||
OutputStream &operator<< (unsigned char s)
|
||||
{
|
||||
put ((const char *) &s, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief << operator: inserts a string
|
||||
*
|
||||
* In binary mode, the string is inserted as a length/data
|
||||
* combination. That matches the extraction in BinaryInputStream.
|
||||
*/
|
||||
BinaryOutputStream &operator<< (const char *s)
|
||||
{
|
||||
put_native (s, strlen (s));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief << operator: inserts a string
|
||||
*
|
||||
* In binary mode, the string is inserted as a length/data
|
||||
* combination. That matches the extraction in BinaryInputStream.
|
||||
*/
|
||||
BinaryOutputStream &operator<< (const std::string &s)
|
||||
{
|
||||
put_native (s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief << operator: inserts an object supported by "put_native".
|
||||
*/
|
||||
template <class T>
|
||||
BinaryOutputStream &operator<< (const T &t)
|
||||
{
|
||||
put_native (t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
void put_native (const std::string &s);
|
||||
void put_native (const char *s, size_t n);
|
||||
void put_native (double v);
|
||||
void put_native (float v);
|
||||
void put_native (bool v);
|
||||
void put_native (uint8_t v);
|
||||
void put_native (int8_t v);
|
||||
void put_native (uint16_t v);
|
||||
void put_native (int16_t v);
|
||||
void put_native (uint32_t v);
|
||||
void put_native (int32_t v);
|
||||
void put_native (uint64_t v);
|
||||
void put_native (int64_t v);
|
||||
|
||||
void set_as_text (bool f);
|
||||
|
||||
// No copying currently
|
||||
BinaryOutputStream (const BinaryOutputStream &);
|
||||
BinaryOutputStream &operator= (const BinaryOutputStream &);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -651,7 +651,7 @@ to_quoted_string (const std::string &s)
|
|||
std::string r;
|
||||
r.reserve (s.size () + 2);
|
||||
r += '\'';
|
||||
for (const char *c = s.c_str (); *c; ++c) {
|
||||
for (auto c = s.begin (); c != s.end (); ++c) {
|
||||
if (*c == '\'' || *c == '\\') {
|
||||
r += '\\';
|
||||
r += *c;
|
||||
|
|
|
|||
|
|
@ -315,6 +315,12 @@ Variant::Variant (const std::vector<char> &ba)
|
|||
m_var.m_bytearray = new std::vector<char> (ba);
|
||||
}
|
||||
|
||||
Variant::Variant (std::vector<char> &&ba)
|
||||
: m_type (t_bytearray), m_string (0)
|
||||
{
|
||||
m_var.m_bytearray = new std::vector<char> (ba);
|
||||
}
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
|
||||
Variant::Variant (const QByteArray &qba)
|
||||
|
|
@ -530,6 +536,12 @@ Variant::Variant (const std::string &s)
|
|||
m_var.m_stdstring = new std::string (s);
|
||||
}
|
||||
|
||||
Variant::Variant (std::string &&s)
|
||||
: m_type (t_stdstring), m_string (0)
|
||||
{
|
||||
m_var.m_stdstring = new std::string (s);
|
||||
}
|
||||
|
||||
Variant::Variant (const char *s)
|
||||
: m_type (s != 0 ? t_string : t_nil)
|
||||
{
|
||||
|
|
@ -645,6 +657,12 @@ Variant::Variant (const Variant &v)
|
|||
operator= (v);
|
||||
}
|
||||
|
||||
Variant::Variant (Variant &&v)
|
||||
: m_type (t_nil), m_string (0)
|
||||
{
|
||||
swap (v);
|
||||
}
|
||||
|
||||
Variant::~Variant ()
|
||||
{
|
||||
reset ();
|
||||
|
|
@ -713,6 +731,20 @@ Variant::operator= (const std::string &s)
|
|||
return *this;
|
||||
}
|
||||
|
||||
Variant &
|
||||
Variant::operator= (std::string &&s)
|
||||
{
|
||||
if (m_type == t_stdstring && &s == m_var.m_stdstring) {
|
||||
// we are assigning to ourselves
|
||||
} else {
|
||||
std::string *snew = new std::string (s);
|
||||
reset ();
|
||||
m_type = t_stdstring;
|
||||
m_var.m_stdstring = snew;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Variant &
|
||||
Variant::operator= (const std::vector<char> &s)
|
||||
{
|
||||
|
|
@ -727,6 +759,20 @@ Variant::operator= (const std::vector<char> &s)
|
|||
return *this;
|
||||
}
|
||||
|
||||
Variant &
|
||||
Variant::operator= (std::vector<char> &&s)
|
||||
{
|
||||
if (m_type == t_bytearray && &s == m_var.m_bytearray) {
|
||||
// we are assigning to ourselves
|
||||
} else {
|
||||
std::vector<char> *snew = new std::vector<char> (s);
|
||||
reset ();
|
||||
m_type = t_bytearray;
|
||||
m_var.m_bytearray = snew;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
|
||||
Variant &
|
||||
|
|
@ -900,6 +946,13 @@ Variant::operator= (__int128 l)
|
|||
}
|
||||
#endif
|
||||
|
||||
Variant &
|
||||
Variant::operator= (Variant &&v)
|
||||
{
|
||||
swap (v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Variant &
|
||||
Variant::operator= (const Variant &v)
|
||||
{
|
||||
|
|
@ -1958,7 +2011,7 @@ Variant::to_string () const
|
|||
} else if (m_type == t_float) {
|
||||
r = tl::to_string (m_var.m_float, 7);
|
||||
} else if (m_type == t_char) {
|
||||
r = tl::to_string ((int) m_var.m_char);
|
||||
r += m_var.m_char;
|
||||
} else if (m_type == t_schar) {
|
||||
r = tl::to_string ((int) m_var.m_schar);
|
||||
} else if (m_type == t_uchar) {
|
||||
|
|
@ -2602,12 +2655,10 @@ Variant::to_parsable_string () const
|
|||
return "nil";
|
||||
} else if (is_stdstring ()) {
|
||||
return tl::to_quoted_string (*m_var.m_stdstring);
|
||||
#if defined(HAVE_QT)
|
||||
} else if (is_cstring () || is_qstring () || is_qbytearray () || is_bytearray ()) {
|
||||
#else
|
||||
} else if (is_cstring () || is_bytearray ()) {
|
||||
#endif
|
||||
return tl::to_quoted_string (to_string ());
|
||||
} else if (is_a_string ()) {
|
||||
return tl::to_quoted_string (to_stdstring ());
|
||||
} else if (is_a_bytearray ()) {
|
||||
return tl::to_quoted_string (to_stdstring ()) + "b";
|
||||
} else if (is_list ()) {
|
||||
std::string r = "(";
|
||||
for (tl::Variant::const_iterator l = begin (); l != end (); ++l) {
|
||||
|
|
@ -2630,6 +2681,10 @@ Variant::to_parsable_string () const
|
|||
}
|
||||
r += "}";
|
||||
return r;
|
||||
} else if (is_char ()) {
|
||||
std::string s;
|
||||
s += to_char ();
|
||||
return tl::to_quoted_string (s) + "c";
|
||||
} else if (is_id ()) {
|
||||
return "[id" + tl::to_string (m_var.m_id) + "]";
|
||||
} else if (is_user ()) {
|
||||
|
|
@ -3049,7 +3104,15 @@ TL_PUBLIC bool test_extractor_impl (tl::Extractor &ex, tl::Variant &v)
|
|||
|
||||
} else if (ex.try_read_word_or_quoted (s)) {
|
||||
|
||||
v = tl::Variant (s);
|
||||
if (ex.test ("c") || ex.test ("C")) {
|
||||
v = s.empty () ? tl::Variant () : tl::Variant ((char) s.front ());
|
||||
} else if (ex.test ("b") || ex.test ("B")) {
|
||||
std::vector<char> cv (s.begin (), s.end ());
|
||||
v = tl::Variant (std::move (cv));
|
||||
} else {
|
||||
v = tl::Variant (s);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -205,11 +205,21 @@ public:
|
|||
*/
|
||||
Variant (const tl::Variant &d);
|
||||
|
||||
/**
|
||||
* @brief Move ctor
|
||||
*/
|
||||
Variant (tl::Variant &&d);
|
||||
|
||||
/**
|
||||
* @brief Initialize the Variant with a std::vector<char>
|
||||
*/
|
||||
Variant (const std::vector<char> &s);
|
||||
|
||||
/**
|
||||
* @brief Initialize the Variant with a std::vector<char> (move semantics)
|
||||
*/
|
||||
Variant (std::vector<char> &&s);
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
/**
|
||||
* @brief Initialize the Variant with a QByteArray
|
||||
|
|
@ -234,6 +244,11 @@ public:
|
|||
*/
|
||||
Variant (const std::string &s);
|
||||
|
||||
/**
|
||||
* @brief Initialize the Variant with "string" (move semantics)
|
||||
*/
|
||||
Variant (std::string &&s);
|
||||
|
||||
/**
|
||||
* @brief Initialize the Variant with "string"
|
||||
*/
|
||||
|
|
@ -466,6 +481,15 @@ public:
|
|||
m_var.m_list = new std::vector<tl::Variant> (list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the Variant with an explicit vector of variants (move semantics)
|
||||
*/
|
||||
Variant (std::vector<tl::Variant> &&list)
|
||||
: m_type (t_list), m_string (0)
|
||||
{
|
||||
m_var.m_list = new std::vector<tl::Variant> (list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the Variant with an explicit map of variants
|
||||
*/
|
||||
|
|
@ -475,6 +499,15 @@ public:
|
|||
m_var.m_array = new std::map<tl::Variant, tl::Variant> (map);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the Variant with an explicit map of variants (move semantics)
|
||||
*/
|
||||
Variant (std::map<tl::Variant, tl::Variant> &&map)
|
||||
: m_type (t_array), m_string (0)
|
||||
{
|
||||
m_var.m_array = new std::map<tl::Variant, tl::Variant> (map);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the Variant with a list
|
||||
*/
|
||||
|
|
@ -546,6 +579,11 @@ public:
|
|||
*/
|
||||
Variant &operator= (const Variant &v);
|
||||
|
||||
/**
|
||||
* @brief Assignment (move)
|
||||
*/
|
||||
Variant &operator= (Variant &&v);
|
||||
|
||||
/**
|
||||
* @brief Assignment of a string
|
||||
*/
|
||||
|
|
@ -568,11 +606,21 @@ public:
|
|||
*/
|
||||
Variant &operator= (const std::string &v);
|
||||
|
||||
/**
|
||||
* @brief Assignment of a string (move)
|
||||
*/
|
||||
Variant &operator= (std::string &&v);
|
||||
|
||||
/**
|
||||
* @brief Assignment of a STL byte array
|
||||
*/
|
||||
Variant &operator= (const std::vector<char> &v);
|
||||
|
||||
/**
|
||||
* @brief Assignment of a STL byte array (move)
|
||||
*/
|
||||
Variant &operator= (std::vector<char> &&v);
|
||||
|
||||
/**
|
||||
* @brief Assignment of a double
|
||||
*/
|
||||
|
|
@ -1173,6 +1221,15 @@ public:
|
|||
m_var.m_list->push_back (v);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a element to the list (move semantics)
|
||||
*/
|
||||
void push (tl::Variant &&v)
|
||||
{
|
||||
tl_assert (m_type == t_list);
|
||||
m_var.m_list->push_back (v);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the back element of the list
|
||||
*/
|
||||
|
|
@ -1280,6 +1337,15 @@ public:
|
|||
m_var.m_array->insert (std::make_pair (k, v));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert an element into the array (move semantics)
|
||||
*/
|
||||
void insert (tl::Variant &&k, tl::Variant &&v)
|
||||
{
|
||||
tl_assert (m_type == t_array);
|
||||
m_var.m_array->insert (std::make_pair (k, v));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the value for the given key or 0 if the variant is not an array or does not contain the key
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,425 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2026 Matthias Koefferlein
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include "tlBinaryStream.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
std::string s2string (tl::OutputMemoryStream &osm)
|
||||
{
|
||||
std::string res;
|
||||
size_t n = osm.size ();
|
||||
const char *d = osm.data ();
|
||||
for (size_t i = 0; i < n; ++i, ++d) {
|
||||
if (i > 0) {
|
||||
res += ",";
|
||||
}
|
||||
res += tl::sprintf ("0x%02x", int ((unsigned char) *d));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
TEST(BinaryStreams1)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << (double) 0.17;
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0xc3,0xf5,0x28,0x5c,0x8f,0xc2,0xc5,0x3f");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
double x = 0.0;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (tl::to_string (x), "0.17");
|
||||
}
|
||||
|
||||
TEST(BinaryStreams2)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << (float) 0.17;
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x7b,0x14,0x2e,0x3e");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
float x = 0.0;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (tl::to_string (x), "0.17");
|
||||
}
|
||||
|
||||
TEST(BinaryStreams3)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << std::string ("ABC");
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x42,0x43");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
std::string x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, "ABC");
|
||||
}
|
||||
|
||||
TEST(BinaryStreams4)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << "ABC";
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x42,0x43");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
std::string x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, "ABC");
|
||||
}
|
||||
|
||||
TEST(BinaryStreams5)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << uint8_t (17);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x11");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
uint8_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 17);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams6)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << int8_t (17);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x11");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
int8_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 17);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams7)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << uint16_t (1742);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0xce,0x06");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
uint16_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 1742);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams8)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << int16_t (1742);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0xce,0x06");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
int16_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 1742);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams9)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << uint32_t (17420000);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0xe0,0xce,0x09,0x01");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
uint32_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 17420000u);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams10)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << int32_t (17420000);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0xe0,0xce,0x09,0x01");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
int32_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 17420000);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams11)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << uint64_t (174200000000l);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x00,0x0e,0x21,0x8f,0x28,0x00,0x00,0x00");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
uint64_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 174200000000lu);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams12)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << int64_t (174200000000l);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x00,0x0e,0x21,0x8f,0x28,0x00,0x00,0x00");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
int64_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 174200000000l);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams13)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << true;
|
||||
os << false;
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x01,0x00");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
bool x = false, y = false;
|
||||
bis >> x >> y;
|
||||
|
||||
EXPECT_EQ (x, true);
|
||||
EXPECT_EQ (y, false);
|
||||
}
|
||||
|
||||
TEST(BinaryStreamsCombined)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << "ABC" << 17.0 << "XUV" << (int32_t) 42;
|
||||
|
||||
os.flush ();
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
std::string a, c;
|
||||
double b = 0.0;
|
||||
int32_t d = 0;
|
||||
|
||||
bis >> a >> b >> c >> d;
|
||||
|
||||
EXPECT_EQ (a, "ABC");
|
||||
EXPECT_EQ (b, 17.0);
|
||||
EXPECT_EQ (c, "XUV");
|
||||
EXPECT_EQ (d, 42);
|
||||
}
|
||||
|
||||
TEST(BinaryStreamsVariants)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
std::vector<char> bytes = { 'X', 'U', 'V' };
|
||||
|
||||
os << tl::Variant ("ABC")
|
||||
<< tl::Variant ()
|
||||
<< tl::Variant (bytes)
|
||||
<< tl::Variant ((float) 42.5)
|
||||
<< tl::Variant ((double) -17.5)
|
||||
<< tl::Variant ((char) 'x')
|
||||
<< tl::Variant ((unsigned char) 'u')
|
||||
<< tl::Variant ((signed char) 'v')
|
||||
<< tl::Variant ((short) 17)
|
||||
<< tl::Variant ((unsigned short) 42)
|
||||
<< tl::Variant ((int) 18)
|
||||
<< tl::Variant ((unsigned int) 43)
|
||||
<< tl::Variant ((long) 19)
|
||||
<< tl::Variant ((unsigned long) 44)
|
||||
<< tl::Variant ((long long) 20)
|
||||
<< tl::Variant ((unsigned long long) 45)
|
||||
<< tl::Variant ((size_t) 202, true /*id*/);
|
||||
|
||||
os.flush ();
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
tl::Variant v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17;
|
||||
|
||||
bis >> v1 >> v2 >> v3 >> v4 >> v5 >> v6 >> v7 >> v8 >> v9 >> v10 >> v11 >> v12 >> v13 >> v14 >> v15 >> v16 >> v17;
|
||||
|
||||
EXPECT_EQ (v1.to_parsable_string (), "'ABC'");
|
||||
EXPECT_EQ (v2.to_parsable_string (), "nil");
|
||||
EXPECT_EQ (v3.to_parsable_string (), "'XUV'b");
|
||||
EXPECT_EQ (v3.type_code (), tl::Variant::t_bytearray);
|
||||
EXPECT_EQ (v4.to_parsable_string (), "##42.5");
|
||||
EXPECT_EQ (v5.to_parsable_string (), "##-17.5");
|
||||
EXPECT_EQ (v6.to_parsable_string (), "'x'c");
|
||||
EXPECT_EQ (v7.to_parsable_string (), "#u117");
|
||||
EXPECT_EQ (v8.to_parsable_string (), "#118");
|
||||
EXPECT_EQ (v9.to_parsable_string (), "#17");
|
||||
EXPECT_EQ (v10.to_parsable_string (), "#u42");
|
||||
EXPECT_EQ (v11.to_parsable_string (), "#18");
|
||||
EXPECT_EQ (v12.to_parsable_string (), "#u43");
|
||||
EXPECT_EQ (v13.to_parsable_string (), "#19");
|
||||
EXPECT_EQ (v14.to_parsable_string (), "#u44");
|
||||
EXPECT_EQ (v15.to_parsable_string (), "#l20");
|
||||
EXPECT_EQ (v16.to_parsable_string (), "#lu45");
|
||||
EXPECT_EQ (v17.to_parsable_string (), "[id202]");
|
||||
}
|
||||
|
||||
TEST(BinaryStreamsVariantList)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
std::vector<tl::Variant> list = { 5.5, -17, "ABC" };
|
||||
|
||||
os << tl::Variant (list);
|
||||
|
||||
os.flush ();
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
tl::Variant v1;
|
||||
|
||||
bis >> v1;
|
||||
|
||||
EXPECT_EQ (v1.to_parsable_string (), "(##5.5,#-17,'ABC')");
|
||||
}
|
||||
|
||||
TEST(BinaryStreamsVariantArray)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
std::vector<std::pair<tl::Variant, tl::Variant> > a = { { 1, 5.5 }, { 2, -17 }, { "id", "ABC" } };
|
||||
|
||||
std::map<tl::Variant, tl::Variant> array (a.begin (), a.end ());
|
||||
os << tl::Variant (array);
|
||||
|
||||
os.flush ();
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
tl::Variant v1;
|
||||
|
||||
bis >> v1;
|
||||
|
||||
EXPECT_EQ (v1.to_parsable_string (), "{#1=>##5.5,#2=>#-17,'id'=>'ABC'}");
|
||||
}
|
||||
|
|
@ -624,304 +624,3 @@ TEST(MatchFormat)
|
|||
EXPECT_EQ (tl::match_filename_to_format ("abc.TEXT", "Text files (*.txt *.TXT)"), false);
|
||||
EXPECT_EQ (tl::match_filename_to_format ("abc.TEXT", "Text files (*)"), true);
|
||||
}
|
||||
|
||||
std::string s2string (tl::OutputMemoryStream &osm)
|
||||
{
|
||||
std::string res;
|
||||
size_t n = osm.size ();
|
||||
const char *d = osm.data ();
|
||||
for (size_t i = 0; i < n; ++i, ++d) {
|
||||
if (i > 0) {
|
||||
res += ",";
|
||||
}
|
||||
res += tl::sprintf ("0x%02x", int ((unsigned char) *d));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
TEST(BinaryStreams1)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << (double) 0.17;
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0xc3,0xf5,0x28,0x5c,0x8f,0xc2,0xc5,0x3f");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
double x = 0.0;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (tl::to_string (x), "0.17");
|
||||
}
|
||||
|
||||
TEST(BinaryStreams2)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << (float) 0.17;
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x7b,0x14,0x2e,0x3e");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
float x = 0.0;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (tl::to_string (x), "0.17");
|
||||
}
|
||||
|
||||
TEST(BinaryStreams3)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << std::string ("ABC");
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x42,0x43");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
std::string x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, "ABC");
|
||||
}
|
||||
|
||||
TEST(BinaryStreams4)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << "ABC";
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x42,0x43");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
std::string x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, "ABC");
|
||||
}
|
||||
|
||||
TEST(BinaryStreams5)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << uint8_t (17);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x11");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
uint8_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 17);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams6)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << int8_t (17);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x11");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
int8_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 17);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams7)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << uint16_t (1742);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0xce,0x06");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
uint16_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 1742);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams8)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << int16_t (1742);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0xce,0x06");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
int16_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 1742);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams9)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << uint32_t (17420000);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0xe0,0xce,0x09,0x01");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
uint32_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 17420000u);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams10)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << int32_t (17420000);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0xe0,0xce,0x09,0x01");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
int32_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 17420000);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams11)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << uint64_t (174200000000l);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x00,0x0e,0x21,0x8f,0x28,0x00,0x00,0x00");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
uint64_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 174200000000lu);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams12)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << int64_t (174200000000l);
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x00,0x0e,0x21,0x8f,0x28,0x00,0x00,0x00");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
int64_t x;
|
||||
bis >> x;
|
||||
|
||||
EXPECT_EQ (x, 174200000000l);
|
||||
}
|
||||
|
||||
TEST(BinaryStreams13)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << true;
|
||||
os << false;
|
||||
|
||||
os.flush ();
|
||||
EXPECT_EQ (s2string (osm), "0x01,0x00");
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
bool x = false, y = false;
|
||||
bis >> x >> y;
|
||||
|
||||
EXPECT_EQ (x, true);
|
||||
EXPECT_EQ (y, false);
|
||||
}
|
||||
|
||||
TEST(BinaryStreamsCombined)
|
||||
{
|
||||
tl::OutputMemoryStream osm;
|
||||
tl::BinaryOutputStream os (osm);
|
||||
|
||||
os << "ABC" << 17.0 << "XUV" << (int32_t) 42;
|
||||
|
||||
os.flush ();
|
||||
|
||||
tl::InputMemoryStream ism (osm.data (), osm.size ());
|
||||
tl::InputStream is (ism);
|
||||
tl::BinaryInputStream bis (is);
|
||||
|
||||
std::string a, c;
|
||||
double b = 0.0;
|
||||
int32_t d = 0;
|
||||
|
||||
bis >> a >> b >> c >> d;
|
||||
|
||||
EXPECT_EQ (a, "ABC");
|
||||
EXPECT_EQ (b, 17.0);
|
||||
EXPECT_EQ (c, "XUV");
|
||||
EXPECT_EQ (d, 42);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ TEST(1)
|
|||
EXPECT_EQ (v.is_ulong (), false);
|
||||
EXPECT_EQ (v.is_ulonglong (), false);
|
||||
EXPECT_EQ (v.is_double (), false);
|
||||
EXPECT_EQ (v.to_string (), "nil");
|
||||
EXPECT_EQ (v.to_parsable_string (), "nil");
|
||||
vv = v;
|
||||
EXPECT_EQ (vv == v, true);
|
||||
|
|
@ -109,6 +110,43 @@ TEST(1)
|
|||
EXPECT_EQ (vx == v, true);
|
||||
}
|
||||
|
||||
{
|
||||
tl::Variant v ((char) '\033');
|
||||
#if defined(HAVE_QT)
|
||||
EXPECT_EQ (tl::to_string (v.to_qvariant ().toString ()), "27");
|
||||
#endif
|
||||
EXPECT_EQ (v.is_nil (), false);
|
||||
EXPECT_EQ (v.is_list (), false);
|
||||
EXPECT_EQ (v.is_cstring (), false);
|
||||
EXPECT_EQ (v.is_id (), false);
|
||||
EXPECT_EQ (v.is<short> (), false);
|
||||
EXPECT_EQ (v.is<unsigned short> (), false);
|
||||
EXPECT_EQ (v.is<int> (), false);
|
||||
EXPECT_EQ (v.is<unsigned int> (), false);
|
||||
EXPECT_EQ (v.is<short> (), false);
|
||||
EXPECT_EQ (v.is<unsigned short> (), false);
|
||||
EXPECT_EQ (v.is<unsigned char> (), false);
|
||||
EXPECT_EQ (v.is<signed char> (), false);
|
||||
EXPECT_EQ (v.is<long> (), false);
|
||||
EXPECT_EQ (v.is_char (), true);
|
||||
EXPECT_EQ (v.is_long (), false);
|
||||
EXPECT_EQ (v.is_longlong (), false);
|
||||
EXPECT_EQ (v.is_ulong (), false);
|
||||
EXPECT_EQ (v.is_ulonglong (), false);
|
||||
EXPECT_EQ (v.is_double (), false);
|
||||
EXPECT_EQ (v.to_string (), "\033");
|
||||
EXPECT_EQ (v.to_parsable_string (), "'\\033'c");
|
||||
vv = v;
|
||||
EXPECT_EQ (vv == v, true);
|
||||
EXPECT_EQ (vv != v, false);
|
||||
tl::Variant vx;
|
||||
std::string s (v.to_parsable_string ());
|
||||
tl::Extractor ex (s.c_str ());
|
||||
ex.read (vx);
|
||||
ex.expect_end ();
|
||||
EXPECT_EQ (vx == v, true);
|
||||
}
|
||||
|
||||
{
|
||||
tl::Variant v (1ul);
|
||||
#if defined(HAVE_QT)
|
||||
|
|
@ -123,6 +161,7 @@ TEST(1)
|
|||
EXPECT_EQ (v.is_long (), false);
|
||||
EXPECT_EQ (v.is_longlong (), false);
|
||||
EXPECT_EQ (v.is_double (), false);
|
||||
EXPECT_EQ (v.to_string (), "1");
|
||||
EXPECT_EQ (v.to_parsable_string (), "#u1");
|
||||
EXPECT_EQ (v.to_long (), 1l);
|
||||
EXPECT_EQ (v.to_longlong (), 1l);
|
||||
|
|
@ -161,6 +200,7 @@ TEST(1)
|
|||
EXPECT_EQ (v.is_longlong (), false);
|
||||
EXPECT_EQ (v.is_id (), false);
|
||||
EXPECT_EQ (v.is_double (), false);
|
||||
EXPECT_EQ (v.to_string (), "2");
|
||||
EXPECT_EQ (v.to_parsable_string (), "#u2");
|
||||
EXPECT_EQ (v.to_long (), 2l);
|
||||
EXPECT_EQ (v.to_longlong (), 2l);
|
||||
|
|
@ -196,6 +236,7 @@ TEST(1)
|
|||
EXPECT_EQ (v.is<int> (), true);
|
||||
EXPECT_EQ (v.is<unsigned int> (), false);
|
||||
EXPECT_EQ (v.is_double (), false);
|
||||
EXPECT_EQ (v.to_string (), "1");
|
||||
EXPECT_EQ (v.to_parsable_string (), "#1");
|
||||
EXPECT_EQ (v.to_long (), 1l);
|
||||
EXPECT_EQ (v.to_longlong (), 1l);
|
||||
|
|
@ -236,6 +277,7 @@ TEST(1)
|
|||
EXPECT_EQ (v.is<unsigned int> (), false);
|
||||
EXPECT_EQ (v.is<unsigned char> (), false);
|
||||
EXPECT_EQ (v.is<signed char> (), false);
|
||||
EXPECT_EQ (v.to_string (), "2");
|
||||
EXPECT_EQ (v.to_parsable_string (), "#2");
|
||||
EXPECT_EQ (v.to_long (), 2l);
|
||||
EXPECT_EQ (v.to_longlong (), 2l);
|
||||
|
|
@ -279,6 +321,7 @@ TEST(1)
|
|||
EXPECT_EQ (v.is<unsigned char> (), false);
|
||||
EXPECT_EQ (v.is<signed char> (), false);
|
||||
EXPECT_EQ (v.is_id (), false);
|
||||
EXPECT_EQ (v.to_string (), "5");
|
||||
EXPECT_EQ (v.to_parsable_string (), "##5");
|
||||
EXPECT_EQ (v.to_double (), 5.0);
|
||||
EXPECT_EQ (v.to_float (), 5.0);
|
||||
|
|
@ -327,6 +370,7 @@ TEST(1)
|
|||
EXPECT_EQ (v.is<unsigned char> (), false);
|
||||
EXPECT_EQ (v.is<signed char> (), false);
|
||||
EXPECT_EQ (v.is_id (), false);
|
||||
EXPECT_EQ (v.to_string (), "5");
|
||||
EXPECT_EQ (v.to_parsable_string (), "##5");
|
||||
EXPECT_EQ (v.to_double (), 5.0);
|
||||
EXPECT_EQ (v.to_long (), 5);
|
||||
|
|
@ -386,6 +430,7 @@ TEST(1)
|
|||
EXPECT_EQ (v.is_longlong (), false);
|
||||
EXPECT_EQ (v.is_ulonglong (), false);
|
||||
EXPECT_EQ (v.is_double (), false);
|
||||
EXPECT_EQ (v.to_string (), "2");
|
||||
EXPECT_EQ (v.to_parsable_string (), "#2");
|
||||
vv = v;
|
||||
EXPECT_EQ (vv == v, true);
|
||||
|
|
@ -419,6 +464,8 @@ TEST(1)
|
|||
EXPECT_EQ (v.is_nil (), false);
|
||||
EXPECT_EQ (v.is_list (), false);
|
||||
EXPECT_EQ (v.is_cstring (), false);
|
||||
EXPECT_EQ (v.is_bytearray (), false);
|
||||
EXPECT_EQ (v.is_a_bytearray (), false);
|
||||
EXPECT_EQ (v.is_id (), false);
|
||||
EXPECT_EQ (v.is_char (), false);
|
||||
EXPECT_EQ (v.is_long (), false);
|
||||
|
|
@ -432,6 +479,7 @@ TEST(1)
|
|||
EXPECT_EQ (v.is<signed char> (), false);
|
||||
EXPECT_EQ (v.is<long> (), false);
|
||||
EXPECT_EQ (v.is<unsigned long> (), false);
|
||||
EXPECT_EQ (v.to_string (), "2");
|
||||
EXPECT_EQ (v.to_parsable_string (), "#u2");
|
||||
vv = v;
|
||||
EXPECT_EQ (vv == v, true);
|
||||
|
|
@ -454,6 +502,39 @@ TEST(1)
|
|||
EXPECT_EQ (*(long *)v.native_ptr(), 2);
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<char> bytes = { '"', 'h', 0, '\033', 'a', 'l', 'l', 'O', '"' };
|
||||
tl::Variant v (std::move (bytes));
|
||||
#if defined(HAVE_QT)
|
||||
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "'\"h\\000\\033allO\"'b");
|
||||
#endif
|
||||
EXPECT_EQ (v.is_nil (), false);
|
||||
EXPECT_EQ (v.is_list (), false);
|
||||
EXPECT_EQ (v.is_cstring (), false);
|
||||
EXPECT_EQ (v.is_bytearray (), true);
|
||||
EXPECT_EQ (v.is_a_bytearray (), true);
|
||||
EXPECT_EQ (v.is_long (), false);
|
||||
EXPECT_EQ (v.is_ulong (), false);
|
||||
EXPECT_EQ (v.is_longlong (), false);
|
||||
EXPECT_EQ (v.is_ulonglong (), false);
|
||||
EXPECT_EQ (v.is_double (), false);
|
||||
EXPECT_EQ (v.is_id (), false);
|
||||
EXPECT_EQ (v.to_parsable_string (), "'\"h\\000\\033allO\"'b");
|
||||
EXPECT_EQ (v.to_stdstring (), std::string ("\"h\000\033allO\"", 9));
|
||||
EXPECT_EQ (vv == v, false);
|
||||
EXPECT_EQ (vv != v, true);
|
||||
vv = v;
|
||||
EXPECT_EQ (vv == v, true);
|
||||
EXPECT_EQ (vv != v, false);
|
||||
tl::Variant vx;
|
||||
std::string s (v.to_parsable_string ());
|
||||
tl::Extractor ex (s.c_str ());
|
||||
ex.read (vx);
|
||||
ex.expect_end ();
|
||||
EXPECT_EQ (vx.is_bytearray (), true);
|
||||
EXPECT_EQ (vx == v, true);
|
||||
}
|
||||
|
||||
{
|
||||
tl::Variant v ("hal'l\"o");
|
||||
#if defined(HAVE_QT)
|
||||
|
|
@ -534,6 +615,7 @@ TEST(1)
|
|||
EXPECT_EQ (v.is_id (), false);
|
||||
EXPECT_EQ (v.is_cstring (), false);
|
||||
EXPECT_EQ (v.is_double (), false);
|
||||
EXPECT_EQ (v.to_string (), "(1,5,25)");
|
||||
EXPECT_EQ (v.to_parsable_string (), "(#1,#5,#25)");
|
||||
EXPECT_EQ (v.get_list ().size (), size_t (3));
|
||||
EXPECT_EQ (v.begin ()->is_long (), true);
|
||||
|
|
@ -571,6 +653,7 @@ TEST(1)
|
|||
EXPECT_EQ (v.is_ulonglong (), false);
|
||||
EXPECT_EQ (v.is_cstring (), false);
|
||||
EXPECT_EQ (v.is_double (), false);
|
||||
EXPECT_EQ (v.to_string (), "17");
|
||||
EXPECT_EQ (v.to_parsable_string (), "#l17");
|
||||
tl::Variant vx;
|
||||
std::string s (v.to_parsable_string ());
|
||||
|
|
@ -595,6 +678,7 @@ TEST(1)
|
|||
EXPECT_EQ (v.is_longlong (), false);
|
||||
EXPECT_EQ (v.is_cstring (), false);
|
||||
EXPECT_EQ (v.is_double (), false);
|
||||
EXPECT_EQ (v.to_string (), "17");
|
||||
EXPECT_EQ (v.to_parsable_string (), "#lu17");
|
||||
tl::Variant vx;
|
||||
std::string s (v.to_parsable_string ());
|
||||
|
|
@ -619,6 +703,7 @@ TEST(1)
|
|||
EXPECT_EQ (v.is_longlong (), false);
|
||||
EXPECT_EQ (v.is_cstring (), false);
|
||||
EXPECT_EQ (v.is_double (), false);
|
||||
EXPECT_EQ (v.to_string (), "[id17]");
|
||||
EXPECT_EQ (v.to_parsable_string (), "[id17]");
|
||||
}
|
||||
|
||||
|
|
@ -642,6 +727,7 @@ TEST(1)
|
|||
v.insert (tl::Variant (1), tl::Variant ("A"));
|
||||
EXPECT_EQ (v.to_parsable_string (), "{#1=>\'A\'}");
|
||||
v.insert (tl::Variant ("B"), tl::Variant (17));
|
||||
EXPECT_EQ (v.to_string (), "{1=>A,B=>17}");
|
||||
EXPECT_EQ (v.to_parsable_string (), "{#1=>\'A\',\'B\'=>#17}");
|
||||
#if defined(HAVE_QT)
|
||||
EXPECT_EQ (tl::Variant (v.to_qvariant ()).to_parsable_string (), "{\'1\'=>\'A\',\'B\'=>#17}");
|
||||
|
|
@ -1138,7 +1224,7 @@ TEST(8)
|
|||
v = tl::Variant (QByteArray ());
|
||||
EXPECT_EQ (v.to_parsable_string (), "nil");
|
||||
v = tl::Variant (QByteArray ("abc"));
|
||||
EXPECT_EQ (v.to_parsable_string (), "'abc'");
|
||||
EXPECT_EQ (v.to_parsable_string (), "'abc'b");
|
||||
v = QByteArray ();
|
||||
EXPECT_EQ (v.to_parsable_string (), "nil");
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ include($$PWD/../../lib_ut.pri)
|
|||
SOURCES = \
|
||||
tlAlgorithmTests.cc \
|
||||
tlBase64Tests.cc \
|
||||
tlBinaryStreamTests.cc \
|
||||
tlClassRegistryTests.cc \
|
||||
tlCommandLineParserTests.cc \
|
||||
tlColorTests.cc \
|
||||
|
|
|
|||
Loading…
Reference in New Issue