xref: /AOO42X/main/basic/source/comp/buffer.cxx (revision a52465541c45a73de2757b73c6e502ca312fea0b)
1e1f63238SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3e1f63238SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4e1f63238SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5e1f63238SAndrew Rist  * distributed with this work for additional information
6e1f63238SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7e1f63238SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8e1f63238SAndrew Rist  * "License"); you may not use this file except in compliance
9e1f63238SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11e1f63238SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13e1f63238SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14e1f63238SAndrew Rist  * software distributed under the License is distributed on an
15e1f63238SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16e1f63238SAndrew Rist  * KIND, either express or implied.  See the License for the
17e1f63238SAndrew Rist  * specific language governing permissions and limitations
18e1f63238SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20e1f63238SAndrew Rist  *************************************************************/
21e1f63238SAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_basic.hxx"
24cdf0e10cSrcweir 
25cdf0e10cSrcweir #include "sbcomp.hxx"
26cdf0e10cSrcweir #include "buffer.hxx"
27cdf0e10cSrcweir #include <string.h>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir const static sal_uInt32 UP_LIMIT=0xFFFFFF00L;
30cdf0e10cSrcweir 
31cdf0e10cSrcweir // Der SbiBuffer wird in Inkrements von mindestens 16 Bytes erweitert.
32*a5246554Smseidel // Dies ist notwendig, da viele Klassen von einer Pufferlänge
33cdf0e10cSrcweir // von x*16 Bytes ausgehen.
34cdf0e10cSrcweir 
SbiBuffer(SbiParser * p,short n)35cdf0e10cSrcweir SbiBuffer::SbiBuffer( SbiParser* p, short n )
36cdf0e10cSrcweir {
37cdf0e10cSrcweir     pParser = p;
38cdf0e10cSrcweir     n = ( (n + 15 ) / 16 ) * 16;
39cdf0e10cSrcweir     if( !n ) n = 16;
40cdf0e10cSrcweir     pBuf  = NULL;
41cdf0e10cSrcweir     pCur  = NULL;
42cdf0e10cSrcweir     nInc  = n;
43cdf0e10cSrcweir     nSize =
44cdf0e10cSrcweir     nOff  = 0;
45cdf0e10cSrcweir }
46cdf0e10cSrcweir 
~SbiBuffer()47cdf0e10cSrcweir SbiBuffer::~SbiBuffer()
48cdf0e10cSrcweir {
49cdf0e10cSrcweir     delete[] pBuf;
50cdf0e10cSrcweir }
51cdf0e10cSrcweir 
52cdf0e10cSrcweir // Rausreichen des Puffers
53*a5246554Smseidel // Dies führt zur Löschung des Puffers!
54cdf0e10cSrcweir 
GetBuffer()55cdf0e10cSrcweir char* SbiBuffer::GetBuffer()
56cdf0e10cSrcweir {
57cdf0e10cSrcweir     char* p = pBuf;
58cdf0e10cSrcweir     pBuf = NULL;
59cdf0e10cSrcweir     pCur = NULL;
60cdf0e10cSrcweir     return p;
61cdf0e10cSrcweir }
62cdf0e10cSrcweir 
63cdf0e10cSrcweir // Test, ob der Puffer n Bytes aufnehmen kann.
64*a5246554Smseidel // Im Zweifelsfall wird er vergrössert
65cdf0e10cSrcweir 
Check(sal_uInt16 n)66cdf0e10cSrcweir sal_Bool SbiBuffer::Check( sal_uInt16 n )
67cdf0e10cSrcweir {
68cdf0e10cSrcweir     if( !n ) return sal_True;
69cdf0e10cSrcweir     if( ( static_cast<sal_uInt32>( nOff )+ n ) >  static_cast<sal_uInt32>( nSize ) )
70cdf0e10cSrcweir     {
71cdf0e10cSrcweir         if( nInc == 0 )
72cdf0e10cSrcweir             return sal_False;
73cdf0e10cSrcweir         sal_uInt16 nn = 0;
74cdf0e10cSrcweir         while( nn < n ) nn = nn + nInc;
75cdf0e10cSrcweir         char* p;
76cdf0e10cSrcweir         if( ( static_cast<sal_uInt32>( nSize ) + nn ) > UP_LIMIT ) p = NULL;
77cdf0e10cSrcweir         else p = new char [nSize + nn];
78cdf0e10cSrcweir         if( !p )
79cdf0e10cSrcweir         {
80cdf0e10cSrcweir             pParser->Error( SbERR_PROG_TOO_LARGE );
81cdf0e10cSrcweir             nInc = 0;
82cdf0e10cSrcweir             delete[] pBuf; pBuf = NULL;
83cdf0e10cSrcweir             return sal_False;
84cdf0e10cSrcweir         }
85cdf0e10cSrcweir         else
86cdf0e10cSrcweir         {
87cdf0e10cSrcweir             if( nSize ) memcpy( p, pBuf, nSize );
88cdf0e10cSrcweir             delete[] pBuf;
89cdf0e10cSrcweir             pBuf = p;
90cdf0e10cSrcweir             pCur = pBuf + nOff;
91cdf0e10cSrcweir             nSize = nSize + nn;
92cdf0e10cSrcweir         }
93cdf0e10cSrcweir     }
94cdf0e10cSrcweir     return sal_True;
95cdf0e10cSrcweir }
96cdf0e10cSrcweir 
97*a5246554Smseidel // Angleich des Puffers auf die übergebene Byte-Grenze
98cdf0e10cSrcweir 
Align(sal_Int32 n)99cdf0e10cSrcweir void SbiBuffer::Align( sal_Int32 n )
100cdf0e10cSrcweir {
101cdf0e10cSrcweir     if( nOff % n ) {
102cdf0e10cSrcweir         sal_uInt32 nn =( ( nOff + n ) / n ) * n;
103cdf0e10cSrcweir         if( nn <= UP_LIMIT )
104cdf0e10cSrcweir         {
105cdf0e10cSrcweir             nn = nn - nOff;
106cdf0e10cSrcweir             if( Check( static_cast<sal_uInt16>(nn) ) )
107cdf0e10cSrcweir             {
108cdf0e10cSrcweir                 memset( pCur, 0, nn );
109cdf0e10cSrcweir                 pCur += nn;
110cdf0e10cSrcweir                 nOff = nOff + nn;
111cdf0e10cSrcweir             }
112cdf0e10cSrcweir         }
113cdf0e10cSrcweir     }
114cdf0e10cSrcweir }
115cdf0e10cSrcweir 
116cdf0e10cSrcweir // Patch einer Location
117cdf0e10cSrcweir 
Patch(sal_uInt32 off,sal_uInt32 val)118cdf0e10cSrcweir void SbiBuffer::Patch( sal_uInt32 off, sal_uInt32 val )
119cdf0e10cSrcweir {
120cdf0e10cSrcweir     if( ( off + sizeof( sal_uInt32 ) ) < nOff )
121cdf0e10cSrcweir     {
122cdf0e10cSrcweir         sal_uInt16 val1 = static_cast<sal_uInt16>( val & 0xFFFF );
123cdf0e10cSrcweir         sal_uInt16 val2 = static_cast<sal_uInt16>( val >> 16 );
124cdf0e10cSrcweir         sal_uInt8* p = (sal_uInt8*) pBuf + off;
125cdf0e10cSrcweir         *p++ = (char) ( val1 & 0xFF );
126cdf0e10cSrcweir         *p++ = (char) ( val1 >> 8 );
127cdf0e10cSrcweir         *p++ = (char) ( val2 & 0xFF );
128cdf0e10cSrcweir         *p   = (char) ( val2 >> 8 );
129cdf0e10cSrcweir     }
130cdf0e10cSrcweir }
131cdf0e10cSrcweir 
132cdf0e10cSrcweir // Forward References auf Labels und Prozeduren
133*a5246554Smseidel // bauen eine Kette auf. Der Anfang der Kette ist beim übergebenen
134cdf0e10cSrcweir // Parameter, das Ende der Kette ist 0.
135cdf0e10cSrcweir 
Chain(sal_uInt32 off)136cdf0e10cSrcweir void SbiBuffer::Chain( sal_uInt32 off )
137cdf0e10cSrcweir {
138cdf0e10cSrcweir     if( off && pBuf )
139cdf0e10cSrcweir     {
140cdf0e10cSrcweir         sal_uInt8 *ip;
141cdf0e10cSrcweir         sal_uInt32 i = off;
142cdf0e10cSrcweir         sal_uInt32 val1 = (nOff & 0xFFFF);
143cdf0e10cSrcweir         sal_uInt32 val2 = (nOff >> 16);
144cdf0e10cSrcweir         do
145cdf0e10cSrcweir         {
146cdf0e10cSrcweir             ip = (sal_uInt8*) pBuf + i;
147cdf0e10cSrcweir             sal_uInt8* pTmp = ip;
148cdf0e10cSrcweir                 i =  *pTmp++; i |= *pTmp++ << 8; i |= *pTmp++ << 16; i |= *pTmp++ << 24;
149cdf0e10cSrcweir 
150cdf0e10cSrcweir             if( i >= nOff )
151cdf0e10cSrcweir             {
152cdf0e10cSrcweir                 pParser->Error( SbERR_INTERNAL_ERROR, "BACKCHAIN" );
153cdf0e10cSrcweir                 break;
154cdf0e10cSrcweir             }
155cdf0e10cSrcweir             *ip++ = (char) ( val1 & 0xFF );
156cdf0e10cSrcweir             *ip++ = (char) ( val1 >> 8 );
157cdf0e10cSrcweir             *ip++ = (char) ( val2 & 0xFF );
158cdf0e10cSrcweir             *ip   = (char) ( val2 >> 8 );
159cdf0e10cSrcweir         } while( i );
160cdf0e10cSrcweir     }
161cdf0e10cSrcweir }
162cdf0e10cSrcweir 
operator +=(sal_Int8 n)163cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( sal_Int8 n )
164cdf0e10cSrcweir {
165cdf0e10cSrcweir     if( Check( 1 ) )
166cdf0e10cSrcweir     {
167cdf0e10cSrcweir         *pCur++ = (char) n; nOff++; return sal_True;
168cdf0e10cSrcweir     } else return sal_False;
169cdf0e10cSrcweir }
170cdf0e10cSrcweir 
operator +=(sal_uInt8 n)171cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( sal_uInt8 n )
172cdf0e10cSrcweir {
173cdf0e10cSrcweir     if( Check( 1 ) )
174cdf0e10cSrcweir     {
175cdf0e10cSrcweir         *pCur++ = (char) n; nOff++; return sal_True;
176cdf0e10cSrcweir     } else return sal_False;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir 
operator +=(sal_Int16 n)179cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( sal_Int16 n )
180cdf0e10cSrcweir {
181cdf0e10cSrcweir     if( Check( 2 ) )
182cdf0e10cSrcweir     {
183cdf0e10cSrcweir         *pCur++ = (char) ( n & 0xFF );
184cdf0e10cSrcweir         *pCur++ = (char) ( n >> 8 );
185cdf0e10cSrcweir         nOff += 2; return sal_True;
186cdf0e10cSrcweir     } else return sal_False;
187cdf0e10cSrcweir }
188cdf0e10cSrcweir 
operator +=(sal_uInt16 n)189cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( sal_uInt16 n )
190cdf0e10cSrcweir {
191cdf0e10cSrcweir     if( Check( 2 ) )
192cdf0e10cSrcweir     {
193cdf0e10cSrcweir         *pCur++ = (char) ( n & 0xFF );
194cdf0e10cSrcweir         *pCur++ = (char) ( n >> 8 );
195cdf0e10cSrcweir         nOff += 2; return sal_True;
196cdf0e10cSrcweir     } else return sal_False;
197cdf0e10cSrcweir }
198cdf0e10cSrcweir 
operator +=(sal_uInt32 n)199cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( sal_uInt32 n )
200cdf0e10cSrcweir {
201cdf0e10cSrcweir     if( Check( 4 ) )
202cdf0e10cSrcweir     {
203cdf0e10cSrcweir         sal_uInt16 n1 = static_cast<sal_uInt16>( n & 0xFFFF );
204cdf0e10cSrcweir         sal_uInt16 n2 = static_cast<sal_uInt16>( n >> 16 );
205cdf0e10cSrcweir         if ( operator +=( n1 ) && operator +=( n2 ) )
206cdf0e10cSrcweir             return sal_True;
207cdf0e10cSrcweir         return sal_True;
208cdf0e10cSrcweir     }
209cdf0e10cSrcweir     return sal_False;
210cdf0e10cSrcweir }
211cdf0e10cSrcweir 
operator +=(sal_Int32 n)212cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( sal_Int32 n )
213cdf0e10cSrcweir {
214cdf0e10cSrcweir     return operator +=( (sal_uInt32) n );
215cdf0e10cSrcweir }
216cdf0e10cSrcweir 
operator +=(const String & n)217cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( const String& n )
218cdf0e10cSrcweir {
219cdf0e10cSrcweir     sal_uInt16 l = n.Len() + 1;
220cdf0e10cSrcweir     if( Check( l ) )
221cdf0e10cSrcweir     {
222cdf0e10cSrcweir         ByteString aByteStr( n, gsl_getSystemTextEncoding() );
223cdf0e10cSrcweir         memcpy( pCur, aByteStr.GetBuffer(), l );
224cdf0e10cSrcweir         pCur += l;
225cdf0e10cSrcweir         nOff = nOff + l;
226cdf0e10cSrcweir         return sal_True;
227cdf0e10cSrcweir     }
228cdf0e10cSrcweir     else return sal_False;
229cdf0e10cSrcweir }
230cdf0e10cSrcweir 
Add(const void * p,sal_uInt16 len)231cdf0e10cSrcweir sal_Bool SbiBuffer::Add( const void* p, sal_uInt16 len )
232cdf0e10cSrcweir {
233cdf0e10cSrcweir     if( Check( len ) )
234cdf0e10cSrcweir     {
235cdf0e10cSrcweir         memcpy( pCur, p, len );
236cdf0e10cSrcweir         pCur += len;
237cdf0e10cSrcweir         nOff = nOff + len;
238cdf0e10cSrcweir         return sal_True;
239cdf0e10cSrcweir     } else return sal_False;
240cdf0e10cSrcweir }
241cdf0e10cSrcweir 
242*a5246554Smseidel /* vim: set noet sw=4 ts=4: */
243