xref: /AOO41X/main/basic/source/comp/buffer.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_basic.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "sbcomp.hxx"
32*cdf0e10cSrcweir #include "buffer.hxx"
33*cdf0e10cSrcweir #include <string.h>
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir const static sal_uInt32 UP_LIMIT=0xFFFFFF00L;
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir // Der SbiBuffer wird in Inkrements von mindestens 16 Bytes erweitert.
38*cdf0e10cSrcweir // Dies ist notwendig, da viele Klassen von einer Pufferlaenge
39*cdf0e10cSrcweir // von x*16 Bytes ausgehen.
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir SbiBuffer::SbiBuffer( SbiParser* p, short n )
42*cdf0e10cSrcweir {
43*cdf0e10cSrcweir 	pParser = p;
44*cdf0e10cSrcweir 	n = ( (n + 15 ) / 16 ) * 16;
45*cdf0e10cSrcweir 	if( !n ) n = 16;
46*cdf0e10cSrcweir 	pBuf  = NULL;
47*cdf0e10cSrcweir 	pCur  = NULL;
48*cdf0e10cSrcweir 	nInc  = n;
49*cdf0e10cSrcweir 	nSize =
50*cdf0e10cSrcweir 	nOff  = 0;
51*cdf0e10cSrcweir }
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir SbiBuffer::~SbiBuffer()
54*cdf0e10cSrcweir {
55*cdf0e10cSrcweir 	delete[] pBuf;
56*cdf0e10cSrcweir }
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir // Rausreichen des Puffers
59*cdf0e10cSrcweir // Dies fuehrt zur Loeschung des Puffers!
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir char* SbiBuffer::GetBuffer()
62*cdf0e10cSrcweir {
63*cdf0e10cSrcweir 	char* p = pBuf;
64*cdf0e10cSrcweir 	pBuf = NULL;
65*cdf0e10cSrcweir 	pCur = NULL;
66*cdf0e10cSrcweir 	return p;
67*cdf0e10cSrcweir }
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir // Test, ob der Puffer n Bytes aufnehmen kann.
70*cdf0e10cSrcweir // Im Zweifelsfall wird er vergroessert
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir sal_Bool SbiBuffer::Check( sal_uInt16 n )
73*cdf0e10cSrcweir {
74*cdf0e10cSrcweir 	if( !n ) return sal_True;
75*cdf0e10cSrcweir 	if( ( static_cast<sal_uInt32>( nOff )+ n ) >  static_cast<sal_uInt32>( nSize ) )
76*cdf0e10cSrcweir 	{
77*cdf0e10cSrcweir 		if( nInc == 0 )
78*cdf0e10cSrcweir 			return sal_False;
79*cdf0e10cSrcweir 		sal_uInt16 nn = 0;
80*cdf0e10cSrcweir 		while( nn < n ) nn = nn + nInc;
81*cdf0e10cSrcweir 		char* p;
82*cdf0e10cSrcweir 		if( ( static_cast<sal_uInt32>( nSize ) + nn ) > UP_LIMIT ) p = NULL;
83*cdf0e10cSrcweir 		else p = new char [nSize + nn];
84*cdf0e10cSrcweir 		if( !p )
85*cdf0e10cSrcweir 		{
86*cdf0e10cSrcweir 			pParser->Error( SbERR_PROG_TOO_LARGE );
87*cdf0e10cSrcweir 			nInc = 0;
88*cdf0e10cSrcweir 			delete[] pBuf; pBuf = NULL;
89*cdf0e10cSrcweir 			return sal_False;
90*cdf0e10cSrcweir 		}
91*cdf0e10cSrcweir 		else
92*cdf0e10cSrcweir 		{
93*cdf0e10cSrcweir 			if( nSize ) memcpy( p, pBuf, nSize );
94*cdf0e10cSrcweir 			delete[] pBuf;
95*cdf0e10cSrcweir 			pBuf = p;
96*cdf0e10cSrcweir 			pCur = pBuf + nOff;
97*cdf0e10cSrcweir 			nSize = nSize + nn;
98*cdf0e10cSrcweir 		}
99*cdf0e10cSrcweir 	}
100*cdf0e10cSrcweir 	return sal_True;
101*cdf0e10cSrcweir }
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir // Angleich des Puffers auf die uebergebene Byte-Grenze
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir void SbiBuffer::Align( sal_Int32 n )
106*cdf0e10cSrcweir {
107*cdf0e10cSrcweir 	if( nOff % n ) {
108*cdf0e10cSrcweir 		sal_uInt32 nn =( ( nOff + n ) / n ) * n;
109*cdf0e10cSrcweir 		if( nn <= UP_LIMIT )
110*cdf0e10cSrcweir 		{
111*cdf0e10cSrcweir 			nn = nn - nOff;
112*cdf0e10cSrcweir 			if( Check( static_cast<sal_uInt16>(nn) ) )
113*cdf0e10cSrcweir 			{
114*cdf0e10cSrcweir 				memset( pCur, 0, nn );
115*cdf0e10cSrcweir 				pCur += nn;
116*cdf0e10cSrcweir 				nOff = nOff + nn;
117*cdf0e10cSrcweir 			}
118*cdf0e10cSrcweir 		}
119*cdf0e10cSrcweir 	}
120*cdf0e10cSrcweir }
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir // Patch einer Location
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir void SbiBuffer::Patch( sal_uInt32 off, sal_uInt32 val )
125*cdf0e10cSrcweir {
126*cdf0e10cSrcweir 	if( ( off + sizeof( sal_uInt32 ) ) < nOff )
127*cdf0e10cSrcweir 	{
128*cdf0e10cSrcweir 		sal_uInt16 val1 = static_cast<sal_uInt16>( val & 0xFFFF );
129*cdf0e10cSrcweir 		sal_uInt16 val2 = static_cast<sal_uInt16>( val >> 16 );
130*cdf0e10cSrcweir 		sal_uInt8* p = (sal_uInt8*) pBuf + off;
131*cdf0e10cSrcweir 		*p++ = (char) ( val1 & 0xFF );
132*cdf0e10cSrcweir 		*p++ = (char) ( val1 >> 8 );
133*cdf0e10cSrcweir 		*p++ = (char) ( val2 & 0xFF );
134*cdf0e10cSrcweir 		*p   = (char) ( val2 >> 8 );
135*cdf0e10cSrcweir 	}
136*cdf0e10cSrcweir }
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir // Forward References auf Labels und Prozeduren
139*cdf0e10cSrcweir // bauen eine Kette auf. Der Anfang der Kette ist beim uebergebenen
140*cdf0e10cSrcweir // Parameter, das Ende der Kette ist 0.
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir void SbiBuffer::Chain( sal_uInt32 off )
143*cdf0e10cSrcweir {
144*cdf0e10cSrcweir 	if( off && pBuf )
145*cdf0e10cSrcweir 	{
146*cdf0e10cSrcweir 		sal_uInt8 *ip;
147*cdf0e10cSrcweir 		sal_uInt32 i = off;
148*cdf0e10cSrcweir 		sal_uInt32 val1 = (nOff & 0xFFFF);
149*cdf0e10cSrcweir 		sal_uInt32 val2 = (nOff >> 16);
150*cdf0e10cSrcweir 		do
151*cdf0e10cSrcweir 		{
152*cdf0e10cSrcweir 			ip = (sal_uInt8*) pBuf + i;
153*cdf0e10cSrcweir 			sal_uInt8* pTmp = ip;
154*cdf0e10cSrcweir              		i =  *pTmp++; i |= *pTmp++ << 8; i |= *pTmp++ << 16; i |= *pTmp++ << 24;
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir 			if( i >= nOff )
157*cdf0e10cSrcweir 			{
158*cdf0e10cSrcweir 				pParser->Error( SbERR_INTERNAL_ERROR, "BACKCHAIN" );
159*cdf0e10cSrcweir 				break;
160*cdf0e10cSrcweir 			}
161*cdf0e10cSrcweir 			*ip++ = (char) ( val1 & 0xFF );
162*cdf0e10cSrcweir 			*ip++ = (char) ( val1 >> 8 );
163*cdf0e10cSrcweir 			*ip++ = (char) ( val2 & 0xFF );
164*cdf0e10cSrcweir 			*ip   = (char) ( val2 >> 8 );
165*cdf0e10cSrcweir 		} while( i );
166*cdf0e10cSrcweir 	}
167*cdf0e10cSrcweir }
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( sal_Int8 n )
170*cdf0e10cSrcweir {
171*cdf0e10cSrcweir 	if( Check( 1 ) )
172*cdf0e10cSrcweir 	{
173*cdf0e10cSrcweir 		*pCur++ = (char) n; nOff++; return sal_True;
174*cdf0e10cSrcweir 	} else return sal_False;
175*cdf0e10cSrcweir }
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( sal_uInt8 n )
178*cdf0e10cSrcweir {
179*cdf0e10cSrcweir 	if( Check( 1 ) )
180*cdf0e10cSrcweir 	{
181*cdf0e10cSrcweir 		*pCur++ = (char) n; nOff++; return sal_True;
182*cdf0e10cSrcweir 	} else return sal_False;
183*cdf0e10cSrcweir }
184*cdf0e10cSrcweir 
185*cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( sal_Int16 n )
186*cdf0e10cSrcweir {
187*cdf0e10cSrcweir 	if( Check( 2 ) )
188*cdf0e10cSrcweir 	{
189*cdf0e10cSrcweir 		*pCur++ = (char) ( n & 0xFF );
190*cdf0e10cSrcweir 		*pCur++ = (char) ( n >> 8 );
191*cdf0e10cSrcweir 		nOff += 2; return sal_True;
192*cdf0e10cSrcweir 	} else return sal_False;
193*cdf0e10cSrcweir }
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( sal_uInt16 n )
196*cdf0e10cSrcweir {
197*cdf0e10cSrcweir 	if( Check( 2 ) )
198*cdf0e10cSrcweir 	{
199*cdf0e10cSrcweir 		*pCur++ = (char) ( n & 0xFF );
200*cdf0e10cSrcweir 		*pCur++ = (char) ( n >> 8 );
201*cdf0e10cSrcweir 		nOff += 2; return sal_True;
202*cdf0e10cSrcweir 	} else return sal_False;
203*cdf0e10cSrcweir }
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( sal_uInt32 n )
206*cdf0e10cSrcweir {
207*cdf0e10cSrcweir 	if( Check( 4 ) )
208*cdf0e10cSrcweir 	{
209*cdf0e10cSrcweir 		sal_uInt16 n1 = static_cast<sal_uInt16>( n & 0xFFFF );
210*cdf0e10cSrcweir 		sal_uInt16 n2 = static_cast<sal_uInt16>( n >> 16 );
211*cdf0e10cSrcweir 		if ( operator +=( n1 ) && operator +=( n2 ) )
212*cdf0e10cSrcweir 			return sal_True;
213*cdf0e10cSrcweir 		return sal_True;
214*cdf0e10cSrcweir 	}
215*cdf0e10cSrcweir 	return sal_False;
216*cdf0e10cSrcweir }
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( sal_Int32 n )
219*cdf0e10cSrcweir {
220*cdf0e10cSrcweir 	return operator +=( (sal_uInt32) n );
221*cdf0e10cSrcweir }
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir sal_Bool SbiBuffer::operator +=( const String& n )
225*cdf0e10cSrcweir {
226*cdf0e10cSrcweir 	sal_uInt16 l = n.Len() + 1;
227*cdf0e10cSrcweir 	if( Check( l ) )
228*cdf0e10cSrcweir 	{
229*cdf0e10cSrcweir 		ByteString aByteStr( n, gsl_getSystemTextEncoding() );
230*cdf0e10cSrcweir 		memcpy( pCur, aByteStr.GetBuffer(), l );
231*cdf0e10cSrcweir 		pCur += l;
232*cdf0e10cSrcweir 		nOff = nOff + l;
233*cdf0e10cSrcweir 		return sal_True;
234*cdf0e10cSrcweir 	}
235*cdf0e10cSrcweir 	else return sal_False;
236*cdf0e10cSrcweir }
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir sal_Bool SbiBuffer::Add( const void* p, sal_uInt16 len )
239*cdf0e10cSrcweir {
240*cdf0e10cSrcweir 	if( Check( len ) )
241*cdf0e10cSrcweir 	{
242*cdf0e10cSrcweir 		memcpy( pCur, p, len );
243*cdf0e10cSrcweir 		pCur += len;
244*cdf0e10cSrcweir 		nOff = nOff + len;
245*cdf0e10cSrcweir 		return sal_True;
246*cdf0e10cSrcweir 	} else return sal_False;
247*cdf0e10cSrcweir }
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir 
251