/* * Copyright (C) 2007-2013 Xagasoft, All rights reserved. * * This file is part of the libgats library and is released under the * terms of the license contained in the file LICENSE. */ using System.IO; namespace Com.Xagasoft.Gats { /// /// Encapsulates a single integer value. /// /// /// The GATS integer encoding is arbitrary precision, and only consumes as /// many bytes as it needs to represent a given number. There is no such /// thing as an unsigned GATS integer. /// /// Internally the GatsInteger stores it's value in a long. /// /// In encoding, the type specifier for a GATS integer is 'i'. /// public class GatsInteger : GatsObject { public long Value { get; set; } public GatsInteger( long val=0 ) { Value = val; } public override string ToString() { return Value.ToString(); } public override void Read( Stream s, char cType ) { Value = ReadPackedInt( s ); } public override void Write( Stream s ) { s.WriteByte( (int)'i' ); WritePackedInt( s, Value ); } public static long ReadPackedInt( Stream s ) { int b; long rOut = 0; bool bNeg; b = s.ReadByte(); if( b == -1 ) throw new GatsException( GatsException.Type.PrematureEnd ); bNeg = (b&0x40) == 0x40; rOut |= ((long)b)&0x3F; int c = 0; while( (b&0x80) == 0x80 ) { b = s.ReadByte(); if( b == -1 ) throw new GatsException( GatsException.Type.PrematureEnd ); rOut |= (long)(b&0x7F) << (6+7*(c++)); } if( bNeg ) return -rOut; return rOut; } public static void WritePackedInt( Stream s, long iIn ) { byte b; if( iIn < 0 ) { iIn = -iIn; b = (byte)(iIn&0x3F); if( iIn > b ) b |= 0x80 | 0x40; else b |= 0x40; } else { b = (byte)(iIn&0x3F); if( iIn > b ) b |= 0x80; } s.WriteByte( b ); iIn = iIn >> 6; while( iIn > 0 ) { b = (byte)(iIn&0x7F); if( iIn > b ) b |= 0x80; s.WriteByte( b ); iIn = iIn >> 7; } } }; }