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