All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jclarion.clarion.ClarionNumber Maven / Gradle / Ivy

There is a newer version: 1.86
Show newest version
/**
 * Copyright 2010, by Andrew Barnham
 *
 * The contents of this file are subject to
 * GNU Lesser General Public License (LGPL), v.3
 * http://www.gnu.org/licenses/lgpl.txt
 * 
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.
 */
package org.jclarion.clarion;


import org.jclarion.clarion.memory.CMem;
import org.jclarion.clarion.primative.AbstractStateFactory;
import org.jclarion.clarion.primative.AbstractStateGetter;
import org.jclarion.clarion.primative.GlobalStateGetter;
import org.jclarion.clarion.primative.ThreadStateGetter;

/**
 * Model number. Internally stored as java primitive 'int'
 * 
 * @author barney
 */
public class ClarionNumber extends ClarionObject {

    public static final int SIGNED  = 0x141;         // 32 bit signed
    public static final int BYTE    = 0x210;         // 8 bit unsigned
    public static final int LONG    = 0x341;         // 32 bit signed
    public static final int ULONG   = 0x440;         // 32 bit unsigned
    public static final int USHORT  = 0x520;         // 16 bit unsigned
    public static final int SHORT   = 0x621;         // 16 bit signed
    public static final int UNSIGNED= 0x740;         // 32 bit unsigned
    public static final int DATE    = 0x840;         // 32 bit
    public static final int TIME    = 0x940;         // 32 bit

    private int encoding=LONG;

    public static class State
    {
        private int    val;
        public State(ClarionNumber.State base) {
            val=base.val;
        }
        public State() {
        }
    }
    
    private static class StateFactory extends AbstractStateFactory
    {
        @Override
        public State cloneState(State base) {
            return new State(base);
        }

        @Override
        public State createState() {
            return new State();
        }
    }
    private static StateFactory factory=new StateFactory();
    
    private AbstractStateGetter state=new GlobalStateGetter(factory);
    
    public void initThread()
    {
        if (!state.isThreaded()) state=new ThreadStateGetter(factory,state);
        super.initThread();
    }

    public ClarionNumber setThread()
    {
        initThread();
        return this;
    }
    
    @Override
    public Object getLockedObject(Thread t) 
    {
        if (!state.isThreaded()) return this;
        return new ClarionNumber(this,t);
    }
    
    public ClarionNumber(ClarionNumber base,Thread lock)
    {
        super(base,lock);
        this.encoding=base.encoding;
        if (lock!=null) this.state=base.state.getLockedGetter(lock);
    }
    
    
    /**
     * Create 0 number
     */
    public ClarionNumber()
    {
        this(0);
    }
    
    /**
     * Create number of specified value
     * 
     * @param number
     */
    public ClarionNumber(int number)
    {
        state.get().val=number;
    }

    /**
     * Create number of specified value
     * 
     * @param value
     */
    public ClarionNumber(String value)
    {
    	int number=0;
    	try {
    		number = Integer.parseInt(value);
    	} catch (NumberFormatException ex) { }
        state.get().val=number;
    }

    public String toString()
    {
        return String.valueOf(state.get().val);
    }
    
    @Override
    public void concatSegment(StringBuilder target)
    {
        target.append(state.get().val); 
    }
    
    /**
     * Clone number
     * 
     * @return
     */
    public ClarionNumber like()
    {
        ClarionNumber n = new ClarionNumber(state.get().val);
        n.encoding=encoding;
        return n;
    }
    
    @Override
    public ClarionObject add(ClarionObject object) 
    {
        if (object.isDecimal()) return getDecimal().add(object);
        return new ClarionNumber(state.get().val+object.intValue());
    }

    @Override
    public void setValue(ClarionObject object) 
    {
        int new_value = object==null? 0 : object.intValue();
        if (new_value!=state.get().val) {
            state.get().val=new_value;
            notifyChange();
        }
    }

    @Override
    public int compareTo(ClarionObject object) {
        
        if (object instanceof ClarionString) {
            // lexical comparison
            return -object.compareTo(this);
        }
        
        if (object instanceof ClarionDecimal) {
            // more accurate comparison
            return -object.compareTo(this);
        }

        if (object instanceof ClarionReal) {
            // more accurate comparison
            return -object.compareTo(this);
        }
        
        int diff = state.get().val - object.intValue();
        if (diff<0) return -1;
        if (diff>0) return 1;
        return 0;
    }


    @Override
    public int intValue() {
        return state.get().val;
    }


    @Override
    public ClarionObject multiply(ClarionObject object) {
        if (object.isDecimal()) return getDecimal().multiply(object);
        return new ClarionNumber(state.get().val*object.intValue());
    }
    
    /**
     * return 1d array clone of the object based on size. Note java object
     * array returned is one larger than specified as clarion starts arrays at
     * offset '1' whilst java as offset '0'
     */ 
    public ClarionArray dim(int size)
    {
    	return new ClarionArray(this,size);
    }
    
    
    /**
     * Set external name for object - used by SQL drivers etc
     * 
     * @param name
     * @return
     */
    public ClarionNumber setName(String name)
    {
        doSetName(name);
        return this;
    }
    
