97b26985 |
1 | #ifndef TAPE_BLOCK_H |
2 | #define TAPE_BLOCK_H |
3 | |
4 | |
5 | /*! |
6 | *\brief Tape data block base class |
7 | * |
8 | * This class represents a Honeywell paper tape block. |
9 | * That may be some kind of data block or a end of tape mark. |
10 | */ |
11 | class tape_block{ |
12 | |
13 | public: // types |
14 | |
15 | /*! |
16 | * The block's initialisation state |
17 | */ |
18 | typedef enum { |
19 | TBS_OK, //!< Block successfully initialised |
20 | TBS_EOF_LEGAL, //!< Legal EOF while initialising |
21 | TBS_EOF_ILLEGAL, //!< Illegal EOF while initialising |
22 | TBS_CHECKSUM, //!< Checksum error |
23 | TBS_IOERR, //!< I/O-Error while reading |
24 | TBS_DEFAULT //!< Block not initialised. |
25 | } tb_state_t; |
26 | |
27 | /*! |
28 | * Tape block types |
29 | */ |
30 | typedef enum { |
31 | TBT_DATA=0x10, //!< Data block |
32 | TBT_EOT, //!< End of tape block |
33 | TBT_DISCARD //!< Invalid block, check block_type |
34 | } tb_type_t; |
35 | |
36 | protected: // methods |
37 | /*! |
38 | *\brief Protected default constructor |
39 | */ |
40 | tape_block(); |
41 | |
42 | public: // methods |
43 | |
44 | tape_block(tape_block &); |
45 | |
46 | /*! |
47 | *\brief Read-in constructor for file descriptor |
48 | * |
49 | * This constructor is used to read in the block's data via a file |
50 | * descriptor.\\ |
51 | * This is done in the following way:\\ |
52 | * - input_start() is called.\\ |
53 | * - Data is read from fd. Stops on end of file or end of block |
54 | * or IO error. On EOF or IO error input_stop() is NOT called.\\ |
55 | * - If there was no IO error the block's checksum is calculated |
56 | * and checked.\ |
57 | * - The block's type field is initialised.\\ |
58 | * - input_stop() is called.\\ |
59 | *\param fd_p A pointer to the device descriptor where |
60 | * the data is taken from \\ |
61 | *\param input_stop A pointer to a function called at the end of input\\ |
62 | *\param input_start A pointer to a function called at the beginning |
63 | * of input\\ |
64 | *\param start_stop_arg A pointer passed to input_start and input_stop(). |
65 | */ |
66 | tape_block (int fd_p, |
67 | void(*input_start)(void *)=0, |
68 | void (*input_stop)(void *)=0, |
69 | void * start_stop_arg=0 |
70 | ); |
71 | |
72 | /*! |
73 | * The virtual destructor |
74 | */ |
75 | virtual ~tape_block(); |
76 | |
77 | /*! |
78 | *\brief Query the block's state. |
79 | * |
80 | * If the state is not TBS_OK, the block must be discarded. |
81 | *\return The block's initialisation state |
82 | */ |
83 | tb_state_t get_state(); |
84 | |
85 | /*! |
86 | *\brief Get size of the internal raw data buffer |
87 | *\return The size of the internal raw data buffer |
88 | */ |
89 | int get_raw_size(); |
90 | |
91 | /*! |
92 | *\brief Access internal raw data buffer |
93 | * |
94 | * The raw data buffer contains all block data except the \\ |
95 | * block start delimiter and block end delimiter. |
96 | *\return Pointer to internal raw data buffer of the block |
97 | */ |
98 | unsigned char * get_raw_data(); |
99 | |
100 | /* |
101 | *\brief Determine the block's type |
102 | * |
103 | * This routine returns the block's type.\\ |
104 | *\retval TBT_DATA if it's a data block |
105 | *\retval TBT_EOT if it's an end of tape mark |
106 | *\retval TBR_DISCARD if the block is unusable |
107 | * |
108 | *\note This function is virtual. That means that if the tape block in |
109 | * question is of the subtype data_block which overwrites this method, |
110 | * it will return the block type contained in the upper 4 bits of the |
111 | * first data word! Try to avoid testing for TBT_DATA. |
112 | */ |
113 | virtual int get_type(); |
114 | |
115 | /*! |
116 | *\brief Determine the block's subtype |
117 | * |
118 | * Some data block types have a subtype. This can be determined this way. |
119 | *\return Block subtype if the block object is of a suitable subclass |
120 | */ |
121 | virtual int get_subtype(); |
122 | |
123 | private: // methods |
124 | /*! |
125 | *\brief Initialize word representation of data |
126 | *\retval 0 on success |
127 | *\retval 1 on error |
128 | */ |
129 | int init_words(void); |
130 | |
131 | /*! |
132 | *\brief Calculate and check checksum |
133 | *\retval 0 on success |
134 | *\retval 1 on error |
135 | */ |
136 | int test_checksum(); |
137 | |
138 | protected: // members |
139 | int block_type; //!< type of this block |
140 | tb_state_t init_state; //!< Initialisation state |
141 | int data_read; //!< Total data consumption during intialisation |
142 | unsigned char * raw_data; //!< Raw block data in bytes |
143 | int raw_size; //!< Size of the raw data |
144 | unsigned short * word_data; //!< Data organized in machine words |
145 | int word_size; //!< Size of the blocks in machine words |
146 | |
147 | }; // tape_block |
148 | |
149 | |
150 | #endif |