summaryrefslogtreecommitdiffstats
path: root/kfile-plugins/torrent/bytetape.h
blob: 55fef4b57ff61ea5378c992cdb238b118bf7285b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*
 * Copyright (c) 2003, 2004 Michael Pyne <michael.pyne@kdemail.net>
 *
 * This software is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this library; see the file COPYING.
 * If not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
#ifndef _BYTETAPE_H
#define _BYTETAPE_H

#include <ksharedptr.h>

#include <qcstring.h>

class ByteTapeShared : public KShared
{
    public:

    unsigned int pos;
};

/**
 * Class to simulate a seekable byte stream.  Very similar to QByteArray,
 * but the difference is that this class "knows" what a current position
 * is.  Also, the copy constructor will share the byte stream of the
 * ByteTape being copied.  This means that any copies made of an object of
 * this class will share BOTH the data and the current position.  This is
 * by design.
 *
 * @author Michael Pyne <mpyne@grammarian.homelinux.net>
 * @see QByteArray
 */
class ByteTape
{
    public:
    
    /**
     * Constructs a new ByteTape object from @p array.  The
     * current position will be set to @p pos.
     *
     * @param array a data buffer to use for reading and writing.
     *        The tape will be fixed to the size of this buffer.
     * @param pos the initial position of the tape head.  It must be
     *        a position within the buffer contained in @p array.
     */
    ByteTape (QByteArray &array, int pos = 0);

    /**
     * Creates a ByteTape as a copy of @p tape.  The newly created
     * object will share both data and the current position with @p tape.
     * This is done using reference counts.
     *
     * @param tape the ByteTape to copy
     */
    ByteTape (const ByteTape &tape);

    /**
     * Increments the current position by @p i.  It is the responsibility
     * of the function caller to ensure that the new position is in bounds.
     * The position will be capped to remain in bounds regardless.
     *
     * @param i the amount to increment the current position by
     * @return t reference to the object incremented
     */
    ByteTape & operator += (const unsigned int i);

    /**
     * Decrements the current position by @p i.  It is the responsibility
     * of the function caller to ensure that the new position is in bounds.
     * Unlike a real Turing machine, attempting to decrement past the
     * start will be capped to the beginning instead of crashing the
     * computer.
     *
     * @param i the amount to decrement the current position by
     * @return a reference to the object decremented
     */
    ByteTape & operator -= (const unsigned int i);

    /**
     * Increments the current position by 1.  This is a postfix
     * operator (i++).  The current position will be capped to the end
     * of the buffer.
     *
     * @return the object before the increment operation
     */
    ByteTape operator ++ (int);

    /**
     * Increments the current position by 1.  This is a prefix
     * operator (++i).  The current position will be capped to the end
     * of the buffer.
     *
     * @return a reference to the object incremented
     */
    ByteTape & operator ++ ();
    
    /**
     * Decrements the current position by 1.  This is a postfix
     * operator (i--).  The current position will be capped to the start
     * of the buffer.
     *
     * @return the object before the decrement operation
     */
    ByteTape operator -- (int);

    /**
     * Decrements the current position by 1.  This is a prefix
     * operator (--i).  The current position will be capped to the start
     * of the buffer.
     *
     * @return a reference to the object decremented
     */
    ByteTape & operator -- ();
    
    /**
     * Returns the byte within the array indexed by @p i.  It is
     * the responsibility of the caller to ensure that @p i is in bounds.
     * Although out-of-range errors will be detected, no exceptions will
     * be thrown.  Since a reference is not returned, you won't be able
     * to assign to the result.  Example: tape[i] = 'a' will not work.
     *
     * The reason a reference isn't returned is because no exceptions are
     * thrown by this class, and we can't return a reference to an out-of-
     * bounds character.
     *
     * @param i the index of the byte to return
     * @return the byte at the given index.  0 may be returned on error,
     *         but does not necessarily indicate an error.
     */
    char operator [] (const unsigned int i);

    /**
     * Returns the byte at the tape's current position.  You can assign
     * to the reference returned.
     *
     * @return a reference to the byte at the tape head's current position
     */
    char &operator * ();

    /**
     * Returns the position in memory of data at the given index, @p i.
     * Unlike operator [], this function returns a pointer, so it can be
     * used to access memory.
     *
     * @param i index of the byte to lookup.
     * @return 0 if @p i is out of range, else the address of memory
     *         at that index
     */
    char *at(const unsigned int i);

    /**
     * Returns the current position of the tape head.
     *
     * @return the tape head's current position
     */
    unsigned int pos() const { return m_shared->pos; }

    /**
     * Sets the current position of the tape head to @p pos.  If the
     * position given is out-of-bounds, it will be capped to be within
     * the array.
     *
     * @param pos the new position of the tape head
     * @return whether the set operation was successful
     */
    bool setPos(unsigned int pos);

    /**
     * Returns a reference to the QByteArray used to hold all the data.
     *
     * @return the QByteArray used to hold the data
     * @see QByteArray
     */
    QByteArray &data() { return m_array; }

    private:
    QByteArray &m_array; 
    KSharedPtr<ByteTapeShared> m_shared;
};

#endif /* _BYTETAPE_H */

// vim: set et ts=4 sw=4: