~ubuntu-branches/ubuntu/karmic/gnash/karmic

« back to all changes in this revision

Viewing changes to libamf/buffer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2008-10-13 14:29:49 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20081013142949-f6qdvnu4mn05ltdc
Tags: 0.8.4~~bzr9980-0ubuntu1
* new upstream release 0.8.4 (LP: #240325)
* ship new lib usr/lib/gnash/libmozsdk.so.* in mozilla-plugin-gnash
  - update debian/mozilla-plugin-gnash.install
* ship new lib usr/lib/gnash/libgnashnet.so.* in gnash-common
  - update debian/gnash-common.install
* add basic debian/build_head script to build latest CVS head packages.
  - add debian/build_head
* new sound architecture requires build depend on libsdl1.2-dev
  - update debian/control
* head build script now has been completely migrated to bzr (upstream +
  ubuntu)
  - update debian/build_head
* disable kde gui until klash/qt4 has been fixed; keep kde packages as empty
  packages for now.
  - update debian/rules
  - debian/klash.install
  - debian/klash.links
  - debian/klash.manpages
  - debian/konqueror-plugin-gnash.install
* drop libkonq5-dev build dependency accordingly
  - update debian/control
* don't install headers manually anymore. gnash doesnt provide a -dev
  package after all
  - update debian/rules
* update libs installed in gnash-common; libgnashserver-*.so is not available
  anymore (removed); in turn we add the new libgnashcore-*.so
  - update debian/gnash-common.install
* use -Os for optimization and properly pass CXXFLAGS=$(CFLAGS) to configure
  - update debian/rules
* touch firefox .autoreg in postinst of mozilla plugin
  - update debian/mozilla-plugin-gnash.postinst
* link gnash in ubufox plugins directory for the plugin alternative switcher
  - add debian/mozilla-plugin-gnash.links
* suggest ubufox accordingly
  - update debian/control
* add new required build-depends on libgif-dev
  - update debian/control
* add Xb-Npp-Description and Xb-Npp-File as new plugin database meta data
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 
 
2
//   Copyright (C) 2008 Free Software Foundation, Inc.
 
3
// 
 
4
// This program is free software; you can redistribute it and/or modify
 
5
// it under the terms of the GNU General Public License as published by
 
6
// the Free Software Foundation; either version 3 of the License, or
 
7
// (at your option) any later version.
 
8
// 
 
9
// This program is distributed in the hope that it will be useful,
 
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
// GNU General Public License for more details.
 
13
//
 
14
// You should have received a copy of the GNU General Public License
 
15
// along with this program; if not, write to the Free Software
 
16
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
17
//
 
18
 
 
19
#include <boost/cstdint.hpp>
 
20
#include <iostream>
 
21
#include "buffer.h"
 
22
#include "amf.h"
 
23
#include "log.h"
 
24
#include "network.h"
 
25
 
 
26
using namespace std;
 
27
using namespace gnash;
 
28
 
 
29
namespace amf
 
30
{
 
31
 
 
32
#if 0
 
33
// convert an ascii hex digit to a number.
 
34
//      param is hex digit.
 
35
//      returns a decimal digit.
 
36
Network::byte_t
 
37
hex2digit (Network::byte_t digit)
 
38
{  
 
39
    if (digit == 0)
 
40
        return 0;
 
41
    
 
42
    if (digit >= '0' && digit <= '9')
 
43
        return digit - '0';
 
44
    if (digit >= 'a' && digit <= 'f')
 
45
        return digit - 'a' + 10;
 
46
    if (digit >= 'A' && digit <= 'F')
 
47
        return digit - 'A' + 10;
 
48
    
 
49
    // shouldn't ever get this far
 
50
    return -1;
 
51
}
 
52
 
 
53
// Convert the hex array pointed to by buf into binary to be placed in mem
 
54
Buffer *
 
55
Buffer::hex2mem(const char *str)
 
56
{
 
57
    size_t count = strlen(str);
 
58
    Network::byte_t ch = 0;
 
59
    _ptr = new Buffer((count/3)+1);
 
60
//    buf->clear();
 
61
 
 
62
    Network::byte_t *strdata = const_cast<Network::byte_t *>(reinterpret_cast<const Network::byte_t *>(str));
 
63
    
 
64
    for (size_t i=0; i<count; i++) {
 
65
        if (*strdata == ' ') {      // skip spaces.
 
66
            strdata++;
 
67
            continue;
 
68
        }
 
69
        ch = hex2digit(*strdata++) << 4;
 
70
        ch |= hex2digit(*strdata++);
 
71
        append(ch);
 
72
    }
 
73
    return _ptr;
 
74
}
 
75
#endif
 
76
 
 
77
void *
 
78
Buffer::init(size_t nbytes)
 
79
{
 
80
//    GNASH_REPORT_FUNCTION;
 
81
    if (_ptr == 0) {
 
82
        _ptr = new Network::byte_t[nbytes];
 
83
        _seekptr = _ptr;
 
84
        if (_ptr == 0) {
 
85
            return _ptr;
 
86
        }
 
87
        _nbytes = nbytes;
 
88
    }
 
89
 
 
90
#ifdef USE_STATS_BUFFERS
 
91
    clock_gettime (CLOCK_REALTIME, &_stamp);
 
92
#endif
 
93
    return _ptr;
 
94
}
 
95
 
 
96
Buffer::Buffer() 
 
97
    : _seekptr(0),
 
98
      _ptr(0)
 
99
{
 
100
//    GNASH_REPORT_FUNCTION;
 
101
    _nbytes = gnash::NETBUFSIZE;
 
102
    init(gnash::NETBUFSIZE);
 
103
}
 
104
    
 
105
// Create with a size other than the default
 
106
Buffer::Buffer(size_t nbytes)
 
107
    : _seekptr(0),
 
108
      _ptr(0)
 
109
{
 
110
//    GNASH_REPORT_FUNCTION;
 
111
    _nbytes = nbytes;
 
112
    init(nbytes);
 
113
}
 
114
 
 
115
// Delete the allocate memory
 
116
Buffer::~Buffer()
 
117
{
 
118
//    GNASH_REPORT_FUNCTION;
 
119
    if (_ptr) {
 
120
#ifdef USE_STATS_BUFFERS
 
121
        struct timespec now;
 
122
        clock_gettime (CLOCK_REALTIME, &now);
 
123
        log_debug("Buffer %x (%d) stayed in queue for %f seconds",
 
124
                  (void *)_ptr, _nbytes,
 
125
                  (float)((now.tv_sec - _stamp.tv_sec) + ((now.tv_nsec - _stamp.tv_nsec)/1e9)));
 
126
#endif
 
127
        delete[] _ptr;
 
128
        _seekptr = _ptr = 0;
 
129
        _nbytes = 0;
 
130
    }
 
131
}
 
132
 
 
133
// Put data into the buffer
 
134
void
 
135
Buffer::copy(Network::byte_t *data, size_t nbytes)
 
136
{    
 
137
//    GNASH_REPORT_FUNCTION;
 
138
    std::copy(data, data + nbytes, _ptr);
 
139
    _seekptr = _ptr + nbytes;
 
140
}
 
141
 
 
142
void
 
143
Buffer::copy(const string &str)
 
144
{    
 
145
//    GNASH_REPORT_FUNCTION;
 
146
    std::copy(str.begin(), str.end(), _ptr);
 
147
    _seekptr = _ptr + str.size();
 
148
}
 
149
 
 
150
void
 
151
Buffer::copy(boost::uint16_t length)
 
152
{
 
153
    Network::byte_t *data = reinterpret_cast<Network::byte_t *>(&length);
 
154
    std::copy(data, data + sizeof(boost::uint16_t), _ptr);    
 
155
    _seekptr = _ptr + sizeof(boost::uint16_t);
 
156
}
 
157
 
 
158
void
 
159
Buffer::copy(double num)
 
160
{
 
161
//    GNASH_REPORT_FUNCTION;
 
162
    Network::byte_t *ptr = reinterpret_cast<Network::byte_t *>(&num);
 
163
    std::copy(ptr, ptr + amf::AMF0_NUMBER_SIZE, _ptr);    
 
164
    _seekptr = _ptr + amf::AMF0_NUMBER_SIZE;
 
165
}
 
166
 
 
167
void
 
168
Buffer::copy(Network::byte_t val)
 
169
{
 
170
    GNASH_REPORT_FUNCTION;
 
171
    *_ptr = val;
 
172
    _seekptr = _ptr + sizeof(bool);
 
173
}
 
174
 
 
175
#if 0
 
176
void
 
177
Buffer::copy(bool val)
 
178
{
 
179
    GNASH_REPORT_FUNCTION;
 
180
    return copy(static_cast<Network::byte_t>(val));
 
181
}
 
182
#endif
 
183
 
 
184
Network::byte_t *
 
185
Buffer::append(boost::uint16_t length)
 
186
{
 
187
//    GNASH_REPORT_FUNCTION;
 
188
    
 
189
    if ((_seekptr + sizeof(boost::uint16_t)) <= (_ptr + _nbytes)) {
 
190
        Network::byte_t *data = reinterpret_cast<Network::byte_t *>(&length);
 
191
        std::copy(data, data + sizeof(boost::uint16_t), _seekptr);
 
192
        _seekptr += sizeof(boost::uint16_t);
 
193
        return _seekptr;
 
194
    }
 
195
    return 0;
 
196
}
 
197
 
 
198
Network::byte_t *
 
199
Buffer::append(gnash::Network::byte_t *data, size_t nbytes)
 
200
{
 
201
//    GNASH_REPORT_FUNCTION;
 
202
 
 
203
    if ((_seekptr + nbytes) <= (_ptr + _nbytes)) {
 
204
        std::copy(data, data + nbytes, _seekptr);    
 
205
        _seekptr += nbytes;
 
206
        return _seekptr;
 
207
    }
 
208
    return 0;
 
209
}
 
210
 
 
211
Network::byte_t *
 
212
Buffer::append(double num)
 
213
{
 
214
//    GNASH_REPORT_FUNCTION;
 
215
    if ((_seekptr + sizeof(double)) <= (_ptr + _nbytes)) {
 
216
        Network::byte_t *ptr = reinterpret_cast<Network::byte_t *>(&num);
 
217
        std::copy(ptr, ptr + amf::AMF0_NUMBER_SIZE, _seekptr);    
 
218
        _seekptr += amf::AMF0_NUMBER_SIZE;
 
219
        return _seekptr;
 
220
    }
 
221
    return 0;
 
222
}
 
223
 
 
224
Network::byte_t *
 
225
Buffer::append(bool val)
 
226
{
 
227
//    GNASH_REPORT_FUNCTION;
 
228
    if ((_seekptr + sizeof(bool)) <= (_ptr + _nbytes)) {
 
229
        *_seekptr = val;
 
230
        _seekptr += sizeof(bool);
 
231
        return _seekptr;
 
232
    }
 
233
    return 0;
 
234
}
 
235
 
 
236
Network::byte_t *
 
237
Buffer::append(boost::uint32_t num)
 
238
{
 
239
//    GNASH_REPORT_FUNCTION;
 
240
    Network::byte_t *ptr = reinterpret_cast< Network::byte_t *>(&num);    
 
241
    return append(ptr, sizeof(boost::uint32_t));
 
242
}
 
243
 
 
244
Network::byte_t *
 
245
Buffer::append(Network::byte_t byte)
 
246
{
 
247
//    GNASH_REPORT_FUNCTION;
 
248
    if ((_seekptr + sizeof(gnash::Network::byte_t)) <= (_ptr + _nbytes)) {
 
249
        *_seekptr = byte;
 
250
        _seekptr += sizeof(gnash::Network::byte_t);
 
251
        return _seekptr;
 
252
    }
 
253
    return 0;
 
254
}
 
255
 
 
256
Network::byte_t *
 
257
Buffer::append(const std::string &str)
 
258
{
 
259
//    GNASH_REPORT_FUNCTION;
 
260
    if ((_seekptr + str.size()) <= (_ptr + _nbytes)) {
 
261
        std::copy(str.begin(), str.end(), _seekptr);    
 
262
        _seekptr += str.size();
 
263
        return _seekptr;
 
264
    }
 
265
    return 0;
 
266
}
 
267
 
 
268
Network::byte_t *
 
269
Buffer::append(amf::Element::amf0_type_e type)
 
270
{
 
271
    return append(static_cast<Network::byte_t>(type));
 
272
}
 
273
 
 
274
Network::byte_t *
 
275
Buffer::append(Buffer &buf)
 
276
{
 
277
//    GNASH_REPORT_FUNCTION;
 
278
    return append(&buf);
 
279
}
 
280
 
 
281
Network::byte_t *
 
282
Buffer::append(Buffer *buf)
 
283
{
 
284
//    GNASH_REPORT_FUNCTION;
 
285
    size_t diff = _seekptr - _ptr;
 
286
    
 
287
    if (buf->size() > (_nbytes - diff)) {
 
288
         resize(buf->size() + diff);
 
289
    }
 
290
    
 
291
    std::copy(buf->begin(), buf->end(), _seekptr);
 
292
    _seekptr += buf->size();
 
293
 
 
294
    return _seekptr;
 
295
}
 
296
 
 
297
// make ourselves be able to appended too. If the source
 
298
// buffer is larger than the current buffer has room for,
 
299
// resize ourselves (which copies the data too) to make
 
300
// enough room.
 
301
// note that using this may have a performance hit due to
 
302
// the resize operation, which has to copy data.
 
303
Buffer &
 
304
Buffer::operator+=(Buffer &buf)
 
305
{
 
306
    return operator+=(&buf);
 
307
}
 
308
 
 
309
Buffer &
 
310
Buffer::operator+=(Buffer *buf)
 
311
{
 
312
//    GNASH_REPORT_FUNCTION;
 
313
    size_t diff = 0;
 
314
    if (buf->size() >= _nbytes) {
 
315
        diff = _seekptr - _ptr;
 
316
        resize(buf->size() + diff);
 
317
    }
 
318
    
 
319
    if ((_seekptr + buf->size()) <= (_ptr + _nbytes)) {
 
320
        std::copy(buf->begin(), buf->end(), _seekptr);
 
321
        _seekptr += buf->size();
 
322
    }
 
323
    return *this;
 
324
}
 
325
 
 
326
Buffer &
 
327
Buffer::operator+=(char byte)
 
328
{
 
329
//    GNASH_REPORT_FUNCTION;
 
330
    return operator+=(static_cast<Network::byte_t>(byte));
 
331
}
 
332
 
 
333
Buffer &
 
334
Buffer::operator+=(Network::byte_t byte)
 
335
{
 
336
//    GNASH_REPORT_FUNCTION;
 
337
    if ((_seekptr + 1) <= (_ptr + _nbytes)) {
 
338
        *_seekptr = byte;
 
339
        _seekptr += sizeof(char);
 
340
    }
 
341
    return *this;
 
342
}
 
343
 
 
344
// make ourselves be able to be copied.
 
345
Buffer &
 
346
Buffer::operator=(Buffer *buf)
 
347
{
 
348
//    GNASH_REPORT_FUNCTION;
 
349
    if (buf->size() > _nbytes) {
 
350
         resize(buf->size());
 
351
    }
 
352
    
 
353
    std::copy(buf->begin(), buf->end(), _ptr);
 
354
    _seekptr += buf->size();
 
355
 
 
356
    return *this;
 
357
}
 
358
 
 
359
Buffer &
 
360
Buffer::operator=(Buffer &buf)
 
361
{
 
362
//    GNASH_REPORT_FUNCTION;
 
363
    if (buf.size() != _nbytes) {
 
364
         resize(buf.size());
 
365
    }
 
366
    
 
367
    std::copy(buf.begin(), buf.end(), _ptr);
 
368
 
 
369
    return *this;
 
370
}
 
371
 
 
372
// Check to see if two Buffer objects are identical
 
373
bool
 
374
Buffer::operator==(Buffer *buf)
 
375
 
376
//    GNASH_REPORT_FUNCTION;
 
377
    Network::byte_t *bufptr = buf->reference();
 
378
    if (buf->size() == _nbytes) {
 
379
        if (memcmp(bufptr, _ptr, _nbytes) == 0)  {
 
380
            return true;
 
381
        }
 
382
    }
 
383
    return false;
 
384
}
 
385
 
 
386
bool
 
387
Buffer::operator==(Buffer &buf)
 
388
{
 
389
//    GNASH_REPORT_FUNCTION;
 
390
//     Network::byte_t *bufptr = buf.reference();
 
391
//     size_t max = 0;
 
392
    
 
393
//     if (buf.size() == _nbytes){
 
394
//         if (memcmp(bufptr, _ptr, _nbytes) == 0) {
 
395
//             return true;
 
396
//         }
 
397
//     }
 
398
//     return false;
 
399
    return operator==(&buf);
 
400
}
 
401
 
 
402
Network::byte_t *
 
403
Buffer::find(Network::byte_t *b, size_t size)
 
404
{
 
405
//    GNASH_REPORT_FUNCTION;
 
406
    for (size_t i=0; i< _nbytes; i++) {
 
407
        if (memcmp((_ptr + i), b, size) == 0) {
 
408
            return _ptr + i;
 
409
        }
 
410
    }
 
411
    return 0;
 
412
}
 
413
 
 
414
Network::byte_t *
 
415
Buffer::find(Network::byte_t c)
 
416
{
 
417
//    GNASH_REPORT_FUNCTION;
 
418
    for (size_t i=0; i< _nbytes; i++) {
 
419
        if (*(_ptr + i) == c) {
 
420
            return _ptr + i;
 
421
        }
 
422
    }
 
423
    return 0;
 
424
}
 
425
 
 
426
Network::byte_t *
 
427
Buffer::remove(Network::byte_t c)
 
428
{
 
429
//    GNASH_REPORT_FUNCTION;
 
430
    Network::byte_t *start = find(c);
 
431
 
 
432
    log_debug("Byte is at %x", (void *)start);
 
433
    
 
434
    if (start == 0) {
 
435
        return 0;
 
436
    }
 
437
    
 
438
    std::copy(start + 1, end(), start);
 
439
//    *(end()) = 0;
 
440
    _nbytes--;
 
441
 
 
442
    return _ptr;
 
443
}
 
444
 
 
445
Network::byte_t *
 
446
Buffer::remove(int start)
 
447
{
 
448
//    GNASH_REPORT_FUNCTION;
 
449
    std::copy((_ptr + start + 1), end(), (_ptr + start)),
 
450
//    *end() = 0;
 
451
    _nbytes--;
 
452
    return _ptr;
 
453
}
 
454
 
 
455
Network::byte_t *
 
456
Buffer::remove(int start, int stop)
 
457
{
 
458
//    GNASH_REPORT_FUNCTION;
 
459
    std::copy((_ptr + stop + 1), end(), (_ptr + start)),
 
460
//    *end() = 0;
 
461
    _nbytes -= stop-start;
 
462
    return _ptr;
 
463
}
 
464
 
 
465
// Just reset to having no data, but still having storage
 
466
void
 
467
Buffer::clear()
 
468
{
 
469
//    GNASH_REPORT_FUNCTION;
 
470
    if (_ptr) {
 
471
        memset(_ptr, 0, _nbytes);
 
472
    }
 
473
    _seekptr = _ptr;
 
474
}
 
475
 
 
476
// Resize the buffer that holds the data.
 
477
// Resize the buffer that holds the data.
 
478
void *
 
479
Buffer::resize()
 
480
{
 
481
//    GNASH_REPORT_FUNCTION;
 
482
    return resize(_seekptr - _ptr);
 
483
}
 
484
 
 
485
void *
 
486
Buffer::resize(size_t size)
 
487
{
 
488
//    GNASH_REPORT_FUNCTION;
 
489
    // Allocate a new memory block
 
490
    if (_nbytes == 0) {
 
491
        init(size);
 
492
    } else {
 
493
        size_t diff =_seekptr - _ptr;
 
494
        Network::byte_t *tmp = new Network::byte_t[size];
 
495
        // The size is the same, don't do anything.
 
496
        if (size == _nbytes) {
 
497
            return _ptr;
 
498
        }
 
499
        // And copy ourselves into it
 
500
        if (size > _nbytes) {
 
501
            std::copy(_ptr, _ptr + _nbytes, tmp);
 
502
            // Delete the old block, it's unused now
 
503
            delete[] _ptr;
 
504
            // Make the memory block use the new space
 
505
            _ptr = tmp;
 
506
            // Make the seekptr point into the new space with the correct offset
 
507
            _seekptr = tmp + diff;
 
508
        }
 
509
        if (size < _nbytes) {
 
510
            std::copy(_ptr, _ptr + size, tmp);
 
511
            // Delete the old block, it's unused now
 
512
            delete[] _ptr;
 
513
            // Make the memory block use the new space
 
514
            _ptr = tmp;
 
515
            // Make the seekptr point into the new space with the correct offset
 
516
            _seekptr = _ptr + size;
 
517
        }
 
518
    }
 
519
    // Adjust the size
 
520
    _nbytes = size;
 
521
    
 
522
    return _ptr;
 
523
}
 
524
 
 
525
void
 
526
Buffer::dump()
 
527
{
 
528
    cerr << "Buffer is " << _nbytes << " bytes at " << (void *)_ptr << endl;
 
529
    if (_nbytes < 0xffff) {
 
530
        cerr << gnash::hexify((unsigned char *)_ptr, _nbytes, false) << endl;
 
531
        cerr << gnash::hexify((unsigned char *)_ptr, _nbytes, true) << endl;
 
532
    } else {
 
533
        cerr << "ERROR: Buffer size out of range!" << endl;
 
534
        abort();
 
535
    }
 
536
}
 
537
 
 
538
} // end of amf namespace
 
539
 
 
540
// local Variables:
 
541
// mode: C++
 
542
// indent-tabs-mode: t
 
543
// End: