Update contrib.
2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
22 #include <securityerr.h>
24 #include "algorithms.h"
25 #include "windowslider.h"
26 #include "stackinteger.h"
31 * Creates a new buffer containing the big-endian binary representation of this
34 * Note that it does not support the exporting of negative integers.
36 * @return The new buffer.
38 * @leave KErrNegativeExportNotSupported If this instance is a negative integer.
41 EXPORT_C HBufC8* TInteger::BufferLC() const
45 User::Leave(KErrNegativeExportNotSupported);
47 TUint bytes = ByteCount();
48 HBufC8* buf = HBufC8::NewMaxLC(bytes);
49 TUint8* bufPtr = (TUint8*)(buf->Ptr());
50 TUint8* regPtr = (TUint8*)Ptr();
52 // we internally store the number little endian, as a string we want it big
54 for(TUint i=0,j=bytes-1; i<bytes; )
56 bufPtr[i++] = regPtr[j--];
61 EXPORT_C HBufC8* TInteger::BufferWithNoTruncationLC() const
65 User::Leave(KErrNegativeExportNotSupported);
68 TUint wordCount = Size();
69 TUint bytes = (wordCount)*WORD_SIZE;
71 HBufC8* buf = HBufC8::NewMaxLC(bytes);
72 TUint8* bufPtr = (TUint8*)(buf->Ptr());
73 TUint8* regPtr = (TUint8*)Ptr();
74 for(TUint i=0,j=bytes-1; i<bytes; )
76 bufPtr[i++] = regPtr[j--];
83 * Gets the number of words required to represent this RInteger.
85 * @return The size of the integer in words.
88 EXPORT_C TUint TInteger::WordCount() const
90 return CountWords(Ptr(), Size());
94 * Gets the number of bytes required to represent this RInteger.
96 * @return The size of the integer in bytes.
99 EXPORT_C TUint TInteger::ByteCount() const
101 TUint wordCount = WordCount();
104 return (wordCount-1)*WORD_SIZE + BytePrecision((Ptr())[wordCount-1]);
113 * Get the number of bits required to represent this RInteger.
115 * @return The size of the integer in bits.
118 EXPORT_C TUint TInteger::BitCount() const
120 TUint wordCount = WordCount();
123 return (wordCount-1)*WORD_BITS + BitPrecision(Ptr()[wordCount-1]);
132 //These 3 declarations instantiate a constant 0, 1, 2 for ease of use and
133 //quick construction elsewhere in the code. Note that the functions
134 //returning references to this static data return const references as you can't
136 //word 0: Size of storage in words
137 //word 1: Pointer to storage
138 //word 2: LSW of storage
139 //word 3: MSW of storage
140 //Note that the flag bits in word 1 (Ptr()) are zero in the case of a positive
141 //stack based integer (SignBit == 0, IsHeapBasedBit == 0)
142 const TUint KBigintZero[4] = {2, (TUint)(KBigintZero+2), 0, 0};
143 const TUint KBigintOne[4] = {2, (TUint)(KBigintOne+2), 1, 0};
144 const TUint KBigintTwo[4] = {2, (TUint)(KBigintTwo+2), 2, 0};
147 * Gets the TInteger that represents zero
149 * @return The TInteger representing zero
151 EXPORT_C const TInteger& TInteger::Zero(void)
153 return *reinterpret_cast<const TStackInteger64*>(KBigintZero);
157 * Gets the TInteger that represents one
159 * @return The TInteger representing one
161 EXPORT_C const TInteger& TInteger::One(void)
163 return *reinterpret_cast<const TStackInteger64*>(KBigintOne);
167 * Gets the TInteger that represents two
169 * @return The TInteger representing two
171 EXPORT_C const TInteger& TInteger::Two(void)
173 return *reinterpret_cast<const TStackInteger64*>(KBigintTwo);
176 EXPORT_C RInteger TInteger::PlusL(const TInteger& aOperand) const
181 if (aOperand.NotNegative())
182 sum = PositiveAddL(*this, aOperand);
184 sum = PositiveSubtractL(*this, aOperand);
188 if (aOperand.NotNegative())
189 sum = PositiveSubtractL(aOperand, *this);
192 sum = PositiveAddL(*this, aOperand);
193 sum.SetSign(TInteger::ENegative);
199 EXPORT_C RInteger TInteger::MinusL(const TInteger& aOperand) const
204 if (aOperand.NotNegative())
205 diff = PositiveSubtractL(*this, aOperand);
207 diff = PositiveAddL(*this, aOperand);
211 if (aOperand.NotNegative())
213 diff = PositiveAddL(*this, aOperand);
214 diff.SetSign(TInteger::ENegative);
217 diff = PositiveSubtractL(aOperand, *this);
222 EXPORT_C RInteger TInteger::TimesL(const TInteger& aOperand) const
224 RInteger product = PositiveMultiplyL(*this, aOperand);
226 if (NotNegative() != aOperand.NotNegative())
233 EXPORT_C RInteger TInteger::DividedByL(const TInteger& aOperand) const
237 DivideL(remainder, quotient, *this, aOperand);
242 EXPORT_C RInteger TInteger::DividedByL(TUint aOperand) const
246 DivideL(remainder, quotient, *this, aOperand);
250 EXPORT_C RInteger TInteger::ModuloL(const TInteger& aOperand) const
254 DivideL(remainder, quotient, *this, aOperand);
259 EXPORT_C TUint TInteger::ModuloL(TUint aOperand) const
263 User::Leave(KErrDivideByZero);
265 return Modulo(*this, aOperand);
268 EXPORT_C RInteger TInteger::SquaredL() const
270 //PositiveMultiplyL optimises for the squaring case already
271 //Any number squared is positive, no need for negative handling in TimesL
272 return PositiveMultiplyL(*this, *this);
275 EXPORT_C RInteger TInteger::ExponentiateL(const TInteger& aExponent) const
279 // 1.1 Precomputation
282 RInteger g2 = SquaredL();
283 CleanupStack::PushL(g2);
284 RInteger g1 = RInteger::NewL(*this);
285 CleanupStack::PushL(g1);
286 TWindowSlider slider(aExponent);
289 // For i from 1 to (2^(k-1) -1) do g2i+1 <- g2i-1 * g2
290 TUint count = (1 << (slider.WindowSize()-1)) - 1; //2^(k-1) -1
291 RRArray<RInteger> powerArray(count+1); //+1 because we append g1
292 User::LeaveIfError(powerArray.Append(g1));
293 CleanupStack::Pop(); //g1
294 CleanupClosePushL(powerArray);
295 for(TUint k=1; k <= count; k++)
297 RInteger g2iplus1 = g2.TimesL(powerArray[k-1]);
298 //This append can't fail as the granularity is set high enough
299 //plus we've already called Append once which will alloc to the
301 powerArray.Append(g2iplus1);
305 RInteger A = RInteger::NewL(One());
306 CleanupStack::PushL(A);
307 TInt i = aExponent.BitCount() - 1;
312 // 3.1 If ei == 0 then A <- A^2
313 if(!aExponent.Bit(i))
318 // 3.2 Find longest bitstring ei,ei-1,...,el s.t. i-l+1<=k and el==1
320 // A <- (A^2^(i-l+1)) * g[the index indicated by the bitstring value]
323 slider.FindNextWindow(i);
324 assert(slider.Length() >= 1);
325 for(TUint j=0; j<slider.Length(); j++)
329 A *= powerArray[slider.Value()>>1];
330 i -= slider.Length();
333 CleanupStack::Pop(&A);
334 CleanupStack::PopAndDestroy(2, &g2); //powerArray, g2
338 EXPORT_C RInteger TInteger::ModularMultiplyL(const TInteger& aA, const TInteger& aB,
339 const TInteger& aMod)
341 RInteger product = aA.TimesL(aB);
342 CleanupStack::PushL(product);
343 RInteger reduced = product.ModuloL(aMod);
344 CleanupStack::PopAndDestroy(&product);
348 EXPORT_C RInteger TInteger::ModularExponentiateL(const TInteger& aBase,
349 const TInteger& aExp, const TInteger& aMod)
351 CMontgomeryStructure* mont = CMontgomeryStructure::NewLC(aMod);
352 RInteger result = RInteger::NewL(mont->ExponentiateL(aBase, aExp));
353 CleanupStack::PopAndDestroy(mont);
357 EXPORT_C RInteger TInteger::GCDL(const TInteger& aOperand) const
359 //Binary GCD algorithm -- see HAC 14.4.1
360 //with a slight variation -- our g counts shifts rather than actually
361 //shifting. We then do one shift at the end.
362 assert(NotNegative());
363 assert(aOperand.NotNegative());
365 RInteger x = RInteger::NewL(*this);
366 CleanupStack::PushL(x);
367 RInteger y = RInteger::NewL(aOperand);
368 CleanupStack::PushL(y);
377 // 2 while x and y even x <- x/2, y <- y/2
378 while( x.IsEven() && y.IsEven() )
387 // 3.1 while x even x <- x/2
392 // 3.2 while y even y <- y/2
397 // 3.3 t <- abs(x-y)/2
398 RInteger t = x.MinusL(y);
400 t.SetSign(TInteger::EPositive);
402 // 3.4 If x>=y then x <- t else y <- t
413 // 4 Return (g*y) (equiv to y<<=g as our g was counting shifts not actually
416 CleanupStack::Pop(&y);
417 CleanupStack::PopAndDestroy(&x);
421 EXPORT_C RInteger TInteger::InverseModL(const TInteger& aMod) const
423 assert(aMod.NotNegative());
426 if(IsNegative() || *this>=aMod)
428 RInteger temp = ModuloL(aMod);
429 CleanupClosePushL(temp);
430 result = temp.InverseModL(aMod);
431 CleanupStack::PopAndDestroy(&temp);
437 if( !aMod || IsEven() )
439 return RInteger::NewL(Zero());
443 return RInteger::NewL(One());
445 RInteger u = aMod.InverseModL(*this);
446 CleanupClosePushL(u);
449 result = RInteger::NewL(Zero());
453 //calculates (aMod*(*this-u)+1)/(*this)
455 CleanupClosePushL(result);
459 CleanupStack::Pop(&result);
461 CleanupStack::PopAndDestroy(&u);
465 result = RInteger::NewEmptyL(aMod.Size());
466 CleanupClosePushL(result);
467 RInteger workspace = RInteger::NewEmptyL(aMod.Size() * 4);
468 TUint k = AlmostInverse(result.Ptr(), workspace.Ptr(), Ptr(), Size(),
469 aMod.Ptr(), aMod.Size());
470 DivideByPower2Mod(result.Ptr(), result.Ptr(), k, aMod.Ptr(), aMod.Size());
472 CleanupStack::Pop(&result);
477 EXPORT_C TInteger& TInteger::operator+=(const TInteger& aOperand)
479 this->Set(PlusL(aOperand));
483 EXPORT_C TInteger& TInteger::operator-=(const TInteger& aOperand)
485 this->Set(MinusL(aOperand));
489 EXPORT_C TInteger& TInteger::operator*=(const TInteger& aOperand)
491 this->Set(TimesL(aOperand));
495 EXPORT_C TInteger& TInteger::operator/=(const TInteger& aOperand)
497 this->Set(DividedByL(aOperand));
501 EXPORT_C TInteger& TInteger::operator%=(const TInteger& aOperand)
503 this->Set(ModuloL(aOperand));
507 EXPORT_C TInteger& TInteger::operator+=(TInt aOperand)
509 TStackInteger64 operand(aOperand);
514 EXPORT_C TInteger& TInteger::operator-=(TInt aOperand)
516 TStackInteger64 operand(aOperand);
521 EXPORT_C TInteger& TInteger::operator*=(TInt aOperand)
523 TStackInteger64 operand(aOperand);
528 EXPORT_C TInteger& TInteger::operator/=(TInt aOperand)
530 TStackInteger64 operand(aOperand);
535 EXPORT_C TInteger& TInteger::operator%=(TInt aOperand)
537 TStackInteger64 operand(aOperand);
538 assert(operand.NotNegative());
543 EXPORT_C TInteger& TInteger::operator--()
547 if (Increment(Ptr(), Size()))
549 CleanGrowL(2*Size());
555 if (Decrement(Ptr(), Size()))
563 EXPORT_C TInteger& TInteger::operator++()
567 if(Increment(Ptr(), Size()))
569 CleanGrowL(2*Size());
575 DecrementNoCarry(Ptr(), Size());
584 EXPORT_C TInteger& TInteger::operator <<=(TUint aBits)
586 const TUint wordCount = WordCount();
587 const TUint shiftWords = aBits / WORD_BITS;
588 const TUint shiftBits = aBits % WORD_BITS;
590 CleanGrowL(wordCount+BitsToWords(aBits));
591 ShiftWordsLeftByWords(Ptr(), wordCount + shiftWords, shiftWords);
592 ShiftWordsLeftByBits(Ptr()+shiftWords, wordCount + BitsToWords(shiftBits),
597 EXPORT_C TInteger& TInteger::operator >>=(TUint aBits)
599 const TUint wordCount = WordCount();
600 const TUint shiftWords = aBits / WORD_BITS;
601 const TUint shiftBits = aBits % WORD_BITS;
603 ShiftWordsRightByWords(Ptr(), wordCount, shiftWords);
604 if(wordCount > shiftWords)
606 ShiftWordsRightByBits(Ptr(), wordCount - shiftWords, shiftBits);
608 if(IsNegative() && WordCount()==0) // avoid negative 0
615 EXPORT_C TInt TInteger::UnsignedCompare(const TInteger& aThat) const
617 TUint size = WordCount();
618 TUint thatSize = aThat.WordCount();
620 if( size == thatSize )
621 return Compare(Ptr(), aThat.Ptr(), size);
623 return size > thatSize ? 1 : -1;
626 EXPORT_C TInt TInteger::SignedCompare(const TInteger& aThat) const
630 if (aThat.NotNegative())
631 return UnsignedCompare(aThat);
637 if (aThat.NotNegative())
640 return -UnsignedCompare(aThat);
644 EXPORT_C TBool TInteger::operator!() const
646 //Ptr()[0] is just a quick way of weeding out non-zero numbers without
647 //doing a full WordCount() == 0. Very good odds that a non-zero number
648 //will have a bit set in the least significant word
649 return IsNegative() ? EFalse : (Ptr()[0]==0 && WordCount()==0);
652 EXPORT_C TInt TInteger::SignedCompare(TInt aInteger) const
654 TStackInteger64 temp(aInteger);
655 return SignedCompare(temp);
658 /* TBool IsPrimeL(void) const
659 * and all primality related functions are implemented in primes.cpp */
661 EXPORT_C TBool TInteger::Bit(TUint aBitPos) const
663 if( aBitPos/WORD_BITS >= Size() )
669 return (((Ptr())[aBitPos/WORD_BITS] >> (aBitPos % WORD_BITS)) & 1);
673 EXPORT_C void TInteger::SetBit(TUint aBitPos)
675 if( aBitPos/WORD_BITS < Size() )
677 ArraySetBit(Ptr(), aBitPos);
681 EXPORT_C void TInteger::Negate()
683 if(!!(*this)) //don't flip sign if *this==0
685 SetSign(TSign((~Sign())&KSignMask));
689 EXPORT_C TInt TInteger::ConvertToLongL(void) const
691 if(!IsConvertableToLong())
693 User::Leave(KErrTotalLossOfPrecision);
695 return ConvertToLong();
698 EXPORT_C void TInteger::CopyL(const TInteger& aInteger, TBool aAllowShrink)
702 CleanResizeL(aInteger.Size());
706 CleanGrowL(aInteger.Size());
711 EXPORT_C void TInteger::CopyL(TInt aInteger, TBool aAllowShrink)
724 EXPORT_C void TInteger::Set(const RInteger& aInteger)
726 assert(IsHeapBased());
727 Mem::FillZ(Ptr(), WordsToBytes(Size()));
729 iPtr = aInteger.iPtr;
730 iSize = aInteger.iSize;
733 RInteger TInteger::PositiveAddL(const TInteger &aA, const TInteger& aB) const
735 RInteger sum = RInteger::NewEmptyL(CryptoMax(aA.Size(), aB.Size()));
736 const word aSize = aA.Size();
737 const word bSize = aB.Size();
738 const word* const aReg = aA.Ptr();
739 const word* const bReg = aB.Ptr();
740 word* const sumReg = sum.Ptr();
744 carry = Add(sumReg, aReg, bReg, aSize);
745 else if (aSize > bSize)
747 carry = Add(sumReg, aReg, bReg, bSize);
748 CopyWords(sumReg+bSize, aReg+bSize, aSize-bSize);
749 carry = Increment(sumReg+bSize, aSize-bSize, carry);
753 carry = Add(sumReg, aReg, bReg, aSize);
754 CopyWords(sumReg+aSize, bReg+aSize, bSize-aSize);
755 carry = Increment(sumReg+aSize, bSize-aSize, carry);
760 CleanupStack::PushL(sum);
761 sum.CleanGrowL(2*sum.Size());
762 CleanupStack::Pop(&sum);
763 sum.Ptr()[sum.Size()/2] = 1;
765 sum.SetSign(TInteger::EPositive);
769 RInteger TInteger::PositiveSubtractL(const TInteger &aA, const TInteger& aB) const
771 RInteger diff = RInteger::NewEmptyL(CryptoMax(aA.Size(), aB.Size()));
772 unsigned aSize = aA.WordCount();
774 unsigned bSize = aB.WordCount();
776 const word* const aReg = aA.Ptr();
777 const word* const bReg = aB.Ptr();
778 word* const diffReg = diff.Ptr();
782 if (Compare(aReg, bReg, aSize) >= 0)
784 Subtract(diffReg, aReg, bReg, aSize);
785 diff.SetSign(TInteger::EPositive);
789 Subtract(diffReg, bReg, aReg, aSize);
790 diff.SetSign(TInteger::ENegative);
793 else if (aSize > bSize)
795 word borrow = Subtract(diffReg, aReg, bReg, bSize);
796 CopyWords(diffReg+bSize, aReg+bSize, aSize-bSize);
797 borrow = Decrement(diffReg+bSize, aSize-bSize, borrow);
799 diff.SetSign(TInteger::EPositive);
803 word borrow = Subtract(diffReg, bReg, aReg, aSize);
804 CopyWords(diffReg+aSize, bReg+aSize, bSize-aSize);
805 borrow = Decrement(diffReg+aSize, bSize-aSize, borrow);
807 diff.SetSign(TInteger::ENegative);
812 RInteger TInteger::PositiveMultiplyL(const TInteger &aA, const TInteger &aB) const
814 unsigned aSize = RoundupSize(aA.WordCount());
815 unsigned bSize = RoundupSize(aB.WordCount());
817 RInteger product = RInteger::NewEmptyL(aSize+bSize);
818 CleanupClosePushL(product);
820 RInteger workspace = RInteger::NewEmptyL(aSize + bSize);
821 AsymmetricMultiply(product.Ptr(), workspace.Ptr(), aA.Ptr(), aSize, aB.Ptr(),
824 CleanupStack::Pop(&product);
828 TUint TInteger::Modulo(const TInteger& aDividend, TUint aDivisor) const
831 TUint i = aDividend.WordCount();
835 remainder = TUint(MAKE_DWORD(aDividend.Ptr()[i], remainder) % aDivisor);
840 void TInteger::PositiveDivide(TUint& aRemainder, TInteger& aQuotient,
841 const TInteger& aDividend, TUint aDivisor) const
845 TUint i = aDividend.WordCount();
846 assert(aQuotient.Size() >= RoundupSize(i));
847 assert(aQuotient.Sign() == TInteger::EPositive);
852 TUint(MAKE_DWORD(aDividend.Ptr()[i], aRemainder) / aDivisor);
854 TUint(MAKE_DWORD(aDividend.Ptr()[i], aRemainder) % aDivisor);
858 void TInteger::DivideL(TUint& aRemainder, RInteger& aQuotient,
859 const TInteger& aDividend, TUint aDivisor) const
863 User::Leave(KErrDivideByZero);
866 TUint i = aDividend.WordCount();
867 aQuotient.CleanNewL(RoundupSize(i));
868 PositiveDivide(aRemainder, aQuotient, aDividend, aDivisor);
870 if(aDividend.NotNegative())
872 aQuotient.SetSign(TInteger::EPositive);
876 aQuotient.SetSign(TInteger::ENegative);
880 aRemainder = aDivisor = aRemainder;
885 void TInteger::PositiveDivideL(RInteger &aRemainder, RInteger &aQuotient,
886 const TInteger &aDividend, const TInteger &aDivisor) const
888 unsigned dividendSize = aDividend.WordCount();
889 unsigned divisorSize = aDivisor.WordCount();
893 User::Leave(KErrDivideByZero);
896 if (aDividend.UnsignedCompare(aDivisor) == -1)
898 aRemainder.CreateNewL(aDividend.Size());
899 CleanupStack::PushL(aRemainder);
900 aRemainder.CopyL(aDividend); //set remainder to a
901 aRemainder.SetSign(TInteger::EPositive);
902 aQuotient.CleanNewL(2); //Set quotient to zero
903 CleanupStack::Pop(&aRemainder);
907 dividendSize += dividendSize%2; // round up to next even number
908 divisorSize += divisorSize%2;
910 aRemainder.CleanNewL(divisorSize);
911 CleanupStack::PushL(aRemainder);
912 aQuotient.CleanNewL(dividendSize-divisorSize+2);
913 CleanupStack::PushL(aQuotient);
915 RInteger T = RInteger::NewEmptyL(dividendSize+2*divisorSize+4);
916 Divide(aRemainder.Ptr(), aQuotient.Ptr(), T.Ptr(), aDividend.Ptr(),
917 dividendSize, aDivisor.Ptr(), divisorSize);
919 CleanupStack::Pop(2, &aRemainder); //aQuotient, aRemainder
922 void TInteger::DivideL(RInteger& aRemainder, RInteger& aQuotient,
923 const TInteger& aDividend, const TInteger& aDivisor) const
925 PositiveDivideL(aRemainder, aQuotient, aDividend, aDivisor);
927 if (aDividend.IsNegative())
930 if (aRemainder.NotZero())
933 assert(aRemainder.Size() <= aDivisor.Size());
934 Subtract(aRemainder.Ptr(), aDivisor.Ptr(), aRemainder.Ptr(),
939 if (aDivisor.IsNegative())
943 TInt TInteger::ConvertToLong(void) const
945 TUint value = ConvertToUnsignedLong();
946 return Sign() == EPositive ? value : -(static_cast<TInt>(value));
949 TBool TInteger::IsConvertableToLong(void) const
955 TUint value = (Ptr())[0];
956 if(Sign() == EPositive)
958 return static_cast<TInt>(value) >= 0;
962 return -(static_cast<TInt>(value)) < 0;
966 void TInteger::RandomizeL(TUint aBits, TRandomAttribute aAttr)
972 const TUint bytes = BitsToBytes(aBits);
973 const TUint words = BitsToWords(aBits);
975 TPtr8 buf((TUint8*)(Ptr()), bytes, WordsToBytes(Size()));
976 TUint bitpos = aBits % BYTE_BITS;
977 GenerateRandomBytesL(buf);
978 //mask with 0 all bits above the num requested in the most significant byte
981 buf[bytes-1] = TUint8( buf[bytes-1] & ((1L << bitpos) - 1) );
983 //set most significant (top) bit
984 if(aAttr == ETopBitSet || aAttr == ETop2BitsSet)
986 SetBit(aBits-1); //Set bit counts from 0
987 assert(BitCount() == aBits);
988 assert(Bit(aBits-1));
990 //set 2nd bit from top
991 if(aAttr == ETop2BitsSet)
993 SetBit(aBits-2); //Set bit counts from 0
994 assert(BitCount() == aBits);
995 assert(Bit(aBits-1));
996 assert(Bit(aBits-2));
1000 void TInteger::RandomizeL(const TInteger& aMin, const TInteger& aMax)
1002 assert(aMax > aMin);
1003 assert(aMin.NotNegative());
1004 RInteger range = RInteger::NewL(aMax);
1005 CleanupStack::PushL(range);
1007 const TUint bits = range.BitCount();
1009 //if we find a number < range then aMin+range < aMax
1012 RandomizeL(bits, EAllBitsRandom);
1014 while(*this > range);
1017 CleanupStack::PopAndDestroy(&range);
1020 /* void PrimeRandomizeL(TUint aBits, TRandomAttribute aAttr)
1021 * and all primality related functions are implemented in primes.cpp */
1023 void TInteger::CreateNewL(TUint aNewSize)
1025 //should only be called on construction
1028 TUint newSize = RoundupSize(aNewSize);
1029 SetPtr((TUint*)User::AllocL(WordsToBytes(newSize)));
1034 void TInteger::CleanNewL(TUint aNewSize)
1036 CreateNewL(aNewSize);
1037 Mem::FillZ(Ptr(), WordsToBytes(Size())); //clear integer storage
1040 void TInteger::CleanGrowL(TUint aNewSize)
1042 assert(IsHeapBased());
1043 TUint newSize = RoundupSize(aNewSize);
1044 TUint oldSize = Size();
1045 if(newSize > oldSize)
1047 TUint* oldPtr = Ptr();
1048 //1) allocate new memory and set ptr and size
1049 SetPtr((TUint*)User::AllocL(WordsToBytes(newSize)));
1051 //2) copy old mem to new mem
1052 Mem::Copy(Ptr(), oldPtr, WordsToBytes(oldSize));
1053 //3) zero all old memory
1054 Mem::FillZ(oldPtr, WordsToBytes(oldSize));
1055 //4) give back old memory
1057 //5) zero new memory from end of copy to end of growth
1058 Mem::FillZ(Ptr() + oldSize, WordsToBytes(newSize-oldSize));
1062 void TInteger::CleanResizeL(TUint aNewSize)
1064 assert(IsHeapBased());
1065 TUint newSize = RoundupSize(aNewSize);
1066 TUint oldSize = Size();
1067 if(newSize > oldSize)
1069 CleanGrowL(aNewSize);
1071 else if(newSize < oldSize)
1073 TUint* oldPtr = Ptr();
1074 //1) zero memory above newsize
1075 Mem::FillZ(oldPtr+WordsToBytes(aNewSize),WordsToBytes(oldSize-newSize));
1076 //2) ReAlloc cell. Since our newsize is less than oldsize, it is
1077 //guarenteed not to move. Thus this is just freeing part of our old
1078 //cell to the heap for other uses.
1079 SetPtr((TUint*)User::ReAllocL(Ptr(), WordsToBytes(newSize)));
1084 TInteger::TInteger() : iSize(0), iPtr(0)
1088 void TInteger::Construct(const TDesC8& aValue)
1090 assert(Size() >= BytesToWords(aValue.Size()));
1091 if(aValue.Size() > 0)
1093 //People write numbers with the most significant digits first (big
1094 //endian) but we store our numbers in little endian. Hence we need to
1095 //reverse the string by bytes.
1097 TUint bytes = aValue.Size();
1098 TUint8* i = (TUint8*)Ptr();
1099 TUint8* j = (TUint8*)aValue.Ptr() + bytes;
1101 //Swap the endianess of the number itself
1102 // (msb) 01 02 03 04 05 06 (lsb) becomes ->
1103 // (lsb) 06 05 04 03 02 01 (msb)
1104 while( j != (TUint8*)aValue.Ptr() )
1108 Mem::FillZ((TUint8*)Ptr() + bytes, WordsToBytes(Size()) - bytes);
1112 //if size is zero, we zero the whole register
1113 Mem::FillZ((TUint8*)Ptr(), WordsToBytes(Size()));
1118 void TInteger::Construct(const TInteger& aInteger)
1120 assert(Size() >= aInteger.Size());
1121 CopyWords(Ptr(), aInteger.Ptr(), aInteger.Size());
1122 if(Size() > aInteger.Size())
1124 Mem::FillZ(Ptr()+aInteger.Size(), WordsToBytes(Size()-aInteger.Size()));
1126 SetSign(aInteger.Sign());
1129 void TInteger::Construct(TInt aInteger)
1131 Construct((TUint)aInteger);
1135 Ptr()[0] = -aInteger;
1139 void TInteger::Construct(TUint aInteger)
1141 assert(Size() >= 2);
1143 Ptr()[0] = aInteger;
1144 Mem::FillZ(Ptr()+1, WordsToBytes(Size()-1));
1147 void TInteger::ConstructStack(TUint aWords, TUint aInteger)
1149 SetPtr((TUint*)(this)+2);
1150 //SetStackBased(); //Not strictly needed as stackbased is a 0 at bit 1
1152 assert(Size() >= 2);
1153 Ptr()[0] = aInteger;
1154 Mem::FillZ(&(Ptr()[1]), WordsToBytes(Size()-1));
1157 void TInteger::ConstructStack(TUint aWords, const TInteger& aInteger)
1159 SetPtr((TUint*)(this)+2);
1160 //SetStackBased(); //Not strictly needed as stackbased is a 0 at bit 1
1162 assert( Size() >= RoundupSize(aInteger.WordCount()) );
1163 CopyWords(Ptr(), aInteger.Ptr(), aInteger.Size());
1164 Mem::FillZ(Ptr()+aInteger.Size(), WordsToBytes(Size()-aInteger.Size()));