gboolean
right_justify_column (gint col, capture_file *cf)
{
    header_field_info *hfi;
    gboolean right_justify = FALSE;

    if (!cf) return FALSE;

    switch (cf->cinfo.col_fmt[col]) {

    case COL_NUMBER:
    case COL_PACKET_LENGTH:
    case COL_CUMULATIVE_BYTES:
    case COL_DCE_CALL:
    case COL_DSCP_VALUE:
    case COL_UNRES_DST_PORT:
    case COL_UNRES_SRC_PORT:
    case COL_DEF_DST_PORT:
    case COL_DEF_SRC_PORT:
    case COL_DELTA_TIME:
    case COL_DELTA_TIME_DIS:
        right_justify = TRUE;
        break;

    case COL_CUSTOM:
        hfi = proto_registrar_get_byname(cf->cinfo.col_custom_field[col]);
        /* Check if this is a valid field and we have no strings lookup table */
        if ((hfi != NULL) && ((hfi->strings == NULL) || !get_column_resolved(col))) {
            /* Check for bool, framenum and decimal/octal integer types */
            if ((hfi->type == FT_BOOLEAN) || (hfi->type == FT_FRAMENUM) ||
                    (((hfi->display == BASE_DEC) || (hfi->display == BASE_OCT)) &&
                     (IS_FT_INT(hfi->type) || IS_FT_UINT(hfi->type)))) {
                right_justify = TRUE;
            }
        }
        break;

    default:
        break;
    }

    return right_justify;
}
//#define MINIMIZE_STRING_COPYING 1
void PacketListRecord::cacheColumnStrings(column_info *cinfo)
{
    // packet_list_store.c:packet_list_change_record(PacketList *packet_list, PacketListRecord *record, gint col, column_info *cinfo)
    if (!cinfo) {
        return;
    }

    col_text_.clear();
    lines_ = 1;
    line_count_changed_ = false;

    for (int column = 0; column < cinfo->num_cols; ++column) {
        int col_lines = 1;

#ifdef MINIMIZE_STRING_COPYING
        int text_col = cinfo_column_.value(column, -1);

        /* Column based on frame_data or it already contains a value */
        if (text_col < 0) {
            col_fill_in_frame_data(fdata_, cinfo, column, FALSE);
            col_text_.append(cinfo->columns[column].col_data);
            continue;
        }

        switch (cinfo->col_fmt[column]) {
        case COL_PROTOCOL:
        case COL_INFO:
        case COL_IF_DIR:
        case COL_DCE_CALL:
        case COL_8021Q_VLAN_ID:
        case COL_EXPERT:
        case COL_FREQ_CHAN:
            if (cinfo->columns[column].col_data && cinfo->columns[column].col_data != cinfo->columns[column].col_buf) {
                /* This is a constant string, so we don't have to copy it */
                // XXX - ui/gtk/packet_list_store.c uses G_MAXUSHORT. We don't do proper UTF8
                // truncation in either case.
                int col_text_len = MIN(qstrlen(cinfo->col_data[column]) + 1, COL_MAX_INFO_LEN);
                col_text_.append(QByteArray::fromRawData(cinfo->columns[column].col_data, col_text_len));
                break;
            }
            /* !! FALL-THROUGH!! */

        case COL_DEF_SRC:
        case COL_RES_SRC:        /* COL_DEF_SRC is currently just like COL_RES_SRC */
        case COL_UNRES_SRC:
        case COL_DEF_DL_SRC:
        case COL_RES_DL_SRC:
        case COL_UNRES_DL_SRC:
        case COL_DEF_NET_SRC:
        case COL_RES_NET_SRC:
        case COL_UNRES_NET_SRC:
        case COL_DEF_DST:
        case COL_RES_DST:        /* COL_DEF_DST is currently just like COL_RES_DST */
        case COL_UNRES_DST:
        case COL_DEF_DL_DST:
        case COL_RES_DL_DST:
        case COL_UNRES_DL_DST:
        case COL_DEF_NET_DST:
        case COL_RES_NET_DST:
        case COL_UNRES_NET_DST:
        default:
            if (!get_column_resolved(column) && cinfo->col_expr.col_expr_val[column]) {
                /* Use the unresolved value in col_expr_val */
                // XXX Use QContiguousCache?
                col_text_.append(cinfo->col_expr.col_expr_val[column]);
            } else {
                col_text_.append(cinfo->columns[column].col_data);
            }
            break;
        }
#else // MINIMIZE_STRING_COPYING
        const char *col_str;
        if (!get_column_resolved(column) && cinfo->col_expr.col_expr_val[column]) {
            /* Use the unresolved value in col_expr_val */
            col_str = cinfo->col_expr.col_expr_val[column];
        } else {
            int text_col = cinfo_column_.value(column, -1);

            if (text_col < 0) {
                col_fill_in_frame_data(fdata_, cinfo, column, FALSE);
            }
            col_str = cinfo->columns[column].col_data;
        }
        // g_string_chunk_insert_const manages a hash table of pointers to
        // strings:
        // https://git.gnome.org/browse/glib/tree/glib/gstringchunk.c
        // We might be better off adding the equivalent functionality to
        // wmem_tree.
        col_text_.append(g_string_chunk_insert_const(string_pool_, col_str));
        for (int i = 0; col_str[i]; i++) {
            if (col_str[i] == '\n') col_lines++;
        }
        if (col_lines > lines_) {
            lines_ = col_lines;
            line_count_changed_ = true;
        }
#endif // MINIMIZE_STRING_COPYING
    }
}