    /**
     * Set memory encoding. A multiple of options for this object type
     * 
     * @param encoding
     * @return
     */
    public ClarionNumber setEncoding(int encoding)
    {
        this.encoding=encoding;
        return this;
    }
    
    public int getEncoding()
    {
        return encoding;
    }


    @Override
    public ClarionBool getBool() {
        return new ClarionBool(boolValue());
    }


    @Override
    public ClarionNumber getNumber() {
        return this;
    }


    @Override
    public ClarionReal getReal() {
        return new ClarionReal(state.get().val);
    }


    @Override
    public ClarionString getString() {
        return new ClarionString(String.valueOf(state.get().val));
    }


    @Override
    public ClarionObject divide(ClarionObject object) {
        

        if (object  instanceof ClarionNumber) {
            int denom = object.getNumber().intValue();
            if (denom==0) return new ClarionNumber(0);
            int value = state.get().val;
            if (value%denom==0) return new ClarionNumber(value/denom);
        }
        
        //if (object.isDecimal()) return getDecimal().divide(object);
        //return new ClarionNumber(value/object.intValue());
        return getDecimal().divide(object);
    }


    @Override
    public ClarionObject modulus(ClarionObject object) {
        if (object.isDecimal()) return getDecimal().modulus(object);
        return new ClarionNumber(state.get().val%object.intValue());
    }


    @Override
    public ClarionObject power(ClarionObject object) {
        if (object.isDecimal()) return getDecimal().power(object);
        
        return new ClarionNumber(
                java.math.BigInteger.valueOf(state.get().val).pow(object.intValue()).intValue());
    }


    @Override
    public ClarionObject subtract(ClarionObject object) {
        if (object.isDecimal()) return getDecimal().subtract(object);
        return new ClarionNumber(state.get().val-object.intValue());
    }


    @Override
    public boolean boolValue() {
        return state.get().val!=0;
    }


    @Override
    public void clear(int method) {
        if (method==0) setValue(0);
        if (method>0) {
        	switch(encoding) {
        		case BYTE:
        			setValue(255);
        			break;
        		case SHORT:
        			setValue(32767);
        			break;
        		case USHORT:
        			setValue(65535);
        			break;
        		default:
                	setValue(0x7fffffff);
                	break;
        	}		        	
        } else if (method<0) {
        	switch(encoding) {
        		case BYTE:
        		case ULONG:
        		case UNSIGNED:
        		case USHORT:
        			setValue(0);
        			break;
        		case SHORT:
        			setValue(-32768);
        			break;
    			default:
    				setValue(0x80000000);
    				break;
        	}
    	}		        	
    }


    @Override
    public ClarionObject negate() {
        return new ClarionNumber(-state.get().val);
    }


    @Override
    public ClarionDecimal getDecimal() {
        return new ClarionDecimal(java.math.BigDecimal.valueOf(state.get().val));
    }

    /**
     * Return absolute value for this object
     * 
     * @return
     */
    public ClarionNumber abs()
    {
        int value=state.get().val;
        return new ClarionNumber(value<0?-value:value);
    }
    
    /**
     * Overlay this object on another objects memory model
     */
    public ClarionNumber setOver(ClarionMemoryModel o)
    {
        doSetOver(o);
        return this;
    }
    
    /**
     * Bit shift a number.
     * 
     * @param value number to shift
     * @param shiftval +ve shift left. -ve = shift right.
     * @return resultant value
     */
    public static int shift(int value,int shiftval)
    {
        if (shiftval>0) {
            return value<>(-shiftval);
        }
        return value;
    }


    @Override
    public void deserialize(CMem is) {
        //if (encoding==DATE) throw new RuntimeException("Not yet implemented");
        //if (encoding==TIME) throw new RuntimeException("Not yet implemented");
        
        int new_value=0;
        int v;

        if ((encoding & 0x70)!=0) {
            v = is.readByte();
            new_value=(v&0xff);
        }

        if ((encoding & 0x60)!=0) {
            v = is.readByte();
            new_value+=((v&0xff)<<8);
        }
        
        if ((encoding & 0x40)!=0) {
            v = is.readByte();
            new_value+=((v&0xff)<<16);
            v = is.readByte();
            new_value+=((v&0xff)<<24);
        }

        
        if ((encoding & 0x01)!=0) {
            if ((encoding & 0x020)!=0 && (new_value&0x008000)!=0) {
                new_value = new_value | 0xffff0000;
            }

            if ((encoding & 0x010)!=0 && (new_value&0x000080)!=0) {
                new_value = new_value | 0xffffff00;
            }
        }
        
        setValue(new_value);
    }


    @Override
    public void serialize(CMem os) {
    
        int value = state.get().val;
        
        if (encoding==DATE) {
            //throw new RuntimeException("Not yet implemented");
        }
        if (encoding==TIME) {
            //throw new RuntimeException("Not yet implemented");
        }

        if ((encoding & 0x70)!=0) {
            os.writeByte(value);
        }

        if ((encoding & 0x60)!=0) {
            os.writeByte(value>>8);
        }
        
        if ((encoding & 0x40)!=0) {
            os.writeByte(value>>16);
            os.writeByte(value>>24);
        }


    }

    @Override
    public ClarionObject genericLike() {
        return like();
    }

    @Override
    public boolean isConstrained() 
    {
        return false;
    }

    @Override
    public int getSize() {
        return -1;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy