Adobe.com
Contents Suites Classes Class Index Member Index

IAIAutoBuffer.h

Go to the documentation of this file.
00001 /*
00002  *        Name: IAIAutoBuffer.h
00003  *   $Revision: 1 $
00004  *      Author:
00005  *        Date:
00006  *     Purpose: 
00007  *
00008  * ADOBE SYSTEMS INCORPORATED
00009  * Copyright 2004-2007 Adobe Systems Incorporated.
00010  * All rights reserved.
00011  *
00012  * NOTICE:  Adobe permits you to use, modify, and distribute this file 
00013  * in accordance with the terms of the Adobe license agreement 
00014  * accompanying it. If you have received this file from a source other 
00015  * than Adobe, then your use, modification, or distribution of it 
00016  * requires the prior written permission of Adobe.
00017  *
00018  */
00019 
00020 
00021 #ifndef _IAIAUTOBUFFER_H_
00022 #define _IAIAUTOBUFFER_H_
00023 
00024 #include "AITypes.h"
00025 
00026 #include <string>
00027 
00030 namespace ai {
00031 
00034 class SPAlloc {
00035 public:
00040         static void* AllocateBlock(size_t byteCount);
00044         static void DeleteBlock(void* block);
00045 };
00046 
00051 /* Notes: elem's type must be limited to POD (plain old data) types for AutoBuffer objects
00052  *  that are to be passed across the Illustrator SuitePea suite boundary.  This is required as the
00053  * ctor and dtor for non-POD types are not available on both sides of this boundary.  For single-side
00054  * of the API boundary usage, clients are free to construct AutoBuffers of any type.
00055  *
00056  * In order for AutoBuffer to function properly across the Illustrator plug-in API boundary,
00057  * the provided SPAlloc class definition must be used.  Allocations MUST be done using the
00058  * SPBlocks suite.
00059  *
00060  * std::vector is not used because AI has no control over the default allocator for the vector and
00061  * the implementations of std::vector could be different on each side of the API boundary causing problems.
00062  */
00063 template<class elem, typename size_type=size_t, class A=SPAlloc> class AutoBuffer {
00064 public:
00065         typedef elem* iterator;
00066         typedef const elem* const_iterator;
00067 
00071         explicit AutoBuffer (size_type count = 0)
00072         : fCapacity(count),
00073           fBuffer(0)
00074         {
00075                 if ( fCapacity > 0 )
00076                 {
00077                         fBuffer = reinterpret_cast<elem*>(A::AllocateBlock(ByteCount(fCapacity)));
00078                         Init();
00079                 }
00080         }
00084         AutoBuffer (const AutoBuffer& b)
00085         : fCapacity(b.fCapacity),
00086           fBuffer(0)
00087         {
00088                 if ( fCapacity > 0 )
00089                 {
00090                         fBuffer = reinterpret_cast<elem*>(A::AllocateBlock(ByteCount(fCapacity)));
00091                         Copy(b.fBuffer);
00092                 }
00093         }
00094 
00095 #ifdef AI_HAS_RVALUE_REFERENCES
00096 
00099         AutoBuffer (AutoBuffer&& b) AINOEXCEPT : fCapacity{b.fCapacity}, fBuffer{b.fBuffer}
00100         {
00101                 b.fBuffer = nullptr;
00102         }
00103 #endif
00104 
00107         ~AutoBuffer ()
00108         {
00109                 if ( fBuffer )
00110                 {
00111                         Destroy(fBuffer);
00112                         A::DeleteBlock(fBuffer);
00113                 }
00114         }
00115 
00119         bool IsValid () const
00120         {
00121                 return fBuffer != 0;
00122         }
00123 
00128         elem* GetBuffer () const
00129         {
00130                 return fBuffer;
00131         }
00132         
00133         explicit operator elem* () const
00134         {
00135                 return GetBuffer();
00136         }
00137 
00144         elem& operator[] (size_type n)
00145         {
00146                 return fBuffer[n];
00147         }
00148 
00149         const elem& operator[] (size_type n) const
00150         {
00151                 return fBuffer[n];
00152         }
00153 
00157         elem& front()
00158         {
00159                 return fBuffer[0];
00160         }
00161 
00162         const elem& front() const
00163         {
00164                 return fBuffer[0];
00165         }
00166 
00170         elem& back()
00171         {
00172                 return fBuffer[fCapacity - 1];
00173         }
00174 
00175         const elem& back() const
00176         {
00177                 return fBuffer[fCapacity - 1];
00178         }
00179 
00183         size_type GetCount () const AINOEXCEPT
00184         {
00185                 return size();
00186         }
00187 
00188         size_type size() const AINOEXCEPT
00189         {
00190                 return fCapacity;
00191         }
00192 
00193         bool empty() const AINOEXCEPT
00194         {
00195                 return fCapacity == 0;
00196         }
00197 
00198 
00205         void Resize (size_type newSize)
00206         {
00207                 if ( newSize != fCapacity )
00208                 {
00209                         elem *newBuffer = reinterpret_cast<elem*>(A::AllocateBlock(ByteCount(newSize)));
00210                         if ( fBuffer )
00211                         {
00212                                 elem* oldBuffer = fBuffer;
00213                                 fBuffer = newBuffer;
00214                                 Copy(oldBuffer, 0, fCapacity < newSize ? fCapacity : newSize );
00215                                 
00216                                 // initialize any new elements
00217                                 Init(fCapacity, newSize);
00218 
00219                                 Destroy(oldBuffer, 0, fCapacity);
00220                                 A::DeleteBlock(oldBuffer);
00221                         }
00222                         else
00223                         {
00224                                 fBuffer = newBuffer;
00225                                 Init();
00226                         }
00227                         fCapacity = newSize;
00228                 }
00229         }
00230 
00231         AutoBuffer& operator= (const AutoBuffer& rhs)
00232         {
00233                 if ( this != &rhs )
00234                 {
00235                         if ( fCapacity != rhs.fCapacity )
00236                         {
00237                                 Destroy(fBuffer);
00238                                 A::DeleteBlock(fBuffer);
00239                                 fBuffer = reinterpret_cast<elem*>(A::AllocateBlock(ByteCount(rhs.fCapacity)));
00240                                 fCapacity = rhs.fCapacity;
00241                         }
00242                         Copy(rhs.fBuffer);
00243                 }
00244                 return *this;
00245         }
00246 
00247 #ifdef AI_HAS_RVALUE_REFERENCES
00248         AutoBuffer& operator= (AutoBuffer&& rhs) AINOEXCEPT
00249         {
00250                 fCapacity = rhs.fCapacity;
00251                 std::swap(fBuffer, rhs.fBuffer);
00252                 return *this;
00253         }
00254 #endif
00255 
00256         iterator begin() AINOEXCEPT { return fBuffer; }
00257         iterator end() AINOEXCEPT { return fBuffer + fCapacity; }
00258         const_iterator begin() const AINOEXCEPT { return fBuffer; }
00259         const_iterator end() const AINOEXCEPT { return fBuffer + fCapacity; }
00260 
00261         static size_type lastIndex ()
00262         { return size_type(-1); }
00263 private:
00264         void Init (size_type start = 0, size_type end = lastIndex())
00265         {
00266                 size_type elemCount = (end == lastIndex() ? GetCount() : end);
00267                 for (size_type i = start; i < elemCount; ++i)
00268                 {
00269                         // invoke the constructor on each element
00270                         new (&fBuffer[i])elem;
00271                 }
00272         }
00273         void Destroy (elem* e, size_type start = 0, size_type end = lastIndex())
00274         {
00275                 size_type elemCount = (end == lastIndex() ? GetCount() : end);
00276                 for (size_type i = start; i < elemCount; ++i)
00277                 {
00278                         e[i].~elem();
00279                 }
00280         }
00281         void Copy (const elem* e, size_type start = 0, size_type end = lastIndex())
00282         {
00283                 size_type elemCount = (end == lastIndex() ? GetCount() : end);
00284                 for (size_type i = start; i < elemCount; ++i)
00285                 {
00286                         fBuffer[i] = e[i];
00287                 }
00288         }
00289         size_type ByteCount (size_type elemCount)
00290         {
00291                 return elemCount * sizeof(elem);
00292         }
00293 private:
00294         size_type fCapacity;
00295         elem* fBuffer;
00296 };
00297 
00298 } // end of namespace ai
00299 
00300 #endif  // _IAIAUTOBUFFER_H_


Contents Suites Classes Class Index Member Index
Adobe Solutions Network
 
Copyright © 2014 Adobe Systems Incorporated. All rights reserved.
Terms of Use Online Privacy Policy Adobe and accessibility Avoid software piracy Permissions and Trademarks