1 /***************************************************************************
2  *   Copyright (C) 2006 by Dominik Seichter                                *
3  *   domseichter@web.de                                                    *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU Library General Public License as       *
7  *   published by the Free Software Foundation; either version 2 of the    *
8  *   License, or (at your option) any later version.                       *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU Library General Public     *
16  *   License along with this program; if not, write to the                 *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  *                                                                         *
20  *   In addition, as a special exception, the copyright holders give       *
21  *   permission to link the code of portions of this program with the      *
22  *   OpenSSL library under certain conditions as described in each         *
23  *   individual source file, and distribute linked combinations            *
24  *   including the two.                                                    *
25  *   You must obey the GNU General Public License in all respects          *
26  *   for all of the code used other than OpenSSL.  If you modify           *
27  *   file(s) with this exception, you may extend this exception to your    *
28  *   version of the file(s), but you are not obligated to do so.  If you   *
29  *   do not wish to do so, delete this exception statement from your       *
30  *   version.  If you delete this exception statement from all source      *
31  *   files in the program, then also delete it here.                       *
32  ***************************************************************************/
33 
34 #include "PdfArray.h"
35 
36 #include "PdfOutputDevice.h"
37 #include "PdfDefinesPrivate.h"
38 
39 #include <limits>
40 
41 namespace PoDoFo {
42 
PdfArray()43 PdfArray::PdfArray()
44     : m_bDirty( false )
45 {
46 }
47 
PdfArray(const PdfObject & var)48 PdfArray::PdfArray( const PdfObject &var )
49     : m_bDirty( false )
50 {
51     this->push_back( var );
52 }
53 
PdfArray(const PdfArray & rhs)54 PdfArray::PdfArray(const PdfArray & rhs)
55     : PdfOwnedDataType( rhs ), m_bDirty( rhs.m_bDirty ), m_objects( rhs.m_objects )
56 {
57 }
58 
~PdfArray()59 PdfArray::~PdfArray()
60 {
61 }
62 
findAt(size_type idx) const63 PdfObject * PdfArray::findAt( size_type idx ) const
64 {
65     PdfObject *obj = &const_cast<PdfArray *>( this )->m_objects[idx];
66     if ( obj->IsReference() )
67         return GetIndirectObject( obj->GetReference() );
68     else
69         return obj;
70 }
71 
clear()72 void PdfArray::clear()
73 {
74     AssertMutable();
75     if ( m_objects.size() == 0 )
76         return;
77 
78     m_objects.clear();
79     m_bDirty = true;
80 }
81 
insert(const iterator & pos,const PdfObject & val)82 PdfArray::iterator PdfArray::insert( const iterator &pos, const PdfObject &val )
83 {
84     AssertMutable();
85 
86     m_bDirty = true;
87     iterator ret = m_objects.insert( pos, val );
88     PdfVecObjects *pOwner = GetObjectOwner();
89     if ( pOwner != NULL )
90         ret->SetOwner( pOwner );
91     return ret;
92 }
93 
erase(const iterator & pos)94 void PdfArray::erase( const iterator &pos )
95 {
96     AssertMutable();
97 
98     m_objects.erase( pos );
99     m_bDirty = true;
100 }
101 
erase(const iterator & first,const iterator & last)102 void PdfArray::erase( const iterator &first, const iterator &last )
103 {
104     AssertMutable();
105 
106     m_objects.erase( first, last );
107     m_bDirty = true;
108 }
109 
operator =(const PdfArray & rhs)110 PdfArray& PdfArray::operator=( const PdfArray &rhs )
111 {
112     if (this != &rhs)
113     {
114         m_bDirty = rhs.m_bDirty;
115         m_objects = rhs.m_objects;
116         this->PdfOwnedDataType::operator=( rhs );
117     }
118     else
119     {
120         //do nothing
121     }
122 
123     return *this;
124 }
125 
resize(size_t count,value_type val)126 void PdfArray::resize( size_t count, value_type val )
127 {
128     AssertMutable();
129 
130     size_t currentSize = size();
131     m_objects.resize( count, val );
132     PdfVecObjects *pOwner = GetObjectOwner();
133     if ( pOwner != NULL )
134     {
135         for ( size_t i = currentSize; i < count; i++ )
136             m_objects[i].SetOwner( pOwner );
137     }
138 
139     m_bDirty = currentSize != count;
140 }
141 
Write(PdfOutputDevice * pDevice,EPdfWriteMode eWriteMode,const PdfEncrypt * pEncrypt) const142 void PdfArray::Write( PdfOutputDevice* pDevice, EPdfWriteMode eWriteMode,
143                       const PdfEncrypt* pEncrypt ) const
144 {
145     PdfArray::const_iterator it = this->begin();
146 
147     int count = 1;
148 
149     if( (eWriteMode & ePdfWriteMode_Clean) == ePdfWriteMode_Clean )
150     {
151         pDevice->Print( "[ " );
152     }
153     else
154     {
155         pDevice->Print( "[" );
156     }
157 
158     while( it != this->end() )
159     {
160         (*it).Write( pDevice, eWriteMode, pEncrypt );
161         if( (eWriteMode & ePdfWriteMode_Clean) == ePdfWriteMode_Clean )
162         {
163             pDevice->Print( (count % 10 == 0) ? "\n" : " " );
164         }
165 
166         ++it;
167         ++count;
168     }
169 
170     pDevice->Print( "]" );
171 }
172 
ContainsString(const std::string & cmpString) const173 bool PdfArray::ContainsString( const std::string& cmpString ) const
174 {
175     bool foundIt = false;
176 
177     TCIVariantList it(this->begin());
178     while( it != this->end() )
179     {
180         if( (*it).GetDataType() == ePdfDataType_String )
181         {
182             if ( (*it).GetString().GetString() == cmpString ) {
183                 foundIt = true;
184                 break;
185             }
186         }
187 
188         ++it;
189     }
190 
191     return foundIt;
192 }
193 
GetStringIndex(const std::string & cmpString) const194 size_t PdfArray::GetStringIndex( const std::string& cmpString ) const
195 {
196     size_t foundIdx = std::numeric_limits<size_t>::max();
197 
198     for ( size_t i=0; i<this->size(); i++ ) {
199         if( (*this)[i].GetDataType() == ePdfDataType_String )
200         {
201             if ( (*this)[i].GetString().GetString() == cmpString )
202             {
203                 foundIdx = i;
204                 break;
205             }
206         }
207     }
208 
209     return foundIdx;
210 }
211 
IsDirty() const212 bool PdfArray::IsDirty() const
213 {
214     // If the array itself is dirty
215     // return immediately
216     // otherwise check all children.
217     if( m_bDirty )
218         return m_bDirty;
219 
220     PdfArray::const_iterator it(this->begin());
221     while( it != this->end() )
222     {
223         if( (*it).IsDirty() )
224             return true;
225 
226         ++it;
227     }
228 
229     return false;
230 }
231 
SetDirty(bool bDirty)232 void PdfArray::SetDirty( bool bDirty )
233 {
234     m_bDirty = bDirty;
235 
236     if( !m_bDirty )
237     {
238         // Propagate state to all subclasses
239         PdfArray::iterator it(this->begin());
240         while( it != this->end() )
241         {
242             (*it).SetDirty( m_bDirty );
243             ++it;
244         }
245     }
246 }
247 
SetOwner(PdfObject * pOwner)248 void PdfArray::SetOwner( PdfObject *pOwner )
249 {
250     PdfOwnedDataType::SetOwner( pOwner );
251     PdfVecObjects *pVecOwner = pOwner->GetOwner();
252     if ( pVecOwner != NULL )
253     {
254         // Set owmership for all children
255         PdfArray::iterator it = this->begin();
256         PdfArray::iterator end = this->end();
257         for ( ; it != end; it++ )
258             it->SetOwner( pVecOwner );
259     }
260 }
261 
262 };
263