source: projects/punch-card/punch-card-editor/src/qpunchcard/format.cc @ 44

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

Import of the Punch Card Editor Project.
This is a C++/Qt project (using qmake) that I've started this weekend.
Of course it's supposed to be released as open source.

I've tried to start with a clean (but now still empty, of course)
directory structure. There will come the sourcecode for a complete
AVR ATmega microcontroller punch card device controller, soon.
I'm planing to finish this editing program and to implement the
communication protocol (over TTY, using some platform indepentent library).
Unfortunately that will take some time (and I don't have much time
any more...)

-- Sven @ workstation

File size: 4.4 KB
Line 
1#include "format.h"
2#include <QDebug>
3
4using namespace QPunchCard;
5
6FileFormat* QPunchCard::autoDetectFileFormat(const QFile&) {
7        // geht soweit ganz einfach:
8        return new JonesFileFormat();
9        /*JonesFileFormat* n = new JonesFileFormat();
10        n->file = new QFile( file.fileName(), n ); // super copy ;-)
11        return n;*/
12}
13
14bool JonesFileFormat::read(QFile& file) {
15        qDebug() << "Jones reading";
16
17        if(!file.isOpen()) {
18                // oeffne Datei
19                if(! file.open(QIODevice::ReadOnly))
20                        return false;
21        }
22
23        // ohne Deck geht gar nix
24        if(!deck)
25                return false;
26
27        // Now we have an open file at `file`. Use
28        // QIODevice methods:
29
30        // At first, check the file prefix (magic bytes)
31        char char1, char2, char3;
32        file.getChar(&char1);
33        file.getChar(&char2);
34        file.getChar(&char3);
35        if( (char1 == 'H') && (char2 == '8') && (char3 == '0') ) {
36                //this.default_col_length = 80; // hum... nice
37        } else if ((char1 == 'H') && (char2 == '8') && (char3 == '2')) {
38                //this.default_col_length = 82;
39                return false; // hum... bad
40        } else {
41                // Fehler spezifizieren...:
42                // Input file not a card file
43                return false;
44        }
45
46        // Process card deck
47        while( file.bytesAvailable() > 0 ) {
48                Card* cur_card = new Card();
49                // try to read in 120 (body) + 3 (header) bytes
50                QByteArray data = file.read(123);
51
52                if( ((data[0] & 0x08) == 0)
53                 || ((data[1] & 0x08) == 0)
54                 || ((data[2] & 0x08) == 0)) {
55                        // This card was corrupt or there were no more data.
56                        // Break it. Don't save the current card any more.
57                        break;
58                }
59
60                /* This algorithm is based on the C algorithm
61                   of Jones */
62                int x = 3;
63                for(int cur_col = 0; cur_col < 80; ) {
64                        /* read in 3 bytes */
65                        int first = data[x++];
66                        int second = data[x++];
67                        int third = data[x++];
68
69                        /* convert to 2 columns */
70                        int even_col = (first << 4) | (second >> 4);
71                        int odd_col = ((second & 0017) << 8) | third;
72
73                        /* save the columns in the card */
74                        // This is integer => Column conversion with
75                        // implicit knowledge that this followes the
76                        // Jones file format
77                        cur_card->column[cur_col++] = jones_integer_to_column(even_col);
78                        cur_card->column[cur_col++] = jones_integer_to_column(odd_col);
79                }
80
81                /* push card on the card deck*/
82                deck->push_back(cur_card);
83        } // while ! eof
84
85        file.close();
86        return true;
87} // jones reader
88
89// jones writer
90bool JonesFileFormat::write(QFile& file) {
91        qDebug() << "Jones writing";
92
93        if(!file.isOpen()) {
94                // oeffne Datei
95                if(! file.open(QIODevice::WriteOnly))
96                        return false;
97        }
98
99        // nen Deck brauchen wir natuerlich auch schon
100        if(!deck)
101                return false;
102
103        int col_length = 80;
104
105        // Write out file prefix
106
107        file.putChar('H');
108        file.putChar('8');
109        file.putChar(col_length==80 ? '0' : '2');
110
111        //QVector::iterator i;
112
113        //for(i = begin(); i != end(); i++ ) {
114        for(int i=0; i < deck->count(); i++) {
115                // iterate throught the Cards
116                // erhmm... write a header...
117                file.putChar(0x80);
118                file.putChar(0x80);
119                file.putChar(0x80);
120
121                //int cur_col = 0;
122                //int max_col = i->col_length;
123
124                //while(cur_col < max_col) {
125                for(int cur_col = 0; cur_col < 80; ) {
126                        char first, second, third;
127
128                        int even = jones_column_to_integer( deck->at(i)->get(cur_col++) );
129                        int odd = jones_column_to_integer( deck->at(i)->get(cur_col++) );
130
131                        first = even >> 4;
132                        second = ((even & 017) << 4) | (odd >> 8);
133                        third = odd & 00377;
134
135                        file.putChar(first);
136                        file.putChar(second);
137                        file.putChar(third);
138                } // while columns
139        } // for cards
140
141        file.close();
142        return true; // done.
143} // jones writer
144
145/**
146 * Like Douglas Jones says in his punchcard proposal:
147 *
148 *     Top                  Bottom
149 *       _ _ _ _ _ _ _ _ _ _ _ _
150 *      |_|_|_|_|_|_|_|_|_|_|_|_|
151 *     12 11 0 1 2 3 4 5 6 7 8 9
152 *      |     |                 |
153 *      |Zone |     Numeric     |
154 *
155 **/
156int JonesFileFormat::jones_column_to_integer(const Column& col) {
157        static const int Mapping[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 14, 10, 11 };
158        // where 14 is a dummy position outside the range since column[10] is also
159        // a dummy position ;-)
160
161        int r;
162        for(int i = 0; i < (int)sizeof(Mapping); i++)
163                r |= (col[i] << Mapping[i]);
164        return r;
165}
166
167Column JonesFileFormat::jones_integer_to_column(int data) {
168        static const int Mapping[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 14, 10, 11 };
169        // where 14 is a dummy position outside the range since column[10] is also
170        // a dummy position ;-)
171
172        // this is just the inverse...
173        Column r;
174        for(int i = 0; i < (int)sizeof(Mapping); i++) {
175                r[i] = ( (1 << Mapping[i]) & data != 0 );
176        }
177        return r;
178}
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