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 
00025 #include <string>
00026 
00029 namespace ai {
00030 
00033 class SPAlloc {
00034 public:
00039         static void* AllocateBlock(size_t byteCount);
00043         static void DeleteBlock(void* block);
00044 };
00045 
00050 /* Notes: elem's type must be limited to POD (plain old data) types for AutoBuffer objects
00051  *  that are to be passed across the Illustrator SuitePea suite boundary.  This is required as the
00052  * ctor and dtor for non-POD types are not available on both sides of this boundary.  For single-side
00053  * of the API boundary usage, clients are free to construct AutoBuffers of any type.
00054  *
00055  * In order for AutoBuffer to function properly across the Illustrator plug-in API boundary,
00056  * the provided SPAlloc class definition must be used.  Allocations MUST be done using the
00057  * SPBlocks suite.
00058  *
00059  * std::vector is not used because AI has no control over the default allocator for the vector and
00060  * the implementations of std::vector could be different on each side of the API boundary causing problems.
00061  */
00062 template<class elem, typename size_type=size_t, class A=SPAlloc> class AutoBuffer {
00063 public:
00067         explicit AutoBuffer (size_type count = 0)
00068         : fCapacity(count),
00069           fBuffer(0)
00070         {
00071                 if ( fCapacity > 0 )
00072                 {
00073                         fBuffer = reinterpret_cast<elem*>(A::AllocateBlock(ByteCount(fCapacity)));
00074                         Init();
00075                 }
00076         }
00080         AutoBuffer (const AutoBuffer& b)
00081         : fCapacity(b.fCapacity),
00082           fBuffer(0)
00083         {
00084                 if ( fCapacity > 0 )
00085                 {
00086                         fBuffer = reinterpret_cast<elem*>(A::AllocateBlock(ByteCount(fCapacity)));
00087                         Copy(b.fBuffer);
00088                 }
00089         }
00092         ~AutoBuffer ()
00093         {
00094                 if ( fBuffer )
00095                 {
00096                         Destroy(fBuffer);
00097                         A::DeleteBlock(fBuffer);
00098                 }
00099         }
00100 
00104         bool IsValid () const
00105         {
00106                 return fBuffer != 0;
00107         }
00108 
00113         elem* GetBuffer () const
00114         {
00115                 return fBuffer;
00116         }
00117         operator elem* () const
00118         {
00119                 return GetBuffer();
00120         }
00121 
00128         elem& operator[] (size_type n)
00129         {
00130                 return fBuffer[n];
00131         }
00135         size_type GetCount () const
00136         {
00137                 return fCapacity;
00138         }
00145         void Resize (size_type newSize)
00146         {
00147                 if ( newSize != fCapacity )
00148                 {
00149                         elem *newBuffer = reinterpret_cast<elem*>(A::AllocateBlock(ByteCount(newSize)));
00150                         if ( fBuffer )
00151                         {
00152                                 elem* oldBuffer = fBuffer;
00153                                 fBuffer = newBuffer;
00154                                 Copy(oldBuffer, 0, fCapacity < newSize ? fCapacity : newSize );
00155                                 
00156                                 // initialize any new elements
00157                                 Init(fCapacity, newSize);
00158 
00159                                 Destroy(oldBuffer, 0, fCapacity);
00160                                 A::DeleteBlock(oldBuffer);
00161                         }
00162                         else
00163                         {
00164                                 fBuffer = newBuffer;
00165                                 Init();
00166                         }
00167                         fCapacity = newSize;
00168                 }
00169         }
00170 
00171         AutoBuffer& operator= (const AutoBuffer& rhs)
00172         {
00173                 if ( this != &rhs )
00174                 {
00175                         if ( fCapacity != rhs.fCapacity )
00176                         {
00177                                 Destroy(fBuffer);
00178                                 A::DeleteBlock(fBuffer);
00179                                 fBuffer = reinterpret_cast<elem*>(A::AllocateBlock(ByteCount(rhs.fCapacity)));
00180                                 fCapacity = rhs.fCapacity;
00181                         }
00182                         Copy(rhs.fBuffer);
00183                 }
00184                 return *this;
00185         }
00186 
00187         static size_type lastIndex ()
00188         { return size_type(-1); }
00189 private:
00190         void Init (size_type start = 0, size_type end = lastIndex())
00191         {
00192                 size_type elemCount = (end == lastIndex() ? GetCount() : end);
00193                 for (size_type i = start; i < elemCount; ++i)
00194                 {
00195                         // invoke the constructor on each element
00196                         new (&fBuffer[i])elem;
00197                 }
00198         }
00199         void Destroy (elem* e, size_type start = 0, size_type end = lastIndex())
00200         {
00201                 size_type elemCount = (end == lastIndex() ? GetCount() : end);
00202                 for (size_type i = start; i < elemCount; ++i)
00203                 {
00204                         e[i].~elem();
00205                 }
00206         }
00207         void Copy (const elem* e, size_type start = 0, size_type end = lastIndex())
00208         {
00209                 size_type elemCount = (end == lastIndex() ? GetCount() : end);
00210                 for (size_type i = start; i < elemCount; ++i)
00211                 {
00212                         fBuffer[i] = e[i];
00213                 }
00214         }
00215         size_type ByteCount (size_type elemCount)
00216         {
00217                 return elemCount * sizeof(elem);
00218         }
00219 private:
00220         size_type fCapacity;
00221         elem* fBuffer;
00222 };
00223 
00224 } // end of namespace ai
00225 
00226 #endif  // _IAIAUTOBUFFER_H_


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