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