]> granicus.if.org Git - imagemagick/blob - Magick++/lib/Blob.cpp
(no commit message)
[imagemagick] / Magick++ / lib / Blob.cpp
1 // 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
22 Magick::Blob::Blob ( void )
23   : _blobRef(new Magick::BlobRef( 0, 0 ))
24 {
25 }
26
27 // Construct with data
28 Magick::Blob::Blob ( const void* data_, size_t length_ )
29   : _blobRef(new Magick::BlobRef( data_, length_ ))
30 {
31 }
32
33 // Copy constructor (reference counted)
34 Magick::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)
43 Magick::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)
61 Magick::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.
85 void 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.
98 std::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.
117 void 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.
138 void 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
159 const void* Magick::Blob::data( void ) const
160 {
161   return _blobRef->_data;
162 }
163
164 // Obtain data length
165 size_t Magick::Blob::length( void ) const
166 {
167   return _blobRef->_length;
168 }
169