BUILD_CLIENT="no"
BUILD_STATIC_AGENT="no"
BUILD_SDK="no"
-NEED_ZLIB="no"
MODULES="libnetxms tools install"
STATIC_SUBAGENT_LIST=""
PROPOSED_STATIC_SUBAGENTS="default"
check_substr "$COMPONENTS" "snmp"
if test $? = 0; then
- NEED_ZLIB="yes"
MODULES="$MODULES snmp"
fi
check_substr "$COMPONENTS" "client"
if test $? = 0; then
BUILD_CLIENT="yes"
- NEED_ZLIB="yes"
MODULES="$MODULES client"
CLIENT_COMPONENTS="$CLIENT_COMPONENTS nxalarm nxevent nxpush nxsms"
fi
check_substr "$COMPONENTS" "raspberrypi"
if test $? = 0; then
- NEED_ZLIB="yes"
SUBAGENT_DIRS="$SUBAGENT_DIRS rpi"
fi
fi
fi
-if test "x$NEED_ZLIB" = "xyes"; then
- if test "x$FORCE_INTERNAL_ZLIB" = "xyes"; then
- HAVE_ZLIB=no
- else
- HAVE_ZLIB=yes
- AC_CHECK_HEADER(zlib.h,,HAVE_ZLIB=no)
- if test "x$HAVE_ZLIB" = "xyes"; then
- AC_CHECK_LIB(z, deflate, [], [ HAVE_ZLIB=no ])
- fi
- fi
- if test "x$HAVE_ZLIB" = "xno"; then
- MODULES="zlib $MODULES"
+if test "x$FORCE_INTERNAL_ZLIB" = "xyes"; then
+ HAVE_ZLIB=no
+else
+ HAVE_ZLIB=yes
+ AC_CHECK_HEADER(zlib.h,,HAVE_ZLIB=no)
+ if test "x$HAVE_ZLIB" = "xyes"; then
+ AC_CHECK_LIB(z, deflate, [], [ HAVE_ZLIB=no ])
fi
fi
+if test "x$HAVE_ZLIB" = "xno"; then
+ MODULES="zlib $MODULES"
+fi
if test "x$FORCE_INTERNAL_EXPAT" = "xyes"; then
HAVE_LIBEXPAT=no
AM_CONDITIONAL([USE_INTERNAL_LIBTRE], [test "x$HAVE_LIBTRE" = "xno"])
AM_CONDITIONAL([USE_INTERNAL_JANSSON], [test "x$HAVE_JANSSON" = "xno"])
AM_CONDITIONAL([USE_INTERNAL_SQLITE], [test "x$HAVE_SQLITE" = "xno"])
-AM_CONDITIONAL([USE_INTERNAL_ZLIB], [test "$NEED_ZLIB/$HAVE_ZLIB" = "yes/no"])
+AM_CONDITIONAL([USE_INTERNAL_ZLIB], [test "$HAVE_ZLIB" = "no"])
AM_CONDITIONAL([STATIC_BUILD], [test "x$STATIC_BUILD" = "xyes"])
AM_CONDITIONAL([ALL_STATIC], [test "x$ALL_STATIC" = "xyes"])
AM_CONDITIONAL([USE_ENCRYPTION], [test "x${HAVE_LIBCRYPTO}" = "xyes"])
echo "Use internal sqlite : NO"
fi
fi
-if test "x${NEED_ZLIB}" = "xyes"; then
- if test "x${HAVE_ZLIB}" = "xno"; then
- echo "Use internal zlib : YES"
- else
- echo "Use internal zlib : NO"
- fi
+if test "x${HAVE_ZLIB}" = "xno"; then
+ echo "Use internal zlib : YES"
+else
+ echo "Use internal zlib : NO"
fi
if test "x${FORCE_32BIT_BUILD}" = "xyes"; then
echo "Force 32bit build : YES"
static Table *createFromXML(const char *xml);
TCHAR *createXML();
+
+ static Table *createFromPackedXML(const char *packedXml);
+ char *createPackedXML();
};
/**
if USE_INTERNAL_LIBTRE
libnetxms_la_LIBADD += ../libtre/libnxtre.la
endif
+if USE_INTERNAL_ZLIB
+libnetxms_la_CPPFLAGS += -I../../zlib
+libnetxms_la_LIBADD += ../../zlib/libnxzlib.la
+endif
EXTRA_DIST = \
libnetxms.vcproj \
#include "libnetxms.h"
#include <expat.h>
+#include <zlib.h>
+
+#define DEFAULT_OBJECT_ID (0)
+#define DEFAULT_STATUS (-1)
/**
* Create empty table row
{
m_cells = new ObjectArray<TableCell>(columnCount, 8, true);
for(int i = 0; i < columnCount; i++)
- m_cells->add(new TableCell);
+ m_cells->add(new TableCell());
m_objectId = 0;
}
m_columns->add(new TableColumnDefinition(src->m_columns->get(i)));
}
+/**
+ * Table destructor
+ */
+Table::~Table()
+{
+ destroy();
+ delete m_columns;
+ delete m_data;
+}
+
+/**
+ * Destroy table data
+ */
+void Table::destroy()
+{
+ m_columns->clear();
+ m_data->clear();
+ safe_free(m_title);
+}
+
/**
* XML parser state for creating LogParser object from XML
*/
if (ps->state == XML_STATE_DATA)
{
ps->table->addRow();
- ps->table->setObjectId(ps->table->getNumRows() - 1, XMLGetAttrInt(attrs, "objectId", 0));
+ ps->table->setObjectId(ps->table->getNumRows() - 1, XMLGetAttrInt(attrs, "objectId", DEFAULT_OBJECT_ID));
ps->column = 0;
ps->state = XML_STATE_ROW;
}
{
if (ps->state == XML_STATE_ROW)
{
- ps->table->setStatus(ps->column, XMLGetAttrInt(attrs, "status", 0));
+ ps->table->setStatus(ps->column, XMLGetAttrInt(attrs, "status", DEFAULT_STATUS));
ps->state = XML_STATE_CELL;
ps->buffer->clear();
}
return NULL;
}
+/**
+ * Create table from packed XML document
+ */
+Table *Table::createFromPackedXML(const char *packedXml)
+{
+ char *compressedXml = NULL;
+ size_t compressedSize = 0;
+ base64_decode_alloc(packedXml, strlen(packedXml), &compressedXml, &compressedSize);
+ if (compressedXml == NULL)
+ return NULL;
+
+ size_t xmlSize = (size_t)ntohl(*((UINT32 *)compressedXml));
+ char *xml = (char *)malloc(xmlSize + 1);
+ uLongf uncompSize = (uLongf)xmlSize;
+ if (uncompress((BYTE *)xml, &uncompSize, (BYTE *)&compressedXml[4], compressedSize - 4) != Z_OK)
+ {
+ free(xml);
+ return NULL;
+ }
+ xml[xmlSize] = 0;
+
+ Table *table = new Table();
+ if (table->parseXML(xml))
+ {
+ free(xml);
+ return table;
+ }
+ free(xml);
+ delete table;
+ return NULL;
+}
+
/**
* Create XML document from table
*/
xml.append(_T("<data>\r\n"));
for(i = 0; i < m_data->size(); i++)
{
- xml.appendFormattedString(_T("<tr objectId=\"%d\">\r\n"), m_data->get(i)->getObjectId());
+ UINT32 objectId = m_data->get(i)->getObjectId();
+ if (objectId != DEFAULT_OBJECT_ID)
+ xml.appendFormattedString(_T("<tr objectId=\"%u\">\r\n"), objectId);
+ else
+ xml.append(_T("<tr>\r\n"));
for(int j = 0; j < m_columns->size(); j++)
{
- xml.appendFormattedString(_T("<td status=\"%d\">%s</td>\r\n"), m_data->get(i)->getStatus(j),
- (const TCHAR *)EscapeStringForXML2(m_data->get(i)->getValue(j), -1));
+ int status = m_data->get(i)->getStatus(j);
+ if (status != DEFAULT_STATUS)
+ {
+ xml.append(_T("<td status=\""));
+ xml.append(status);
+ xml.append(_T("\">"));
+ }
+ else
+ {
+ xml.append(_T("<td>"));
+ }
+ xml.append((const TCHAR *)EscapeStringForXML2(m_data->get(i)->getValue(j), -1));
+ xml.append(_T("</td>\r\n"));
}
xml.append(_T("</tr>\r\n"));
}
}
/**
- * Table destructor
- */
-Table::~Table()
-{
- destroy();
- delete m_columns;
- delete m_data;
-}
-
-/**
- * Destroy table data
+ * Create packed XML document
*/
-void Table::destroy()
+char *Table::createPackedXML()
{
- m_columns->clear();
- m_data->clear();
- safe_free(m_title);
+ TCHAR *xml = createXML();
+ if (xml == NULL)
+ return NULL;
+ char *utf8xml = UTF8StringFromTString(xml);
+ free(xml);
+ size_t len = strlen(utf8xml);
+ uLongf buflen = compressBound(len);
+ BYTE *buffer = (BYTE *)malloc(buflen + 4);
+ if (compress(&buffer[4], &buflen, (BYTE *)utf8xml, len) != Z_OK)
+ {
+ free(utf8xml);
+ free(buffer);
+ return NULL;
+ }
+ free(utf8xml);
+ char *encodedBuffer = NULL;
+ *((UINT32 *)buffer) = htonl((UINT32)len);
+ base64_encode_alloc((char *)buffer, buflen + 4, &encodedBuffer);
+ free(buffer);
+ return encodedBuffer;
}
/**
AssertEquals(table->getNumRows(), 1);
AssertEquals(table->getNumColumns(), 0);
EndTest();
+
+ table->addColumn(_T("NAME"));
+ table->addColumn(_T("VALUE"));
+ table->addColumn(_T("DATA1"));
+ table->addColumn(_T("DATA2"));
+ table->addColumn(_T("DATA3"));
+ table->addColumn(_T("DATA4"));
+ for(int i = 0; i < 50; i++)
+ {
+ table->addRow();
+ TCHAR b[64];
+ _sntprintf(b, 64, _T("Process #%d"), i);
+ table->set(0, b);
+ table->set(1, i);
+ table->set(2, i * 100);
+ table->set(3, i * 100001);
+ table->set(4, _T("/some/long/path/on/file/system"));
+ table->set(5, _T("constant"));
+ }
+
+ StartTest(_T("Table: pack"));
+ INT64 start = GetCurrentTimeMs();
+ char *packedTable = table->createPackedXML();
+ AssertNotNull(packedTable);
+ EndTest(GetCurrentTimeMs() - start);
+
+ StartTest(_T("Table: unpack"));
+ start = GetCurrentTimeMs();
+ Table *table2 = Table::createFromPackedXML(packedTable);
+ free(packedTable);
+ AssertNotNull(table2);
+ AssertEquals(table2->getNumColumns(), table->getNumColumns());
+ AssertEquals(table2->getNumRows(), table->getNumRows());
+ AssertEquals(table2->getAsInt(10, 1), table->getAsInt(10, 1));
+ EndTest(GetCurrentTimeMs() - start);
}
/**