source: projects/punch-card/punch-card-editor/src/text/codec.cc @ 52

Last change on this file since 52 was 52, checked in by sven, 10 years ago

Punch Card Editor: Code reordering and class renaming, rewriting.
Now using the namespace QPunchCard everywhere.

Parted the whole application into 5 parts/directories:

  • app: The application core with MainWindow and main() function
  • qpunchcard: Everything directly binary card related (no interpretation): modeling, input/output, view. Most important classes are Card, Deck, FileFormat, Widget
  • text: Everything related to text interpretation of Cards/Card Decks. Having the abstract Codec classes and the Text::Editor, Text::EditorDock
  • deckviewer: Application components like binary card editing central widget (CardEditor) and Navigator (Model View Controller classes)
  • driver: Basis for the driver framework, must be written soon.

Deck now hides the complete Storage to implement frontend methods that
implement versioning (Undo framework). All code was cleaned up, but doesn't
compile right now (still quite some non heavy errors).

-- Sven @ workstation

File size: 3.6 KB
Line 
1#include <QDebug>
2#include <QHash>
3#include <QMap>
4#include <QSharedPointer>
5
6#include "codec.h"
7#include "text/cardcodes.h"
8
9using namespace QPunchCard;
10
11QString Codec::toAscii(const Card* target_card) const {
12        QString ret;
13        for(int x = 0; x < target_card->length(); x++) {
14                ret += toAscii( &target_card->get(x) );
15        }
16        return ret;
17}
18
19void Codec::fromAscii(const QString& string, Card* target_card) const {
20        if(string.count() > 80) {
21                qDebug() << "Codec: String has "<< string.count() << " chars, will translate 80: "
22                         << string << "<<END";
23        }
24        Q_ASSERT(target_card != 0);
25        for(int x = 0; x < qMin(target_card->length(), string.count()); x++) {
26                target_card->get(x) = fromAscii( string[x].toAscii() );
27        }
28}
29
30bool Codec::canEncode(const QString& string) const {
31        for(int x = 0; x < string.count(); x++) {
32                if(!canEncode( string[x].toAscii() ))
33                        return false;
34        }
35        return true;
36}
37
38int Codec::countIllegalColumns(const Card* card) const {
39        int fail;
40        for(int x = 0; x < card->length(); x++) {
41                if( !canEncode(card->get(x)) )
42                        fail++;
43        }
44        return fail;
45}
46
47int Codec::countIllegalColumns(const Deck* deck) const {
48        int fail;
49        for(int x = 0; x < deck->count(); x++) {
50                fail += countIllegalColumns(&deck->at(x));
51        }
52        return fail;
53}
54
55CharArrayCodec::CharArrayCodec(const int* table, char illegal) : Codec(illegal), table(table) {
56        // Inverse Tabelle (ASCII -> Column-Tabelle) erstellen
57        if(!table) {
58                // uhh... miserable failure. Sehr schlecht.
59                qDebug() << "CharArrayCodec: Table is NULL! This will *CRASH* application!";
60                //this->table = o29_code;
61        }
62
63        for(int i = 0; i < 4096; i++) {
64                // Illegal characters setzen
65                inverse_table[i] = illegal;
66        }
67
68        for(char c = ' '; c < '`'; c++) {
69                inverse_table[ this->table[c] ] = c;
70        }
71}
72
73QList<QString> CodecFactory::availableCodecs() {
74        QList<QString> list;
75        list << "o29_code" << "o29_ftn_code" << "o26_comm_code";
76        return list;
77}
78
79const Codec* CodecFactory::createCodec(const QString& name, char illegal) {
80        if("o29_code" == name)
81                return new CharArrayCodec(o29_code, illegal);
82        else if("o26_ftn_code" == name)
83                return new CharArrayCodec(o26_ftn_code, illegal);
84        else if("o26_comm_code" == name)
85                return new CharArrayCodec(o26_comm_code, illegal);
86        else {
87                qDebug() << QString("Codec '%s' not supported!").arg(name);
88                return NULL;
89        }
90}
91
92static const QString autoDetectCodec(const Card* card) {
93        QMap<int, QString> bad_chars;
94
95        // alle moeglichen Codec-Namen kriegen
96        QList<QString> codec_names = CodecFactory::availableCodecs();
97        // ueber alle Codecnamen iterieren
98        for(QList<QString>::iterator name = codec_names.begin(); name != codec_names.end(); ++name) {
99                // dieser Pointer loescht das Objekt nach dem Scope:
100                QSharedPointer<const Codec> codec( CodecFactory::createCodec(*name) );
101
102                // Anzahl Bad chars in Map (=> sortiert) speichern
103                bad_chars.insertMulti(codec->countIllegalColumns( card ), *name );
104        }
105
106        // den erstbesten Codec nehmen (da Map nach anzahl schlechter Zeichen sortiert)
107        QString best_code = bad_chars.begin().value();
108        return best_code;
109}
110
111const QString autoDetectCodec(const Deck* deck) {
112        QHash<QString, int> best_codec_counter;
113
114        // alle karten itereieren und hochzaehlen, welcher codec am besten abschnitt
115        for(int x = 0; x < deck->count(); x++) {
116                // INEFFIZIENZ: bei autoDetectCodec wird *jeder* Codec *neu* erstellt.
117                // Loesung: Codec-Caching in der CodecFactory
118                best_codec_counter[ autoDetectCodec(&deck->at(x)) ]++;
119        }
120
121        // besten Wert kriegen
122        QHashIterator<QString, int> i(best_codec_counter);
123        QString min_failes_name;
124        int min_failes = 0;
125        while(i.hasNext()) {
126                i.next();
127                if(i.value() < min_failes) {
128                        min_failes = i.value();
129                        min_failes_name = i.key();
130                }
131        }
132
133        // der ist es
134        return min_failes_name;
135}
Note: See TracBrowser for help on using the repository browser.
© 2008 - 2013 technikum29 • Sven Köppel • Some rights reserved
Powered by Trac
Expect where otherwise noted, content on this site is licensed under a Creative Commons 3.0 License