com.adobe.xfa.formcalc.ScopeTable Maven / Gradle / Ivy
Show all versions of aem-sdk-api Show documentation
/*
* ADOBE CONFIDENTIAL
*
* Copyright 2007 Adobe Systems Incorporated All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains the property of
* Adobe Systems Incorporated and its suppliers, if any. The intellectual and
* technical concepts contained herein are proprietary to Adobe Systems
* Incorporated and its suppliers and may be covered by U.S. and Foreign
* Patents, patents in process, and are protected by trade secret or copyright
* law. Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained from
* Adobe Systems Incorporated.
*/
package com.adobe.xfa.formcalc;
/**
* Class ScopeTable defines the scope table used by
* the FormCalc scripting engine.
* The scope table is used to record
*
* - the current scope block,
*
- the next available scope block,
*
- the set of active scope blocks
*
* Scope blocks are identified by an int number, assigned
* sequentially 1...n, each time a new lexical scope block is encountered
* by the FormCalc parser. Because scope blocks can be nested, i.e.,
* more than one scope may be active, the set of active scope blocks
* is maintained.
*
* @author Mike P. Tardif
*
* @exclude from published api.
*/
final class ScopeTable {
static final int SIZE = 128;
/**
* Instantiates an ScopeTable object.
*/
ScopeTable() {
// empty
}
/**
* Creates storage for this object, including
* a set of active scopes of the size given.
* @param nSize an initial size for the set of active scopes.
* @return integer 1 upon success, and 0 otherwise.
*/
int create(int nSize /* = SIZE */) {
mnNextScope = 0;
mnPrevScope = 0;
mnActiveScopeSize = nSize;
moActiveScope = bitAlloc(mnActiveScopeSize);
return 1;
}
/**
* Initializes this object. The set of active scopes is cleared.
*/
void init(CalcParser oParser) {
if (! oParser.mbWasInSaveMode) {
mnNextScope = 1;
mnPrevScope = 1;
}
else if (oParser.mbSyntaxErrorSeen) {
mnNextScope = mnPrevScope;
}
else {
mnPrevScope = mnNextScope;
}
for (int i = mnNextScope - 1; i >= 0; i--)
bitClr(moActiveScope, i);
mnFrameCounter = 0;
}
/**
* Gets this object's current scope block.
* @return the current scope block.
*/
int getScope() {
return mnCurrentScope;
}
/**
* Sets this object's current scope block.
* @param scope a scope block.
*/
void setScope(int scope) {
mnCurrentScope = scope;
}
/**
* Gets this object's current activation frame.
* @return the current activation frame.
*/
int getFrame() {
return mnFrameCounter;
}
/**
* Sets this object's current activation frame.
* @param frame the new activation frame.
*/
void setFrame(int frame) {
mnFrameCounter = frame;
}
/**
* Enters a new scope. Make next available scope the current scope
* and add to the set of active scopes. The size of the active set
* is allowed to grow as needed.
* @return the new (current) scope block.
*/
int enter() {
//
// Grow set of active scopes as needed.
//
if (mnNextScope == mnActiveScopeSize) {
mnActiveScopeSize <<= 1;
int[] oNewScope = bitAlloc(mnActiveScopeSize);
System.arraycopy(moActiveScope, 0, oNewScope, 0,
((mnActiveScopeSize >> 1) + NBPI) >> LNBPI);
moActiveScope = oNewScope;
}
setActive(++mnNextScope);
return mnCurrentScope;
}
/**
* Exits the current scope. Remove the current scope from the set
* of active scopes, and make the prior scope the current scope.
* @return the old (current) scope block.
*/
int exit() {
int nOldScope = mnCurrentScope;
if (mnCurrentScope > 0)
clearActive(mnCurrentScope);
return nOldScope;
}
/**
* Set the given to this object's current scope block, and make it active.
* @param scope a scope block.
*/
void setActive(int scope) {
mnCurrentScope = scope;
bitSet(moActiveScope, scope - 1);
}
/**
* Clear the given scope from this object's active set,
* and make the prior scope block the current scope block.
* @param scope a scope block.
*/
void clearActive(int scope) {
bitClr(moActiveScope, scope - 1);
int i = scope - 2;
while (i >= 0) {
if (isbSet(moActiveScope, i))
break;
i--;
}
mnCurrentScope = i + 1;
}
/**
* Is the given scope in this object's active set.
* @param scope a scope block.
* @return boolean true if active and false otherwise.
*/
boolean isActive(int scope) {
return (scope > 0 && isbSet(moActiveScope, scope - 1));
}
/**
* Is the current scope global.
* @return boolean true if the current scope is global.
*/
boolean isGlobal() {
return (mnCurrentScope == 1);
}
private int mnNextScope; // the next available scope block.
private int mnPrevScope; // the prev available scope block.
private int mnCurrentScope; // the current scope block.
private int mnActiveScopeSize; // the size of set of active scopes.
private int[] moActiveScope; // the set of active scopes.
private int mnFrameCounter; // the activation frame counter.
/*
* Set Operator -- Efficient Bit Mapped Arrays.
*
* Usage:
* int MANYBITS = (1024 * 1024);
* ...
* int[] a = null;
* if ((a = bitAlloc(MANYBITS)) != null) {
* if (isbSet(a, i))
* bitClr(a, i);
* else
* bitSet(a, i);
* }
* ...
*/
private static final int NBPI = 32; /* number of bitS per int */
private static final int LNBPI = 5; /* log2(NBPI) */
private static void bitSet(int[] a, int i) {
a[i >> LNBPI] |= (1 << (i & (NBPI - 1)));
}
private static void bitClr(int[] a, int i) {
a[i >> LNBPI] &= ~(1 << (i & (NBPI - 1)));
}
private static boolean isbSet(int[] a, int i) {
return ((a[i >> LNBPI] & (1 << (i & (NBPI - 1)))) != 0);
}
// Javaport: not used!
// private static boolean isbClr(int[] a, int i) {
// return ((a[i >> LNBPI] & (1 << (i & (NBPI - 1)))) == 0);
// }
private static int[] bitAlloc(int n) {
return new int[(n + NBPI) >> LNBPI];
}
}