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 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 47 SbiBuffer::~SbiBuffer() 48 { 49 delete[] pBuf; 50 } 51 52 // Rausreichen des Puffers 53 // Dies führt zur Löschung des Puffers! 54 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 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 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 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 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 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 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 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 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 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 212 sal_Bool SbiBuffer::operator +=( sal_Int32 n ) 213 { 214 return operator +=( (sal_uInt32) n ); 215 } 216 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 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