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