Subversion Repositories autosfx

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 daniel-mar 1
#include "stdafx.h"
2
#pragma hdrstop
3
 
4
#include "DZRaw.h"
5
 
6
#include <assert.h>
7
#include "dz_errs.h"
8
 
9
#undef _DZ_FILE_
10
#define _DZ_FILE_ DZ_DZRAW_CPP
11
 
12
/* DZRaw.cpp * Copyright (C)  2009 Russell Peters
13
* Permission is granted to any individual or institution to use, copy, or
14
* redistribute this software so long as all of the original files are included,
15
* that it is not sold for profit, and that this copyright notice is retained.
16
** distributed under LGPL license
17
** see license.txt for details
18
 
19
************************************************************************
20
 Copyright (C) 2009, 2010  by Russell J. Peters, Roger Aelbrecht
21
 
22
   This file is part of TZipMaster Version 1.9.
23
 
24
    TZipMaster is free software: you can redistribute it and/or modify
25
    it under the terms of the GNU Lesser General Public License as published by
26
    the Free Software Foundation, either version 3 of the License, or
27
    (at your option) any later version.
28
 
29
    TZipMaster is distributed in the hope that it will be useful,
30
    but WITHOUT ANY WARRANTY; without even the implied warranty of
31
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32
    GNU Lesser General Public License for more details.
33
 
34
    You should have received a copy of the GNU Lesser General Public License
35
    along with TZipMaster.  If not, see <http://www.gnu.org/licenses/>.
36
 
37
    contact: problems@delphizip.org (include ZipMaster in the subject).
38
    updates: http://www.delphizip.org
39
    DelphiZip maillist subscribe at http://www.freelists.org/list/delphizip
40
************************************************************************/
41
 
42
dzraw_imp* __fastcall DZRawData::NewImp(unsigned siz)
43
{
44
    unsigned rawsize = sizeof(dzraw_imp) + siz - (8 * sizeof(char));
45
    if (rawsize & 63)
46
        rawsize = (rawsize | 63) + 1;
47
    if (rawsize > 0xFFF0)
48
        rawsize = 0xFFF0;
49
 
50
    dzraw_imp* _imp = (dzraw_imp*) (new char[rawsize]);
51
    if (! _imp)
52
        throw DZException(DZ_ERM_MEMORY);
53
 
54
    _imp->refs      = 1;
55
        _imp->capacity  = (WORD)((rawsize - sizeof(dzraw_imp)) + (8 * sizeof(char)));
56
        _imp->len       = 0;
57
    return _imp;
58
}
59
 
60
dzraw_imp* DZRawData::NewImp(const unsigned char* src, int Len, int Space)
61
{
62
    if (!src)
63
        Len = 0;
64
    if (Space >= 0 && Len > Space)
65
        Len = Space;
66
 
67
    int siz = (Space >= 0) ? Space : Len;
68
 
69
    if (!siz)
70
        return NULL;    // empty
71
 
72
    dzraw_imp* nimp = NewImp(siz); // make new
73
    if (src && Len)
74
    {
75
        memcpy(nimp->data, src, Len);
76
        nimp->len = (WORD)Len;
77
    }
78
    return nimp;
79
}
80
 
81
void __fastcall DZRawData::Release(void)
82
{
83
    if (imp)
84
    {
85
        if (!DecRefs())
86
        {
87
            void *_imp = imp;
88
            imp = NULL;
89
//            free(_imp);
90
            delete[] _imp;
91
        }
92
        imp = NULL;
93
    }
94
}
95
 
96
int __fastcall DZRawData::IncRefs(void)
97
{
98
    if (imp)
99
        return InterlockedIncrement(&(imp->refs));
100
    return 0;
101
}
102
 
103
int __fastcall DZRawData::DecRefs(void)
104
{
105
    if (imp && imp->refs)
106
        return InterlockedDecrement(&(imp->refs));
107
    return -1;
108
}
109
 
110
void __fastcall DZRawData::Append(const unsigned char* src, int Len)
111
{
112
    if (!src)
113
        Len = 0;
114
 
115
    // check something to append
116
    if (Len)
117
    {
118
        if (!imp)
119
            imp = NewImp(src, Len);
120
        else
121
        {
122
            unsigned nlen = imp->len + Len;
123
            if (nlen > 0xFFF0)
124
                return;
125
 
126
            // do we need a new one
127
            if (imp->refs > 1 || (WORD)nlen > imp->capacity)
128
            {
129
                // need new imp - make copy with enough space
130
                dzraw_imp* nimp = NewImp(imp->data, imp->len, nlen);
131
                Release();      // out with the old
132
                imp = nimp;     // in with the new
133
            }
134
            // append data
135
            unsigned char *bf = &imp->data[imp->len];
136
            memcpy(bf, src, Len);
137
            imp->len = (WORD)nlen;
138
        }
139
    }
140
}
141
 
142
void __fastcall DZRawData::Assign(const unsigned char* src, int Len)
143
{
144
    Release();
145
    imp = NewImp(src, Len);
146
}
147
 
148
unsigned char * __fastcall DZRawData::GetBuffer(unsigned size)
149
{
150
    Release();
151
    imp = NewImp(size);
152
        imp->len = (WORD)size;
153
    return imp->data;
154
}
155
 
