Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / basic / source / comp / buffer.cxx
bloba7dca978b27a93b7917d168e346006fe2782f086
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <buffer.hxx>
21 #include <parser.hxx>
23 #include <basic/sberrors.hxx>
25 const static sal_uInt32 UP_LIMIT=0xFFFFFF00;
27 // The SbiBuffer will be expanded in increments of at least 16 Bytes.
28 // This is necessary, because many classes emanate from a buffer length
29 // of x*16 Bytes.
31 SbiBuffer::SbiBuffer( SbiParser* p, short n )
33 pParser = p;
34 n = ( (n + 15 ) / 16 ) * 16;
35 if( !n ) n = 16;
36 pBuf = nullptr;
37 pCur = nullptr;
38 nInc = n;
39 nSize =
40 nOff = 0;
43 SbiBuffer::~SbiBuffer()
47 // Reach out the buffer
48 // This lead to the deletion of the buffer!
50 char* SbiBuffer::GetBuffer()
52 char* p = pBuf.release();
53 pCur = nullptr;
54 return p;
57 // Test, if the buffer can contain n Bytes.
58 // In case of doubt it will be enlarged
60 bool SbiBuffer::Check( sal_Int32 n )
62 if( !n )
64 return true;
66 if( nOff + n > nSize )
68 if( nInc == 0 )
70 return false;
73 sal_Int32 nn = 0;
74 while( nn < n )
76 nn = nn + nInc;
78 char* p;
79 if( ( nSize + nn ) > UP_LIMIT )
81 p = nullptr;
83 else
85 p = new char [nSize + nn];
87 if( !p )
89 pParser->Error( ERRCODE_BASIC_PROG_TOO_LARGE );
90 nInc = 0;
91 pBuf.reset();
92 return false;
94 else
96 if( nSize ) memcpy( p, pBuf.get(), nSize );
97 pBuf.reset(p);
98 pCur = pBuf.get() + nOff;
99 nSize = nSize + nn;
102 return true;
105 // Patch of a Location
107 void SbiBuffer::Patch( sal_uInt32 off, sal_uInt32 val )
109 if( ( off + sizeof( sal_uInt32 ) ) < nOff )
111 sal_uInt16 val1 = static_cast<sal_uInt16>( val & 0xFFFF );
112 sal_uInt16 val2 = static_cast<sal_uInt16>( val >> 16 );
113 sal_uInt8* p = reinterpret_cast<sal_uInt8*>(pBuf.get()) + off;
114 *p++ = static_cast<char>( val1 & 0xFF );
115 *p++ = static_cast<char>( val1 >> 8 );
116 *p++ = static_cast<char>( val2 & 0xFF );
117 *p = static_cast<char>( val2 >> 8 );
121 // Forward References upon label and procedures
122 // establish a linkage. The beginning of the linkage is at the passed parameter,
123 // the end of the linkage is 0.
125 void SbiBuffer::Chain( sal_uInt32 off )
127 if( off && pBuf )
129 sal_uInt8 *ip;
130 sal_uInt32 i = off;
131 sal_uInt32 val1 = (nOff & 0xFFFF);
132 sal_uInt32 val2 = (nOff >> 16);
135 ip = reinterpret_cast<sal_uInt8*>(pBuf.get()) + i;
136 sal_uInt8* pTmp = ip;
137 i = *pTmp++; i |= *pTmp++ << 8; i |= *pTmp++ << 16; i |= *pTmp++ << 24;
139 if( i >= nOff )
141 pParser->Error( ERRCODE_BASIC_INTERNAL_ERROR, "BACKCHAIN" );
142 break;
144 *ip++ = static_cast<char>( val1 & 0xFF );
145 *ip++ = static_cast<char>( val1 >> 8 );
146 *ip++ = static_cast<char>( val2 & 0xFF );
147 *ip = static_cast<char>( val2 >> 8 );
148 } while( i );
152 void SbiBuffer::operator +=( sal_Int8 n )
154 if( Check( 1 ) )
156 *pCur++ = static_cast<char>(n);
157 nOff += 1;
161 bool SbiBuffer::operator +=( sal_uInt8 n )
163 if( Check( 1 ) )
165 *pCur++ = static_cast<char>(n);
166 nOff += 1;
167 return true;
169 else
171 return false;
175 void SbiBuffer::operator +=( sal_Int16 n )
177 if( Check( 2 ) )
179 *pCur++ = static_cast<char>( n & 0xFF );
180 *pCur++ = static_cast<char>( n >> 8 );
181 nOff += 2;
185 bool SbiBuffer::operator +=( sal_uInt16 n )
187 if( Check( 2 ) )
189 *pCur++ = static_cast<char>( n & 0xFF );
190 *pCur++ = static_cast<char>( n >> 8 );
191 nOff += 2;
192 return true;
194 else
196 return false;
200 bool SbiBuffer::operator +=( sal_uInt32 n )
202 if( Check( 4 ) )
204 sal_uInt16 n1 = static_cast<sal_uInt16>( n & 0xFFFF );
205 sal_uInt16 n2 = static_cast<sal_uInt16>( n >> 16 );
206 operator +=(n1) && operator +=(n2);
207 return true;
209 else
211 return false;
215 void SbiBuffer::operator +=( sal_Int32 n )
217 operator +=( static_cast<sal_uInt32>(n) );
221 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */