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 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_basic.hxx"
24
25 #include "sbcomp.hxx"
26 #include "buffer.hxx"
27 #include <string.h>
28
29 const static sal_uInt32 UP_LIMIT=0xFFFFFF00L;
30
31 // Der SbiBuffer wird in Inkrements von mindestens 16 Bytes erweitert.
32 // Dies ist notwendig, da viele Klassen von einer Pufferlänge
33 // von x*16 Bytes ausgehen.
34
SbiBuffer(SbiParser * p,short n)35 SbiBuffer::SbiBuffer( SbiParser* p, short n )
36 {
37 pParser = p;
38 n = ( (n + 15 ) / 16 ) * 16;
39 if( !n ) n = 16;
40 pBuf = NULL;
41 pCur = NULL;
42 nInc = n;
43 nSize =
44 nOff = 0;
45 }
46
~SbiBuffer()47 SbiBuffer::~SbiBuffer()
48 {
49 delete[] pBuf;
50 }
51
52 // Rausreichen des Puffers
53 // Dies führt zur Löschung des Puffers!
54
GetBuffer()55 char* SbiBuffer::GetBuffer()
56 {
57 char* p = pBuf;
58 pBuf = NULL;
59 pCur = NULL;
60 return p;
61 }
62
63 // Test, ob der Puffer n Bytes aufnehmen kann.
64 // Im Zweifelsfall wird er vergrössert
65
Check(sal_uInt16 n)66 sal_Bool SbiBuffer::Check( sal_uInt16 n )
67 {
68 if( !n ) return sal_True;
69 if( ( static_cast<sal_uInt32>( nOff )+ n ) > static_cast<sal_uInt32>( nSize ) )
70 {
71 if( nInc == 0 )
72 return sal_False;
73 sal_uInt16 nn = 0;
74 while( nn < n ) nn = nn + nInc;
75 char* p;
76 if( ( static_cast<sal_uInt32>( nSize ) + nn ) > UP_LIMIT ) p = NULL;
77 else p = new char [nSize + nn];
78 if( !p )
79 {
80 pParser->Error( SbERR_PROG_TOO_LARGE );
81 nInc = 0;
82 delete[] pBuf; pBuf = NULL;
83 return sal_False;
84 }
85 else
86 {
87 if( nSize ) memcpy( p, pBuf, nSize );
88 delete[] pBuf;
89 pBuf = p;
90 pCur = pBuf + nOff;
91 nSize = nSize + nn;
92 }
93 }
94 return sal_True;
95 }
96
97 // Angleich des Puffers auf die übergebene Byte-Grenze
98
Align(sal_Int32 n)99 void SbiBuffer::Align( sal_Int32 n )
100 {
101 if( nOff % n ) {
102 sal_uInt32 nn =( ( nOff + n ) / n ) * n;
103 if( nn <= UP_LIMIT )
104 {
105 nn = nn - nOff;
106 if( Check( static_cast<sal_uInt16>(nn) ) )
107 {
108 memset( pCur, 0, nn );
109 pCur += nn;
110 nOff = nOff + nn;
111 }
112 }
113 }
114 }
115
116 // Patch einer Location
117
Patch(sal_uInt32 off,sal_uInt32 val)118 void SbiBuffer::Patch( sal_uInt32 off, sal_uInt32 val )
119 {
120 if( ( off + sizeof( sal_uInt32 ) ) < nOff )
121 {
122 sal_uInt16 val1 = static_cast<sal_uInt16>( val & 0xFFFF );
123 sal_uInt16 val2 = static_cast<sal_uInt16>( val >> 16 );
124 sal_uInt8* p = (sal_uInt8*) pBuf + off;
125 *p++ = (char) ( val1 & 0xFF );
126 *p++ = (char) ( val1 >> 8 );
127 *p++ = (char) ( val2 & 0xFF );
128 *p = (char) ( val2 >> 8 );
129 }
130 }
131
132 // Forward References auf Labels und Prozeduren
133 // bauen eine Kette auf. Der Anfang der Kette ist beim übergebenen
134 // Parameter, das Ende der Kette ist 0.
135
Chain(sal_uInt32 off)136 void SbiBuffer::Chain( sal_uInt32 off )
137 {
138 if( off && pBuf )
139 {
140 sal_uInt8 *ip;
141 sal_uInt32 i = off;
142 sal_uInt32 val1 = (nOff & 0xFFFF);
143 sal_uInt32 val2 = (nOff >> 16);
144 do
145 {
146 ip = (sal_uInt8*) pBuf + i;
147 sal_uInt8* pTmp = ip;
148 i = *pTmp++; i |= *pTmp++ << 8; i |= *pTmp++ << 16; i |= *pTmp++ << 24;
149
150 if( i >= nOff )
151 {
152 pParser->Error( SbERR_INTERNAL_ERROR, "BACKCHAIN" );
153 break;
154 }
155 *ip++ = (char) ( val1 & 0xFF );
156 *ip++ = (char) ( val1 >> 8 );
157 *ip++ = (char) ( val2 & 0xFF );
158 *ip = (char) ( val2 >> 8 );
159 } while( i );
160 }
161 }
162
operator +=(sal_Int8 n)163 sal_Bool SbiBuffer::operator +=( sal_Int8 n )
164 {
165 if( Check( 1 ) )
166 {
167 *pCur++ = (char) n; nOff++; return sal_True;
168 } else return sal_False;
169 }
170
operator +=(sal_uInt8 n)171 sal_Bool SbiBuffer::operator +=( sal_uInt8 n )
172 {
173 if( Check( 1 ) )
174 {
175 *pCur++ = (char) n; nOff++; return sal_True;
176 } else return sal_False;
177 }
178
operator +=(sal_Int16 n)179 sal_Bool SbiBuffer::operator +=( sal_Int16 n )
180 {
181 if( Check( 2 ) )
182 {
183 *pCur++ = (char) ( n & 0xFF );
184 *pCur++ = (char) ( n >> 8 );
185 nOff += 2; return sal_True;
186 } else return sal_False;
187 }
188
operator +=(sal_uInt16 n)189 sal_Bool SbiBuffer::operator +=( sal_uInt16 n )
190 {
191 if( Check( 2 ) )
192 {
193 *pCur++ = (char) ( n & 0xFF );
194 *pCur++ = (char) ( n >> 8 );
195 nOff += 2; return sal_True;
196 } else return sal_False;
197 }
198
operator +=(sal_uInt32 n)199 sal_Bool SbiBuffer::operator +=( sal_uInt32 n )
200 {
201 if( Check( 4 ) )
202 {
203 sal_uInt16 n1 = static_cast<sal_uInt16>( n & 0xFFFF );
204 sal_uInt16 n2 = static_cast<sal_uInt16>( n >> 16 );
205 if ( operator +=( n1 ) && operator +=( n2 ) )
206 return sal_True;
207 return sal_True;
208 }
209 return sal_False;
210 }
211
operator +=(sal_Int32 n)212 sal_Bool SbiBuffer::operator +=( sal_Int32 n )
213 {
214 return operator +=( (sal_uInt32) n );
215 }
216
operator +=(const String & n)217 sal_Bool SbiBuffer::operator +=( const String& n )
218 {
219 sal_uInt16 l = n.Len() + 1;
220 if( Check( l ) )
221 {
222 ByteString aByteStr( n, gsl_getSystemTextEncoding() );
223 memcpy( pCur, aByteStr.GetBuffer(), l );
224 pCur += l;
225 nOff = nOff + l;
226 return sal_True;
227 }
228 else return sal_False;
229 }
230
Add(const void * p,sal_uInt16 len)231 sal_Bool SbiBuffer::Add( const void* p, sal_uInt16 len )
232 {
233 if( Check( len ) )
234 {
235 memcpy( pCur, p, len );
236 pCur += len;
237 nOff = nOff + len;
238 return sal_True;
239 } else return sal_False;
240 }
241
242 /* vim: set noet sw=4 ts=4: */
243