xref: /AOO41X/main/basic/source/comp/buffer.cxx (revision e1f63238eb022c8a12b30d46a012444ff20e0951)
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