From 8b8316038ba0c190ac24b5c3c6901cc8fe53bef8 Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Thu, 18 Mar 2010 09:49:49 +0000 Subject: [PATCH] Converted the BitArray class into "BigInteger", replacing its clunky old arithmetic methods with a proper set of arithmetic operators so it can be used like an int. All the bit-access methods are still there, and there's a typedef of BitArray -> BigInteger to allow most old code to still work. (You might need to change calls to isEmpty() to isZero() though). Also fixed a bug in MidiBuffer. --- .../Source/model/jucer_ProjectExport_MSVC.h | 24 +- juce_amalgamated.cpp | 1130 +++++++++-------- juce_amalgamated.h | 219 ++-- .../audio_sources/juce_MixerAudioSource.cpp | 2 +- .../audio_sources/juce_MixerAudioSource.h | 2 +- src/audio/devices/juce_AudioDeviceManager.h | 8 +- src/audio/devices/juce_AudioIODevice.h | 12 +- src/audio/midi/juce_MidiBuffer.cpp | 4 +- .../plugins/juce_AudioPluginFormatManager.cpp | 4 +- src/audio/processors/juce_AudioProcessor.h | 2 +- src/audio/synthesisers/juce_Sampler.cpp | 2 +- src/audio/synthesisers/juce_Sampler.h | 4 +- src/containers/juce_Array.h | 6 +- src/containers/juce_BitArray.cpp | 759 +++++------ src/containers/juce_BitArray.h | 326 +++-- src/containers/juce_OwnedArray.h | 4 +- src/containers/juce_ReferenceCountedArray.h | 2 +- src/containers/juce_SparseSet.h | 6 +- src/core/juce_Random.cpp | 8 +- src/core/juce_Random.h | 8 +- src/core/juce_StandardHeader.h | 2 +- src/cryptography/juce_Primes.cpp | 159 ++- src/cryptography/juce_Primes.h | 13 +- src/cryptography/juce_RSAKey.cpp | 76 +- src/cryptography/juce_RSAKey.h | 16 +- .../components/controls/juce_TableListBox.cpp | 2 +- src/gui/components/controls/juce_TreeView.cpp | 2 +- .../filebrowser/juce_FileBrowserComponent.cpp | 6 +- .../filebrowser/juce_FileBrowserComponent.h | 2 +- .../juce_AudioDeviceSelectorComponent.cpp | 8 +- .../special/juce_MidiKeyboardComponent.h | 2 +- src/native/linux/juce_linux_Audio.cpp | 14 +- src/native/linux/juce_linux_JackAudio.cpp | 18 +- src/native/mac/juce_iphone_Audio.cpp | 10 +- src/native/mac/juce_mac_CoreAudio.cpp | 20 +- src/native/windows/juce_win32_ASIO.cpp | 12 +- src/native/windows/juce_win32_DirectSound.cpp | 18 +- src/native/windows/juce_win32_WASAPI.cpp | 14 +- 38 files changed, 1474 insertions(+), 1452 deletions(-) diff --git a/extras/Jucer (experimental)/Source/model/jucer_ProjectExport_MSVC.h b/extras/Jucer (experimental)/Source/model/jucer_ProjectExport_MSVC.h index d1010c0862..18683643cc 100644 --- a/extras/Jucer (experimental)/Source/model/jucer_ProjectExport_MSVC.h +++ b/extras/Jucer (experimental)/Source/model/jucer_ProjectExport_MSVC.h @@ -626,7 +626,7 @@ private: void writeVC6Project (OutputStream& out) { - String defaultConfig (createConfigNameVC6 (project.getConfiguration (0))); + const String defaultConfigName (createConfigNameVC6 (project.getConfiguration (0))); const bool isDLL = project.isAudioPlugin() || project.isBrowserPlugin(); String targetType, targetCode; @@ -641,7 +641,7 @@ private: << "# Microsoft Developer Studio Generated Build File, Format Version 6.00" << newLine << "# ** DO NOT EDIT **" << newLine << "# TARGTYPE " << targetType << " " << targetCode << newLine - << "CFG=" << defaultConfig << newLine + << "CFG=" << defaultConfigName << newLine << "!MESSAGE This is not a valid makefile. To build this project using NMAKE," << newLine << "!MESSAGE use the Export Makefile command and run" << newLine << "!MESSAGE " << newLine @@ -650,7 +650,7 @@ private: << "!MESSAGE You can specify a configuration when running NMAKE" << newLine << "!MESSAGE by defining the macro CFG on the command line. For example:" << newLine << "!MESSAGE " << newLine - << "!MESSAGE NMAKE /f \"" << project.getProjectName() << ".mak\" CFG=\"" << defaultConfig << '"' << newLine + << "!MESSAGE NMAKE /f \"" << project.getProjectName() << ".mak\" CFG=\"" << defaultConfigName << '"' << newLine << "!MESSAGE " << newLine << "!MESSAGE Possible choices for configuration are:" << newLine << "!MESSAGE " << newLine; @@ -676,29 +676,31 @@ private: const String configName (createConfigNameVC6 (config)); targetList << "# Name \"" << configName << '"' << newLine; - const String outFile (windowsStylePath (getConfigTargetPath(config) + "/" + config.getTargetBinaryName().toString() + getTargetBinarySuffix())); + const String binariesPath (getConfigTargetPath (config)); + const String targetBinary (windowsStylePath (binariesPath + "/" + config.getTargetBinaryName().toString() + getTargetBinarySuffix())); const String optimisationFlag (((int) config.getOptimisationLevel().getValue() <= 1) ? "Od" : (config.getOptimisationLevel() == 2 ? "O2" : "O3")); const String defines (getPreprocessorDefs (config, " /D ")); const bool isDebug = (bool) config.isDebug().getValue(); const String extraDebugFlags (isDebug ? "/Gm /ZI /GZ" : ""); - const String includes (getHeaderSearchPaths (config).joinIntoString (" /I ")); out << (i == 0 ? "!IF" : "!ELSEIF") << " \"$(CFG)\" == \"" << configName << '"' << newLine << "# PROP BASE Use_MFC 0" << newLine << "# PROP BASE Use_Debug_Libraries " << (isDebug ? "1" : "0") << newLine - << "# PROP BASE Output_Dir \"" << getConfigTargetPath (config) << '"' << newLine + << "# PROP BASE Output_Dir \"" << binariesPath << '"' << newLine << "# PROP BASE Intermediate_Dir \"" << getIntermediatesPath (config) << '"' << newLine << "# PROP BASE Target_Dir \"\"" << newLine << "# PROP Use_MFC 0" << newLine << "# PROP Use_Debug_Libraries " << (isDebug ? "1" : "0") << newLine - << "# PROP Output_Dir \"" << getConfigTargetPath (config) << '"' << newLine + << "# PROP Output_Dir \"" << binariesPath << '"' << newLine << "# PROP Intermediate_Dir \"" << getIntermediatesPath (config) << '"' << newLine << "# PROP Ignore_Export_Lib 0" << newLine << "# PROP Target_Dir \"\"" << newLine << "# ADD BASE CPP /nologo /W3 /GX /" << optimisationFlag << " /D " << defines << " /YX /FD /c " << extraDebugFlags << " /Zm1024" << newLine << "# ADD CPP /nologo " << (isDebug ? "/MTd" : "/MT") << " /W3 /GR /GX /" << optimisationFlag - << " /I " << includes << " /D " << defines << " /D \"_UNICODE\" /D \"UNICODE\" /FD /c " << extraDebugFlags << " /Zm1024" << newLine; + << " /I " << getHeaderSearchPaths (config).joinIntoString (" /I ") + << " /D " << defines << " /D \"_UNICODE\" /D \"UNICODE\" /FD /c " << extraDebugFlags + << " /Zm1024" << newLine; if (! isDebug) out << "# SUBTRACT CPP /YX" << newLine; @@ -707,7 +709,7 @@ private: out << "# ADD BASE MTL /nologo /D " << defines << " /mktyplib203 /win32" << newLine << "# ADD MTL /nologo /D " << defines << " /mktyplib203 /win32" << newLine; - out << "# ADD BASE RSC /l 0x40c /d " << defines << newLine + out << "# ADD BASE RSC /l 0x40c /d " << defines << newLine << "# ADD RSC /l 0x40c /d " << defines << newLine << "BSC32=bscmake.exe" << newLine << "# ADD BASE BSC32 /nologo" << newLine @@ -717,7 +719,7 @@ private: { out << "LIB32=link.exe -lib" << newLine << "# ADD BASE LIB32 /nologo" << newLine - << "# ADD LIB32 /nologo /out:\"" << outFile << '"' << newLine; + << "# ADD LIB32 /nologo /out:\"" << targetBinary << '"' << newLine; } else { @@ -726,7 +728,7 @@ private: << "# ADD LINK32 \"C:\\Program Files\\Microsoft Visual Studio\\VC98\\LIB\\shell32.lib\" " // This is avoid debug information corruption when mixing Platform SDK << "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib " << (isDebug ? " /debug" : "") - << " /nologo /machine:I386 /out:\"" << outFile << "\" " + << " /nologo /machine:I386 /out:\"" << targetBinary << "\" " << (isDLL ? "/dll" : (project.isCommandLineApp() ? "/subsystem:console" : "/subsystem:windows")) << newLine; } diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 2e2e1f74db..0ca9178c5c 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -1103,20 +1103,20 @@ double Random::nextDouble() throw() return static_cast (nextInt()) / (double) 0xffffffff; } -const BitArray Random::nextLargeNumber (const BitArray& maximumValue) throw() +const BigInteger Random::nextLargeNumber (const BigInteger& maximumValue) { - BitArray n; + BigInteger n; do { fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1); } - while (n.compare (maximumValue) >= 0); + while (n >= maximumValue); return n; } -void Random::fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw() +void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits) { arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space @@ -2037,7 +2037,7 @@ END_JUCE_NAMESPACE /*** Start of inlined file: juce_BitArray.cpp ***/ BEGIN_JUCE_NAMESPACE -BitArray::BitArray() throw() +BigInteger::BigInteger() : numValues (4), highestBit (-1), negative (false) @@ -2045,7 +2045,7 @@ BitArray::BitArray() throw() values.calloc (numValues + 1); } -BitArray::BitArray (const int value) throw() +BigInteger::BigInteger (const int value) : numValues (4), highestBit (31), negative (value < 0) @@ -2055,7 +2055,7 @@ BitArray::BitArray (const int value) throw() highestBit = getHighestBit(); } -BitArray::BitArray (int64 value) throw() +BigInteger::BigInteger (int64 value) : numValues (4), highestBit (63), negative (value < 0) @@ -2070,7 +2070,7 @@ BitArray::BitArray (int64 value) throw() highestBit = getHighestBit(); } -BitArray::BitArray (const unsigned int value) throw() +BigInteger::BigInteger (const unsigned int value) : numValues (4), highestBit (31), negative (false) @@ -2080,7 +2080,7 @@ BitArray::BitArray (const unsigned int value) throw() highestBit = getHighestBit(); } -BitArray::BitArray (const BitArray& other) throw() +BigInteger::BigInteger (const BigInteger& other) : numValues (jmax (4, (other.highestBit >> 5) + 1)), highestBit (other.getHighestBit()), negative (other.negative) @@ -2089,11 +2089,19 @@ BitArray::BitArray (const BitArray& other) throw() memcpy (values, other.values, sizeof (unsigned int) * (numValues + 1)); } -BitArray::~BitArray() throw() +BigInteger::~BigInteger() { } -BitArray& BitArray::operator= (const BitArray& other) throw() +void BigInteger::swapWith (BigInteger& other) throw() +{ + values.swapWith (other.values); + swapVariables (numValues, other.numValues); + swapVariables (highestBit, other.highestBit); + swapVariables (negative, other.negative); +} + +BigInteger& BigInteger::operator= (const BigInteger& other) { if (this != &other) { @@ -2107,61 +2115,91 @@ BitArray& BitArray::operator= (const BitArray& other) throw() return *this; } -// result == 0 = the same -// result < 0 = this number is smaller -// result > 0 = this number is bigger -int BitArray::compare (const BitArray& other) const throw() +void BigInteger::ensureSize (const int numVals) { - if (isNegative() == other.isNegative()) - { - const int absComp = compareAbsolute (other); - return isNegative() ? -absComp : absComp; - } - else + if (numVals + 2 >= numValues) { - return isNegative() ? -1 : 1; + int oldSize = numValues; + numValues = ((numVals + 2) * 3) / 2; + values.realloc (numValues + 1); + + while (oldSize < numValues) + values [oldSize++] = 0; } } -int BitArray::compareAbsolute (const BitArray& other) const throw() +bool BigInteger::operator[] (const int bit) const throw() { - const int h1 = getHighestBit(); - const int h2 = other.getHighestBit(); - - if (h1 > h2) - return 1; - else if (h1 < h2) - return -1; - - for (int i = (h1 >> 5) + 1; --i >= 0;) - if (values[i] != other.values[i]) - return (values[i] > other.values[i]) ? 1 : -1; - - return 0; + return bit <= highestBit && bit >= 0 + && ((values [bit >> 5] & (1 << (bit & 31))) != 0); } -bool BitArray::operator== (const BitArray& other) const throw() +int BigInteger::toInteger() const throw() { - return compare (other) == 0; + const int n = (int) (values[0] & 0x7fffffff); + return negative ? -n : n; } -bool BitArray::operator!= (const BitArray& other) const throw() +const BigInteger BigInteger::getBitRange (int startBit, int numBits) const { - return compare (other) != 0; + BigInteger r; + numBits = jmin (numBits, getHighestBit() + 1 - startBit); + r.ensureSize (numBits >> 5); + r.highestBit = numBits; + + int i = 0; + while (numBits > 0) + { + r.values[i++] = getBitRangeAsInt (startBit, jmin (32, numBits)); + numBits -= 32; + startBit += 32; + } + + r.highestBit = r.getHighestBit(); + return r; } -bool BitArray::operator[] (const int bit) const throw() +int BigInteger::getBitRangeAsInt (const int startBit, int numBits) const throw() { - return bit >= 0 && bit <= highestBit - && ((values [bit >> 5] & (1 << (bit & 31))) != 0); + if (numBits > 32) + { + jassertfalse // use getBitRange() if you need more than 32 bits.. + numBits = 32; + } + + numBits = jmin (numBits, highestBit + 1 - startBit); + + if (numBits <= 0) + return 0; + + const int pos = startBit >> 5; + const int offset = startBit & 31; + const int endSpace = 32 - numBits; + + uint32 n = ((uint32) values [pos]) >> offset; + + if (offset > endSpace) + n |= ((uint32) values [pos + 1]) << (32 - offset); + + return (int) (n & (((uint32) 0xffffffff) >> endSpace)); } -bool BitArray::isEmpty() const throw() +void BigInteger::setBitRangeAsInt (const int startBit, int numBits, unsigned int valueToSet) { - return getHighestBit() < 0; + if (numBits > 32) + { + jassertfalse + numBits = 32; + } + + for (int i = 0; i < numBits; ++i) + { + setBit (startBit + i, (valueToSet & 1) != 0); + valueToSet >>= 1; + } } -void BitArray::clear() throw() +void BigInteger::clear() { if (numValues > 16) { @@ -2177,7 +2215,7 @@ void BitArray::clear() throw() negative = false; } -void BitArray::setBit (const int bit) throw() +void BigInteger::setBit (const int bit) { if (bit >= 0) { @@ -2191,8 +2229,7 @@ void BitArray::setBit (const int bit) throw() } } -void BitArray::setBit (const int bit, - const bool shouldBeSet) throw() +void BigInteger::setBit (const int bit, const bool shouldBeSet) { if (shouldBeSet) setBit (bit); @@ -2200,22 +2237,19 @@ void BitArray::setBit (const int bit, clearBit (bit); } -void BitArray::clearBit (const int bit) throw() +void BigInteger::clearBit (const int bit) throw() { if (bit >= 0 && bit <= highestBit) values [bit >> 5] &= ~(1 << (bit & 31)); } -void BitArray::setRange (int startBit, - int numBits, - const bool shouldBeSet) throw() +void BigInteger::setRange (int startBit, int numBits, const bool shouldBeSet) { while (--numBits >= 0) setBit (startBit++, shouldBeSet); } -void BitArray::insertBit (const int bit, - const bool shouldBeSet) throw() +void BigInteger::insertBit (const int bit, const bool shouldBeSet) { if (bit >= 0) shiftBits (1, bit); @@ -2223,149 +2257,157 @@ void BitArray::insertBit (const int bit, setBit (bit, shouldBeSet); } -void BitArray::andWith (const BitArray& other) throw() +bool BigInteger::isZero() const throw() { - // this operation will only work with the absolute values - jassert (isNegative() == other.isNegative()); - - int n = numValues; - - while (n > other.numValues) - values[--n] = 0; - - while (--n >= 0) - values[n] &= other.values[n]; - - if (other.highestBit < highestBit) - highestBit = other.highestBit; + return getHighestBit() < 0; +} - highestBit = getHighestBit(); +bool BigInteger::isOne() const throw() +{ + return getHighestBit() == 0 && ! negative; } -void BitArray::orWith (const BitArray& other) throw() +bool BigInteger::isNegative() const throw() { - if (other.highestBit < 0) - return; + return negative && ! isZero(); +} - // this operation will only work with the absolute values - jassert (isNegative() == other.isNegative()); +void BigInteger::setNegative (const bool neg) throw() +{ + negative = neg; +} - ensureSize (other.highestBit >> 5); +void BigInteger::negate() throw() +{ + negative = (! negative) && ! isZero(); +} - int n = (other.highestBit >> 5) + 1; +int BigInteger::countNumberOfSetBits() const throw() +{ + int total = 0; - while (--n >= 0) - values[n] |= other.values[n]; + for (int i = (highestBit >> 5) + 1; --i >= 0;) + { + unsigned int n = values[i]; - if (other.highestBit > highestBit) - highestBit = other.highestBit; + if (n == 0xffffffff) + { + total += 32; + } + else + { + while (n != 0) + { + total += (n & 1); + n >>= 1; + } + } + } - highestBit = getHighestBit(); + return total; } -void BitArray::xorWith (const BitArray& other) throw() +int BigInteger::getHighestBit() const throw() { - if (other.highestBit < 0) - return; - - // this operation will only work with the absolute values - jassert (isNegative() == other.isNegative()); + for (int i = highestBit + 1; --i >= 0;) + if ((values [i >> 5] & (1 << (i & 31))) != 0) + return i; - ensureSize (other.highestBit >> 5); + return -1; +} - int n = (other.highestBit >> 5) + 1; +int BigInteger::findNextSetBit (int i) const throw() +{ + for (; i <= highestBit; ++i) + if ((values [i >> 5] & (1 << (i & 31))) != 0) + return i; - while (--n >= 0) - values[n] ^= other.values[n]; + return -1; +} - if (other.highestBit > highestBit) - highestBit = other.highestBit; +int BigInteger::findNextClearBit (int i) const throw() +{ + for (; i <= highestBit; ++i) + if ((values [i >> 5] & (1 << (i & 31))) == 0) + break; - highestBit = getHighestBit(); + return i; } -void BitArray::add (const BitArray& other) throw() +BigInteger& BigInteger::operator+= (const BigInteger& other) { if (other.isNegative()) - { - BitArray o (other); - o.negate(); - subtract (o); - return; - } + return operator-= (-other); if (isNegative()) { if (compareAbsolute (other) < 0) { - BitArray temp (*this); + BigInteger temp (*this); temp.negate(); *this = other; - subtract (temp); + operator-= (temp); } else { negate(); - subtract (other); + operator-= (other); negate(); } - - return; } + else + { + if (other.highestBit > highestBit) + highestBit = other.highestBit; - if (other.highestBit > highestBit) - highestBit = other.highestBit; + ++highestBit; - ++highestBit; + const int numInts = (highestBit >> 5) + 1; + ensureSize (numInts); - const int numInts = (highestBit >> 5) + 1; - ensureSize (numInts); + int64 remainder = 0; - int64 remainder = 0; + for (int i = 0; i <= numInts; ++i) + { + if (i < numValues) + remainder += values[i]; - for (int i = 0; i <= numInts; ++i) - { - if (i < numValues) - remainder += values[i]; + if (i < other.numValues) + remainder += other.values[i]; - if (i < other.numValues) - remainder += other.values[i]; + values[i] = (unsigned int) remainder; + remainder >>= 32; + } - values[i] = (unsigned int) remainder; - remainder >>= 32; + jassert (remainder == 0); + highestBit = getHighestBit(); } - jassert (remainder == 0); - highestBit = getHighestBit(); + return *this; } -void BitArray::subtract (const BitArray& other) throw() +BigInteger& BigInteger::operator-= (const BigInteger& other) { if (other.isNegative()) - { - BitArray o (other); - o.negate(); - add (o); - return; - } + return operator+= (-other); if (! isNegative()) { if (compareAbsolute (other) < 0) { - BitArray temp (*this); - *this = other; - subtract (temp); + BigInteger temp (other); + swapWith (temp); + operator-= (temp); negate(); - return; + return *this; } } else { negate(); - add (other); + operator+= (other); negate(); - return; + return *this; } const int numInts = (highestBit >> 5) + 1; @@ -2375,7 +2417,7 @@ void BitArray::subtract (const BitArray& other) throw() for (int i = 0; i <= numInts; ++i) { if (i <= maxOtherInts) - amountToSubtract += (int64)other.values[i]; + amountToSubtract += (int64) other.values[i]; if (values[i] >= amountToSubtract) { @@ -2389,11 +2431,13 @@ void BitArray::subtract (const BitArray& other) throw() amountToSubtract = 1; } } + + return *this; } -void BitArray::multiplyBy (const BitArray& other) throw() +BigInteger& BigInteger::operator*= (const BigInteger& other) { - BitArray total; + BigInteger total; highestBit = getHighestBit(); const bool wasNegative = isNegative(); setNegative (false); @@ -2402,18 +2446,19 @@ void BitArray::multiplyBy (const BitArray& other) throw() { if (operator[](i)) { - BitArray n (other); + BigInteger n (other); n.setNegative (false); - n.shiftBits (i); - total.add (n); + n <<= i; + total += n; } } - *this = total; - negative = wasNegative ^ other.isNegative(); + total.setNegative (wasNegative ^ other.isNegative()); + swapWith (total); + return *this; } -void BitArray::divideBy (const BitArray& divisor, BitArray& remainder) throw() +void BigInteger::divideBy (const BigInteger& divisor, BigInteger& remainder) { jassert (this != &remainder); // (can't handle passing itself in to get the remainder) @@ -2428,27 +2473,28 @@ void BitArray::divideBy (const BitArray& divisor, BitArray& remainder) throw() } else { - remainder = *this; - remainder.setNegative (false); const bool wasNegative = isNegative(); + + swapWith (remainder); + remainder.setNegative (false); clear(); - BitArray temp (divisor); + BigInteger temp (divisor); temp.setNegative (false); int leftShift = ourHB - divHB; - temp.shiftBits (leftShift); + temp <<= leftShift; while (leftShift >= 0) { if (remainder.compareAbsolute (temp) >= 0) { - remainder.subtract (temp); + remainder -= temp; setBit (leftShift); } if (--leftShift >= 0) - temp.shiftBits (-1); + temp >>= 1; } negative = wasNegative ^ divisor.isNegative(); @@ -2456,128 +2502,153 @@ void BitArray::divideBy (const BitArray& divisor, BitArray& remainder) throw() } } -void BitArray::modulo (const BitArray& divisor) throw() +BigInteger& BigInteger::operator/= (const BigInteger& other) { - BitArray remainder; - divideBy (divisor, remainder); - *this = remainder; + BigInteger remainder; + divideBy (other, remainder); + return *this; } -static const BitArray simpleGCD (BitArray* m, BitArray* n) throw() +BigInteger& BigInteger::operator|= (const BigInteger& other) { - while (! m->isEmpty()) + // this operation doesn't take into account negative values.. + jassert (isNegative() == other.isNegative()); + + if (other.highestBit >= 0) { - if (n->compareAbsolute (*m) > 0) - swapVariables (m, n); + ensureSize (other.highestBit >> 5); - m->subtract (*n); + int n = (other.highestBit >> 5) + 1; + + while (--n >= 0) + values[n] |= other.values[n]; + + if (other.highestBit > highestBit) + highestBit = other.highestBit; + + highestBit = getHighestBit(); } - return *n; + return *this; } -const BitArray BitArray::findGreatestCommonDivisor (BitArray n) const throw() +BigInteger& BigInteger::operator&= (const BigInteger& other) { - BitArray m (*this); + // this operation doesn't take into account negative values.. + jassert (isNegative() == other.isNegative()); - while (! n.isEmpty()) - { - if (abs (m.getHighestBit() - n.getHighestBit()) <= 16) - return simpleGCD (&m, &n); + int n = numValues; - BitArray temp1 (m), temp2; - temp1.divideBy (n, temp2); + while (n > other.numValues) + values[--n] = 0; - m = n; - n = temp2; - } + while (--n >= 0) + values[n] &= other.values[n]; - return m; + if (other.highestBit < highestBit) + highestBit = other.highestBit; + + highestBit = getHighestBit(); + return *this; } -void BitArray::exponentModulo (const BitArray& exponent, - const BitArray& modulus) throw() +BigInteger& BigInteger::operator^= (const BigInteger& other) { - BitArray exp (exponent); - exp.modulo (modulus); + // this operation will only work with the absolute values + jassert (isNegative() == other.isNegative()); - BitArray value (*this); - value.modulo (modulus); + if (other.highestBit >= 0) + { + ensureSize (other.highestBit >> 5); - clear(); - setBit (0); + int n = (other.highestBit >> 5) + 1; - while (! exp.isEmpty()) - { - if (exp [0]) - { - multiplyBy (value); - this->modulo (modulus); - } + while (--n >= 0) + values[n] ^= other.values[n]; - value.multiplyBy (value); - value.modulo (modulus); + if (other.highestBit > highestBit) + highestBit = other.highestBit; - exp.shiftBits (-1); + highestBit = getHighestBit(); } + + return *this; } -void BitArray::inverseModulo (const BitArray& modulus) throw() +BigInteger& BigInteger::operator%= (const BigInteger& divisor) { - const BitArray one (1); + BigInteger remainder; + divideBy (divisor, remainder); + swapWith (remainder); + return *this; +} - if (modulus == one || modulus.isNegative()) - { - clear(); - return; - } +BigInteger& BigInteger::operator<<= (int numBitsToShift) +{ + shiftBits (numBitsToShift, 0); + return *this; +} - if (isNegative() || compareAbsolute (modulus) >= 0) - this->modulo (modulus); +BigInteger& BigInteger::operator>>= (int numBitsToShift) +{ + return operator<<= (-numBitsToShift); +} - if (*this == one) - return; +BigInteger& BigInteger::operator++() { return operator+= (1); } +BigInteger& BigInteger::operator--() { return operator-= (1); } +const BigInteger BigInteger::operator++ (int) { const BigInteger old (*this); operator+= (1); return old; } +const BigInteger BigInteger::operator-- (int) { const BigInteger old (*this); operator-= (1); return old; } - if (! (*this)[0]) +const BigInteger BigInteger::operator+ (const BigInteger& other) const { BigInteger b (*this); return b += other; } +const BigInteger BigInteger::operator- (const BigInteger& other) const { BigInteger b (*this); return b -= other; } +const BigInteger BigInteger::operator* (const BigInteger& other) const { BigInteger b (*this); return b *= other; } +const BigInteger BigInteger::operator/ (const BigInteger& other) const { BigInteger b (*this); return b /= other; } +const BigInteger BigInteger::operator| (const BigInteger& other) const { BigInteger b (*this); return b |= other; } +const BigInteger BigInteger::operator& (const BigInteger& other) const { BigInteger b (*this); return b &= other; } +const BigInteger BigInteger::operator^ (const BigInteger& other) const { BigInteger b (*this); return b ^= other; } +const BigInteger BigInteger::operator% (const BigInteger& other) const { BigInteger b (*this); return b %= other; } +const BigInteger BigInteger::operator<< (const int numBits) const { BigInteger b (*this); return b <<= numBits; } +const BigInteger BigInteger::operator>> (const int numBits) const { BigInteger b (*this); return b >>= numBits; } +const BigInteger BigInteger::operator-() const { BigInteger b (*this); b.negate(); return b; } + +int BigInteger::compare (const BigInteger& other) const throw() +{ + if (isNegative() == other.isNegative()) { - // not invertible - clear(); - return; + const int absComp = compareAbsolute (other); + return isNegative() ? -absComp : absComp; } - - BitArray a1 (modulus); - BitArray a2 (*this); - BitArray b1 (modulus); - BitArray b2 (1); - - while (a2 != one) + else { - BitArray temp1, temp2, multiplier (a1); - multiplier.divideBy (a2, temp1); + return isNegative() ? -1 : 1; + } +} - temp1 = a2; - temp1.multiplyBy (multiplier); - temp2 = a1; - temp2.subtract (temp1); - a1 = a2; - a2 = temp2; +int BigInteger::compareAbsolute (const BigInteger& other) const throw() +{ + const int h1 = getHighestBit(); + const int h2 = other.getHighestBit(); - temp1 = b2; - temp1.multiplyBy (multiplier); - temp2 = b1; - temp2.subtract (temp1); - b1 = b2; - b2 = temp2; - } + if (h1 > h2) + return 1; + else if (h1 < h2) + return -1; - while (b2.isNegative()) - b2.add (modulus); + for (int i = (h1 >> 5) + 1; --i >= 0;) + if (values[i] != other.values[i]) + return (values[i] > other.values[i]) ? 1 : -1; - b2.modulo (modulus); - *this = b2; + return 0; } -void BitArray::shiftBits (int bits, const int startBit) throw() +bool BigInteger::operator== (const BigInteger& other) const throw() { return compare (other) == 0; } +bool BigInteger::operator!= (const BigInteger& other) const throw() { return compare (other) != 0; } +bool BigInteger::operator< (const BigInteger& other) const throw() { return compare (other) < 0; } +bool BigInteger::operator<= (const BigInteger& other) const throw() { return compare (other) <= 0; } +bool BigInteger::operator> (const BigInteger& other) const throw() { return compare (other) > 0; } +bool BigInteger::operator>= (const BigInteger& other) const throw() { return compare (other) >= 0; } + +void BigInteger::shiftBits (int bits, const int startBit) { if (highestBit < 0) return; @@ -2681,163 +2752,136 @@ void BitArray::shiftBits (int bits, const int startBit) throw() } } -const BitArray BitArray::getBitRange (int startBit, int numBits) const throw() +const BigInteger BigInteger::simpleGCD (BigInteger* m, BigInteger* n) { - BitArray r; - numBits = jmin (numBits, getHighestBit() + 1 - startBit); - r.ensureSize (numBits >> 5); - r.highestBit = numBits; - - int i = 0; - while (numBits > 0) + while (! m->isZero()) { - r.values[i++] = getBitRangeAsInt (startBit, jmin (32, numBits)); - numBits -= 32; - startBit += 32; - } + if (n->compareAbsolute (*m) > 0) + swapVariables (m, n); - r.highestBit = r.getHighestBit(); + *m -= *n; + } - return r; + return *n; } -int BitArray::getBitRangeAsInt (const int startBit, int numBits) const throw() +const BigInteger BigInteger::findGreatestCommonDivisor (BigInteger n) const { - if (numBits > 32) - { - jassertfalse // use getBitRange() if you need more than 32 bits.. - numBits = 32; - } - - numBits = jmin (numBits, highestBit + 1 - startBit); + BigInteger m (*this); - if (numBits <= 0) - return 0; - - const int pos = startBit >> 5; - const int offset = startBit & 31; - const int endSpace = 32 - numBits; + while (! n.isZero()) + { + if (abs (m.getHighestBit() - n.getHighestBit()) <= 16) + return simpleGCD (&m, &n); - uint32 n = ((uint32) values [pos]) >> offset; + BigInteger temp1 (m), temp2; + temp1.divideBy (n, temp2); - if (offset > endSpace) - n |= ((uint32) values [pos + 1]) << (32 - offset); + m = n; + n = temp2; + } - return (int) (n & (((uint32) 0xffffffff) >> endSpace)); + return m; } -void BitArray::setBitRangeAsInt (const int startBit, int numBits, unsigned int valueToSet) throw() +void BigInteger::exponentModulo (const BigInteger& exponent, const BigInteger& modulus) { - if (numBits > 32) - { - jassertfalse - numBits = 32; - } + BigInteger exp (exponent); + exp %= modulus; - for (int i = 0; i < numBits; ++i) + BigInteger value (1); + swapWith (value); + value %= modulus; + + while (! exp.isZero()) { - setBit (startBit + i, (valueToSet & 1) != 0); - valueToSet >>= 1; - } -} + if (exp [0]) + { + operator*= (value); + operator%= (modulus); + } -bool BitArray::isNegative() const throw() -{ - return negative && ! isEmpty(); + value *= value; + value %= modulus; + exp >>= 1; + } } -void BitArray::setNegative (const bool neg) throw() +void BigInteger::inverseModulo (const BigInteger& modulus) { - negative = neg; -} + if (modulus.isOne() || modulus.isNegative()) + { + clear(); + return; + } -void BitArray::negate() throw() -{ - negative = (! negative) && ! isEmpty(); -} + if (isNegative() || compareAbsolute (modulus) >= 0) + operator%= (modulus); -int BitArray::countNumberOfSetBits() const throw() -{ - int total = 0; + if (isOne()) + return; - for (int i = (highestBit >> 5) + 1; --i >= 0;) + if (! (*this)[0]) { - unsigned int n = values[i]; - - if (n == 0xffffffff) - { - total += 32; - } - else - { - while (n != 0) - { - total += (n & 1); - n >>= 1; - } - } + // not invertible + clear(); + return; } - return total; -} + BigInteger a1 (modulus); + BigInteger a2 (*this); + BigInteger b1 (modulus); + BigInteger b2 (1); -int BitArray::getHighestBit() const throw() -{ - for (int i = highestBit + 1; --i >= 0;) - if ((values [i >> 5] & (1 << (i & 31))) != 0) - return i; - - return -1; -} + while (! a2.isOne()) + { + BigInteger temp1, temp2, multiplier (a1); + multiplier.divideBy (a2, temp1); -int BitArray::findNextSetBit (int i) const throw() -{ - for (; i <= highestBit; ++i) - if ((values [i >> 5] & (1 << (i & 31))) != 0) - return i; + temp1 = a2; + temp1 *= multiplier; + temp2 = a1; + temp2 -= temp1; + a1 = a2; + a2 = temp2; - return -1; -} + temp1 = b2; + temp1 *= multiplier; + temp2 = b1; + temp2 -= temp1; + b1 = b2; + b2 = temp2; + } -int BitArray::findNextClearBit (int i) const throw() -{ - for (; i <= highestBit; ++i) - if ((values [i >> 5] & (1 << (i & 31))) == 0) - break; + while (b2.isNegative()) + b2 += modulus; - return i; + b2 %= modulus; + swapWith (b2); } -void BitArray::ensureSize (const int numVals) throw() +OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const BigInteger& value) { - if (numVals + 2 >= numValues) - { - int oldSize = numValues; - numValues = ((numVals + 2) * 3) / 2; - values.realloc (numValues + 1); - - while (oldSize < numValues) - values [oldSize++] = 0; - } + return stream << value.toString (10); } -const String BitArray::toString (const int base, const int minimumNumCharacters) const throw() +const String BigInteger::toString (const int base, const int minimumNumCharacters) const { String s; - BitArray v (*this); + BigInteger v (*this); if (base == 2 || base == 8 || base == 16) { const int bits = (base == 2) ? 1 : (base == 8 ? 3 : 4); - static const tchar* const hexDigits = T("0123456789abcdef"); + static const juce_wchar* const hexDigits = T("0123456789abcdef"); for (;;) { const int remainder = v.getBitRangeAsInt (0, bits); - v.shiftBits (-bits); + v >>= bits; - if (remainder == 0 && v.isEmpty()) + if (remainder == 0 && v.isZero()) break; s = String::charToString (hexDigits [remainder]) + s; @@ -2845,14 +2889,14 @@ const String BitArray::toString (const int base, const int minimumNumCharacters) } else if (base == 10) { - const BitArray ten (10); - BitArray remainder; + const BigInteger ten (10); + BigInteger remainder; for (;;) { v.divideBy (ten, remainder); - if (remainder.isEmpty() && v.isEmpty()) + if (remainder.isZero() && v.isZero()) break; s = String (remainder.getBitRangeAsInt (0, 8)) + s; @@ -2860,7 +2904,7 @@ const String BitArray::toString (const int base, const int minimumNumCharacters) } else { - jassertfalse // can't do the specified base + jassertfalse // can't do the specified base! return String::empty; } @@ -2869,11 +2913,10 @@ const String BitArray::toString (const int base, const int minimumNumCharacters) return isNegative() ? T("-") + s : s; } -void BitArray::parseString (const String& text, - const int base) throw() +void BigInteger::parseString (const String& text, const int base) { clear(); - const tchar* t = (const tchar*) text; + const juce_wchar* t = (const juce_wchar*) text; if (base == 2 || base == 8 || base == 16) { @@ -2881,13 +2924,13 @@ void BitArray::parseString (const String& text, for (;;) { - const tchar c = *t++; + const juce_wchar c = *t++; const int digit = CharacterFunctions::getHexDigitValue (c); if (((unsigned int) digit) < (unsigned int) base) { - shiftBits (bits); - add (digit); + operator<<= (bits); + operator+= (digit); } else if (c == 0) { @@ -2897,16 +2940,16 @@ void BitArray::parseString (const String& text, } else if (base == 10) { - const BitArray ten ((unsigned int) 10); + const BigInteger ten ((unsigned int) 10); for (;;) { - const tchar c = *t++; + const juce_wchar c = *t++; if (c >= T('0') && c <= T('9')) { - multiplyBy (ten); - add ((int) (c - T('0'))); + operator*= (ten); + operator+= ((int) (c - T('0'))); } else if (c == 0) { @@ -2918,7 +2961,7 @@ void BitArray::parseString (const String& text, setNegative (text.trimStart().startsWithChar (T('-'))); } -const MemoryBlock BitArray::toMemoryBlock() const throw() +const MemoryBlock BigInteger::toMemoryBlock() const { const int numBytes = (getHighestBit() + 8) >> 3; MemoryBlock mb ((size_t) numBytes); @@ -2929,7 +2972,7 @@ const MemoryBlock BitArray::toMemoryBlock() const throw() return mb; } -void BitArray::loadFromMemoryBlock (const MemoryBlock& data) throw() +void BigInteger::loadFromMemoryBlock (const MemoryBlock& data) { clear(); @@ -4801,7 +4844,7 @@ BEGIN_JUCE_NAMESPACE namespace PrimesHelpers { - static void createSmallSieve (const int numBits, BitArray& result) throw() + static void createSmallSieve (const int numBits, BigInteger& result) { result.setBit (numBits); result.clearBit (numBits); // to enlarge the array @@ -4819,11 +4862,8 @@ namespace PrimesHelpers while (n <= (numBits >> 1)); } - static void bigSieve (const BitArray& base, - const int numBits, - BitArray& result, - const BitArray& smallSieve, - const int smallSieveSize) throw() + static void bigSieve (const BigInteger& base, const int numBits, BigInteger& result, + const BigInteger& smallSieve, const int smallSieveSize) { jassert (! base[0]); // must be even! @@ -4836,13 +4876,12 @@ namespace PrimesHelpers { const int prime = (index << 1) + 1; - BitArray r (base); - BitArray remainder; + BigInteger r (base), remainder; r.divideBy (prime, remainder); int i = prime - remainder.getBitRangeAsInt (0, 32); - if (r.isEmpty()) + if (r.isZero()) i += prime; if ((i & 1) == 0) @@ -4861,18 +4900,14 @@ namespace PrimesHelpers while (index < smallSieveSize); } - static bool findCandidate (const BitArray& base, - const BitArray& sieve, - const int numBits, - BitArray& result, - const int certainty) throw() + static bool findCandidate (const BigInteger& base, const BigInteger& sieve, + const int numBits, BigInteger& result, const int certainty) { for (int i = 0; i < numBits; ++i) { if (! sieve[i]) { - result = base; - result.add (BitArray ((unsigned int) ((i << 1) + 1))); + result = base + (unsigned int) ((i << 1) + 1); if (Primes::isProbablyPrime (result, certainty)) return true; @@ -4881,12 +4916,62 @@ namespace PrimesHelpers return false; } + + static bool passesMillerRabin (const BigInteger& n, int iterations) + { + const BigInteger one (1), two (2); + const BigInteger nMinusOne (n - one); + + BigInteger d (nMinusOne); + const int s = d.findNextSetBit (0); + d >>= s; + + BigInteger smallPrimes; + int numBitsInSmallPrimes = 0; + + for (;;) + { + numBitsInSmallPrimes += 256; + createSmallSieve (numBitsInSmallPrimes, smallPrimes); + + const int numPrimesFound = numBitsInSmallPrimes - smallPrimes.countNumberOfSetBits(); + + if (numPrimesFound > iterations + 1) + break; + } + + int smallPrime = 2; + + while (--iterations >= 0) + { + smallPrime = smallPrimes.findNextClearBit (smallPrime + 1); + + BigInteger r (smallPrime); + r.exponentModulo (d, n); + + if (r != one && r != nMinusOne) + { + for (int j = 0; j < s; ++j) + { + r.exponentModulo (two, n); + + if (r == nMinusOne) + break; + } + + if (r != nMinusOne) + return false; + } + } + + return true; + } } -const BitArray Primes::createProbablePrime (const int bitLength, - const int certainty, - const int* randomSeeds, - int numRandomSeeds) throw() +const BigInteger Primes::createProbablePrime (const int bitLength, + const int certainty, + const int* randomSeeds, + int numRandomSeeds) { using namespace PrimesHelpers; int defaultSeeds [16]; @@ -4906,20 +4991,20 @@ const BitArray Primes::createProbablePrime (const int bitLength, } } - BitArray smallSieve; + BigInteger smallSieve; const int smallSieveSize = 15000; createSmallSieve (smallSieveSize, smallSieve); - BitArray p; + BigInteger p; for (int i = numRandomSeeds; --i >= 0;) { - BitArray p2; + BigInteger p2; Random r (randomSeeds[i]); r.fillBitsRandomly (p2, 0, bitLength); - p.xorWith (p2); + p ^= p2; } p.setBit (bitLength - 1); @@ -4929,81 +5014,26 @@ const BitArray Primes::createProbablePrime (const int bitLength, while (p.getHighestBit() < bitLength) { - p.add (2 * searchLen); + p += 2 * searchLen; - BitArray sieve; + BigInteger sieve; bigSieve (p, searchLen, sieve, smallSieve, smallSieveSize); - BitArray candidate; + BigInteger candidate; if (findCandidate (p, sieve, searchLen, candidate, certainty)) return candidate; } jassertfalse - return BitArray(); + return BigInteger(); } -static bool passesMillerRabin (const BitArray& n, int iterations) throw() +bool Primes::isProbablyPrime (const BigInteger& number, const int certainty) { using namespace PrimesHelpers; - const BitArray one (1); - const BitArray two (2); - - BitArray nMinusOne (n); - nMinusOne.subtract (one); - - BitArray d (nMinusOne); - const int s = d.findNextSetBit (0); - d.shiftBits (-s); - - BitArray smallPrimes; - int numBitsInSmallPrimes = 0; - - for (;;) - { - numBitsInSmallPrimes += 256; - createSmallSieve (numBitsInSmallPrimes, smallPrimes); - - const int numPrimesFound = numBitsInSmallPrimes - smallPrimes.countNumberOfSetBits(); - - if (numPrimesFound > iterations + 1) - break; - } - - int smallPrime = 2; - - while (--iterations >= 0) - { - smallPrime = smallPrimes.findNextClearBit (smallPrime + 1); - - BitArray r (smallPrime); - //r.createRandomNumber (nMinusOne); - r.exponentModulo (d, n); - - if (! (r == one || r == nMinusOne)) - { - for (int j = 0; j < s; ++j) - { - r.exponentModulo (two, n); - - if (r == nMinusOne) - break; - } - - if (r != nMinusOne) - return false; - } - } - - return true; -} - -bool Primes::isProbablyPrime (const BitArray& number, - const int certainty) throw() -{ if (! number[0]) return false; @@ -5019,9 +5049,7 @@ bool Primes::isProbablyPrime (const BitArray& number, } else { - const BitArray screen (2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23); - - if (number.findGreatestCommonDivisor (screen) != BitArray (1)) + if (number.findGreatestCommonDivisor (2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23) != 1) return false; return passesMillerRabin (number, certainty); @@ -5035,11 +5063,11 @@ END_JUCE_NAMESPACE /*** Start of inlined file: juce_RSAKey.cpp ***/ BEGIN_JUCE_NAMESPACE -RSAKey::RSAKey() throw() +RSAKey::RSAKey() { } -RSAKey::RSAKey (const String& s) throw() +RSAKey::RSAKey (const String& s) { if (s.containsChar (T(','))) { @@ -5053,97 +5081,75 @@ RSAKey::RSAKey (const String& s) throw() } } -RSAKey::~RSAKey() throw() +RSAKey::~RSAKey() { } -const String RSAKey::toString() const throw() +const String RSAKey::toString() const { - return part1.toString (16) + T(",") + part2.toString (16); + return part1.toString (16) + "," + part2.toString (16); } -bool RSAKey::applyToValue (BitArray& value) const throw() +bool RSAKey::applyToValue (BigInteger& value) const { - if (part1.isEmpty() || part2.isEmpty() - || value.compare (0) <= 0) + if (part1.isZero() || part2.isZero() || value <= 0) { jassertfalse // using an uninitialised key value.clear(); return false; } - BitArray result; + BigInteger result; - while (! value.isEmpty()) + while (! value.isZero()) { - result.multiplyBy (part2); + result *= part2; - BitArray remainder; + BigInteger remainder; value.divideBy (part2, remainder); remainder.exponentModulo (part1, part2); - result.add (remainder); + result += remainder; } - value = result; - + value.swapWith (result); return true; } -static const BitArray findBestCommonDivisor (const BitArray& p, - const BitArray& q) throw() +static const BigInteger findBestCommonDivisor (const BigInteger& p, const BigInteger& q) { - const BitArray one (1); - // try 3, 5, 9, 17, etc first because these only contain 2 bits and so // are fast to divide + multiply for (int i = 2; i <= 65536; i *= 2) { - const BitArray e (1 + i); + const BigInteger e (1 + i); - if (e.findGreatestCommonDivisor (p) == one - && e.findGreatestCommonDivisor (q) == one) - { + if (e.findGreatestCommonDivisor (p).isOne() && e.findGreatestCommonDivisor (q).isOne()) return e; - } } - BitArray e (4); + BigInteger e (4); - while (! (e.findGreatestCommonDivisor (p) == one - && e.findGreatestCommonDivisor (q) == one)) - { - e.add (one); - } + while (! (e.findGreatestCommonDivisor (p).isOne() && e.findGreatestCommonDivisor (q).isOne())) + ++e; return e; } -void RSAKey::createKeyPair (RSAKey& publicKey, - RSAKey& privateKey, - const int numBits, - const int* randomSeeds, - const int numRandomSeeds) throw() +void RSAKey::createKeyPair (RSAKey& publicKey, RSAKey& privateKey, + const int numBits, const int* randomSeeds, const int numRandomSeeds) { jassert (numBits > 16); // not much point using less than this.. - BitArray p (Primes::createProbablePrime (numBits / 2, 30, randomSeeds, numRandomSeeds)); - BitArray q (Primes::createProbablePrime (numBits - numBits / 2, 30, randomSeeds, numRandomSeeds)); - - BitArray n (p); - n.multiplyBy (q); // n = pq + BigInteger p (Primes::createProbablePrime (numBits / 2, 30, randomSeeds, numRandomSeeds)); + BigInteger q (Primes::createProbablePrime (numBits - numBits / 2, 30, randomSeeds, numRandomSeeds)); - const BitArray one (1); - p.subtract (one); - q.subtract (one); + const BigInteger n (p * q); + const BigInteger m (--p * --q); + const BigInteger e (findBestCommonDivisor (p, q)); - BitArray m (p); - m.multiplyBy (q); // m = (p - 1)(q - 1) - - const BitArray e (findBestCommonDivisor (p, q)); - - BitArray d (e); + BigInteger d (e); d.inverseModulo (m); publicKey.part1 = e; @@ -23604,7 +23610,7 @@ void MixerAudioSource::removeInputSource (AudioSource* input, const bool deleteI void MixerAudioSource::removeAllInputs() { VoidArray inputsCopy; - BitArray inputsToDeleteCopy; + BigInteger inputsToDeleteCopy; { const ScopedLock sl (lock); @@ -26550,7 +26556,7 @@ void MidiBuffer::clear (const int startSample, if (end > start) { - const size_t bytesToMove = (size_t) (bytesUsed - (end - getData())); + const int bytesToMove = bytesUsed - (int) (end - getData()); if (bytesToMove > 0) memmove (start, end, bytesToMove); @@ -26608,7 +26614,7 @@ void MidiBuffer::addEvent (const uint8* const newData, data.ensureSize ((spaceNeeded + spaceNeeded / 2 + 8) & ~7); uint8* d = findEventAfter (getData(), sampleNumber); - const size_t bytesToMove = (size_t) (bytesUsed - (d - getData())); + const int bytesToMove = bytesUsed - (int) (d - getData()); if (bytesToMove > 0) memmove (d + numBytes + 6, @@ -28923,7 +28929,7 @@ void AudioPluginFormatManager::addDefaultFormats() // you should only call this method once! for (int i = formats.size(); --i >= 0;) { - #if JUCE_PLUGINHOST_VST + #if JUCE_PLUGINHOST_VST && ! (JUCE_MAC && JUCE_64BIT) jassert (dynamic_cast (formats[i]) == 0); #endif @@ -28945,7 +28951,7 @@ void AudioPluginFormatManager::addDefaultFormats() formats.add (new AudioUnitPluginFormat()); #endif -#if JUCE_PLUGINHOST_VST +#if JUCE_PLUGINHOST_VST && ! (JUCE_MAC && JUCE_64BIT) formats.add (new VSTPluginFormat()); #endif @@ -36345,7 +36351,7 @@ BEGIN_JUCE_NAMESPACE SamplerSound::SamplerSound (const String& name_, AudioFormatReader& source, - const BitArray& midiNotes_, + const BigInteger& midiNotes_, const int midiNoteForNormalPitch, const double attackTimeSecs, const double releaseTimeSecs, @@ -50602,7 +50608,7 @@ private: TableListBox& owner; int row; bool isSelected, isDragging, selectRowOnMouseUp; - BitArray columnsWithComponents; + BigInteger columnsWithComponents; Component* findChildComponentForColumn (const int columnId) const { @@ -54813,7 +54819,7 @@ public: const int visibleTop = -getY(); const int visibleBottom = visibleTop + getParentHeight(); - BitArray itemsToKeep; + BigInteger itemsToKeep; TreeViewItem* item = owner->rootItem; int y = (item != 0 && !owner->rootItemVisible) ? -item->itemHeight : 0; @@ -56795,7 +56801,7 @@ FileBrowserComponent::FileBrowserComponent (int flags_, currentPathBox->setEditableText (true); StringArray rootNames, rootPaths; - const BitArray separators (getRoots (rootNames, rootPaths)); + const BigInteger separators (getRoots (rootNames, rootPaths)); for (int i = 0; i < rootNames.size(); ++i) { @@ -57142,9 +57148,9 @@ void FileBrowserComponent::comboBoxChanged (ComboBox*) } } -const BitArray FileBrowserComponent::getRoots (StringArray& rootNames, StringArray& rootPaths) +const BigInteger FileBrowserComponent::getRoots (StringArray& rootNames, StringArray& rootPaths) { - BitArray separators; + BigInteger separators; #if JUCE_WINDOWS Array roots; @@ -72190,9 +72196,9 @@ public: if (setup.useStereoPairs) { - BitArray bits; - BitArray& original = (type == audioInputType ? config.inputChannels - : config.outputChannels); + BigInteger bits; + BigInteger& original = (type == audioInputType ? config.inputChannels + : config.outputChannels); int i; for (i = 0; i < 256; i += 2) @@ -72235,7 +72241,7 @@ public: } } - static void flipBit (BitArray& chans, int index, int minNumber, int maxNumber) + static void flipBit (BigInteger& chans, int index, int minNumber, int maxNumber) { const int numActive = chans.countNumberOfSetBits(); @@ -222644,8 +222650,8 @@ public: return preferredSize; } - const String open (const BitArray& inputChannels, - const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sr, int bufferSizeSamples) { @@ -223111,12 +223117,12 @@ public: return currentSampleRate; } - const BitArray getActiveOutputChannels() const + const BigInteger getActiveOutputChannels() const { return currentChansOut; } - const BitArray getActiveInputChannels() const + const BigInteger getActiveInputChannels() const { return currentChansIn; } @@ -223239,7 +223245,7 @@ public: AudioIODeviceCallback* const oldCallback = currentCallback; close(); - open (BitArray (currentChansIn), BitArray (currentChansOut), + open (BigInteger (currentChansIn), BigInteger (currentChansOut), currentSampleRate, currentBlockSizeSamples); if (oldCallback != 0) @@ -223274,7 +223280,7 @@ private: int volatile currentBlockSizeSamples; int volatile currentBitDepth; double volatile currentSampleRate; - BitArray currentChansOut, currentChansIn; + BigInteger currentChansOut, currentChansIn; AudioIODeviceCallback* volatile currentCallback; CriticalSection callbackLock; @@ -225398,8 +225404,8 @@ public: return 2560; } - const String open (const BitArray& inputChannels, - const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) { @@ -225451,12 +225457,12 @@ public: return bits; } - const BitArray getActiveOutputChannels() const + const BigInteger getActiveOutputChannels() const { return enabledOutputs; } - const BitArray getActiveInputChannels() const + const BigInteger getActiveInputChannels() const { return enabledInputs; } @@ -225534,7 +225540,7 @@ private: int volatile totalSamplesOut; int64 volatile lastBlockTime; double sampleRate; - BitArray enabledInputs, enabledOutputs; + BigInteger enabledInputs, enabledOutputs; HeapBlock inputBuffers, outputBuffers; AudioIODeviceCallback* callback; @@ -225543,8 +225549,8 @@ private: DSoundAudioIODevice (const DSoundAudioIODevice&); DSoundAudioIODevice& operator= (const DSoundAudioIODevice&); - const String openDevice (const BitArray& inputChannels, - const BitArray& outputChannels, + const String openDevice (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate_, int bufferSizeSamples_); @@ -225856,8 +225862,8 @@ private: DSoundAudioIODeviceType& operator= (const DSoundAudioIODeviceType&); }; -const String DSoundAudioIODevice::openDevice (const BitArray& inputChannels, - const BitArray& outputChannels, +const String DSoundAudioIODevice::openDevice (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate_, int bufferSizeSamples_) { @@ -226157,7 +226163,7 @@ public: bool isOk() const throw() { return defaultBufferSize > 0 && defaultSampleRate > 0; } - bool openClient (const double newSampleRate, const BitArray& newChannels) + bool openClient (const double newSampleRate, const BigInteger& newChannels) { sampleRate = newSampleRate; channels = newChannels; @@ -226207,7 +226213,7 @@ public: const bool useExclusiveMode; Array rates; HANDLE clientEvent; - BitArray channels; + BigInteger channels; AudioDataConverters::DataFormat dataFormat; Array channelMaps; UINT32 actualBufferSize; @@ -226312,7 +226318,7 @@ public: close(); } - bool open (const double newSampleRate, const BitArray& newChannels) + bool open (const double newSampleRate, const BigInteger& newChannels) { reservoirSize = 0; reservoirCapacity = 16384; @@ -226456,7 +226462,7 @@ public: close(); } - bool open (const double newSampleRate, const BitArray& newChannels) + bool open (const double newSampleRate, const BigInteger& newChannels) { return openClient (newSampleRate, newChannels) && (numChannels == 0 || OK (client->GetService (__uuidof (IAudioRenderClient), (void**) &renderClient))); @@ -226646,11 +226652,11 @@ public: int getCurrentBitDepth() { return 32; } int getOutputLatencyInSamples() { return latencyOut; } int getInputLatencyInSamples() { return latencyIn; } - const BitArray getActiveOutputChannels() const { return outputDevice != 0 ? outputDevice->channels : BitArray(); } - const BitArray getActiveInputChannels() const { return inputDevice != 0 ? inputDevice->channels : BitArray(); } + const BigInteger getActiveOutputChannels() const { return outputDevice != 0 ? outputDevice->channels : BigInteger(); } + const BigInteger getActiveInputChannels() const { return inputDevice != 0 ? inputDevice->channels : BigInteger(); } const String getLastError() { return lastError; } - const String open (const BitArray& inputChannels, const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) { close(); @@ -234952,8 +234958,8 @@ public: close(); } - void open (BitArray inputChannels, - BitArray outputChannels, + void open (BigInteger inputChannels, + BigInteger outputChannels, const double sampleRate_, const int bufferSize_) { @@ -235170,7 +235176,7 @@ public: String error; double sampleRate; int bufferSize; - BitArray currentInputChans, currentOutputChans; + BigInteger currentInputChans, currentOutputChans; Array sampleRates; StringArray channelNamesOut, channelNamesIn; @@ -235291,8 +235297,8 @@ public: return 512; } - const String open (const BitArray& inputChannels, - const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) { @@ -235347,12 +235353,12 @@ public: return internal->getBitDepth(); } - const BitArray getActiveOutputChannels() const + const BigInteger getActiveOutputChannels() const { return internal->currentOutputChans; } - const BitArray getActiveInputChannels() const + const BigInteger getActiveInputChannels() const { return internal->currentInputChans; } @@ -235763,7 +235769,7 @@ public: int getBufferSizeSamples (int index) { return getDefaultBufferSize(); } int getDefaultBufferSize() { return client != 0 ? JUCE_NAMESPACE::jack_get_buffer_size (client) : 0; } - const String open (const BitArray& inputChannels, const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) { if (client == 0) @@ -235780,13 +235786,13 @@ public: JUCE_NAMESPACE::jack_activate (client); isOpen_ = true; - if (! inputChannels.isEmpty()) + if (! inputChannels.isZero()) { const char** const ports = JUCE_NAMESPACE::jack_get_ports (client, 0, 0, /* JackPortIsPhysical | */ JackPortIsOutput); if (ports != 0) { - const int numInputChannels = inputChannels.getHighestBit () + 1; + const int numInputChannels = inputChannels.getHighestBit() + 1; for (int i = 0; i < numInputChannels; ++i) { @@ -235804,13 +235810,13 @@ public: } } - if (! outputChannels.isEmpty()) + if (! outputChannels.isZero()) { const char** const ports = JUCE_NAMESPACE::jack_get_ports (client, 0, 0, /* JackPortIsPhysical | */ JackPortIsInput); if (ports != 0) { - const int numOutputChannels = outputChannels.getHighestBit () + 1; + const int numOutputChannels = outputChannels.getHighestBit() + 1; for (int i = 0; i < numOutputChannels; ++i) { @@ -235876,9 +235882,9 @@ public: int getCurrentBitDepth() { return 32; } const String getLastError() { return lastError; } - const BitArray getActiveOutputChannels() const + const BigInteger getActiveOutputChannels() const { - BitArray outputBits; + BigInteger outputBits; for (int i = 0; i < outputPorts.size(); i++) if (JUCE_NAMESPACE::jack_port_connected ((jack_port_t*) outputPorts [i])) @@ -235887,9 +235893,9 @@ public: return outputBits; } - const BitArray getActiveInputChannels() const + const BigInteger getActiveInputChannels() const { - BitArray inputBits; + BigInteger inputBits; for (int i = 0; i < inputPorts.size(); i++) if (JUCE_NAMESPACE::jack_port_connected ((jack_port_t*) inputPorts [i])) @@ -242674,8 +242680,8 @@ public: return 1024; } - const String open (const BitArray& inputChannels, - const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate, int bufferSize) { @@ -242754,12 +242760,12 @@ public: return 16; } - const BitArray getActiveOutputChannels() const + const BigInteger getActiveOutputChannels() const { return activeOutputChans; } - const BitArray getActiveInputChannels() const + const BigInteger getActiveInputChannels() const { return activeInputChans; } @@ -242827,7 +242833,7 @@ private: AudioUnit audioUnit; UInt32 audioInputIsAvailable; AudioIODeviceCallback* callback; - BitArray activeOutputChans, activeInputChans; + BigInteger activeOutputChans, activeInputChans; AudioSampleBuffer floatData; float* inputChannels[3]; @@ -250222,8 +250228,8 @@ public: } } - const String reopen (const BitArray& inputChannels, - const BitArray& outputChannels, + const String reopen (const BigInteger& inputChannels, + const BigInteger& outputChannels, double newSampleRate, int bufferSizeSamples) { @@ -250561,7 +250567,7 @@ public: juce_UseDebuggingNewOperator int inputLatency, outputLatency; - BitArray activeInputChans, activeOutputChans; + BigInteger activeInputChans, activeOutputChans; StringArray inChanNames, outChanNames; Array sampleRates; Array bufferSizes; @@ -250756,8 +250762,8 @@ public: return 512; } - const String open (const BitArray& inputChannels, - const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) { @@ -250797,21 +250803,21 @@ public: return 32; // no way to find out, so just assume it's high.. } - const BitArray getActiveOutputChannels() const + const BigInteger getActiveOutputChannels() const { - return internal != 0 ? internal->activeOutputChans : BitArray(); + return internal != 0 ? internal->activeOutputChans : BigInteger(); } - const BitArray getActiveInputChannels() const + const BigInteger getActiveInputChannels() const { - BitArray chans; + BigInteger chans; if (internal != 0) { chans = internal->activeInputChans; if (internal->inputDevice != 0) - chans.orWith (internal->inputDevice->activeInputChans); + chans |= internal->inputDevice->activeInputChans; } return chans; diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 9cdd79ffba..84a59cf5f3 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -43,7 +43,7 @@ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 51 -#define JUCE_BUILDNUMBER 10 +#define JUCE_BUILDNUMBER 11 #define JUCE_VERSION ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8) + JUCE_BUILDNUMBER) @@ -2050,7 +2050,7 @@ public: while (e != end) { if (elementToLookFor == *e) - return (int) (e - data.elements.getData()); + return static_cast (e - data.elements.getData()); ++e; } @@ -2310,7 +2310,7 @@ public: { if (valueToRemove == *e) { - remove ((int) (e - data.elements.getData())); + remove (static_cast (e - data.elements.getData())); break; } @@ -2326,7 +2326,7 @@ public: if (endIndex > startIndex) { - ElementType* e = data.elements + startIndex; + ElementType* const e = data.elements + startIndex; numberToRemove = endIndex - startIndex; for (int i = 0; i < numberToRemove; ++i) @@ -2495,82 +2495,109 @@ private: class MemoryBlock; -class JUCE_API BitArray +class JUCE_API BigInteger { public: - BitArray() throw(); + BigInteger(); - BitArray (const unsigned int value) throw(); + BigInteger (unsigned int value); - BitArray (const int value) throw(); + BigInteger (int value); - BitArray (int64 value) throw(); + BigInteger (int64 value); - BitArray (const BitArray& other) throw(); + BigInteger (const BigInteger& other); - ~BitArray() throw(); + ~BigInteger(); - BitArray& operator= (const BitArray& other) throw(); + BigInteger& operator= (const BigInteger& other); - bool operator== (const BitArray& other) const throw(); - bool operator!= (const BitArray& other) const throw(); + void swapWith (BigInteger& other) throw(); - void clear() throw(); - - void clearBit (const int bitNumber) throw(); - - void setBit (const int bitNumber) throw(); - - void setBit (const int bitNumber, - const bool shouldBeSet) throw(); - - void setRange (int startBit, - int numBits, - const bool shouldBeSet) throw(); - - void insertBit (const int bitNumber, - const bool shouldBeSet) throw(); - - bool operator[] (const int bit) const throw(); + bool operator[] (int bit) const throw(); - bool isEmpty() const throw(); + bool isZero() const throw(); - const BitArray getBitRange (int startBit, int numBits) const throw(); + bool isOne() const throw(); - int getBitRangeAsInt (int startBit, int numBits) const throw(); + int toInteger() const throw(); - void setBitRangeAsInt (int startBit, int numBits, - unsigned int valueToSet) throw(); + void clear(); - void orWith (const BitArray& other) throw(); + void clearBit (int bitNumber) throw(); - void andWith (const BitArray& other) throw(); + void setBit (int bitNumber); - void xorWith (const BitArray& other) throw(); + void setBit (int bitNumber, bool shouldBeSet); - void add (const BitArray& other) throw(); + void setRange (int startBit, int numBits, bool shouldBeSet); - void subtract (const BitArray& other) throw(); + void insertBit (int bitNumber, bool shouldBeSet); - void multiplyBy (const BitArray& other) throw(); + const BigInteger getBitRange (int startBit, int numBits) const; - void divideBy (const BitArray& divisor, BitArray& remainder) throw(); + int getBitRangeAsInt (int startBit, int numBits) const throw(); - const BitArray findGreatestCommonDivisor (BitArray other) const throw(); + void setBitRangeAsInt (int startBit, int numBits, unsigned int valueToSet); - void modulo (const BitArray& divisor) throw(); + void shiftBits (int howManyBitsLeft, int startBit); - void exponentModulo (const BitArray& exponent, const BitArray& modulus) throw(); + int countNumberOfSetBits() const throw(); - void inverseModulo (const BitArray& modulus) throw(); + int findNextSetBit (int startIndex = 0) const throw(); - void shiftBits (int howManyBitsLeft, - int startBit = 0) throw(); + int findNextClearBit (int startIndex = 0) const throw(); - int compare (const BitArray& other) const throw(); + int getHighestBit() const throw(); - int compareAbsolute (const BitArray& other) const throw(); + // All the standard arithmetic ops... + + BigInteger& operator+= (const BigInteger& other); + BigInteger& operator-= (const BigInteger& other); + BigInteger& operator*= (const BigInteger& other); + BigInteger& operator/= (const BigInteger& other); + BigInteger& operator|= (const BigInteger& other); + BigInteger& operator&= (const BigInteger& other); + BigInteger& operator^= (const BigInteger& other); + BigInteger& operator%= (const BigInteger& other); + BigInteger& operator<<= (int numBitsToShift); + BigInteger& operator>>= (int numBitsToShift); + BigInteger& operator++(); + BigInteger& operator--(); + const BigInteger operator++ (int); + const BigInteger operator-- (int); + + const BigInteger operator-() const; + const BigInteger operator+ (const BigInteger& other) const; + const BigInteger operator- (const BigInteger& other) const; + const BigInteger operator* (const BigInteger& other) const; + const BigInteger operator/ (const BigInteger& other) const; + const BigInteger operator| (const BigInteger& other) const; + const BigInteger operator& (const BigInteger& other) const; + const BigInteger operator^ (const BigInteger& other) const; + const BigInteger operator% (const BigInteger& other) const; + const BigInteger operator<< (int numBitsToShift) const; + const BigInteger operator>> (int numBitsToShift) const; + + bool operator== (const BigInteger& other) const throw(); + bool operator!= (const BigInteger& other) const throw(); + bool operator< (const BigInteger& other) const throw(); + bool operator<= (const BigInteger& other) const throw(); + bool operator> (const BigInteger& other) const throw(); + bool operator>= (const BigInteger& other) const throw(); + + int compare (const BigInteger& other) const throw(); + + int compareAbsolute (const BigInteger& other) const throw(); + + void divideBy (const BigInteger& divisor, BigInteger& remainder); + + const BigInteger findGreatestCommonDivisor (BigInteger other) const; + + void exponentModulo (const BigInteger& exponent, const BigInteger& modulus); + + void inverseModulo (const BigInteger& modulus); bool isNegative() const throw(); @@ -2578,32 +2605,29 @@ public: void negate() throw(); - int countNumberOfSetBits() const throw(); - - int findNextSetBit (int startIndex = 0) const throw(); - - int findNextClearBit (int startIndex = 0) const throw(); - - int getHighestBit() const throw(); - - const String toString (const int base, const int minimumNumCharacters = 1) const throw(); + const String toString (int base, int minimumNumCharacters = 1) const; - void parseString (const String& text, - const int base) throw(); + void parseString (const String& text, int base); - const MemoryBlock toMemoryBlock() const throw(); + const MemoryBlock toMemoryBlock() const; - void loadFromMemoryBlock (const MemoryBlock& data) throw(); + void loadFromMemoryBlock (const MemoryBlock& data); juce_UseDebuggingNewOperator private: - void ensureSize (const int numVals) throw(); HeapBlock values; int numValues, highestBit; bool negative; + + void ensureSize (int numVals); + static const BigInteger simpleGCD (BigInteger* m, BigInteger* n); }; +OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const BigInteger& value); + +typedef BigInteger BitArray; + #endif // __JUCE_BITARRAY_JUCEHEADER__ /*** End of inlined file: juce_BitArray.h ***/ @@ -3470,7 +3494,7 @@ public: while (e != end) { if (objectToLookFor == *e) - return (int) (e - data.elements.getData()); + return static_cast (e - data.elements.getData()); ++e; } @@ -3666,7 +3690,7 @@ public: { if (objectToRemove == *e) { - remove ((int) (e - data.elements.getData()), deleteObject); + remove (static_cast (e - data.elements.getData()), deleteObject); break; } @@ -4947,7 +4971,7 @@ public: while (e != end) { if (objectToLookFor == *e) - return (int) (e - data.elements.getData()); + return static_cast (e - data.elements.getData()); ++e; } @@ -7067,9 +7091,9 @@ public: bool nextBool() throw(); - const BitArray nextLargeNumber (const BitArray& maximumValue) throw(); + const BigInteger nextLargeNumber (const BigInteger& maximumValue); - void fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw(); + void fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits); static Random& getSystemRandom() throw(); @@ -7503,13 +7527,12 @@ class JUCE_API Primes { public: - static const BitArray createProbablePrime (int bitLength, - int certainty, - const int* randomSeeds = 0, - int numRandomSeeds = 0) throw(); + static const BigInteger createProbablePrime (int bitLength, + int certainty, + const int* randomSeeds = 0, + int numRandomSeeds = 0); - static bool isProbablyPrime (const BitArray& number, - int certainty) throw(); + static bool isProbablyPrime (const BigInteger& number, int certainty); }; #endif // __JUCE_PRIMES_JUCEHEADER__ @@ -7527,26 +7550,26 @@ class JUCE_API RSAKey { public: - RSAKey() throw(); + RSAKey(); - RSAKey (const String& stringRepresentation) throw(); + RSAKey (const String& stringRepresentation); - ~RSAKey() throw(); + ~RSAKey(); - const String toString() const throw(); + const String toString() const; - bool applyToValue (BitArray& value) const throw(); + bool applyToValue (BigInteger& value) const; static void createKeyPair (RSAKey& publicKey, RSAKey& privateKey, - const int numBits, + int numBits, const int* randomSeeds = 0, - const int numRandomSeeds = 0) throw(); + int numRandomSeeds = 0); juce_UseDebuggingNewOperator protected: - BitArray part1, part2; + BigInteger part1, part2; }; #endif // __JUCE_RSAKEY_JUCEHEADER__ @@ -14595,8 +14618,8 @@ public: virtual int getDefaultBufferSize() = 0; - virtual const String open (const BitArray& inputChannels, - const BitArray& outputChannels, + virtual const String open (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) = 0; @@ -14618,9 +14641,9 @@ public: virtual int getCurrentBitDepth() = 0; - virtual const BitArray getActiveOutputChannels() const = 0; + virtual const BigInteger getActiveOutputChannels() const = 0; - virtual const BitArray getActiveInputChannels() const = 0; + virtual const BigInteger getActiveInputChannels() const = 0; virtual int getOutputLatencyInSamples() = 0; @@ -15068,7 +15091,7 @@ public: private: VoidArray inputs; - BitArray inputsToDelete; + BigInteger inputsToDelete; CriticalSection lock; AudioSampleBuffer tempBuffer; double currentSampleRate; @@ -17013,11 +17036,11 @@ public: int bufferSize; - BitArray inputChannels; + BigInteger inputChannels; bool useDefaultInputChannels; - BitArray outputChannels; + BigInteger outputChannels; bool useDefaultOutputChannels; }; @@ -17094,7 +17117,7 @@ private: SortedSet callbacks; int numInputChansNeeded, numOutputChansNeeded; String currentDeviceType; - BitArray inputChannels, outputChannels; + BigInteger inputChannels, outputChannels; ScopedPointer lastExplicitSettings; mutable bool listNeedsScanning; bool useInputNames; @@ -17147,7 +17170,7 @@ private: void handleIncomingMidiMessageInt (MidiInput* source, const MidiMessage& message); const String restartDevice (int blockSizeToUse, double sampleRateToUse, - const BitArray& ins, const BitArray& outs); + const BigInteger& ins, const BigInteger& outs); void stopDevice(); void updateXml(); @@ -17810,7 +17833,7 @@ private: CriticalSection callbackLock, listenerLock; #ifdef JUCE_DEBUG - BitArray changingParams; + BigInteger changingParams; #endif AudioProcessor (const AudioProcessor&); @@ -19299,7 +19322,7 @@ public: SamplerSound (const String& name, AudioFormatReader& source, - const BitArray& midiNotes, + const BigInteger& midiNotes, const int midiNoteForNormalPitch, const double attackTimeSecs, const double releaseTimeSecs, @@ -19322,7 +19345,7 @@ private: String name; ScopedPointer data; double sourceSampleRate; - BitArray midiNotes; + BigInteger midiNotes; int length, attackSamples, releaseSamples; int midiRootNote; }; @@ -22459,7 +22482,7 @@ public: juce_UseDebuggingNewOperator protected: - virtual const BitArray getRoots (StringArray& rootNames, StringArray& rootPaths); + virtual const BigInteger getRoots (StringArray& rootNames, StringArray& rootPaths); private: @@ -26584,7 +26607,7 @@ private: int midiChannel, midiInChannelMask; float velocity; int noteUnderMouse, mouseDownNote; - BitArray keysPressed, keysCurrentlyDrawnDown; + BigInteger keysPressed, keysCurrentlyDrawnDown; int rangeStart, rangeEnd, firstKey; bool canScroll, mouseDragging, useMousePositionForVelocity; diff --git a/src/audio/audio_sources/juce_MixerAudioSource.cpp b/src/audio/audio_sources/juce_MixerAudioSource.cpp index ee4f844d16..30ae1b24fc 100644 --- a/src/audio/audio_sources/juce_MixerAudioSource.cpp +++ b/src/audio/audio_sources/juce_MixerAudioSource.cpp @@ -99,7 +99,7 @@ void MixerAudioSource::removeInputSource (AudioSource* input, const bool deleteI void MixerAudioSource::removeAllInputs() { VoidArray inputsCopy; - BitArray inputsToDeleteCopy; + BigInteger inputsToDeleteCopy; { const ScopedLock sl (lock); diff --git a/src/audio/audio_sources/juce_MixerAudioSource.h b/src/audio/audio_sources/juce_MixerAudioSource.h index 17f5b23a20..e68d3ef2e6 100644 --- a/src/audio/audio_sources/juce_MixerAudioSource.h +++ b/src/audio/audio_sources/juce_MixerAudioSource.h @@ -112,7 +112,7 @@ public: private: //============================================================================== VoidArray inputs; - BitArray inputsToDelete; + BigInteger inputsToDelete; CriticalSection lock; AudioSampleBuffer tempBuffer; double currentSampleRate; diff --git a/src/audio/devices/juce_AudioDeviceManager.h b/src/audio/devices/juce_AudioDeviceManager.h index 61cbeed89e..65e67cdaf3 100644 --- a/src/audio/devices/juce_AudioDeviceManager.h +++ b/src/audio/devices/juce_AudioDeviceManager.h @@ -124,7 +124,7 @@ public: The bits that are set in this array indicate the channels of the input device that are active. */ - BitArray inputChannels; + BigInteger inputChannels; /** If this is true, it indicates that the inputChannels array should be ignored, and instead, the device's default channels @@ -136,7 +136,7 @@ public: The bits that are set in this array indicate the channels of the input device that are active. */ - BitArray outputChannels; + BigInteger outputChannels; /** If this is true, it indicates that the outputChannels array should be ignored, and instead, the device's default channels @@ -426,7 +426,7 @@ private: SortedSet callbacks; int numInputChansNeeded, numOutputChansNeeded; String currentDeviceType; - BitArray inputChannels, outputChannels; + BigInteger inputChannels, outputChannels; ScopedPointer lastExplicitSettings; mutable bool listNeedsScanning; bool useInputNames; @@ -480,7 +480,7 @@ private: void handleIncomingMidiMessageInt (MidiInput* source, const MidiMessage& message); const String restartDevice (int blockSizeToUse, double sampleRateToUse, - const BitArray& ins, const BitArray& outs); + const BigInteger& ins, const BigInteger& outs); void stopDevice(); void updateXml(); diff --git a/src/audio/devices/juce_AudioIODevice.h b/src/audio/devices/juce_AudioIODevice.h index baa81bb695..bd7021aab6 100644 --- a/src/audio/devices/juce_AudioIODevice.h +++ b/src/audio/devices/juce_AudioIODevice.h @@ -203,9 +203,9 @@ public: //============================================================================== /** Tries to open the device ready to play. - @param inputChannels a BitArray in which a set bit indicates that the corresponding + @param inputChannels a BigInteger in which a set bit indicates that the corresponding input channel should be enabled - @param outputChannels a BitArray in which a set bit indicates that the corresponding + @param outputChannels a BigInteger in which a set bit indicates that the corresponding output channel should be enabled @param sampleRate the sample rate to try to use - to find out which rates are available, see getNumSampleRates() and getSampleRate() @@ -215,8 +215,8 @@ public: opening the device @see close */ - virtual const String open (const BitArray& inputChannels, - const BitArray& outputChannels, + virtual const String open (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) = 0; @@ -279,13 +279,13 @@ public: enabled. @see getOutputChannelNames */ - virtual const BitArray getActiveOutputChannels() const = 0; + virtual const BigInteger getActiveOutputChannels() const = 0; /** Returns a mask showing which of the available input channels are currently enabled. @see getInputChannelNames */ - virtual const BitArray getActiveInputChannels() const = 0; + virtual const BigInteger getActiveInputChannels() const = 0; /** Returns the device's output latency. diff --git a/src/audio/midi/juce_MidiBuffer.cpp b/src/audio/midi/juce_MidiBuffer.cpp index aacb226f74..870e3059e4 100644 --- a/src/audio/midi/juce_MidiBuffer.cpp +++ b/src/audio/midi/juce_MidiBuffer.cpp @@ -79,7 +79,7 @@ void MidiBuffer::clear (const int startSample, if (end > start) { - const size_t bytesToMove = (size_t) (bytesUsed - (end - getData())); + const int bytesToMove = bytesUsed - (int) (end - getData()); if (bytesToMove > 0) memmove (start, end, bytesToMove); @@ -137,7 +137,7 @@ void MidiBuffer::addEvent (const uint8* const newData, data.ensureSize ((spaceNeeded + spaceNeeded / 2 + 8) & ~7); uint8* d = findEventAfter (getData(), sampleNumber); - const size_t bytesToMove = (size_t) (bytesUsed - (d - getData())); + const int bytesToMove = bytesUsed - (int) (d - getData()); if (bytesToMove > 0) memmove (d + numBytes + 6, diff --git a/src/audio/plugins/juce_AudioPluginFormatManager.cpp b/src/audio/plugins/juce_AudioPluginFormatManager.cpp index e0e45b46b2..dbb4a16ef7 100644 --- a/src/audio/plugins/juce_AudioPluginFormatManager.cpp +++ b/src/audio/plugins/juce_AudioPluginFormatManager.cpp @@ -56,7 +56,7 @@ void AudioPluginFormatManager::addDefaultFormats() // you should only call this method once! for (int i = formats.size(); --i >= 0;) { - #if JUCE_PLUGINHOST_VST + #if JUCE_PLUGINHOST_VST && ! (JUCE_MAC && JUCE_64BIT) jassert (dynamic_cast (formats[i]) == 0); #endif @@ -78,7 +78,7 @@ void AudioPluginFormatManager::addDefaultFormats() formats.add (new AudioUnitPluginFormat()); #endif -#if JUCE_PLUGINHOST_VST +#if JUCE_PLUGINHOST_VST && ! (JUCE_MAC && JUCE_64BIT) formats.add (new VSTPluginFormat()); #endif diff --git a/src/audio/processors/juce_AudioProcessor.h b/src/audio/processors/juce_AudioProcessor.h index 2d9ef3e1c6..a9389d2f3d 100644 --- a/src/audio/processors/juce_AudioProcessor.h +++ b/src/audio/processors/juce_AudioProcessor.h @@ -579,7 +579,7 @@ private: CriticalSection callbackLock, listenerLock; #ifdef JUCE_DEBUG - BitArray changingParams; + BigInteger changingParams; #endif AudioProcessor (const AudioProcessor&); diff --git a/src/audio/synthesisers/juce_Sampler.cpp b/src/audio/synthesisers/juce_Sampler.cpp index cb72b6b8ed..35191c9456 100644 --- a/src/audio/synthesisers/juce_Sampler.cpp +++ b/src/audio/synthesisers/juce_Sampler.cpp @@ -34,7 +34,7 @@ BEGIN_JUCE_NAMESPACE //============================================================================== SamplerSound::SamplerSound (const String& name_, AudioFormatReader& source, - const BitArray& midiNotes_, + const BigInteger& midiNotes_, const int midiNoteForNormalPitch, const double attackTimeSecs, const double releaseTimeSecs, diff --git a/src/audio/synthesisers/juce_Sampler.h b/src/audio/synthesisers/juce_Sampler.h index bff63a7bc1..8f8e5b0c5d 100644 --- a/src/audio/synthesisers/juce_Sampler.h +++ b/src/audio/synthesisers/juce_Sampler.h @@ -66,7 +66,7 @@ public: */ SamplerSound (const String& name, AudioFormatReader& source, - const BitArray& midiNotes, + const BigInteger& midiNotes, const int midiNoteForNormalPitch, const double attackTimeSecs, const double releaseTimeSecs, @@ -99,7 +99,7 @@ private: String name; ScopedPointer data; double sourceSampleRate; - BitArray midiNotes; + BigInteger midiNotes; int length, attackSamples, releaseSamples; int midiRootNote; }; diff --git a/src/containers/juce_Array.h b/src/containers/juce_Array.h index 99b2826258..852fbe3eb6 100644 --- a/src/containers/juce_Array.h +++ b/src/containers/juce_Array.h @@ -288,7 +288,7 @@ public: while (e != end) { if (elementToLookFor == *e) - return (int) (e - data.elements.getData()); + return static_cast (e - data.elements.getData()); ++e; } @@ -683,7 +683,7 @@ public: { if (valueToRemove == *e) { - remove ((int) (e - data.elements.getData())); + remove (static_cast (e - data.elements.getData())); break; } @@ -711,7 +711,7 @@ public: if (endIndex > startIndex) { - ElementType* e = data.elements + startIndex; + ElementType* const e = data.elements + startIndex; numberToRemove = endIndex - startIndex; for (int i = 0; i < numberToRemove; ++i) diff --git a/src/containers/juce_BitArray.cpp b/src/containers/juce_BitArray.cpp index 2e31e48f25..eb0d9914ec 100644 --- a/src/containers/juce_BitArray.cpp +++ b/src/containers/juce_BitArray.cpp @@ -27,14 +27,13 @@ BEGIN_JUCE_NAMESPACE - #include "juce_BitArray.h" #include "juce_MemoryBlock.h" #include "../core/juce_Random.h" //============================================================================== -BitArray::BitArray() throw() +BigInteger::BigInteger() : numValues (4), highestBit (-1), negative (false) @@ -42,7 +41,7 @@ BitArray::BitArray() throw() values.calloc (numValues + 1); } -BitArray::BitArray (const int value) throw() +BigInteger::BigInteger (const int value) : numValues (4), highestBit (31), negative (value < 0) @@ -52,7 +51,7 @@ BitArray::BitArray (const int value) throw() highestBit = getHighestBit(); } -BitArray::BitArray (int64 value) throw() +BigInteger::BigInteger (int64 value) : numValues (4), highestBit (63), negative (value < 0) @@ -67,7 +66,7 @@ BitArray::BitArray (int64 value) throw() highestBit = getHighestBit(); } -BitArray::BitArray (const unsigned int value) throw() +BigInteger::BigInteger (const unsigned int value) : numValues (4), highestBit (31), negative (false) @@ -77,7 +76,7 @@ BitArray::BitArray (const unsigned int value) throw() highestBit = getHighestBit(); } -BitArray::BitArray (const BitArray& other) throw() +BigInteger::BigInteger (const BigInteger& other) : numValues (jmax (4, (other.highestBit >> 5) + 1)), highestBit (other.getHighestBit()), negative (other.negative) @@ -86,11 +85,19 @@ BitArray::BitArray (const BitArray& other) throw() memcpy (values, other.values, sizeof (unsigned int) * (numValues + 1)); } -BitArray::~BitArray() throw() +BigInteger::~BigInteger() +{ +} + +void BigInteger::swapWith (BigInteger& other) throw() { + values.swapWith (other.values); + swapVariables (numValues, other.numValues); + swapVariables (highestBit, other.highestBit); + swapVariables (negative, other.negative); } -BitArray& BitArray::operator= (const BitArray& other) throw() +BigInteger& BigInteger::operator= (const BigInteger& other) { if (this != &other) { @@ -104,61 +111,93 @@ BitArray& BitArray::operator= (const BitArray& other) throw() return *this; } -// result == 0 = the same -// result < 0 = this number is smaller -// result > 0 = this number is bigger -int BitArray::compare (const BitArray& other) const throw() +void BigInteger::ensureSize (const int numVals) { - if (isNegative() == other.isNegative()) - { - const int absComp = compareAbsolute (other); - return isNegative() ? -absComp : absComp; - } - else + if (numVals + 2 >= numValues) { - return isNegative() ? -1 : 1; + int oldSize = numValues; + numValues = ((numVals + 2) * 3) / 2; + values.realloc (numValues + 1); + + while (oldSize < numValues) + values [oldSize++] = 0; } } -int BitArray::compareAbsolute (const BitArray& other) const throw() +//============================================================================== +bool BigInteger::operator[] (const int bit) const throw() { - const int h1 = getHighestBit(); - const int h2 = other.getHighestBit(); - - if (h1 > h2) - return 1; - else if (h1 < h2) - return -1; - - for (int i = (h1 >> 5) + 1; --i >= 0;) - if (values[i] != other.values[i]) - return (values[i] > other.values[i]) ? 1 : -1; - - return 0; + return bit <= highestBit && bit >= 0 + && ((values [bit >> 5] & (1 << (bit & 31))) != 0); } -bool BitArray::operator== (const BitArray& other) const throw() +int BigInteger::toInteger() const throw() { - return compare (other) == 0; + const int n = (int) (values[0] & 0x7fffffff); + return negative ? -n : n; } -bool BitArray::operator!= (const BitArray& other) const throw() +const BigInteger BigInteger::getBitRange (int startBit, int numBits) const { - return compare (other) != 0; + BigInteger r; + numBits = jmin (numBits, getHighestBit() + 1 - startBit); + r.ensureSize (numBits >> 5); + r.highestBit = numBits; + + int i = 0; + while (numBits > 0) + { + r.values[i++] = getBitRangeAsInt (startBit, jmin (32, numBits)); + numBits -= 32; + startBit += 32; + } + + r.highestBit = r.getHighestBit(); + return r; } -bool BitArray::operator[] (const int bit) const throw() +int BigInteger::getBitRangeAsInt (const int startBit, int numBits) const throw() { - return bit >= 0 && bit <= highestBit - && ((values [bit >> 5] & (1 << (bit & 31))) != 0); + if (numBits > 32) + { + jassertfalse // use getBitRange() if you need more than 32 bits.. + numBits = 32; + } + + numBits = jmin (numBits, highestBit + 1 - startBit); + + if (numBits <= 0) + return 0; + + const int pos = startBit >> 5; + const int offset = startBit & 31; + const int endSpace = 32 - numBits; + + uint32 n = ((uint32) values [pos]) >> offset; + + if (offset > endSpace) + n |= ((uint32) values [pos + 1]) << (32 - offset); + + return (int) (n & (((uint32) 0xffffffff) >> endSpace)); } -bool BitArray::isEmpty() const throw() +void BigInteger::setBitRangeAsInt (const int startBit, int numBits, unsigned int valueToSet) { - return getHighestBit() < 0; + if (numBits > 32) + { + jassertfalse + numBits = 32; + } + + for (int i = 0; i < numBits; ++i) + { + setBit (startBit + i, (valueToSet & 1) != 0); + valueToSet >>= 1; + } } -void BitArray::clear() throw() +//============================================================================== +void BigInteger::clear() { if (numValues > 16) { @@ -174,7 +213,7 @@ void BitArray::clear() throw() negative = false; } -void BitArray::setBit (const int bit) throw() +void BigInteger::setBit (const int bit) { if (bit >= 0) { @@ -188,8 +227,7 @@ void BitArray::setBit (const int bit) throw() } } -void BitArray::setBit (const int bit, - const bool shouldBeSet) throw() +void BigInteger::setBit (const int bit, const bool shouldBeSet) { if (shouldBeSet) setBit (bit); @@ -197,22 +235,19 @@ void BitArray::setBit (const int bit, clearBit (bit); } -void BitArray::clearBit (const int bit) throw() +void BigInteger::clearBit (const int bit) throw() { if (bit >= 0 && bit <= highestBit) values [bit >> 5] &= ~(1 << (bit & 31)); } -void BitArray::setRange (int startBit, - int numBits, - const bool shouldBeSet) throw() +void BigInteger::setRange (int startBit, int numBits, const bool shouldBeSet) { while (--numBits >= 0) setBit (startBit++, shouldBeSet); } -void BitArray::insertBit (const int bit, - const bool shouldBeSet) throw() +void BigInteger::insertBit (const int bit, const bool shouldBeSet) { if (bit >= 0) shiftBits (1, bit); @@ -221,150 +256,158 @@ void BitArray::insertBit (const int bit, } //============================================================================== -void BitArray::andWith (const BitArray& other) throw() +bool BigInteger::isZero() const throw() { - // this operation will only work with the absolute values - jassert (isNegative() == other.isNegative()); - - int n = numValues; - - while (n > other.numValues) - values[--n] = 0; - - while (--n >= 0) - values[n] &= other.values[n]; - - if (other.highestBit < highestBit) - highestBit = other.highestBit; + return getHighestBit() < 0; +} - highestBit = getHighestBit(); +bool BigInteger::isOne() const throw() +{ + return getHighestBit() == 0 && ! negative; } -void BitArray::orWith (const BitArray& other) throw() +bool BigInteger::isNegative() const throw() { - if (other.highestBit < 0) - return; + return negative && ! isZero(); +} - // this operation will only work with the absolute values - jassert (isNegative() == other.isNegative()); +void BigInteger::setNegative (const bool neg) throw() +{ + negative = neg; +} - ensureSize (other.highestBit >> 5); +void BigInteger::negate() throw() +{ + negative = (! negative) && ! isZero(); +} - int n = (other.highestBit >> 5) + 1; +int BigInteger::countNumberOfSetBits() const throw() +{ + int total = 0; - while (--n >= 0) - values[n] |= other.values[n]; + for (int i = (highestBit >> 5) + 1; --i >= 0;) + { + unsigned int n = values[i]; - if (other.highestBit > highestBit) - highestBit = other.highestBit; + if (n == 0xffffffff) + { + total += 32; + } + else + { + while (n != 0) + { + total += (n & 1); + n >>= 1; + } + } + } - highestBit = getHighestBit(); + return total; } -void BitArray::xorWith (const BitArray& other) throw() +int BigInteger::getHighestBit() const throw() { - if (other.highestBit < 0) - return; - - // this operation will only work with the absolute values - jassert (isNegative() == other.isNegative()); + for (int i = highestBit + 1; --i >= 0;) + if ((values [i >> 5] & (1 << (i & 31))) != 0) + return i; - ensureSize (other.highestBit >> 5); + return -1; +} - int n = (other.highestBit >> 5) + 1; +int BigInteger::findNextSetBit (int i) const throw() +{ + for (; i <= highestBit; ++i) + if ((values [i >> 5] & (1 << (i & 31))) != 0) + return i; - while (--n >= 0) - values[n] ^= other.values[n]; + return -1; +} - if (other.highestBit > highestBit) - highestBit = other.highestBit; +int BigInteger::findNextClearBit (int i) const throw() +{ + for (; i <= highestBit; ++i) + if ((values [i >> 5] & (1 << (i & 31))) == 0) + break; - highestBit = getHighestBit(); + return i; } //============================================================================== -void BitArray::add (const BitArray& other) throw() +BigInteger& BigInteger::operator+= (const BigInteger& other) { if (other.isNegative()) - { - BitArray o (other); - o.negate(); - subtract (o); - return; - } + return operator-= (-other); if (isNegative()) { if (compareAbsolute (other) < 0) { - BitArray temp (*this); + BigInteger temp (*this); temp.negate(); *this = other; - subtract (temp); + operator-= (temp); } else { negate(); - subtract (other); + operator-= (other); negate(); } - - return; } + else + { + if (other.highestBit > highestBit) + highestBit = other.highestBit; - if (other.highestBit > highestBit) - highestBit = other.highestBit; + ++highestBit; - ++highestBit; + const int numInts = (highestBit >> 5) + 1; + ensureSize (numInts); - const int numInts = (highestBit >> 5) + 1; - ensureSize (numInts); + int64 remainder = 0; - int64 remainder = 0; + for (int i = 0; i <= numInts; ++i) + { + if (i < numValues) + remainder += values[i]; - for (int i = 0; i <= numInts; ++i) - { - if (i < numValues) - remainder += values[i]; + if (i < other.numValues) + remainder += other.values[i]; - if (i < other.numValues) - remainder += other.values[i]; + values[i] = (unsigned int) remainder; + remainder >>= 32; + } - values[i] = (unsigned int) remainder; - remainder >>= 32; + jassert (remainder == 0); + highestBit = getHighestBit(); } - jassert (remainder == 0); - highestBit = getHighestBit(); + return *this; } -void BitArray::subtract (const BitArray& other) throw() +BigInteger& BigInteger::operator-= (const BigInteger& other) { if (other.isNegative()) - { - BitArray o (other); - o.negate(); - add (o); - return; - } + return operator+= (-other); if (! isNegative()) { if (compareAbsolute (other) < 0) { - BitArray temp (*this); - *this = other; - subtract (temp); + BigInteger temp (other); + swapWith (temp); + operator-= (temp); negate(); - return; + return *this; } } else { negate(); - add (other); + operator+= (other); negate(); - return; + return *this; } const int numInts = (highestBit >> 5) + 1; @@ -374,7 +417,7 @@ void BitArray::subtract (const BitArray& other) throw() for (int i = 0; i <= numInts; ++i) { if (i <= maxOtherInts) - amountToSubtract += (int64)other.values[i]; + amountToSubtract += (int64) other.values[i]; if (values[i] >= amountToSubtract) { @@ -388,11 +431,13 @@ void BitArray::subtract (const BitArray& other) throw() amountToSubtract = 1; } } + + return *this; } -void BitArray::multiplyBy (const BitArray& other) throw() +BigInteger& BigInteger::operator*= (const BigInteger& other) { - BitArray total; + BigInteger total; highestBit = getHighestBit(); const bool wasNegative = isNegative(); setNegative (false); @@ -401,18 +446,19 @@ void BitArray::multiplyBy (const BitArray& other) throw() { if (operator[](i)) { - BitArray n (other); + BigInteger n (other); n.setNegative (false); - n.shiftBits (i); - total.add (n); + n <<= i; + total += n; } } - *this = total; - negative = wasNegative ^ other.isNegative(); + total.setNegative (wasNegative ^ other.isNegative()); + swapWith (total); + return *this; } -void BitArray::divideBy (const BitArray& divisor, BitArray& remainder) throw() +void BigInteger::divideBy (const BigInteger& divisor, BigInteger& remainder) { jassert (this != &remainder); // (can't handle passing itself in to get the remainder) @@ -427,27 +473,28 @@ void BitArray::divideBy (const BitArray& divisor, BitArray& remainder) throw() } else { - remainder = *this; - remainder.setNegative (false); const bool wasNegative = isNegative(); + + swapWith (remainder); + remainder.setNegative (false); clear(); - BitArray temp (divisor); + BigInteger temp (divisor); temp.setNegative (false); int leftShift = ourHB - divHB; - temp.shiftBits (leftShift); + temp <<= leftShift; while (leftShift >= 0) { if (remainder.compareAbsolute (temp) >= 0) { - remainder.subtract (temp); + remainder -= temp; setBit (leftShift); } if (--leftShift >= 0) - temp.shiftBits (-1); + temp >>= 1; } negative = wasNegative ^ divisor.isNegative(); @@ -455,129 +502,155 @@ void BitArray::divideBy (const BitArray& divisor, BitArray& remainder) throw() } } -void BitArray::modulo (const BitArray& divisor) throw() +BigInteger& BigInteger::operator/= (const BigInteger& other) { - BitArray remainder; - divideBy (divisor, remainder); - *this = remainder; + BigInteger remainder; + divideBy (other, remainder); + return *this; } -static const BitArray simpleGCD (BitArray* m, BitArray* n) throw() +BigInteger& BigInteger::operator|= (const BigInteger& other) { - while (! m->isEmpty()) + // this operation doesn't take into account negative values.. + jassert (isNegative() == other.isNegative()); + + if (other.highestBit >= 0) { - if (n->compareAbsolute (*m) > 0) - swapVariables (m, n); + ensureSize (other.highestBit >> 5); - m->subtract (*n); + int n = (other.highestBit >> 5) + 1; + + while (--n >= 0) + values[n] |= other.values[n]; + + if (other.highestBit > highestBit) + highestBit = other.highestBit; + + highestBit = getHighestBit(); } - return *n; + return *this; } -const BitArray BitArray::findGreatestCommonDivisor (BitArray n) const throw() +BigInteger& BigInteger::operator&= (const BigInteger& other) { - BitArray m (*this); + // this operation doesn't take into account negative values.. + jassert (isNegative() == other.isNegative()); - while (! n.isEmpty()) - { - if (abs (m.getHighestBit() - n.getHighestBit()) <= 16) - return simpleGCD (&m, &n); + int n = numValues; - BitArray temp1 (m), temp2; - temp1.divideBy (n, temp2); + while (n > other.numValues) + values[--n] = 0; - m = n; - n = temp2; - } + while (--n >= 0) + values[n] &= other.values[n]; - return m; + if (other.highestBit < highestBit) + highestBit = other.highestBit; + + highestBit = getHighestBit(); + return *this; } -void BitArray::exponentModulo (const BitArray& exponent, - const BitArray& modulus) throw() +BigInteger& BigInteger::operator^= (const BigInteger& other) { - BitArray exp (exponent); - exp.modulo (modulus); + // this operation will only work with the absolute values + jassert (isNegative() == other.isNegative()); - BitArray value (*this); - value.modulo (modulus); + if (other.highestBit >= 0) + { + ensureSize (other.highestBit >> 5); - clear(); - setBit (0); + int n = (other.highestBit >> 5) + 1; - while (! exp.isEmpty()) - { - if (exp [0]) - { - multiplyBy (value); - this->modulo (modulus); - } + while (--n >= 0) + values[n] ^= other.values[n]; - value.multiplyBy (value); - value.modulo (modulus); + if (other.highestBit > highestBit) + highestBit = other.highestBit; - exp.shiftBits (-1); + highestBit = getHighestBit(); } + + return *this; } -void BitArray::inverseModulo (const BitArray& modulus) throw() +BigInteger& BigInteger::operator%= (const BigInteger& divisor) { - const BitArray one (1); + BigInteger remainder; + divideBy (divisor, remainder); + swapWith (remainder); + return *this; +} - if (modulus == one || modulus.isNegative()) - { - clear(); - return; - } +BigInteger& BigInteger::operator<<= (int numBitsToShift) +{ + shiftBits (numBitsToShift, 0); + return *this; +} - if (isNegative() || compareAbsolute (modulus) >= 0) - this->modulo (modulus); +BigInteger& BigInteger::operator>>= (int numBitsToShift) +{ + return operator<<= (-numBitsToShift); +} - if (*this == one) - return; +BigInteger& BigInteger::operator++() { return operator+= (1); } +BigInteger& BigInteger::operator--() { return operator-= (1); } +const BigInteger BigInteger::operator++ (int) { const BigInteger old (*this); operator+= (1); return old; } +const BigInteger BigInteger::operator-- (int) { const BigInteger old (*this); operator-= (1); return old; } - if (! (*this)[0]) +const BigInteger BigInteger::operator+ (const BigInteger& other) const { BigInteger b (*this); return b += other; } +const BigInteger BigInteger::operator- (const BigInteger& other) const { BigInteger b (*this); return b -= other; } +const BigInteger BigInteger::operator* (const BigInteger& other) const { BigInteger b (*this); return b *= other; } +const BigInteger BigInteger::operator/ (const BigInteger& other) const { BigInteger b (*this); return b /= other; } +const BigInteger BigInteger::operator| (const BigInteger& other) const { BigInteger b (*this); return b |= other; } +const BigInteger BigInteger::operator& (const BigInteger& other) const { BigInteger b (*this); return b &= other; } +const BigInteger BigInteger::operator^ (const BigInteger& other) const { BigInteger b (*this); return b ^= other; } +const BigInteger BigInteger::operator% (const BigInteger& other) const { BigInteger b (*this); return b %= other; } +const BigInteger BigInteger::operator<< (const int numBits) const { BigInteger b (*this); return b <<= numBits; } +const BigInteger BigInteger::operator>> (const int numBits) const { BigInteger b (*this); return b >>= numBits; } +const BigInteger BigInteger::operator-() const { BigInteger b (*this); b.negate(); return b; } + +//============================================================================== +int BigInteger::compare (const BigInteger& other) const throw() +{ + if (isNegative() == other.isNegative()) { - // not invertible - clear(); - return; + const int absComp = compareAbsolute (other); + return isNegative() ? -absComp : absComp; } - - BitArray a1 (modulus); - BitArray a2 (*this); - BitArray b1 (modulus); - BitArray b2 (1); - - while (a2 != one) + else { - BitArray temp1, temp2, multiplier (a1); - multiplier.divideBy (a2, temp1); + return isNegative() ? -1 : 1; + } +} - temp1 = a2; - temp1.multiplyBy (multiplier); - temp2 = a1; - temp2.subtract (temp1); - a1 = a2; - a2 = temp2; +int BigInteger::compareAbsolute (const BigInteger& other) const throw() +{ + const int h1 = getHighestBit(); + const int h2 = other.getHighestBit(); - temp1 = b2; - temp1.multiplyBy (multiplier); - temp2 = b1; - temp2.subtract (temp1); - b1 = b2; - b2 = temp2; - } + if (h1 > h2) + return 1; + else if (h1 < h2) + return -1; - while (b2.isNegative()) - b2.add (modulus); + for (int i = (h1 >> 5) + 1; --i >= 0;) + if (values[i] != other.values[i]) + return (values[i] > other.values[i]) ? 1 : -1; - b2.modulo (modulus); - *this = b2; + return 0; } +bool BigInteger::operator== (const BigInteger& other) const throw() { return compare (other) == 0; } +bool BigInteger::operator!= (const BigInteger& other) const throw() { return compare (other) != 0; } +bool BigInteger::operator< (const BigInteger& other) const throw() { return compare (other) < 0; } +bool BigInteger::operator<= (const BigInteger& other) const throw() { return compare (other) <= 0; } +bool BigInteger::operator> (const BigInteger& other) const throw() { return compare (other) > 0; } +bool BigInteger::operator>= (const BigInteger& other) const throw() { return compare (other) >= 0; } + //============================================================================== -void BitArray::shiftBits (int bits, const int startBit) throw() +void BigInteger::shiftBits (int bits, const int startBit) { if (highestBit < 0) return; @@ -681,165 +754,138 @@ void BitArray::shiftBits (int bits, const int startBit) throw() } } -const BitArray BitArray::getBitRange (int startBit, int numBits) const throw() +//============================================================================== +const BigInteger BigInteger::simpleGCD (BigInteger* m, BigInteger* n) { - BitArray r; - numBits = jmin (numBits, getHighestBit() + 1 - startBit); - r.ensureSize (numBits >> 5); - r.highestBit = numBits; - - int i = 0; - while (numBits > 0) + while (! m->isZero()) { - r.values[i++] = getBitRangeAsInt (startBit, jmin (32, numBits)); - numBits -= 32; - startBit += 32; - } + if (n->compareAbsolute (*m) > 0) + swapVariables (m, n); - r.highestBit = r.getHighestBit(); + *m -= *n; + } - return r; + return *n; } -int BitArray::getBitRangeAsInt (const int startBit, int numBits) const throw() +const BigInteger BigInteger::findGreatestCommonDivisor (BigInteger n) const { - if (numBits > 32) - { - jassertfalse // use getBitRange() if you need more than 32 bits.. - numBits = 32; - } - - numBits = jmin (numBits, highestBit + 1 - startBit); - - if (numBits <= 0) - return 0; + BigInteger m (*this); - const int pos = startBit >> 5; - const int offset = startBit & 31; - const int endSpace = 32 - numBits; + while (! n.isZero()) + { + if (abs (m.getHighestBit() - n.getHighestBit()) <= 16) + return simpleGCD (&m, &n); - uint32 n = ((uint32) values [pos]) >> offset; + BigInteger temp1 (m), temp2; + temp1.divideBy (n, temp2); - if (offset > endSpace) - n |= ((uint32) values [pos + 1]) << (32 - offset); + m = n; + n = temp2; + } - return (int) (n & (((uint32) 0xffffffff) >> endSpace)); + return m; } -void BitArray::setBitRangeAsInt (const int startBit, int numBits, unsigned int valueToSet) throw() +void BigInteger::exponentModulo (const BigInteger& exponent, const BigInteger& modulus) { - if (numBits > 32) - { - jassertfalse - numBits = 32; - } + BigInteger exp (exponent); + exp %= modulus; - for (int i = 0; i < numBits; ++i) + BigInteger value (1); + swapWith (value); + value %= modulus; + + while (! exp.isZero()) { - setBit (startBit + i, (valueToSet & 1) != 0); - valueToSet >>= 1; - } -} + if (exp [0]) + { + operator*= (value); + operator%= (modulus); + } -//============================================================================== -bool BitArray::isNegative() const throw() -{ - return negative && ! isEmpty(); + value *= value; + value %= modulus; + exp >>= 1; + } } -void BitArray::setNegative (const bool neg) throw() +void BigInteger::inverseModulo (const BigInteger& modulus) { - negative = neg; -} + if (modulus.isOne() || modulus.isNegative()) + { + clear(); + return; + } -void BitArray::negate() throw() -{ - negative = (! negative) && ! isEmpty(); -} + if (isNegative() || compareAbsolute (modulus) >= 0) + operator%= (modulus); -int BitArray::countNumberOfSetBits() const throw() -{ - int total = 0; + if (isOne()) + return; - for (int i = (highestBit >> 5) + 1; --i >= 0;) + if (! (*this)[0]) { - unsigned int n = values[i]; - - if (n == 0xffffffff) - { - total += 32; - } - else - { - while (n != 0) - { - total += (n & 1); - n >>= 1; - } - } + // not invertible + clear(); + return; } - return total; -} + BigInteger a1 (modulus); + BigInteger a2 (*this); + BigInteger b1 (modulus); + BigInteger b2 (1); -int BitArray::getHighestBit() const throw() -{ - for (int i = highestBit + 1; --i >= 0;) - if ((values [i >> 5] & (1 << (i & 31))) != 0) - return i; - - return -1; -} + while (! a2.isOne()) + { + BigInteger temp1, temp2, multiplier (a1); + multiplier.divideBy (a2, temp1); -int BitArray::findNextSetBit (int i) const throw() -{ - for (; i <= highestBit; ++i) - if ((values [i >> 5] & (1 << (i & 31))) != 0) - return i; + temp1 = a2; + temp1 *= multiplier; + temp2 = a1; + temp2 -= temp1; + a1 = a2; + a2 = temp2; - return -1; -} + temp1 = b2; + temp1 *= multiplier; + temp2 = b1; + temp2 -= temp1; + b1 = b2; + b2 = temp2; + } -int BitArray::findNextClearBit (int i) const throw() -{ - for (; i <= highestBit; ++i) - if ((values [i >> 5] & (1 << (i & 31))) == 0) - break; + while (b2.isNegative()) + b2 += modulus; - return i; + b2 %= modulus; + swapWith (b2); } -void BitArray::ensureSize (const int numVals) throw() +//============================================================================== +OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const BigInteger& value) { - if (numVals + 2 >= numValues) - { - int oldSize = numValues; - numValues = ((numVals + 2) * 3) / 2; - values.realloc (numValues + 1); - - while (oldSize < numValues) - values [oldSize++] = 0; - } + return stream << value.toString (10); } -//============================================================================== -const String BitArray::toString (const int base, const int minimumNumCharacters) const throw() +const String BigInteger::toString (const int base, const int minimumNumCharacters) const { String s; - BitArray v (*this); + BigInteger v (*this); if (base == 2 || base == 8 || base == 16) { const int bits = (base == 2) ? 1 : (base == 8 ? 3 : 4); - static const tchar* const hexDigits = T("0123456789abcdef"); + static const juce_wchar* const hexDigits = T("0123456789abcdef"); for (;;) { const int remainder = v.getBitRangeAsInt (0, bits); - v.shiftBits (-bits); + v >>= bits; - if (remainder == 0 && v.isEmpty()) + if (remainder == 0 && v.isZero()) break; s = String::charToString (hexDigits [remainder]) + s; @@ -847,14 +893,14 @@ const String BitArray::toString (const int base, const int minimumNumCharacters) } else if (base == 10) { - const BitArray ten (10); - BitArray remainder; + const BigInteger ten (10); + BigInteger remainder; for (;;) { v.divideBy (ten, remainder); - if (remainder.isEmpty() && v.isEmpty()) + if (remainder.isZero() && v.isZero()) break; s = String (remainder.getBitRangeAsInt (0, 8)) + s; @@ -862,7 +908,7 @@ const String BitArray::toString (const int base, const int minimumNumCharacters) } else { - jassertfalse // can't do the specified base + jassertfalse // can't do the specified base! return String::empty; } @@ -871,11 +917,10 @@ const String BitArray::toString (const int base, const int minimumNumCharacters) return isNegative() ? T("-") + s : s; } -void BitArray::parseString (const String& text, - const int base) throw() +void BigInteger::parseString (const String& text, const int base) { clear(); - const tchar* t = (const tchar*) text; + const juce_wchar* t = (const juce_wchar*) text; if (base == 2 || base == 8 || base == 16) { @@ -883,13 +928,13 @@ void BitArray::parseString (const String& text, for (;;) { - const tchar c = *t++; + const juce_wchar c = *t++; const int digit = CharacterFunctions::getHexDigitValue (c); if (((unsigned int) digit) < (unsigned int) base) { - shiftBits (bits); - add (digit); + operator<<= (bits); + operator+= (digit); } else if (c == 0) { @@ -899,16 +944,16 @@ void BitArray::parseString (const String& text, } else if (base == 10) { - const BitArray ten ((unsigned int) 10); + const BigInteger ten ((unsigned int) 10); for (;;) { - const tchar c = *t++; + const juce_wchar c = *t++; if (c >= T('0') && c <= T('9')) { - multiplyBy (ten); - add ((int) (c - T('0'))); + operator*= (ten); + operator+= ((int) (c - T('0'))); } else if (c == 0) { @@ -920,7 +965,7 @@ void BitArray::parseString (const String& text, setNegative (text.trimStart().startsWithChar (T('-'))); } -const MemoryBlock BitArray::toMemoryBlock() const throw() +const MemoryBlock BigInteger::toMemoryBlock() const { const int numBytes = (getHighestBit() + 8) >> 3; MemoryBlock mb ((size_t) numBytes); @@ -931,7 +976,7 @@ const MemoryBlock BitArray::toMemoryBlock() const throw() return mb; } -void BitArray::loadFromMemoryBlock (const MemoryBlock& data) throw() +void BigInteger::loadFromMemoryBlock (const MemoryBlock& data) { clear(); diff --git a/src/containers/juce_BitArray.h b/src/containers/juce_BitArray.h index 8bbe448c89..dcb1a3f877 100644 --- a/src/containers/juce_BitArray.h +++ b/src/containers/juce_BitArray.h @@ -27,77 +27,89 @@ #define __JUCE_BITARRAY_JUCEHEADER__ #include "../text/juce_String.h" -#include "juce_Array.h" #include "juce_HeapBlock.h" class MemoryBlock; //============================================================================== /** - An array of on/off bits, also usable to store large binary integers. + An arbitrarily large integer class. - A BitArray acts like an arbitrarily large integer whose bits can be set or - cleared, and some basic mathematical operations can be done on the number as - a whole. + A BigInteger can be used in a similar way to a normal integer, but has no size + limit (except for memory and performance constraints). + + Negative values are possible, but the value isn't stored as 2s-complement, so + be careful if you use negative values and look at the values of individual bits. */ -class JUCE_API BitArray +class JUCE_API BigInteger { public: //============================================================================== - /** Creates an empty BitArray */ - BitArray() throw(); + /** Creates an empty BigInteger */ + BigInteger(); - /** Creates a BitArray containing an integer value in its low bits. + /** Creates a BigInteger containing an integer value in its low bits. - The low 32 bits of the array are initialised with this value. + The low 32 bits of the number are initialised with this value. */ - BitArray (const unsigned int value) throw(); + BigInteger (unsigned int value); - /** Creates a BitArray containing an integer value in its low bits. + /** Creates a BigInteger containing an integer value in its low bits. - The low 32 bits of the array are initialised with the absolute value + The low 32 bits of the number are initialised with the absolute value passed in, and its sign is set to reflect the sign of the number. */ - BitArray (const int value) throw(); + BigInteger (int value); - /** Creates a BitArray containing an integer value in its low bits. + /** Creates a BigInteger containing an integer value in its low bits. - The low 64 bits of the array are initialised with the absolute value + The low 64 bits of the number are initialised with the absolute value passed in, and its sign is set to reflect the sign of the number. */ - BitArray (int64 value) throw(); + BigInteger (int64 value); - /** Creates a copy of another BitArray. */ - BitArray (const BitArray& other) throw(); + /** Creates a copy of another BigInteger. */ + BigInteger (const BigInteger& other); /** Destructor. */ - ~BitArray() throw(); + ~BigInteger(); //============================================================================== - /** Copies another BitArray onto this one. */ - BitArray& operator= (const BitArray& other) throw(); + /** Copies another BigInteger onto this one. */ + BigInteger& operator= (const BigInteger& other); - /** Two arrays are the same if the same bits are set. */ - bool operator== (const BitArray& other) const throw(); - /** Two arrays are the same if the same bits are set. */ - bool operator!= (const BitArray& other) const throw(); + /** Swaps the internal contents of this with another object. */ + void swapWith (BigInteger& other) throw(); //============================================================================== - /** Clears all bits in the BitArray to 0. */ - void clear() throw(); + /** Returns the value of a specified bit in the number. + If the index is out-of-range, the result will be false. + */ + bool operator[] (int bit) const throw(); - /** Clears a particular bit in the array. */ - void clearBit (const int bitNumber) throw(); + /** Returns true if no bits are set. */ + bool isZero() const throw(); - /** Sets a specified bit to 1. + /** Returns true if the value is 1. */ + bool isOne() const throw(); - If the bit number is high, this will grow the array to accomodate it. + /** Attempts to get the lowest bits of the value as an integer. + If the value is bigger than the integer limits, this will return only the lower bits. */ - void setBit (const int bitNumber) throw(); + int toInteger() const throw(); + + //============================================================================== + /** Resets the value to 0. */ + void clear(); + + /** Clears a particular bit in the number. */ + void clearBit (int bitNumber) throw(); + + /** Sets a specified bit to 1. */ + void setBit (int bitNumber); /** Sets or clears a specified bit. */ - void setBit (const int bitNumber, - const bool shouldBeSet) throw(); + void setBit (int bitNumber, bool shouldBeSet); /** Sets a range of bits to be either on or off. @@ -105,32 +117,19 @@ public: @param numBits the number of bits to change @param shouldBeSet whether to turn these bits on or off */ - void setRange (int startBit, - int numBits, - const bool shouldBeSet) throw(); + void setRange (int startBit, int numBits, bool shouldBeSet); /** Inserts a bit an a given position, shifting up any bits above it. */ - void insertBit (const int bitNumber, - const bool shouldBeSet) throw(); - - /** Returns the value of a specified bit in the array. + void insertBit (int bitNumber, bool shouldBeSet); - If the index is out-of-range, the result will be false. - */ - bool operator[] (const int bit) const throw(); - - /** Returns true if no bits are set. */ - bool isEmpty() const throw(); - - //============================================================================== - /** Returns a range of bits in the array as a new BitArray. + /** Returns a range of bits as a new BigInteger. e.g. getBitRangeAsInt (0, 64) would return the lowest 64 bits. @see getBitRangeAsInt */ - const BitArray getBitRange (int startBit, int numBits) const throw(); + const BigInteger getBitRange (int startBit, int numBits) const; - /** Returns a range of bits in the array as an integer value. + /** Returns a range of bits as an integer value. e.g. getBitRangeAsInt (0, 32) would return the lowest 32 bits. @@ -139,206 +138,191 @@ public: */ int getBitRangeAsInt (int startBit, int numBits) const throw(); - /** Sets a range of bits in the array based on an integer value. + /** Sets a range of bits to an integer value. - Copies the given integer into the array, starting at startBit, - and only using up to numBits of the available bits. + Copies the given integer onto a range of bits, starting at startBit, + and using up to numBits of the available bits. */ - void setBitRangeAsInt (int startBit, int numBits, - unsigned int valueToSet) throw(); + void setBitRangeAsInt (int startBit, int numBits, unsigned int valueToSet); - //============================================================================== - /** Performs a bitwise OR with another BitArray. + /** Shifts a section of bits left or right. - The result ends up in this array. + @param howManyBitsLeft how far to move the bits (+ve numbers shift it left, -ve numbers shift it right). + @param startBit the first bit to affect - if this is > 0, only bits above that index will be affected. */ - void orWith (const BitArray& other) throw(); + void shiftBits (int howManyBitsLeft, int startBit); - /** Performs a bitwise AND with another BitArray. + /** Returns the total number of set bits in the value. */ + int countNumberOfSetBits() const throw(); - The result ends up in this array. + /** Looks for the index of the next set bit after a given starting point. + + This searches from startIndex (inclusive) upwards for the first set bit, + and returns its index. If no set bits are found, it returns -1. */ - void andWith (const BitArray& other) throw(); + int findNextSetBit (int startIndex = 0) const throw(); - /** Performs a bitwise XOR with another BitArray. + /** Looks for the index of the next clear bit after a given starting point. - The result ends up in this array. + This searches from startIndex (inclusive) upwards for the first clear bit, + and returns its index. */ - void xorWith (const BitArray& other) throw(); - - /** Adds another BitArray's value to this one. + int findNextClearBit (int startIndex = 0) const throw(); - Treating the two arrays as large positive integers, this - adds them up and puts the result in this array. + /** Returns the index of the highest set bit in the number. + If the value is zero, this will return -1. */ - void add (const BitArray& other) throw(); + int getHighestBit() const throw(); - /** Subtracts another BitArray's value from this one. + //============================================================================== + // All the standard arithmetic ops... + + BigInteger& operator+= (const BigInteger& other); + BigInteger& operator-= (const BigInteger& other); + BigInteger& operator*= (const BigInteger& other); + BigInteger& operator/= (const BigInteger& other); + BigInteger& operator|= (const BigInteger& other); + BigInteger& operator&= (const BigInteger& other); + BigInteger& operator^= (const BigInteger& other); + BigInteger& operator%= (const BigInteger& other); + BigInteger& operator<<= (int numBitsToShift); + BigInteger& operator>>= (int numBitsToShift); + BigInteger& operator++(); + BigInteger& operator--(); + const BigInteger operator++ (int); + const BigInteger operator-- (int); + + const BigInteger operator-() const; + const BigInteger operator+ (const BigInteger& other) const; + const BigInteger operator- (const BigInteger& other) const; + const BigInteger operator* (const BigInteger& other) const; + const BigInteger operator/ (const BigInteger& other) const; + const BigInteger operator| (const BigInteger& other) const; + const BigInteger operator& (const BigInteger& other) const; + const BigInteger operator^ (const BigInteger& other) const; + const BigInteger operator% (const BigInteger& other) const; + const BigInteger operator<< (int numBitsToShift) const; + const BigInteger operator>> (int numBitsToShift) const; + + bool operator== (const BigInteger& other) const throw(); + bool operator!= (const BigInteger& other) const throw(); + bool operator< (const BigInteger& other) const throw(); + bool operator<= (const BigInteger& other) const throw(); + bool operator> (const BigInteger& other) const throw(); + bool operator>= (const BigInteger& other) const throw(); - Treating the two arrays as large positive integers, this - subtracts them and puts the result in this array. + //============================================================================== + /** Does a signed comparison of two BigIntegers. - Note that if the result should be negative, this won't be - handled correctly. + Return values are: + - 0 if the numbers are the same + - < 0 if this number is smaller than the other + - > 0 if this number is bigger than the other */ - void subtract (const BitArray& other) throw(); + int compare (const BigInteger& other) const throw(); - /** Multiplies another BitArray's value with this one. + /** Compares the magnitudes of two BigIntegers, ignoring their signs. - Treating the two arrays as large positive integers, this - multiplies them and puts the result in this array. + Return values are: + - 0 if the numbers are the same + - < 0 if this number is smaller than the other + - > 0 if this number is bigger than the other */ - void multiplyBy (const BitArray& other) throw(); + int compareAbsolute (const BigInteger& other) const throw(); - /** Divides another BitArray's value into this one and also produces a remainder. + /** Divides this value by another one and returns the remainder. - Treating the two arrays as large positive integers, this - divides this value by the other, leaving the quotient in this - array, and the remainder is copied into the other BitArray passed in. + This number is divided by other, leaving the quotient in this number, + with the remainder being copied to the other BigInteger passed in. */ - void divideBy (const BitArray& divisor, BitArray& remainder) throw(); - - /** Returns the largest value that will divide both this value and the one - passed-in. - */ - const BitArray findGreatestCommonDivisor (BitArray other) const throw(); - - /** Performs a modulo operation on this value. + void divideBy (const BigInteger& divisor, BigInteger& remainder); - The result is stored in this value. + /** Returns the largest value that will divide both this value and the one passed-in. */ - void modulo (const BitArray& divisor) throw(); + const BigInteger findGreatestCommonDivisor (BigInteger other) const; /** Performs a combined exponent and modulo operation. - This BitArray's value becomes (this ^ exponent) % modulus. + This BigInteger's value becomes (this ^ exponent) % modulus. */ - void exponentModulo (const BitArray& exponent, const BitArray& modulus) throw(); + void exponentModulo (const BigInteger& exponent, const BigInteger& modulus); /** Performs an inverse modulo on the value. i.e. the result is (this ^ -1) mod (modulus). */ - void inverseModulo (const BitArray& modulus) throw(); - - /** Shifts a section of bits left or right. - - @param howManyBitsLeft how far to move the bits (+ve numbers shift it left, -ve numbers shift it right). - @param startBit the first bit to affect - if this is > 0, only bits above that index will be affected. - */ - void shiftBits (int howManyBitsLeft, - int startBit = 0) throw(); - - /** Does a signed comparison of two BitArrays. - - Return values are: - - 0 if the numbers are the same - - < 0 if this number is smaller than the other - - > 0 if this number is bigger than the other - */ - int compare (const BitArray& other) const throw(); - - /** Compares the magnitudes of two BitArrays, ignoring their signs. - - Return values are: - - 0 if the numbers are the same - - < 0 if this number is smaller than the other - - > 0 if this number is bigger than the other - */ - int compareAbsolute (const BitArray& other) const throw(); + void inverseModulo (const BigInteger& modulus); //============================================================================== /** Returns true if the value is less than zero. - @see setNegative, negate */ bool isNegative() const throw(); /** Changes the sign of the number to be positive or negative. - @see isNegative, negate */ void setNegative (const bool shouldBeNegative) throw(); /** Inverts the sign of the number. - @see isNegative, setNegative */ void negate() throw(); //============================================================================== - /** Counts the total number of set bits in the array. */ - int countNumberOfSetBits() const throw(); - - /** Looks for the index of the next set bit after a given starting point. - - searches from startIndex (inclusive) upwards for the first set bit, - and returns its index. - - If no set bits are found, it returns -1. - */ - int findNextSetBit (int startIndex = 0) const throw(); - - /** Looks for the index of the next clear bit after a given starting point. - - searches from startIndex (inclusive) upwards for the first clear bit, - and returns its index. - */ - int findNextClearBit (int startIndex = 0) const throw(); - - /** Returns the index of the highest set bit in the array. - - If the array is empty, this will return -1. - */ - int getHighestBit() const throw(); - - //============================================================================== - /** Converts the array to a number string. + /** Converts the number to a string. Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). - - If minuimumNumCharacters is greater than 0, the returned string will be + If minimumNumCharacters is greater than 0, the returned string will be padded with leading zeros to reach at least that length. */ - const String toString (const int base, const int minimumNumCharacters = 1) const throw(); - - /** Converts a number string to an array. + const String toString (int base, int minimumNumCharacters = 1) const; - Any non-valid characters will be ignored. + /** Reads the numeric value from a string. Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). + Any invalid characters will be ignored. */ - void parseString (const String& text, - const int base) throw(); + void parseString (const String& text, int base); //============================================================================== - /** Turns the array into a block of binary data. + /** Turns the number into a block of binary data. The data is arranged as little-endian, so the first byte of data is the low 8 bits - of the array, and so on. + of the number, and so on. @see loadFromMemoryBlock */ - const MemoryBlock toMemoryBlock() const throw(); + const MemoryBlock toMemoryBlock() const; - /** Copies a block of raw data onto this array. + /** Converts a block of raw data into a number. The data is arranged as little-endian, so the first byte of data is the low 8 bits - of the array, and so on. + of the number, and so on. @see toMemoryBlock */ - void loadFromMemoryBlock (const MemoryBlock& data) throw(); + void loadFromMemoryBlock (const MemoryBlock& data); //============================================================================== juce_UseDebuggingNewOperator private: - void ensureSize (const int numVals) throw(); HeapBlock values; int numValues, highestBit; bool negative; + + void ensureSize (int numVals); + static const BigInteger simpleGCD (BigInteger* m, BigInteger* n); }; +/** Writes a BigInteger to an OutputStream as a UTF8 decimal string. */ +OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const BigInteger& value); + +//============================================================================== +/** For backwards compatibility, BitArray is defined to be an alias for BigInteger. +*/ +typedef BigInteger BitArray; + #endif // __JUCE_BITARRAY_JUCEHEADER__ diff --git a/src/containers/juce_OwnedArray.h b/src/containers/juce_OwnedArray.h index 46874cdb5c..a4c3dcd4d1 100644 --- a/src/containers/juce_OwnedArray.h +++ b/src/containers/juce_OwnedArray.h @@ -165,7 +165,7 @@ public: while (e != end) { if (objectToLookFor == *e) - return (int) (e - data.elements.getData()); + return static_cast (e - data.elements.getData()); ++e; } @@ -466,7 +466,7 @@ public: { if (objectToRemove == *e) { - remove ((int) (e - data.elements.getData()), deleteObject); + remove (static_cast (e - data.elements.getData()), deleteObject); break; } diff --git a/src/containers/juce_ReferenceCountedArray.h b/src/containers/juce_ReferenceCountedArray.h index eacd8e3730..33d0a398ca 100644 --- a/src/containers/juce_ReferenceCountedArray.h +++ b/src/containers/juce_ReferenceCountedArray.h @@ -184,7 +184,7 @@ public: while (e != end) { if (objectToLookFor == *e) - return (int) (e - data.elements.getData()); + return static_cast (e - data.elements.getData()); ++e; } diff --git a/src/containers/juce_SparseSet.h b/src/containers/juce_SparseSet.h index aaed3cb6ae..949f400548 100644 --- a/src/containers/juce_SparseSet.h +++ b/src/containers/juce_SparseSet.h @@ -34,9 +34,9 @@ /** Holds a set of primitive values, storing them as a set of ranges. - This container acts like a simple BitArray, but can efficiently hold large - continguous ranges of values. It's quite a specialised class, mostly useful - for things like keeping the set of selected rows in a listbox. + This container acts like an array, but can efficiently hold large continguous + ranges of values. It's quite a specialised class, mostly useful for things + like keeping the set of selected rows in a listbox. The type used as a template paramter must be an integer type, such as int, short, int64, etc. diff --git a/src/core/juce_Random.cpp b/src/core/juce_Random.cpp index 15eb16b4e5..7b09448a28 100644 --- a/src/core/juce_Random.cpp +++ b/src/core/juce_Random.cpp @@ -94,20 +94,20 @@ double Random::nextDouble() throw() return static_cast (nextInt()) / (double) 0xffffffff; } -const BitArray Random::nextLargeNumber (const BitArray& maximumValue) throw() +const BigInteger Random::nextLargeNumber (const BigInteger& maximumValue) { - BitArray n; + BigInteger n; do { fillBitsRandomly (n, 0, maximumValue.getHighestBit() + 1); } - while (n.compare (maximumValue) >= 0); + while (n >= maximumValue); return n; } -void Random::fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw() +void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits) { arrayToChange.setBit (startBit + numBits - 1, true); // to force the array to pre-allocate space diff --git a/src/core/juce_Random.h b/src/core/juce_Random.h index 19c019ddcd..4218988a80 100644 --- a/src/core/juce_Random.h +++ b/src/core/juce_Random.h @@ -84,14 +84,14 @@ public: */ bool nextBool() throw(); - /** Returns a BitArray containing a random number. + /** Returns a BigInteger containing a random number. @returns a random value in the range 0 to (maximumValue - 1). */ - const BitArray nextLargeNumber (const BitArray& maximumValue) throw(); + const BigInteger nextLargeNumber (const BigInteger& maximumValue); - /** Sets a range of bits in a BitArray to random values. */ - void fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw(); + /** Sets a range of bits in a BigInteger to random values. */ + void fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numBits); //============================================================================== /** To avoid the overhead of having to create a new Random object whenever diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index f4bb55cbf8..d979342ddb 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 51 -#define JUCE_BUILDNUMBER 10 +#define JUCE_BUILDNUMBER 11 /** Current Juce version number. diff --git a/src/cryptography/juce_Primes.cpp b/src/cryptography/juce_Primes.cpp index 366e7fc1ba..c00fb06ee3 100644 --- a/src/cryptography/juce_Primes.cpp +++ b/src/cryptography/juce_Primes.cpp @@ -35,7 +35,7 @@ BEGIN_JUCE_NAMESPACE //============================================================================== namespace PrimesHelpers { - static void createSmallSieve (const int numBits, BitArray& result) throw() + static void createSmallSieve (const int numBits, BigInteger& result) { result.setBit (numBits); result.clearBit (numBits); // to enlarge the array @@ -53,11 +53,8 @@ namespace PrimesHelpers while (n <= (numBits >> 1)); } - static void bigSieve (const BitArray& base, - const int numBits, - BitArray& result, - const BitArray& smallSieve, - const int smallSieveSize) throw() + static void bigSieve (const BigInteger& base, const int numBits, BigInteger& result, + const BigInteger& smallSieve, const int smallSieveSize) { jassert (! base[0]); // must be even! @@ -70,13 +67,12 @@ namespace PrimesHelpers { const int prime = (index << 1) + 1; - BitArray r (base); - BitArray remainder; + BigInteger r (base), remainder; r.divideBy (prime, remainder); int i = prime - remainder.getBitRangeAsInt (0, 32); - if (r.isEmpty()) + if (r.isZero()) i += prime; if ((i & 1) == 0) @@ -95,18 +91,14 @@ namespace PrimesHelpers while (index < smallSieveSize); } - static bool findCandidate (const BitArray& base, - const BitArray& sieve, - const int numBits, - BitArray& result, - const int certainty) throw() + static bool findCandidate (const BigInteger& base, const BigInteger& sieve, + const int numBits, BigInteger& result, const int certainty) { for (int i = 0; i < numBits; ++i) { if (! sieve[i]) { - result = base; - result.add (BitArray ((unsigned int) ((i << 1) + 1))); + result = base + (unsigned int) ((i << 1) + 1); if (Primes::isProbablyPrime (result, certainty)) return true; @@ -115,13 +107,63 @@ namespace PrimesHelpers return false; } + + static bool passesMillerRabin (const BigInteger& n, int iterations) + { + const BigInteger one (1), two (2); + const BigInteger nMinusOne (n - one); + + BigInteger d (nMinusOne); + const int s = d.findNextSetBit (0); + d >>= s; + + BigInteger smallPrimes; + int numBitsInSmallPrimes = 0; + + for (;;) + { + numBitsInSmallPrimes += 256; + createSmallSieve (numBitsInSmallPrimes, smallPrimes); + + const int numPrimesFound = numBitsInSmallPrimes - smallPrimes.countNumberOfSetBits(); + + if (numPrimesFound > iterations + 1) + break; + } + + int smallPrime = 2; + + while (--iterations >= 0) + { + smallPrime = smallPrimes.findNextClearBit (smallPrime + 1); + + BigInteger r (smallPrime); + r.exponentModulo (d, n); + + if (r != one && r != nMinusOne) + { + for (int j = 0; j < s; ++j) + { + r.exponentModulo (two, n); + + if (r == nMinusOne) + break; + } + + if (r != nMinusOne) + return false; + } + } + + return true; + } } //============================================================================== -const BitArray Primes::createProbablePrime (const int bitLength, - const int certainty, - const int* randomSeeds, - int numRandomSeeds) throw() +const BigInteger Primes::createProbablePrime (const int bitLength, + const int certainty, + const int* randomSeeds, + int numRandomSeeds) { using namespace PrimesHelpers; int defaultSeeds [16]; @@ -141,20 +183,20 @@ const BitArray Primes::createProbablePrime (const int bitLength, } } - BitArray smallSieve; + BigInteger smallSieve; const int smallSieveSize = 15000; createSmallSieve (smallSieveSize, smallSieve); - BitArray p; + BigInteger p; for (int i = numRandomSeeds; --i >= 0;) { - BitArray p2; + BigInteger p2; Random r (randomSeeds[i]); r.fillBitsRandomly (p2, 0, bitLength); - p.xorWith (p2); + p ^= p2; } p.setBit (bitLength - 1); @@ -164,81 +206,26 @@ const BitArray Primes::createProbablePrime (const int bitLength, while (p.getHighestBit() < bitLength) { - p.add (2 * searchLen); + p += 2 * searchLen; - BitArray sieve; + BigInteger sieve; bigSieve (p, searchLen, sieve, smallSieve, smallSieveSize); - BitArray candidate; + BigInteger candidate; if (findCandidate (p, sieve, searchLen, candidate, certainty)) return candidate; } jassertfalse - return BitArray(); + return BigInteger(); } -static bool passesMillerRabin (const BitArray& n, int iterations) throw() +bool Primes::isProbablyPrime (const BigInteger& number, const int certainty) { using namespace PrimesHelpers; - const BitArray one (1); - const BitArray two (2); - - BitArray nMinusOne (n); - nMinusOne.subtract (one); - - BitArray d (nMinusOne); - const int s = d.findNextSetBit (0); - d.shiftBits (-s); - - BitArray smallPrimes; - int numBitsInSmallPrimes = 0; - - for (;;) - { - numBitsInSmallPrimes += 256; - createSmallSieve (numBitsInSmallPrimes, smallPrimes); - - const int numPrimesFound = numBitsInSmallPrimes - smallPrimes.countNumberOfSetBits(); - - if (numPrimesFound > iterations + 1) - break; - } - - int smallPrime = 2; - - while (--iterations >= 0) - { - smallPrime = smallPrimes.findNextClearBit (smallPrime + 1); - - BitArray r (smallPrime); - //r.createRandomNumber (nMinusOne); - r.exponentModulo (d, n); - - if (! (r == one || r == nMinusOne)) - { - for (int j = 0; j < s; ++j) - { - r.exponentModulo (two, n); - - if (r == nMinusOne) - break; - } - - if (r != nMinusOne) - return false; - } - } - - return true; -} - -bool Primes::isProbablyPrime (const BitArray& number, - const int certainty) throw() -{ if (! number[0]) return false; @@ -254,9 +241,7 @@ bool Primes::isProbablyPrime (const BitArray& number, } else { - const BitArray screen (2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23); - - if (number.findGreatestCommonDivisor (screen) != BitArray (1)) + if (number.findGreatestCommonDivisor (2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23) != 1) return false; return passesMillerRabin (number, certainty); diff --git a/src/cryptography/juce_Primes.h b/src/cryptography/juce_Primes.h index 06a0a0df24..5251c225ab 100644 --- a/src/cryptography/juce_Primes.h +++ b/src/cryptography/juce_Primes.h @@ -35,7 +35,7 @@ This class contains static methods for generating and testing prime numbers. - @see BitArray + @see BigInteger */ class JUCE_API Primes { @@ -50,10 +50,10 @@ public: which to seed the random number generation, improving the security of the keys generated. */ - static const BitArray createProbablePrime (int bitLength, - int certainty, - const int* randomSeeds = 0, - int numRandomSeeds = 0) throw(); + static const BigInteger createProbablePrime (int bitLength, + int certainty, + const int* randomSeeds = 0, + int numRandomSeeds = 0); /** Tests a number to see if it's prime. @@ -63,8 +63,7 @@ public: The certainty parameter specifies how many iterations to use when testing - a safe value might be anything over about 20-30. */ - static bool isProbablyPrime (const BitArray& number, - int certainty) throw(); + static bool isProbablyPrime (const BigInteger& number, int certainty); }; diff --git a/src/cryptography/juce_RSAKey.cpp b/src/cryptography/juce_RSAKey.cpp index 67086187ef..dce5123cd2 100644 --- a/src/cryptography/juce_RSAKey.cpp +++ b/src/cryptography/juce_RSAKey.cpp @@ -33,11 +33,11 @@ BEGIN_JUCE_NAMESPACE //============================================================================== -RSAKey::RSAKey() throw() +RSAKey::RSAKey() { } -RSAKey::RSAKey (const String& s) throw() +RSAKey::RSAKey (const String& s) { if (s.containsChar (T(','))) { @@ -51,97 +51,75 @@ RSAKey::RSAKey (const String& s) throw() } } -RSAKey::~RSAKey() throw() +RSAKey::~RSAKey() { } -const String RSAKey::toString() const throw() +const String RSAKey::toString() const { - return part1.toString (16) + T(",") + part2.toString (16); + return part1.toString (16) + "," + part2.toString (16); } -bool RSAKey::applyToValue (BitArray& value) const throw() +bool RSAKey::applyToValue (BigInteger& value) const { - if (part1.isEmpty() || part2.isEmpty() - || value.compare (0) <= 0) + if (part1.isZero() || part2.isZero() || value <= 0) { jassertfalse // using an uninitialised key value.clear(); return false; } - BitArray result; + BigInteger result; - while (! value.isEmpty()) + while (! value.isZero()) { - result.multiplyBy (part2); + result *= part2; - BitArray remainder; + BigInteger remainder; value.divideBy (part2, remainder); remainder.exponentModulo (part1, part2); - result.add (remainder); + result += remainder; } - value = result; - + value.swapWith (result); return true; } -static const BitArray findBestCommonDivisor (const BitArray& p, - const BitArray& q) throw() +static const BigInteger findBestCommonDivisor (const BigInteger& p, const BigInteger& q) { - const BitArray one (1); - // try 3, 5, 9, 17, etc first because these only contain 2 bits and so // are fast to divide + multiply for (int i = 2; i <= 65536; i *= 2) { - const BitArray e (1 + i); + const BigInteger e (1 + i); - if (e.findGreatestCommonDivisor (p) == one - && e.findGreatestCommonDivisor (q) == one) - { + if (e.findGreatestCommonDivisor (p).isOne() && e.findGreatestCommonDivisor (q).isOne()) return e; - } } - BitArray e (4); + BigInteger e (4); - while (! (e.findGreatestCommonDivisor (p) == one - && e.findGreatestCommonDivisor (q) == one)) - { - e.add (one); - } + while (! (e.findGreatestCommonDivisor (p).isOne() && e.findGreatestCommonDivisor (q).isOne())) + ++e; return e; } -void RSAKey::createKeyPair (RSAKey& publicKey, - RSAKey& privateKey, - const int numBits, - const int* randomSeeds, - const int numRandomSeeds) throw() +void RSAKey::createKeyPair (RSAKey& publicKey, RSAKey& privateKey, + const int numBits, const int* randomSeeds, const int numRandomSeeds) { jassert (numBits > 16); // not much point using less than this.. - BitArray p (Primes::createProbablePrime (numBits / 2, 30, randomSeeds, numRandomSeeds)); - BitArray q (Primes::createProbablePrime (numBits - numBits / 2, 30, randomSeeds, numRandomSeeds)); - - BitArray n (p); - n.multiplyBy (q); // n = pq - - const BitArray one (1); - p.subtract (one); - q.subtract (one); - - BitArray m (p); - m.multiplyBy (q); // m = (p - 1)(q - 1) + BigInteger p (Primes::createProbablePrime (numBits / 2, 30, randomSeeds, numRandomSeeds)); + BigInteger q (Primes::createProbablePrime (numBits - numBits / 2, 30, randomSeeds, numRandomSeeds)); - const BitArray e (findBestCommonDivisor (p, q)); + const BigInteger n (p * q); + const BigInteger m (--p * --q); + const BigInteger e (findBestCommonDivisor (p, q)); - BitArray d (e); + BigInteger d (e); d.inverseModulo (m); publicKey.part1 = e; diff --git a/src/cryptography/juce_RSAKey.h b/src/cryptography/juce_RSAKey.h index 98f9f9d907..d03d6f8a0b 100644 --- a/src/cryptography/juce_RSAKey.h +++ b/src/cryptography/juce_RSAKey.h @@ -44,23 +44,23 @@ public: Initialise a pair of objects for use with the createKeyPair() method. */ - RSAKey() throw(); + RSAKey(); /** Loads a key from an encoded string representation. This reloads a key from a string created by the toString() method. */ - RSAKey (const String& stringRepresentation) throw(); + RSAKey (const String& stringRepresentation); /** Destructor. */ - ~RSAKey() throw(); + ~RSAKey(); //============================================================================== /** Turns the key into a string representation. This can be reloaded using the constructor that takes a string. */ - const String toString() const throw(); + const String toString() const; //============================================================================== /** Encodes or decodes a value. @@ -76,7 +76,7 @@ public: happily do its job and return true, but the result won't be what you were expecting. It's your responsibility to check that the result is what you wanted. */ - bool applyToValue (BitArray& value) const throw(); + bool applyToValue (BigInteger& value) const; //============================================================================== /** Creates a public/private key-pair. @@ -93,16 +93,16 @@ public: */ static void createKeyPair (RSAKey& publicKey, RSAKey& privateKey, - const int numBits, + int numBits, const int* randomSeeds = 0, - const int numRandomSeeds = 0) throw(); + int numRandomSeeds = 0); //============================================================================== juce_UseDebuggingNewOperator protected: - BitArray part1, part2; + BigInteger part1, part2; }; diff --git a/src/gui/components/controls/juce_TableListBox.cpp b/src/gui/components/controls/juce_TableListBox.cpp index cb9e3fcf98..05b920fe68 100644 --- a/src/gui/components/controls/juce_TableListBox.cpp +++ b/src/gui/components/controls/juce_TableListBox.cpp @@ -243,7 +243,7 @@ private: TableListBox& owner; int row; bool isSelected, isDragging, selectRowOnMouseUp; - BitArray columnsWithComponents; + BigInteger columnsWithComponents; Component* findChildComponentForColumn (const int columnId) const { diff --git a/src/gui/components/controls/juce_TreeView.cpp b/src/gui/components/controls/juce_TreeView.cpp index b2b28ba45f..1b59f76bfd 100644 --- a/src/gui/components/controls/juce_TreeView.cpp +++ b/src/gui/components/controls/juce_TreeView.cpp @@ -192,7 +192,7 @@ public: const int visibleTop = -getY(); const int visibleBottom = visibleTop + getParentHeight(); - BitArray itemsToKeep; + BigInteger itemsToKeep; TreeViewItem* item = owner->rootItem; int y = (item != 0 && !owner->rootItemVisible) ? -item->itemHeight : 0; diff --git a/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp b/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp index c996a6145e..1bfeec644a 100644 --- a/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp +++ b/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp @@ -101,7 +101,7 @@ FileBrowserComponent::FileBrowserComponent (int flags_, currentPathBox->setEditableText (true); StringArray rootNames, rootPaths; - const BitArray separators (getRoots (rootNames, rootPaths)); + const BigInteger separators (getRoots (rootNames, rootPaths)); for (int i = 0; i < rootNames.size(); ++i) { @@ -457,9 +457,9 @@ void FileBrowserComponent::comboBoxChanged (ComboBox*) } } -const BitArray FileBrowserComponent::getRoots (StringArray& rootNames, StringArray& rootPaths) +const BigInteger FileBrowserComponent::getRoots (StringArray& rootNames, StringArray& rootPaths) { - BitArray separators; + BigInteger separators; #if JUCE_WINDOWS Array roots; diff --git a/src/gui/components/filebrowser/juce_FileBrowserComponent.h b/src/gui/components/filebrowser/juce_FileBrowserComponent.h index 672e692c09..3283299f1a 100644 --- a/src/gui/components/filebrowser/juce_FileBrowserComponent.h +++ b/src/gui/components/filebrowser/juce_FileBrowserComponent.h @@ -203,7 +203,7 @@ public: juce_UseDebuggingNewOperator protected: - virtual const BitArray getRoots (StringArray& rootNames, StringArray& rootPaths); + virtual const BigInteger getRoots (StringArray& rootNames, StringArray& rootPaths); private: //============================================================================== diff --git a/src/gui/components/special/juce_AudioDeviceSelectorComponent.cpp b/src/gui/components/special/juce_AudioDeviceSelectorComponent.cpp index 3030495b14..b71b8279b8 100644 --- a/src/gui/components/special/juce_AudioDeviceSelectorComponent.cpp +++ b/src/gui/components/special/juce_AudioDeviceSelectorComponent.cpp @@ -856,9 +856,9 @@ public: if (setup.useStereoPairs) { - BitArray bits; - BitArray& original = (type == audioInputType ? config.inputChannels - : config.outputChannels); + BigInteger bits; + BigInteger& original = (type == audioInputType ? config.inputChannels + : config.outputChannels); int i; for (i = 0; i < 256; i += 2) @@ -901,7 +901,7 @@ public: } } - static void flipBit (BitArray& chans, int index, int minNumber, int maxNumber) + static void flipBit (BigInteger& chans, int index, int minNumber, int maxNumber) { const int numActive = chans.countNumberOfSetBits(); diff --git a/src/gui/components/special/juce_MidiKeyboardComponent.h b/src/gui/components/special/juce_MidiKeyboardComponent.h index eefaca2aea..3f19eebcfa 100644 --- a/src/gui/components/special/juce_MidiKeyboardComponent.h +++ b/src/gui/components/special/juce_MidiKeyboardComponent.h @@ -392,7 +392,7 @@ private: int midiChannel, midiInChannelMask; float velocity; int noteUnderMouse, mouseDownNote; - BitArray keysPressed, keysCurrentlyDrawnDown; + BigInteger keysPressed, keysCurrentlyDrawnDown; int rangeStart, rangeEnd, firstKey; bool canScroll, mouseDragging, useMousePositionForVelocity; diff --git a/src/native/linux/juce_linux_Audio.cpp b/src/native/linux/juce_linux_Audio.cpp index 1f4eb336f0..255da06fd3 100644 --- a/src/native/linux/juce_linux_Audio.cpp +++ b/src/native/linux/juce_linux_Audio.cpp @@ -362,8 +362,8 @@ public: close(); } - void open (BitArray inputChannels, - BitArray outputChannels, + void open (BigInteger inputChannels, + BigInteger outputChannels, const double sampleRate_, const int bufferSize_) { @@ -581,7 +581,7 @@ public: String error; double sampleRate; int bufferSize; - BitArray currentInputChans, currentOutputChans; + BigInteger currentInputChans, currentOutputChans; Array sampleRates; StringArray channelNamesOut, channelNamesIn; @@ -704,8 +704,8 @@ public: return 512; } - const String open (const BitArray& inputChannels, - const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) { @@ -760,12 +760,12 @@ public: return internal->getBitDepth(); } - const BitArray getActiveOutputChannels() const + const BigInteger getActiveOutputChannels() const { return internal->currentOutputChans; } - const BitArray getActiveInputChannels() const + const BigInteger getActiveInputChannels() const { return internal->currentInputChans; } diff --git a/src/native/linux/juce_linux_JackAudio.cpp b/src/native/linux/juce_linux_JackAudio.cpp index c2ba9bbf6e..607eb83a9d 100644 --- a/src/native/linux/juce_linux_JackAudio.cpp +++ b/src/native/linux/juce_linux_JackAudio.cpp @@ -211,7 +211,7 @@ public: int getBufferSizeSamples (int index) { return getDefaultBufferSize(); } int getDefaultBufferSize() { return client != 0 ? JUCE_NAMESPACE::jack_get_buffer_size (client) : 0; } - const String open (const BitArray& inputChannels, const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) { if (client == 0) @@ -228,13 +228,13 @@ public: JUCE_NAMESPACE::jack_activate (client); isOpen_ = true; - if (! inputChannels.isEmpty()) + if (! inputChannels.isZero()) { const char** const ports = JUCE_NAMESPACE::jack_get_ports (client, 0, 0, /* JackPortIsPhysical | */ JackPortIsOutput); if (ports != 0) { - const int numInputChannels = inputChannels.getHighestBit () + 1; + const int numInputChannels = inputChannels.getHighestBit() + 1; for (int i = 0; i < numInputChannels; ++i) { @@ -252,13 +252,13 @@ public: } } - if (! outputChannels.isEmpty()) + if (! outputChannels.isZero()) { const char** const ports = JUCE_NAMESPACE::jack_get_ports (client, 0, 0, /* JackPortIsPhysical | */ JackPortIsInput); if (ports != 0) { - const int numOutputChannels = outputChannels.getHighestBit () + 1; + const int numOutputChannels = outputChannels.getHighestBit() + 1; for (int i = 0; i < numOutputChannels; ++i) { @@ -324,9 +324,9 @@ public: int getCurrentBitDepth() { return 32; } const String getLastError() { return lastError; } - const BitArray getActiveOutputChannels() const + const BigInteger getActiveOutputChannels() const { - BitArray outputBits; + BigInteger outputBits; for (int i = 0; i < outputPorts.size(); i++) if (JUCE_NAMESPACE::jack_port_connected ((jack_port_t*) outputPorts [i])) @@ -335,9 +335,9 @@ public: return outputBits; } - const BitArray getActiveInputChannels() const + const BigInteger getActiveInputChannels() const { - BitArray inputBits; + BigInteger inputBits; for (int i = 0; i < inputPorts.size(); i++) if (JUCE_NAMESPACE::jack_port_connected ((jack_port_t*) inputPorts [i])) diff --git a/src/native/mac/juce_iphone_Audio.cpp b/src/native/mac/juce_iphone_Audio.cpp index 25e5869b5e..6b13f077db 100644 --- a/src/native/mac/juce_iphone_Audio.cpp +++ b/src/native/mac/juce_iphone_Audio.cpp @@ -98,8 +98,8 @@ public: return 1024; } - const String open (const BitArray& inputChannels, - const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate, int bufferSize) { @@ -178,12 +178,12 @@ public: return 16; } - const BitArray getActiveOutputChannels() const + const BigInteger getActiveOutputChannels() const { return activeOutputChans; } - const BitArray getActiveInputChannels() const + const BigInteger getActiveInputChannels() const { return activeInputChans; } @@ -251,7 +251,7 @@ private: AudioUnit audioUnit; UInt32 audioInputIsAvailable; AudioIODeviceCallback* callback; - BitArray activeOutputChans, activeInputChans; + BigInteger activeOutputChans, activeInputChans; AudioSampleBuffer floatData; float* inputChannels[3]; diff --git a/src/native/mac/juce_mac_CoreAudio.cpp b/src/native/mac/juce_mac_CoreAudio.cpp index c0f8fcb330..c33a426692 100644 --- a/src/native/mac/juce_mac_CoreAudio.cpp +++ b/src/native/mac/juce_mac_CoreAudio.cpp @@ -421,8 +421,8 @@ public: } //============================================================================== - const String reopen (const BitArray& inputChannels, - const BitArray& outputChannels, + const String reopen (const BigInteger& inputChannels, + const BigInteger& outputChannels, double newSampleRate, int bufferSizeSamples) { @@ -761,7 +761,7 @@ public: juce_UseDebuggingNewOperator int inputLatency, outputLatency; - BitArray activeInputChans, activeOutputChans; + BigInteger activeInputChans, activeOutputChans; StringArray inChanNames, outChanNames; Array sampleRates; Array bufferSizes; @@ -960,8 +960,8 @@ public: return 512; } - const String open (const BitArray& inputChannels, - const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) { @@ -1001,21 +1001,21 @@ public: return 32; // no way to find out, so just assume it's high.. } - const BitArray getActiveOutputChannels() const + const BigInteger getActiveOutputChannels() const { - return internal != 0 ? internal->activeOutputChans : BitArray(); + return internal != 0 ? internal->activeOutputChans : BigInteger(); } - const BitArray getActiveInputChannels() const + const BigInteger getActiveInputChannels() const { - BitArray chans; + BigInteger chans; if (internal != 0) { chans = internal->activeInputChans; if (internal->inputDevice != 0) - chans.orWith (internal->inputDevice->activeInputChans); + chans |= internal->inputDevice->activeInputChans; } return chans; diff --git a/src/native/windows/juce_win32_ASIO.cpp b/src/native/windows/juce_win32_ASIO.cpp index ada06cf94a..e7f59576e8 100644 --- a/src/native/windows/juce_win32_ASIO.cpp +++ b/src/native/windows/juce_win32_ASIO.cpp @@ -186,8 +186,8 @@ public: return preferredSize; } - const String open (const BitArray& inputChannels, - const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sr, int bufferSizeSamples) { @@ -653,12 +653,12 @@ public: return currentSampleRate; } - const BitArray getActiveOutputChannels() const + const BigInteger getActiveOutputChannels() const { return currentChansOut; } - const BitArray getActiveInputChannels() const + const BigInteger getActiveInputChannels() const { return currentChansIn; } @@ -781,7 +781,7 @@ public: AudioIODeviceCallback* const oldCallback = currentCallback; close(); - open (BitArray (currentChansIn), BitArray (currentChansOut), + open (BigInteger (currentChansIn), BigInteger (currentChansOut), currentSampleRate, currentBlockSizeSamples); if (oldCallback != 0) @@ -817,7 +817,7 @@ private: int volatile currentBlockSizeSamples; int volatile currentBitDepth; double volatile currentSampleRate; - BitArray currentChansOut, currentChansIn; + BigInteger currentChansOut, currentChansIn; AudioIODeviceCallback* volatile currentCallback; CriticalSection callbackLock; diff --git a/src/native/windows/juce_win32_DirectSound.cpp b/src/native/windows/juce_win32_DirectSound.cpp index fb1a7597af..d857b169ec 100644 --- a/src/native/windows/juce_win32_DirectSound.cpp +++ b/src/native/windows/juce_win32_DirectSound.cpp @@ -1030,8 +1030,8 @@ public: return 2560; } - const String open (const BitArray& inputChannels, - const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) { @@ -1083,12 +1083,12 @@ public: return bits; } - const BitArray getActiveOutputChannels() const + const BigInteger getActiveOutputChannels() const { return enabledOutputs; } - const BitArray getActiveInputChannels() const + const BigInteger getActiveInputChannels() const { return enabledInputs; } @@ -1167,7 +1167,7 @@ private: int volatile totalSamplesOut; int64 volatile lastBlockTime; double sampleRate; - BitArray enabledInputs, enabledOutputs; + BigInteger enabledInputs, enabledOutputs; HeapBlock inputBuffers, outputBuffers; AudioIODeviceCallback* callback; @@ -1176,8 +1176,8 @@ private: DSoundAudioIODevice (const DSoundAudioIODevice&); DSoundAudioIODevice& operator= (const DSoundAudioIODevice&); - const String openDevice (const BitArray& inputChannels, - const BitArray& outputChannels, + const String openDevice (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate_, int bufferSizeSamples_); @@ -1497,8 +1497,8 @@ private: }; //============================================================================== -const String DSoundAudioIODevice::openDevice (const BitArray& inputChannels, - const BitArray& outputChannels, +const String DSoundAudioIODevice::openDevice (const BigInteger& inputChannels, + const BigInteger& outputChannels, double sampleRate_, int bufferSizeSamples_) { diff --git a/src/native/windows/juce_win32_WASAPI.cpp b/src/native/windows/juce_win32_WASAPI.cpp index e86dedc034..e214de6d12 100644 --- a/src/native/windows/juce_win32_WASAPI.cpp +++ b/src/native/windows/juce_win32_WASAPI.cpp @@ -182,7 +182,7 @@ public: bool isOk() const throw() { return defaultBufferSize > 0 && defaultSampleRate > 0; } - bool openClient (const double newSampleRate, const BitArray& newChannels) + bool openClient (const double newSampleRate, const BigInteger& newChannels) { sampleRate = newSampleRate; channels = newChannels; @@ -232,7 +232,7 @@ public: const bool useExclusiveMode; Array rates; HANDLE clientEvent; - BitArray channels; + BigInteger channels; AudioDataConverters::DataFormat dataFormat; Array channelMaps; UINT32 actualBufferSize; @@ -338,7 +338,7 @@ public: close(); } - bool open (const double newSampleRate, const BitArray& newChannels) + bool open (const double newSampleRate, const BigInteger& newChannels) { reservoirSize = 0; reservoirCapacity = 16384; @@ -483,7 +483,7 @@ public: close(); } - bool open (const double newSampleRate, const BitArray& newChannels) + bool open (const double newSampleRate, const BigInteger& newChannels) { return openClient (newSampleRate, newChannels) && (numChannels == 0 || OK (client->GetService (__uuidof (IAudioRenderClient), (void**) &renderClient))); @@ -674,12 +674,12 @@ public: int getCurrentBitDepth() { return 32; } int getOutputLatencyInSamples() { return latencyOut; } int getInputLatencyInSamples() { return latencyIn; } - const BitArray getActiveOutputChannels() const { return outputDevice != 0 ? outputDevice->channels : BitArray(); } - const BitArray getActiveInputChannels() const { return inputDevice != 0 ? inputDevice->channels : BitArray(); } + const BigInteger getActiveOutputChannels() const { return outputDevice != 0 ? outputDevice->channels : BigInteger(); } + const BigInteger getActiveInputChannels() const { return inputDevice != 0 ? inputDevice->channels : BigInteger(); } const String getLastError() { return lastError; } - const String open (const BitArray& inputChannels, const BitArray& outputChannels, + const String open (const BigInteger& inputChannels, const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) { close();