void uat_swap(uat_t* uat, guint a, guint b) { size_t s = uat->record_size; void* tmp = ep_alloc(s); g_assert( a < uat->user_data->len && b < uat->user_data->len ); if (a == b) return; memcpy(tmp, UAT_INDEX_PTR(uat,a), s); memcpy(UAT_INDEX_PTR(uat,a), UAT_INDEX_PTR(uat,b), s); memcpy(UAT_INDEX_PTR(uat,b), tmp, s); }
void* uat_add_record(uat_t* uat, const void* data, gboolean valid_rec) { void* rec; gboolean* valid; /* Save a copy of the raw (possibly that may contain invalid field values) data */ g_array_append_vals (uat->raw_data, data, 1); rec = UAT_INDEX_PTR(uat, uat->raw_data->len - 1); if (uat->copy_cb) { uat->copy_cb(rec, data, (unsigned int) uat->record_size); } if (valid_rec) { /* Add a "known good" record to the list to be used by the dissector */ g_array_append_vals (uat->user_data, data, 1); rec = UAT_USER_INDEX_PTR(uat, uat->user_data->len - 1); if (uat->copy_cb) { uat->copy_cb(rec, data, (unsigned int) uat->record_size); } UAT_UPDATE(uat); } else { rec = NULL; } g_array_append_vals (uat->valid_data, &valid_rec, 1); valid = &g_array_index(uat->valid_data, gboolean, uat->valid_data->len-1); *valid = valid_rec; return rec; }
void UatDialog::enumPrefCurrentIndexChanged(int index) { QTreeWidgetItem *item = ui->uatTreeWidget->currentItem(); if (!cur_combo_box_ || !item || index < 0) return; guint row = item->data(0, Qt::UserRole).toUInt(); void *rec = UAT_INDEX_PTR(uat_, row); uat_field_t *field = &uat_->fields[cur_column_]; const QByteArray& enum_txt = cur_combo_box_->itemText(index).toUtf8(); char *err = NULL; if (field->cb.chk && !field->cb.chk(rec, enum_txt.constData(), (unsigned) enum_txt.size(), field->cbdata.chk, field->fld_data, &err)) { QString err_string = "<font color='red'>%1</font>"; ui->hintLabel->setText(err_string.arg(err)); g_free(err); ok_button_->setEnabled(false); uat_update_record(uat_, rec, FALSE); } else { ui->hintLabel->clear(); field->cb.set(rec, enum_txt.constData(), (unsigned) enum_txt.size(), field->cbdata.set, field->fld_data); ok_button_->setEnabled(true); uat_update_record(uat_, rec, TRUE); } this->update(); uat_->changed = TRUE; }
void uat_swap(uat_t* uat, guint a, guint b) { size_t s = uat->record_size; void* tmp = ep_alloc(s); gboolean tmp_bool; g_assert( a < uat->raw_data->len && b < uat->raw_data->len ); if (a == b) return; memcpy(tmp, UAT_INDEX_PTR(uat,a), s); memcpy(UAT_INDEX_PTR(uat,a), UAT_INDEX_PTR(uat,b), s); memcpy(UAT_INDEX_PTR(uat,b), tmp, s); tmp_bool = *(gboolean*)(uat->valid_data->data + (sizeof(gboolean) * (a))); *(gboolean*)(uat->valid_data->data + (sizeof(gboolean) * (a))) = *(gboolean*)(uat->valid_data->data + (sizeof(gboolean) * (b))); *(gboolean*)(uat->valid_data->data + (sizeof(gboolean) * (b))) = tmp_bool; }
void uat_remove_record_idx(uat_t* uat, guint idx) { g_assert( idx < uat->raw_data->len ); if (uat->free_cb) { uat->free_cb(UAT_INDEX_PTR(uat,idx)); } g_array_remove_index(uat->raw_data, idx); g_array_remove_index(uat->valid_data, idx); }
void uat_remove_record_idx(uat_t* uat, guint idx) { g_assert( idx < uat->user_data->len ); if (uat->free_cb) { uat->free_cb(UAT_INDEX_PTR(uat,idx)); } g_array_remove_index(uat->user_data, idx); UAT_UPDATE(uat); }
void uat_clear(uat_t* uat) { guint i; for ( i = 0 ; i < uat->user_data->len ; i++ ) { if (uat->free_cb) { uat->free_cb(UAT_INDEX_PTR(uat,i)); } } g_array_set_size(uat->user_data,0); *((uat)->user_ptr) = NULL; *((uat)->nrows_p) = 0; }
static void append_row(uat_t *uat, guint idx) { void *rec = UAT_INDEX_PTR(uat, idx); uat_field_t *f = uat->fields; guint colnum; GtkTreeIter iter; gchar* tmp_str; if (! uat->rep) return; gtk_list_store_insert_before(uat->rep->list_store, &iter, NULL); for ( colnum = 0; colnum < uat->ncols; colnum++ ) { tmp_str = fld_tostr(rec, &(f[colnum])); gtk_list_store_set(uat->rep->list_store, &iter, colnum, tmp_str, -1); g_free(tmp_str); } }
static void append_row(uat_t *uat, guint idx) { GPtrArray *a = g_ptr_array_new(); void *rec = UAT_INDEX_PTR(uat, idx); uat_field_t *f = uat->fields; guint colnum; GtkTreeIter iter; if (! uat->rep) return; gtk_list_store_insert_before(uat->rep->list_store, &iter, NULL); for ( colnum = 0; colnum < uat->ncols; colnum++ ) { g_ptr_array_add(a, fld_tostr(rec, &(f[colnum]))); gtk_list_store_set(uat->rep->list_store, &iter, colnum, fld_tostr(rec, &(f[colnum])), -1); } g_ptr_array_free(a, TRUE); }
static void reset_row(uat_t *uat, guint idx) { void *rec = UAT_INDEX_PTR(uat, idx); uat_field_t *f = uat->fields; guint colnum; GtkTreePath *path; GtkTreeIter iter; if (! uat->rep) return; path = gtk_tree_path_new_from_indices(idx, -1); if (!path || !gtk_tree_model_get_iter(GTK_TREE_MODEL(uat->rep->list_store), &iter, path)) { return; } for ( colnum = 0; colnum < uat->ncols; colnum++ ) { gtk_list_store_set(uat->rep->list_store, &iter, colnum, fld_tostr(rec, &(f[colnum])), -1); } }
/* Updates the validity of a record. */ void uat_update_record(uat_t *uat, const void *data, gboolean valid_rec) { guint pos; gboolean *valid; /* Locate internal UAT data pointer. */ for (pos = 0; pos < uat->raw_data->len; pos++) { if (UAT_INDEX_PTR(uat, pos) == data) { break; } } if (pos == uat->raw_data->len) { /* Data is not within list?! */ g_assert_not_reached(); } valid = &g_array_index(uat->valid_data, gboolean, pos); *valid = valid_rec; }
void UatDialog::stringPrefTextChanged(const QString &text) { QTreeWidgetItem *item = ui->uatTreeWidget->currentItem(); if (!cur_line_edit_) { cur_line_edit_ = new SyntaxLineEdit(); } if (!cur_line_edit_ || !item) return; guint row = item->data(0, Qt::UserRole).toUInt(); void *rec = UAT_INDEX_PTR(uat_, row); uat_field_t *field = &uat_->fields[cur_column_]; SyntaxLineEdit::SyntaxState ss = SyntaxLineEdit::Empty; bool enable_ok = true; QString qt_err; const QByteArray &txt = (field->mode == PT_TXTMOD_HEXBYTES) ? unhexbytes(text, qt_err) : text.toUtf8(); QString err_string = "<font color='red'>%1</font>"; if (!qt_err.isEmpty()) { ui->hintLabel->setText(err_string.arg(qt_err)); enable_ok = false; ss = SyntaxLineEdit::Invalid; } else { char *err = NULL; if (field->cb.chk && !field->cb.chk(rec, txt.constData(), (unsigned) txt.size(), field->cbdata.chk, field->fld_data, &err)) { ui->hintLabel->setText(err_string.arg(err)); g_free(err); enable_ok = false; ss = SyntaxLineEdit::Invalid; uat_update_record(uat_, rec, FALSE); } else { ui->hintLabel->clear(); field->cb.set(rec, txt.constData(), (unsigned) txt.size(), field->cbdata.set, field->fld_data); saved_string_pref_ = text; ss = SyntaxLineEdit::Valid; uat_update_record(uat_, rec, TRUE); } } this->update(); ok_button_->setEnabled(enable_ok); cur_line_edit_->setSyntaxState(ss); uat_->changed = TRUE; }
void UatDialog::addRecord(bool copy_from_current) { if (!uat_) return; void *rec = g_malloc0(uat_->record_size); if (copy_from_current && uat_->copy_cb) { QTreeWidgetItem *item = ui->uatTreeWidget->currentItem(); if (!item) return; guint row = item->data(0, Qt::UserRole).toUInt(); uat_->copy_cb(rec, UAT_INDEX_PTR(uat_, row), uat_->record_size); } else { for (guint col = 0; col < uat_->ncols; col++) { uat_field_t *field = &uat_->fields[col]; switch (field->mode) { case PT_TXTMOD_ENUM: guint length; char *str; field->cb.tostr(rec, &str, &length, field->cbdata.tostr, field->fld_data); field->cb.set(rec, str, length, field->cbdata.set, field->fld_data); g_free(str); break; case PT_TXTMOD_NONE: break; default: field->cb.set(rec, "", 0, field->cbdata.set, field->fld_data); break; } } } uat_add_record(uat_, rec, TRUE); if (uat_->free_cb) { uat_->free_cb(rec); } g_free(rec); uat_->changed = TRUE; updateItems(); activateLastItem(); }
QString UatDialog::fieldString(guint row, guint column) { QString string_rep; if (!uat_) return string_rep; void *rec = UAT_INDEX_PTR(uat_, row); uat_field_t *field = &uat_->fields[column]; guint length; char *str; field->cb.tostr(rec, &str, &length, field->cbdata.tostr, field->fld_data); switch(field->mode) { case PT_TXTMOD_NONE: case PT_TXTMOD_STRING: case PT_TXTMOD_ENUM: case PT_TXTMOD_FILENAME: case PT_TXTMOD_DIRECTORYNAME: string_rep = str; break; case PT_TXTMOD_HEXBYTES: { { char* temp_str = bytes_to_str(NULL, (const guint8 *) str, length); QString qstr(temp_str); string_rep = qstr; wmem_free(NULL, temp_str); } break; } default: g_assert_not_reached(); break; } g_free(str); return string_rep; }
void UatDialog::stringPrefEditingFinished() { QTreeWidgetItem *item = ui->uatTreeWidget->currentItem(); if (!cur_line_edit_ || !item) return; item->setText(cur_column_, saved_string_pref_); ok_button_->setEnabled(true); if (uat_ && uat_->update_cb) { gchar *err; void *rec = UAT_INDEX_PTR(uat_, item->data(0, Qt::UserRole).toUInt()); if (!uat_->update_cb(rec, &err)) { QString err_string = "<font color='red'>%1</font>"; ui->hintLabel->setText(err_string.arg(err)); g_free(err); ok_button_->setEnabled(false); } else { ui->hintLabel->clear(); } this->update(); } updateItem(*item); }
gboolean uat_save(uat_t* uat, char** error) { guint i; gchar* fname = uat_get_actual_filename(uat,TRUE); FILE* fp; if (! fname ) return FALSE; fp = ws_fopen(fname,"w"); if (!fp && errno == ENOENT) { /* Parent directory does not exist, try creating first */ gchar *pf_dir_path = NULL; if (create_persconffile_dir(&pf_dir_path) != 0) { *error = g_strdup_printf("uat_save: error creating '%s'", pf_dir_path); g_free (pf_dir_path); return FALSE; } fp = ws_fopen(fname,"w"); } if (!fp) { *error = g_strdup_printf("uat_save: error opening '%s': %s",fname,g_strerror(errno)); return FALSE; } *error = NULL; g_free (fname); /* Ensure raw_data is synced with user_data and all "good" entries have been accounted for */ /* Start by clearing current user_data */ for ( i = 0 ; i < uat->user_data->len ; i++ ) { if (uat->free_cb) { uat->free_cb(UAT_USER_INDEX_PTR(uat,i)); } } g_array_set_size(uat->user_data,0); *((uat)->user_ptr) = NULL; *((uat)->nrows_p) = 0; /* Now copy "good" raw_data entries to user_data */ for ( i = 0 ; i < uat->raw_data->len ; i++ ) { void *rec = UAT_INDEX_PTR(uat, i); gboolean* valid = (gboolean*)(uat->valid_data->data + sizeof(gboolean)*i); if (*valid) { g_array_append_vals(uat->user_data, rec, 1); if (uat->copy_cb) { uat->copy_cb(UAT_USER_INDEX_PTR(uat, uat->user_data->len - 1), rec, (unsigned int) uat->record_size); } UAT_UPDATE(uat); } } fprintf(fp,"# This file is automatically generated, DO NOT MODIFY.\n"); for ( i = 0 ; i < uat->user_data->len ; i++ ) { void* rec = uat->user_data->data + (uat->record_size * i); uat_field_t* f; guint j; f = uat->fields; for( j=0 ; j < uat->ncols ; j++ ) { putfld(fp, rec, &(f[j])); fputs((j == uat->ncols - 1) ? "\n" : "," ,fp); } } fclose(fp); uat->changed = FALSE; return TRUE; }
void UatDialog::on_uatTreeWidget_itemActivated(QTreeWidgetItem *item, int column) { if (!uat_) return; cur_line_edit_ = NULL; cur_combo_box_ = NULL; uat_field_t *field = &uat_->fields[column]; guint row = item->data(0, Qt::UserRole).toUInt(); void *rec = UAT_INDEX_PTR(uat_, row); cur_column_ = column; QWidget *editor = NULL; // Reset any active items QTreeWidgetItemIterator uat_it(ui->uatTreeWidget); while (*uat_it) { for (int col = 0; col < ui->uatTreeWidget->columnCount(); col++) { if (ui->uatTreeWidget->itemWidget((*uat_it), col)) { ui->uatTreeWidget->removeItemWidget((*uat_it), col); updateItem(*(*uat_it)); } } ++uat_it; } switch(field->mode) { case PT_TXTMOD_DIRECTORYNAME: { QString cur_path = fieldString(row, column); const QByteArray& new_path = QFileDialog::getExistingDirectory(this, field->title, cur_path).toUtf8(); field->cb.set(rec, new_path.constData(), (unsigned) new_path.size(), field->cbdata.set, field->fld_data); updateItem(*item); break; } case PT_TXTMOD_FILENAME: { QString cur_path = fieldString(row, column); const QByteArray& new_path = QFileDialog::getOpenFileName(this, field->title, cur_path, QString(), NULL, QFileDialog::DontConfirmOverwrite).toUtf8(); field->cb.set(rec, new_path.constData(), (unsigned) new_path.size(), field->cbdata.set, field->fld_data); updateItem(*item); break; } case PT_TXTMOD_STRING: case PT_TXTMOD_HEXBYTES: { cur_line_edit_ = new SyntaxLineEdit(); break; } case PT_TXTMOD_ENUM: { cur_combo_box_ = new QComboBox(); // const enum_val_t *ev; const value_string *enum_vals = (const value_string *)field->fld_data; for (int i = 0; enum_vals[i].strptr != NULL; i++) { cur_combo_box_->addItem(enum_vals[i].strptr, QVariant(enum_vals[i].value)); if (item->text(column).compare(enum_vals[i].strptr) == 0) { cur_combo_box_->setCurrentIndex(cur_combo_box_->count() - 1); } } saved_combo_idx_ = cur_combo_box_->currentIndex(); break; } case PT_TXTMOD_NONE: break; default: g_assert_not_reached(); break; } if (cur_line_edit_) { editor = cur_line_edit_; cur_line_edit_->setText(fieldString(row, column)); cur_line_edit_->selectAll(); connect(cur_line_edit_, SIGNAL(destroyed()), this, SLOT(lineEditPrefDestroyed())); connect(cur_line_edit_, SIGNAL(textChanged(QString)), this, SLOT(stringPrefTextChanged(QString))); } if (cur_combo_box_) { editor = cur_combo_box_; connect(cur_combo_box_, SIGNAL(currentIndexChanged(int)), this, SLOT(enumPrefCurrentIndexChanged(int))); connect(cur_combo_box_, SIGNAL(destroyed()), this, SLOT(enumPrefDestroyed())); } if (editor) { QFrame *edit_frame = new QFrame(); QHBoxLayout *hb = new QHBoxLayout(); QSpacerItem *spacer = new QSpacerItem(5, 10); hb->addWidget(editor, 0); hb->addSpacerItem(spacer); hb->setStretch(1, 1); hb->setContentsMargins(0, 0, 0, 0); edit_frame->setLineWidth(0); edit_frame->setFrameStyle(QFrame::NoFrame); // The documentation suggests setting autoFillbackground. That looks silly // so we clear the item text instead. saved_string_pref_ = item->text(column); item->setText(column, ""); edit_frame->setLayout(hb); ui->uatTreeWidget->setItemWidget(item, column, edit_frame); if (cur_line_edit_) { ui->uatTreeWidget->setCurrentItem(item); } editor->setFocus(); } }