blob: 96b97ec6f528c8a4ec44c18110ad3087ebe90045 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001// This may look like C code, but it is really -*- C++ -*-
2//
3// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2004
4//
5// Implementation of Blob
6//
7
8#define MAGICKCORE_IMPLEMENTATION 1
9#define MAGICK_PLUSPLUS_IMPLEMENTATION 1
10
11#include "Magick++/Include.h"
12#include "Magick++/Blob.h"
13#include "Magick++/BlobRef.h"
14
15#include <string.h>
16
17//
18// Implementation of Magick::Blob
19//
20
21// Default constructor
22Magick::Blob::Blob ( void )
23 : _blobRef(new Magick::BlobRef( 0, 0 ))
24{
25}
26
27// Construct with data
28Magick::Blob::Blob ( const void* data_, size_t length_ )
29 : _blobRef(new Magick::BlobRef( data_, length_ ))
30{
31}
32
33// Copy constructor (reference counted)
34Magick::Blob::Blob ( const Magick::Blob& blob_ )
35 : _blobRef(blob_._blobRef)
36{
37 // Increase reference count
38 Lock( &_blobRef->_mutexLock );
39 ++_blobRef->_refCount;
40}
41
42// Destructor (reference counted)
43Magick::Blob::~Blob ()
44{
45 bool doDelete = false;
46 {
47 Lock( &_blobRef->_mutexLock );
48 if ( --_blobRef->_refCount == 0 )
49 doDelete = true;
50 }
51
52 if ( doDelete )
53 {
54 // Delete old blob reference with associated data
55 delete _blobRef;
56 }
57 _blobRef=0;
58}
59
60// Assignment operator (reference counted)
61Magick::Blob& Magick::Blob::operator= ( const Magick::Blob& blob_ )
62{
63 if(this != &blob_)
64 {
65 {
66 Lock( &blob_._blobRef->_mutexLock );
67 ++blob_._blobRef->_refCount;
68 }
69 bool doDelete = false;
70 {
71 Lock( &_blobRef->_mutexLock );
72 if ( --_blobRef->_refCount == 0 )
73 doDelete = true;
74 }
75 if ( doDelete )
76 {
77 delete _blobRef;
78 }
79 _blobRef = blob_._blobRef;
80 }
81 return *this;
82}
83
84// Update object contents from Base64-encoded string representation.
85void Magick::Blob::base64 ( const std::string base64_ )
86{
87 size_t length;
88
89 unsigned char *decoded =
90 Base64Decode( base64_.c_str(), &length );
91
92 if(decoded)
93 updateNoCopy( static_cast<void*>(decoded), length,
94 Magick::Blob::MallocAllocator );
95}
96
97// Return Base64-encoded string representation.
98std::string Magick::Blob::base64 ( void )
99{
100 size_t encoded_length = 0;
101
102 char *encoded =
103 Base64Encode(static_cast<const unsigned char*>(data()), length(), &encoded_length);
104
105 if(encoded)
106 {
107 std::string result(encoded,encoded_length);
108 encoded=(char *) RelinquishMagickMemory(encoded);
109 return result;
110 }
111
112 return std::string();
113}
114
115// Update object contents, making a copy of the supplied data.
116// Any existing data in the object is deallocated.
117void Magick::Blob::update ( const void* data_, size_t length_ )
118{
119 bool doDelete = false;
120 {
121 Lock( &_blobRef->_mutexLock );
122 if ( --_blobRef->_refCount == 0 )
123 doDelete = true;
124 }
125 if ( doDelete )
126 {
127 // Delete old blob reference with associated data
128 delete _blobRef;
129 }
130
131 _blobRef = new Magick::BlobRef( data_, length_ );
132}
133
134// Update object contents, using supplied pointer directly (no copy)
135// Any existing data in the object is deallocated. The user must
136// ensure that the pointer supplied is not deleted or otherwise
137// modified after it has been supplied to this method.
138void Magick::Blob::updateNoCopy ( void* data_, size_t length_,
139 Magick::Blob::Allocator allocator_ )
140{
141 bool doDelete = false;
142 {
143 Lock( &_blobRef->_mutexLock );
144 if ( --_blobRef->_refCount == 0 )
145 doDelete = true;
146 }
147 if ( doDelete )
148 {
149 // Delete old blob reference with associated data
150 delete _blobRef;
151 }
152 _blobRef = new Magick::BlobRef( 0, 0 );
153 _blobRef->_data = data_;
154 _blobRef->_length = length_;
155 _blobRef->_allocator = allocator_;
156}
157
158// Obtain pointer to data
159const void* Magick::Blob::data( void ) const
160{
161 return _blobRef->_data;
162}
163
164// Obtain data length
165size_t Magick::Blob::length( void ) const
166{
167 return _blobRef->_length;
168}
169