1 // This may look like C code, but it is really -*- C++ -*-
2 //
3 // Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2004
4 // Copyright Dirk Lemstra 2013-2017
5 //
6 // Implementation of Blob
7 //
8 
9 #define MAGICKCORE_IMPLEMENTATION  1
10 #define MAGICK_PLUSPLUS_IMPLEMENTATION 1
11 
12 #include "Magick++/Include.h"
13 #include "Magick++/Blob.h"
14 #include "Magick++/BlobRef.h"
15 #include "Magick++/Exception.h"
16 
17 #include <string.h>
18 
Blob(void)19 Magick::Blob::Blob(void)
20   : _blobRef(new Magick::BlobRef(0,0))
21 {
22 }
23 
Blob(const void * data_,const size_t length_)24 Magick::Blob::Blob(const void* data_,const size_t length_)
25   : _blobRef(new Magick::BlobRef(data_, length_))
26 {
27 }
28 
Blob(const Magick::Blob & blob_)29 Magick::Blob::Blob(const Magick::Blob& blob_)
30   : _blobRef(blob_._blobRef)
31 {
32   // Increase reference count
33   _blobRef->increase();
34 }
35 
~Blob()36 Magick::Blob::~Blob()
37 {
38   try
39   {
40     if (_blobRef->decrease() == 0)
41       delete _blobRef;
42   }
43   catch(Magick::Exception&)
44   {
45   }
46 
47   _blobRef=(Magick::BlobRef *) NULL;
48 }
49 
operator =(const Magick::Blob & blob_)50 Magick::Blob& Magick::Blob::operator=(const Magick::Blob& blob_)
51 {
52   if (this != &blob_)
53     {
54       blob_._blobRef->increase();
55       if (_blobRef->decrease() == 0)
56         delete _blobRef;
57 
58       _blobRef=blob_._blobRef;
59     }
60   return(*this);
61 }
62 
base64(const std::string base64_)63 void Magick::Blob::base64(const std::string base64_)
64 {
65   size_t
66     length;
67 
68   unsigned char
69     *decoded;
70 
71   decoded=Base64Decode(base64_.c_str(),&length);
72 
73   if(decoded)
74     updateNoCopy(static_cast<void*>(decoded),length,
75       Magick::Blob::MallocAllocator);
76 }
77 
base64(void) const78 std::string Magick::Blob::base64(void) const
79 {
80   size_t
81     encoded_length;
82 
83   char
84     *encoded;
85 
86   std::string
87     result;
88 
89   encoded_length=0;
90   encoded=Base64Encode(static_cast<const unsigned char*>(data()),length(),
91     &encoded_length);
92 
93   if(encoded)
94     {
95       result=std::string(encoded,encoded_length);
96       encoded=(char *) RelinquishMagickMemory(encoded);
97       return result;
98     }
99 
100   return(std::string());
101 }
102 
data(void) const103 const void* Magick::Blob::data(void) const
104 {
105   return(_blobRef->data);
106 }
107 
length(void) const108 size_t Magick::Blob::length(void) const
109 {
110   return(_blobRef->length);
111 }
112 
update(const void * data_,size_t length_)113 void Magick::Blob::update(const void* data_,size_t length_)
114 {
115   if (_blobRef->decrease() == 0)
116     delete _blobRef;
117 
118   _blobRef=new Magick::BlobRef(data_,length_);
119 }
120 
updateNoCopy(void * data_,size_t length_,Magick::Blob::Allocator allocator_)121 void Magick::Blob::updateNoCopy(void* data_,size_t length_,
122   Magick::Blob::Allocator allocator_)
123 {
124   if (_blobRef->decrease() == 0)
125     delete _blobRef;
126 
127   _blobRef=new Magick::BlobRef((const void*) NULL,0);
128   _blobRef->data=data_;
129   _blobRef->length=length_;
130   _blobRef->allocator=allocator_;
131 }
132 
133