156
void __fastcall DZRawData::SetLength(unsigned Len)
157
{
158
    if (!Len)
159
        Release();
160
        else
161
    {
162
        dzraw_imp* nimp;
163
        // do we need a new one
164
        if (!imp || imp->refs > 1 || (WORD)Len > imp->capacity)
165
        {
166
            // need new imp - make copy with enough space
167
            if (!imp)
168
                nimp = NewImp(Len);
169
            else
170
                nimp = NewImp(imp->data, imp->len, Len);
171
            Release();      // out with the old
172
            imp = nimp;     // in with the new
173
        }
174
        imp->len = (WORD)Len;
175
    }
176
}
177
 
178
__fastcall DZRawData::DZRawData(const DZRawData& other)
179
{
180
    imp = NULL;
181
    if (!other.IsEmpty())
182
    {
183
        imp = other.imp;
184
        IncRefs();
185
    }
186
}
187
 
188
__fastcall DZRawData::DZRawData(unsigned size)
189
{
190
    imp = NULL;
191
    if (size)
192
        imp = NewImp(size);
193
}
194
 
195
__fastcall DZRawData::DZRawData(const unsigned char* str, unsigned len)
196
{
197
    imp = NULL;
198
    if (str && len)
199
    {
200
        imp = NewImp(str, len);
201
    }
202
}
203
 
204
unsigned __fastcall DZRawData::Capacity(void) const
205
{
206
    if (imp)
207
        return imp->capacity;
208
    return NULL;
209
}
210
 
211
unsigned __fastcall DZRawData::Length(void) const
212
{
213
    if (imp)
214
        return imp->len;
215
    return 0;
216
}
217
 
218
const unsigned char* DZRawData::begin(void) const
219
{
220
    if (imp)
221
        return imp->data;
222
    return NULL;
223
}
224
 
225
const unsigned char* DZRawData::end(void) const
226
{
227
    if (imp)
228
        return imp->data + imp->len;
229
    return NULL;
230
}
231
 
232
const unsigned char* DZRawData::Find(WORD tag) const
233
{
234
    if (Length() < sizeof(XWord))
235
        return NULL;
236
    const unsigned char *p = begin();
237
    const unsigned char *q;
238
    const unsigned char *e = end();
239
    XWord tg, sz;
240
    while (p + 3 < e)
241
    {
242
        q = p;
243
        tg.b[0] = *p++;
244
        tg.b[1] = *p++;
245
        if (tg.w == tag)
246
            return q;   // found
247
        sz.b[0] = *p++;
248
        sz.b[1] = *p++;
249
        p += sz.w;
250
    }
251
    return NULL;
252
}
253
 
254
DZRawData& __fastcall DZRawData::operator =(const DZRawData& other)
255
{
256
    if (this != &other)
257
    {
258
        Release();
259
        if (!other.IsEmpty())
260
        {
261
            imp = other.imp;
262
            IncRefs();
263
        }
264
    }
265
    return *this;
266
}
267
 
268
DZRawData __fastcall DZRawData::operator +(const DZRawData& other)
269
{
270
    DZRawData res(*this);
271
    res.Append(other.begin(), other.Length());
272
    return res;
273
}
274
 
275
DZRawData& __fastcall DZRawData::operator +=(const DZRawData& other)
276
{
277
    Append(other.begin(), other.Length());
278
    return *this;
279
}
280
 
281
DZRawData& __fastcall DZRawData::operator +=(unsigned char ch)
282
{
283
    Append(&ch, 1);
284
    return *this;
285
}
286
 
287
DZRawData& __fastcall DZRawData::operator +=(WORD w)
288
{
289
    Append((const unsigned char*)&w, sizeof(WORD));
290
    return *this;
291
}
292
 
293
//unsigned char __fastcall DZRawData::operator [](unsigned idx) const
294
//{
295
//    if (!imp || idx >= Length())
296
//        return 0;
297
//    return *(imp + idx);
298
//}
299
 
300
 
301
WORD  __fastcall DZRawData::operator [](unsigned idx) const
302
{
303
    unsigned widx = idx * sizeof(WORD);
304
    if (!imp || widx >= Length() - (sizeof(WORD)-1))
305
        return 0;
306
    return ((WORD*)idx)[idx];
307
}
308
 
309
DZRawData __fastcall DZRawData::operator -(WORD tag)
310
{
311
    DZRawData res(Capacity());
312
    if (imp)
313
    {
314
        const unsigned char *p = begin();
315
        const unsigned char *e = end();
316
        XWord tg, sz;
317
        while (p + 3 < e)
318
        {
319
            tg.b[0] = *p++;
320
            tg.b[1] = *p++;
321
            sz.b[0] = *p++;
322
            sz.b[1] = *p++;
323
 
324
            if (tg.w != tag)
325
            {
326
                res += tg.w;
327
                res += sz.w;
328
 
329
                while (p < e && sz.w-- > 0)
330
                    res += *p++;
331
            }
332
            else
333
                p += sz.w;
334
        }
335
 
336
        while (p < e)
337
            res += *p++;
338
    }
339
    return res;
340
}
341
 
342
 
343
DZRawData& __fastcall DZRawData::operator -=(WORD tag)
344
{
345
    if (Find(tag))
346
    {
347
        DZRawData tmp = (*this) - tag;
348
        (*this) = tmp;
349
    }
350
    return *this;
351
}
352