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-2015
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
16#include <string.h>
17
18Magick::Blob::Blob(void)
19  : _blobRef(new Magick::BlobRef(0,0))
20{
21}
22
23Magick::Blob::Blob(const void* data_,const size_t length_)
24  : _blobRef(new Magick::BlobRef(data_, length_))
25{
26}
27
28Magick::Blob::Blob(const Magick::Blob& blob_)
29  : _blobRef(blob_._blobRef)
30{
31  // Increase reference count
32  _blobRef->increase();
33}
34
35Magick::Blob::~Blob()
36{
37  if (_blobRef->decrease() == 0)
38    delete _blobRef;
39
40  _blobRef=(Magick::BlobRef *) NULL;
41}
42
43Magick::Blob& Magick::Blob::operator=(const Magick::Blob& blob_)
44{
45  if (this != &blob_)
46    {
47      blob_._blobRef->increase();
48      if (_blobRef->decrease() == 0)
49        delete _blobRef;
50
51      _blobRef=blob_._blobRef;
52    }
53  return(*this);
54}
55
56void Magick::Blob::base64(const std::string base64_)
57{
58  size_t
59    length;
60
61  unsigned char
62    *decoded;
63
64  decoded=Base64Decode(base64_.c_str(),&length);
65
66  if(decoded)
67    updateNoCopy(static_cast<void*>(decoded),length,
68      Magick::Blob::MallocAllocator);
69}
70
71std::string Magick::Blob::base64(void) const
72{
73  size_t
74    encoded_length;
75
76  char
77    *encoded;
78
79  std::string
80    result;
81
82  encoded_length=0;
83  encoded=Base64Encode(static_cast<const unsigned char*>(data()),length(),
84    &encoded_length);
85
86  if(encoded)
87    {
88      result=std::string(encoded,encoded_length);
89      encoded=(char *) RelinquishMagickMemory(encoded);
90      return result;
91    }
92
93  return(std::string());
94}
95
96const void* Magick::Blob::data(void) const
97{
98  return(_blobRef->data);
99}
100
101size_t Magick::Blob::length(void) const
102{
103  return(_blobRef->length);
104}
105
106void Magick::Blob::update(const void* data_,size_t length_)
107{
108  if (_blobRef->decrease() == 0)
109    delete _blobRef;
110
111  _blobRef=new Magick::BlobRef(data_,length_);
112}
113
114void Magick::Blob::updateNoCopy(void* data_,size_t length_,
115  Magick::Blob::Allocator allocator_)
116{
117  if (_blobRef->decrease() == 0)
118    delete _blobRef;
119
120  _blobRef=new Magick::BlobRef((const void*) NULL,0);
121  _blobRef->data=data_;
122  _blobRef->length=length_;
123  _blobRef->allocator=allocator_;
124}
125
126