aboutsummaryrefslogtreecommitdiffstats
path: root/ui/qt/utils
diff options
context:
space:
mode:
authorRoland Knall <roland.knall@br-automation.com>2017-10-30 13:58:28 +0100
committerRoland Knall <rknall@gmail.com>2017-11-08 20:20:31 +0000
commit8a6ea0e454dddcc1d9c14ad1e02a43a53a4ef667 (patch)
tree1afd59377e5e62f8f0b057cfb406f077823872e4 /ui/qt/utils
parent87431fef2836c8d77ea694844cd5dff0e8b801f8 (diff)
Qt: Further cleanup ByteView
This further separates ByteView and the rest of the system. Using FieldInformation and DataPrinter, this is the final cleanup of the ByteViewTab Change-Id: If41521167527cf5664c2564cdd0d45fea0f3f612 Reviewed-on: https://code.wireshark.org/review/22783 Petri-Dish: Roland Knall <rknall@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Roland Knall <rknall@gmail.com>
Diffstat (limited to 'ui/qt/utils')
-rw-r--r--ui/qt/utils/data_printer.cpp182
-rw-r--r--ui/qt/utils/data_printer.h85
-rw-r--r--ui/qt/utils/field_information.cpp175
-rw-r--r--ui/qt/utils/field_information.h91
-rw-r--r--ui/qt/utils/frame_information.cpp117
-rw-r--r--ui/qt/utils/frame_information.h80
6 files changed, 730 insertions, 0 deletions
diff --git a/ui/qt/utils/data_printer.cpp b/ui/qt/utils/data_printer.cpp
new file mode 100644
index 0000000000..fbb8a3c797
--- /dev/null
+++ b/ui/qt/utils/data_printer.cpp
@@ -0,0 +1,182 @@
+/* data_printer.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <ui/qt/utils/data_printer.h>
+
+#include <stdint.h>
+
+#include <QApplication>
+#include <QClipboard>
+#include <QString>
+#include <QMimeData>
+
+DataPrinter::DataPrinter(QObject * parent)
+: QObject(parent),
+ byteLineLength_(16)
+{}
+
+void DataPrinter::toClipboard(DataPrinter::DumpType type, IDataPrintable * printable)
+{
+ QByteArray printData = printable->printableData();
+
+ QString clipboard_text;
+
+ switch(type)
+ {
+ case DP_PrintableText:
+ for (int i = 0; i < printData.length(); i++) {
+ if (QChar::isSpace(printData[i]) || QChar::isLetter(printData[i])) {
+ clipboard_text += QChar(printData[i]);
+ }
+ }
+ break;
+ case DP_HexStream:
+ for (int i = 0; i < printData.length(); i++)
+ clipboard_text += QString("%1").arg(printData[i], 2, 16, QChar('0'));
+ break;
+ case DP_EscapedString:
+ // Beginning quote
+ clipboard_text += QString("\"");
+
+ for (int i = 0; i < printData.length(); i++) {
+ // Terminate this line if it has reached 16 bytes,
+ // unless it is also the very last byte in the data,
+ // as the termination after this for loop will take
+ // care of that.
+ if (i % 16 == 0 && i != 0 && i != printData.length() - 1) {
+ clipboard_text += QString("\" \\\n\"");
+ }
+ clipboard_text += QString("\\x%1").arg(printData[i], 2, 16, QChar('0'));
+ }
+ // End quote
+ clipboard_text += QString("\"\n");
+ break;
+ case DP_Binary:
+ binaryDump(printData);
+ break;
+ case DP_HexDump:
+ clipboard_text = hexTextDump(printData, true);
+ break;
+ case DP_HexOnly:
+ clipboard_text = hexTextDump(printData, false);
+ break;
+ default:
+ break;
+ }
+
+ if (!clipboard_text.isEmpty()) {
+ qApp->clipboard()->setText(clipboard_text);
+ }
+}
+
+void DataPrinter::binaryDump(QByteArray printData)
+{
+ if (!printData.isEmpty()) {
+ QMimeData *mime_data = new QMimeData;
+ // gtk/gui_utils.c:copy_binary_to_clipboard says:
+ /* XXX - this is not understood by most applications,
+ * but can be pasted into the better hex editors - is
+ * there something better that we can do?
+ */
+ // As of 2015-07-30, pasting into Frhed works on Windows. Pasting into
+ // Hex Editor Neo and HxD does not.
+ mime_data->setData("application/octet-stream", printData);
+ qApp->clipboard()->setMimeData(mime_data);
+ }
+}
+
+void DataPrinter::setByteLineLength(int bll)
+{
+ byteLineLength_ = bll;
+}
+
+int DataPrinter::byteLineLength() const
+{
+ return byteLineLength_;
+}
+
+QString DataPrinter::hexTextDump(QByteArray printData, bool showText)
+{
+ QString clipboard_text;
+
+ QString byteStr;
+ QString dataStr;
+
+ int cnt = 0;
+ while ( cnt < printData.length() )
+ {
+ byteStr += QString(" %1").arg((uint8_t) printData[cnt], 2, 16, QChar('0'));
+ if ( showText )
+ {
+ char ch = '.';
+ if ( QChar::isPrint(printData[cnt]) )
+ ch = (char) printData[cnt];
+ dataStr += QChar( ch );
+ }
+ cnt++;
+ }
+
+ int lines = printData.length() / byteLineLength_;
+ if ( printData.length() % byteLineLength_ > 0 )
+ lines++;
+
+ for ( cnt = 0; cnt < lines; cnt++ )
+ {
+ int offset = cnt * 0x10;
+
+ clipboard_text += QString("%1 ").arg(offset, 4, 16, QChar('0'));
+ clipboard_text += byteStr.mid(offset * 3, byteLineLength_ * 3);
+
+ if ( showText )
+ {
+ /* separation bytes for byte and text */
+ clipboard_text += QString(3, ' ');
+
+ /* separation bytes last line */
+ if ( cnt == ( lines - 1 ) )
+ {
+ int remSpace = byteLineLength_ - dataStr.mid(offset, byteLineLength_).length();
+ clipboard_text += QString(remSpace * 3, ' ');
+ }
+
+ /* text representation */
+ clipboard_text += dataStr.mid(offset, byteLineLength_);
+ }
+
+ clipboard_text += "\n";
+ }
+
+ return clipboard_text;
+}
+
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/utils/data_printer.h b/ui/qt/utils/data_printer.h
new file mode 100644
index 0000000000..923c15169b
--- /dev/null
+++ b/ui/qt/utils/data_printer.h
@@ -0,0 +1,85 @@
+/* data_printer.h
+ *
+ * Used by ByteView and others, to create data dumps in printable
+ * form
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef DATA_PRINTER_H
+#define DATA_PRINTER_H
+
+#include <config.h>
+
+#include <QObject>
+
+
+class IDataPrintable
+{
+public:
+ virtual ~IDataPrintable() {}
+
+ virtual QByteArray printableData() = 0;
+};
+
+class DataPrinter : public QObject
+{
+ Q_OBJECT
+public:
+ explicit DataPrinter(QObject *parent = 0);
+
+ enum DumpType {
+ DP_HexDump,
+ DP_HexOnly,
+ DP_HexStream,
+ DP_PrintableText,
+ DP_EscapedString,
+ DP_Binary
+ };
+
+ void toClipboard(DataPrinter::DumpType type, IDataPrintable * printable);
+
+ void setByteLineLength(int);
+ int byteLineLength() const;
+
+private:
+ QString hexTextDump(QByteArray printData, bool append_text);
+ void binaryDump(QByteArray printData);
+
+ int byteLineLength_;
+};
+
+#define IDataPrintable_iid "org.wireshark.Qt.UI.IDataPrintable"
+
+Q_DECLARE_INTERFACE(IDataPrintable, IDataPrintable_iid)
+
+#endif // DATA_PRINTER_H
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/utils/field_information.cpp b/ui/qt/utils/field_information.cpp
new file mode 100644
index 0000000000..77997eab84
--- /dev/null
+++ b/ui/qt/utils/field_information.cpp
@@ -0,0 +1,175 @@
+/* field_information.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdint.h>
+
+#include <ui/qt/utils/field_information.h>
+
+FieldInformation::FieldInformation(field_info * fi, QObject * parent)
+:QObject(parent)
+{
+ fi_ = fi;
+ parent_fi_ = 0;
+}
+
+bool FieldInformation::isValid()
+{
+ bool ret = false;
+
+ if ( fi_ )
+ {
+ if (fi_->hfinfo->blurb != 0 && fi_->hfinfo->blurb[0] != '\0') {
+ ret = true;
+ } else {
+ ret = ((QString().fromUtf8(fi_->hfinfo->name)).length() > 0 );
+ }
+ }
+
+ return ret;
+}
+
+void FieldInformation::setParentField(field_info * par_fi)
+{
+ parent_fi_ = par_fi;
+}
+
+field_info * FieldInformation::fieldInfo() const
+{
+ return fi_;
+}
+
+FieldInformation::HeaderInfo FieldInformation::headerInfo() const
+{
+ HeaderInfo header;
+ header.isValid = false;
+
+ if ( fi_ && fi_->hfinfo )
+ {
+ header.isValid = true;
+ header.name = QString().fromUtf8(fi_->hfinfo->name);
+ header.description = QString().fromUtf8(fi_->hfinfo->blurb);
+ header.abbreviation = QString().fromUtf8(fi_->hfinfo->abbrev);
+ }
+
+ return header;
+}
+
+FieldInformation * FieldInformation::parentField() const
+{
+ return new FieldInformation(parent_fi_);
+}
+
+bool FieldInformation::tvbContains(FieldInformation *child)
+{
+ if ( fi_ && child && fi_->ds_tvb == child->fieldInfo()->ds_tvb )
+ return true;
+
+ return false;
+}
+
+FieldInformation::Position FieldInformation::position() const
+{
+ Position pos = {-1, -1, -1};
+ if ( fi_ )
+ {
+ guint len = tvb_captured_length(fi_->ds_tvb);
+
+ pos.start = fi_->start;
+ pos.length = fi_->length;
+
+ if (pos.start >= 0 && pos.length > 0 && (guint)pos.start < len)
+ {
+ pos.end = pos.start + pos.length;
+ }
+ else
+ {
+ if ( fi_->appendix_start >= 0 && fi_->appendix_length > 0 && (guint)fi_->appendix_start < len )
+ {
+ pos.start = fi_->appendix_start;
+ pos.end = fi_->appendix_start + fi_->appendix_length;
+ }
+ }
+
+ if (pos.end != -1 && (guint)pos.end > len)
+ pos.end = len;
+ }
+
+ return pos;
+}
+
+FieldInformation::Position FieldInformation::appendix() const
+{
+ Position pos = {-1, -1, -1};
+ if ( fi_ )
+ {
+ guint len = tvb_captured_length(fi_->ds_tvb);
+
+ pos.start = fi_->appendix_start;
+ pos.length = fi_->appendix_length;
+
+ if (pos.start >= 0 && pos.length > 0 && (guint)pos.start < len)
+ pos.end = pos.start + pos.length;
+
+ /* sanity check with total field length */
+ if ( position().end == -1 )
+ {
+ pos.start = -1;
+ pos.end = -1;
+ }
+
+ if (pos.end != -1 && (guint)pos.end > len)
+ pos.end = len;
+ }
+
+ return pos;
+}
+#include <QDebug>
+QByteArray FieldInformation::printableData()
+{
+ QByteArray data;
+
+ if ( fi_ && fi_->ds_tvb )
+ {
+ FieldInformation::Position pos = position();
+ int rem_length = tvb_captured_length_remaining(fi_->ds_tvb, pos.start);
+
+ int length = pos.length;
+ if ( length > rem_length )
+ length = rem_length;
+qDebug() << "Bin hier";
+ uint8_t * dataSet = (uint8_t *)tvb_memdup(wmem_file_scope(), fi_->ds_tvb, pos.start, length );
+ data = QByteArray::fromRawData((char *)dataSet, length);
+ }
+
+ return data;
+}
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/utils/field_information.h b/ui/qt/utils/field_information.h
new file mode 100644
index 0000000000..71f49b5a47
--- /dev/null
+++ b/ui/qt/utils/field_information.h
@@ -0,0 +1,91 @@
+/* field_information.h
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef FIELD_INFORMATION_H_
+#define FIELD_INFORMATION_H_
+
+#include <config.h>
+
+#include <epan/proto.h>
+
+#include <ui/qt/utils/data_printer.h>
+
+#include <QObject>
+
+class FieldInformation : public QObject, public IDataPrintable
+{
+ Q_OBJECT
+ Q_INTERFACES(IDataPrintable)
+
+public:
+
+ struct HeaderInfo
+ {
+ QString name;
+ QString description;
+ QString abbreviation;
+ bool isValid;
+ };
+
+ struct Position
+ {
+ int start;
+ int end;
+ int length;
+ };
+
+ explicit FieldInformation(field_info * fi, QObject * parent = Q_NULLPTR);
+
+ bool isValid();
+
+ field_info * fieldInfo() const;
+
+ HeaderInfo headerInfo() const;
+ Position position() const;
+ Position appendix() const;
+
+ void setParentField(field_info * fi);
+ FieldInformation * parentField() const;
+ bool tvbContains(FieldInformation *);
+
+ QByteArray printableData();
+
+private:
+
+ field_info * fi_;
+ field_info * parent_fi_;
+};
+
+
+#endif // FIELD_INFORMATION_H_
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/utils/frame_information.cpp b/ui/qt/utils/frame_information.cpp
new file mode 100644
index 0000000000..0b4116d2bc
--- /dev/null
+++ b/ui/qt/utils/frame_information.cpp
@@ -0,0 +1,117 @@
+/* frame_information.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <epan/epan_dissect.h>
+#include "epan/epan.h"
+#include "epan/column.h"
+#include "epan/ftypes/ftypes.h"
+
+#include "wiretap/wtap.h"
+
+#include "cfile.h"
+#include "file.h"
+#include <ui/qt/capture_file.h>
+
+#include "frame_tvbuff.h"
+
+#include <stdint.h>
+
+#include <ui/qt/utils/frame_information.h>
+
+FrameInformation::FrameInformation(CaptureFile * capfile, frame_data * fi, QObject * parent)
+:QObject(parent),
+ fi_(fi),
+ cap_file_(capfile),
+ packet_data_(0)
+{
+ loadFrameTree();
+}
+
+void FrameInformation::loadFrameTree()
+{
+ if ( ! fi_ || ! cap_file_ )
+ return;
+
+ if (!cf_read_record(cap_file_->capFile(), fi_))
+ return;
+
+ struct wtap_pkthdr phdr_ = cap_file_->capFile()->phdr;
+ packet_data_ = (guint8 *) g_memdup(ws_buffer_start_ptr(&(cap_file_->capFile()->buf)), fi_->cap_len);
+
+ /* proto tree, visible. We need a proto tree if there's custom columns */
+ epan_dissect_init(&edt_, cap_file_->capFile()->epan, TRUE, TRUE);
+ col_custom_prime_edt(&edt_, &(cap_file_->capFile()->cinfo));
+
+ epan_dissect_run(&edt_, cap_file_->capFile()->cd_t, &phdr_,
+ frame_tvbuff_new(fi_, packet_data_),
+ fi_, &(cap_file_->capFile()->cinfo));
+ epan_dissect_fill_in_columns(&edt_, TRUE, TRUE);
+}
+
+FrameInformation::~FrameInformation()
+{
+ epan_dissect_cleanup(&edt_);
+ delete(packet_data_);
+}
+
+bool FrameInformation::isValid()
+{
+ bool ret = false;
+
+ if ( fi_ && cap_file_ && edt_.tvb )
+ {
+ ret = true;
+ }
+
+ return ret;
+}
+
+frame_data * FrameInformation::frameData() const
+{
+ return fi_;
+}
+
+QByteArray FrameInformation::printableData()
+{
+ QByteArray data;
+
+ if ( fi_ )
+ {
+ int rem_length = tvb_captured_length(edt_.tvb);
+
+ uint8_t * dataSet = (uint8_t *)tvb_memdup(wmem_file_scope(), edt_.tvb, 0, rem_length );
+ data = QByteArray::fromRawData((char *)dataSet, rem_length);
+ }
+
+ return data;
+}
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/qt/utils/frame_information.h b/ui/qt/utils/frame_information.h
new file mode 100644
index 0000000000..1a3a8fda3f
--- /dev/null
+++ b/ui/qt/utils/frame_information.h
@@ -0,0 +1,80 @@
+/* frame_information.h
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef FRAME_INFORMATION_H_
+#define FRAME_INFORMATION_H_
+
+#include <config.h>
+
+#include <epan/proto.h>
+#include <epan/epan_dissect.h>
+#include "epan/epan.h"
+#include "epan/column.h"
+#include "epan/ftypes/ftypes.h"
+
+#include <ui/qt/capture_file.h>
+
+#include <ui/qt/utils/data_printer.h>
+
+#include <QObject>
+
+class FrameInformation : public QObject, public IDataPrintable
+{
+ Q_OBJECT
+ Q_INTERFACES(IDataPrintable)
+
+public:
+
+ explicit FrameInformation(CaptureFile * cfile, frame_data * fi, QObject * parent = Q_NULLPTR);
+ virtual ~FrameInformation();
+
+ bool isValid();
+
+ frame_data * frameData() const;
+
+ QByteArray printableData();
+
+private:
+
+ frame_data * fi_;
+ CaptureFile * cap_file_;
+ guint8 *packet_data_;
+ epan_dissect_t edt_;
+
+ void loadFrameTree();
+
+};
+
+
+#endif // FRAME_INFORMATION_H_
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */