コード例 #1
0
void CtrlrMIDITransaction::constructResponseMask()
{
	MemoryBlock responseMask;

	MemoryBlock prefix 	= getFormulaAsMemoryBlock(getProperty(Ids::transRespFormulaPrefix));
	MemoryBlock data((int)getProperty(Ids::transRespDataLen), true);
	MemoryBlock suffix 	= getFormulaAsMemoryBlock(getProperty(Ids::transRespFormulaSuffix));
	MemoryBlock name	= getNameAsMemoryBlock();

	if (data.getSize() < name.getSize())
	{
		TRANS("["+getName()+"] CtrlrMIDITransaction::constructResponseMask data block will not fit name");
	}

	if (prefix.getSize() > 0)
	{
		responseMask.append (prefix.getData(), prefix.getSize());
	}

	if (data.getSize() > 0)
	{
		responseMask.append (data.getData(), data.getSize());
	}

	if (suffix.getSize() > 0)
	{
		responseMask.append (suffix.getData(), suffix.getSize());
	}

	setResponseMask (responseMask);
}
コード例 #2
0
void CtrlrMIDITransaction::constructConfirmation()
{
	MemoryBlock request;

	MemoryBlock prefix 	= getFormulaAsMemoryBlock(getProperty(Ids::transConfFormulaPrefix));
	MemoryBlock data   	= getConfirmationDataAsMemoryBlock();
	MemoryBlock suffix 	= getFormulaAsMemoryBlock(getProperty(Ids::transConfFormulaSuffix));

	if (prefix.getSize() > 0)
	{
		request.append (prefix.getData(), prefix.getSize());
	}

	if (data.getSize() > 0)
	{
		request.append (data.getData(), data.getSize());
	}

	if (suffix.getSize() > 0)
	{
		request.append (suffix.getData(), suffix.getSize());
	}

	setRequest (request);
}
コード例 #3
0
void CtrlrMIDITransaction::constructRequest()
{
	MemoryBlock request;

	MemoryBlock prefix 	= getFormulaAsMemoryBlock(getProperty(Ids::transReqFormulaPrefix));
	MemoryBlock data   	= getRequestDataAsMemoryBlock();
	MemoryBlock suffix 	= getFormulaAsMemoryBlock(getProperty(Ids::transReqFormulaSuffix));
	MemoryBlock name 	= getNameAsMemoryBlock();

	if (data.getSize() < name.getSize())
	{
		TRANS("["+getName()+"] CtrlrMIDITransaction::constructRequest data block will not fit name");
	}

	if (prefix.getSize() > 0)
	{
		request.append (prefix.getData(), prefix.getSize());
	}

	if (data.getSize() > 0)
	{
		request.append (data.getData(), data.getSize());
	}

	if (suffix.getSize() > 0)
	{
		request.append (suffix.getData(), suffix.getSize());
	}

	setRequest (request);
}
コード例 #4
0
String InputStream::readNextLine()
{
    MemoryBlock buffer (256);
    char* data = static_cast<char*> (buffer.getData());
    size_t i = 0;

    while ((data[i] = readByte()) != 0)
    {
        if (data[i] == '\n')
            break;

        if (data[i] == '\r')
        {
            const int64 lastPos = getPosition();

            if (readByte() != '\n')
                setPosition (lastPos);

            break;
        }

        if (++i >= buffer.getSize())
        {
            buffer.setSize (buffer.getSize() + 512);
            data = static_cast<char*> (buffer.getData());
        }
    }

    return String::fromUTF8 (data, (int) i);
}
コード例 #5
0
void CtrlrLuaAudioConverter::convertInt16 (MemoryBlock &sourceData, AudioSampleBuffer &destination, const int numSamples, const int numChannels, const bool interleaved)
{
	if (interleaved)
	{
		AudioData::ConverterInstance <	AudioData::Pointer <AudioData::Int16,
																		AudioData::NativeEndian,
																		AudioData::Interleaved,
																		AudioData::Const>, 
													AudioData::Pointer <AudioData::Float32,
																		AudioData::NativeEndian,
																		AudioData::Interleaved,
																		AudioData::NonConst>
									> converter;
		for (int ch=0; ch<numChannels; ch++)
		{
			converter.convertSamples ((void *)destination.getReadPointer(ch), sourceData.getData(), numSamples);
		}
	}
	else
	{
		AudioData::ConverterInstance <	AudioData::Pointer <AudioData::Int16,
																		AudioData::NativeEndian,
																		AudioData::NonInterleaved,
																		AudioData::Const>, 
													AudioData::Pointer <AudioData::Float32,
																		AudioData::NativeEndian,
																		AudioData::Interleaved,
																		AudioData::NonConst>
									> converter;
		for (int ch=0; ch<numChannels; ch++)
		{
			converter.convertSamples ((void *)destination.getReadPointer(ch), ch, sourceData.getData(), ch, numSamples);
		}
	}
}
コード例 #6
0
//==============================================================================
bool InterprocessConnection::sendMessage (const MemoryBlock& message)
{
    uint32 messageHeader[2] = { ByteOrder::swapIfBigEndian (magicMessageHeader),
                                ByteOrder::swapIfBigEndian ((uint32) message.getSize()) };

    MemoryBlock messageData (sizeof (messageHeader) + message.getSize());
    messageData.copyFrom (messageHeader, 0, sizeof (messageHeader));
    messageData.copyFrom (message.getData(), sizeof (messageHeader), message.getSize());

    return writeData (messageData.getData(), (int) messageData.getSize()) == (int) messageData.getSize();
}
コード例 #7
0
    static String getValue (const String& regValuePath, const String& defaultValue, DWORD wow64Flags)
    {
        MemoryBlock buffer;
        switch (getBinaryValue (regValuePath, buffer, wow64Flags))
        {
            case REG_SZ:    return static_cast <const WCHAR*> (buffer.getData());
            case REG_DWORD: return String ((int) *reinterpret_cast<const DWORD*> (buffer.getData()));
            default:        break;
        }

        return defaultValue;
    }
コード例 #8
0
ファイル: CtrlrUtilities.cpp プロジェクト: Srikrishna31/ctrlr
const MidiMessage createFromHexData (const String &hexData)
{
	MemoryBlock bl;
	bl.loadFromHexString(hexData);

	return (MidiMessage ((uint8*)bl.getData(), (int)bl.getSize()));
}
コード例 #9
0
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const MemoryBlock& data)
{
    if (data.getSize() > 0)
        stream.write (data.getData(), data.getSize());

    return stream;
}
コード例 #10
0
ファイル: CtrlrWindows.cpp プロジェクト: RomanKubiak/ctrlr
const Result CtrlrWindows::getDefaultResources(MemoryBlock& dataToWrite)
{
#ifdef DEBUG_INSTANCE
	File temp("c:\\devel\\debug_small.bpanelz");

	MemoryBlock data;
	{
		ScopedPointer <FileInputStream> fis (temp.createInputStream());
		fis->readIntoMemoryBlock (data);
	}

	ValueTree t = ValueTree::readFromGZIPData(data.getData(), data.getSize());

	if (t.isValid())
	{
		ValueTree r = t.getChildWithName (Ids::resourceExportList);
		if (r.isValid())
		{
			MemoryOutputStream mos (dataToWrite, false);
			{
				GZIPCompressorOutputStream gzipOutputStream (&mos);
				r.writeToStream(gzipOutputStream);
				gzipOutputStream.flush();
			}
			return (Result::ok());
		}
	}
	else
	{
		return (Result::fail("Windows Native: getDefaultResources got data but couldn't parse it as a compressed ValueTree"));
	}
#endif

	return (readResource (nullptr, MAKEINTRESOURCE(CTRLR_INTERNAL_RESOURCES_RESID), RT_RCDATA, dataToWrite));
}
コード例 #11
0
ファイル: juce_OutputStream.cpp プロジェクト: Frongo/JUCE
OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryBlock& data)
{
    if (data.getSize() > 0)
        stream.write (data.getData(), (int) data.getSize());

    return stream;
}
コード例 #12
0
    static std::uint32_t getBinaryValue (const String& regValuePath, MemoryBlock& result, DWORD wow64Flags)
    {
        const RegistryKeyWrapper key (regValuePath, false, wow64Flags);

        if (key.key != 0)
        {
            for (unsigned long bufferSize = 1024; ; bufferSize *= 2)
            {
                result.setSize (bufferSize, false);
                DWORD type = REG_NONE;

                const LONG err = RegQueryValueEx (key.key, key.wideCharValueName, 0, &type,
                                                  (LPBYTE) result.getData(), &bufferSize);

                if (err == ERROR_SUCCESS)
                {
                    result.setSize (bufferSize, false);
                    return type;
                }

                if (err != ERROR_MORE_DATA)
                    break;
            }
        }

        return REG_NONE;
    }
コード例 #13
0
ファイル: Juce_plugins.cpp プロジェクト: erdoukki/radium
static void save_fxbp(SoundPlugin *plugin, wchar_t *wfilename, bool is_fxb){
  Data *data = (Data*)plugin->data;
  AudioPluginInstance *instance = data->audio_instance;

  MemoryBlock memoryBlock;
  bool result = VSTPluginFormat::saveToFXBFile(instance, memoryBlock, is_fxb);
  if (result==false){
    GFX_Message(NULL, "Unable to create FXB/FXP data for this plugin");
    return;
  }
  
  String filename(wfilename);

  File file(filename);

  Result result2 = file.create();

  if (result2.failed()){
    GFX_Message(NULL, "Unable to create file %s (%s)", STRING_get_chars(wfilename), result2.getErrorMessage().toRawUTF8());
    return;
  }
  
  bool result3 = file.replaceWithData(memoryBlock.getData(), memoryBlock.getSize());
  if (result3==false){
    GFX_Message(NULL, "Unable to write data to file %s (disk full?)", STRING_get_chars(wfilename));
    return;
  }
  
  
  printf("\n\n\n ***************** result: %d\n\n\n\n",result);
}
コード例 #14
0
void HostFilterComponent::handleSaveCommand(bool saveToExistingFileAndDontPrompt)
{
   File tmp = currentSessionFile;
   
   bool userConfirmed = true;
   if (!saveToExistingFileAndDontPrompt || !tmp.exists())
   {
      FileChooser myChooser (T("Save Session..."),
                              currentSessionFile.exists() ? tmp : Config::getInstance ()->lastSessionDirectory,
                              JOST_SESSION_WILDCARD,
                              JOST_USE_NATIVE_FILE_CHOOSER);

      if (myChooser.browseForFileToSave (true))
         tmp = myChooser.getResult().withFileExtension (JOST_SESSION_EXTENSION);
      else
         userConfirmed = false;      
   }
   
   if (userConfirmed && (tmp != File::nonexistent))
   {
      MemoryBlock fileData;
      getFilter ()->getStateInformation (fileData);

      if (tmp.replaceWithData (fileData.getData (), fileData.getSize()))
      {
         Config::getInstance()->addRecentSession (tmp);
         setCurrentSessionFile(tmp);
         Config::getInstance()->lastSessionFile = tmp;
      }
   }
}
コード例 #15
0
void OnlineUnlockStatus::load()
{
    MemoryBlock mb;
    mb.fromBase64Encoding (getState());

    if (mb.getSize() > 0)
        status = ValueTree::readFromGZIPData (mb.getData(), mb.getSize());
    else
        status = ValueTree (stateTagName);

    StringArray localMachineNums (getLocalMachineIDs());

    if (machineNumberAllowed (StringArray ("1234"), localMachineNums))
        status.removeProperty (unlockedProp, nullptr);

    KeyFileUtils::KeyFileData data;
    data = KeyFileUtils::getDataFromKeyFile (KeyFileUtils::getXmlFromKeyFile (status[keyfileDataProp], getPublicKey()));

    if (data.keyFileExpires)
    {
        if (! doesProductIDMatch (data.appID))
            status.removeProperty (expiryTimeProp, nullptr);

        if (! machineNumberAllowed (data.machineNumbers, localMachineNums))
            status.removeProperty (expiryTimeProp, nullptr);
    }
    else
    {
        if (! doesProductIDMatch (data.appID))
            status.removeProperty (unlockedProp, nullptr);

        if (! machineNumberAllowed (data.machineNumbers, localMachineNums))
            status.removeProperty (unlockedProp, nullptr);
    }
}
コード例 #16
0
String InputStream::readString()
{
    MemoryBlock buffer (256);
    char* data = static_cast<char*> (buffer.getData());
    size_t i = 0;

    while ((data[i] = readByte()) != 0)
    {
        if (++i >= buffer.getSize())
        {
            buffer.setSize (buffer.getSize() + 512);
            data = static_cast<char*> (buffer.getData());
        }
    }

    return String::fromUTF8 (data, (int) i);
}
コード例 #17
0
ファイル: juce_win32_Network.cpp プロジェクト: Amcut/pizmidi
    void openHTTPConnection (URL_COMPONENTS& uc, URL::OpenStreamProgressCallback* progressCallback,
                             void* progressCallbackContext)
    {
        const TCHAR* mimeTypes[] = { _T("*/*"), 0 };

        DWORD flags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES;

        if (address.startsWithIgnoreCase ("https:"))
            flags |= INTERNET_FLAG_SECURE;  // (this flag only seems necessary if the OS is running IE6 -
                                            //  IE7 seems to automatically work out when it's https)

        request = HttpOpenRequest (connection, isPost ? _T("POST") : _T("GET"),
                                   uc.lpszUrlPath, 0, 0, mimeTypes, flags, 0);

        if (request != 0)
        {
            INTERNET_BUFFERS buffers = { 0 };
            buffers.dwStructSize = sizeof (INTERNET_BUFFERS);
            buffers.lpcszHeader = headers.toWideCharPointer();
            buffers.dwHeadersLength = (DWORD) headers.length();
            buffers.dwBufferTotal = (DWORD) postData.getSize();

            if (HttpSendRequestEx (request, &buffers, 0, HSR_INITIATE, 0))
            {
                int bytesSent = 0;

                for (;;)
                {
                    const int bytesToDo = jmin (1024, (int) postData.getSize() - bytesSent);
                    DWORD bytesDone = 0;

                    if (bytesToDo > 0
                         && ! InternetWriteFile (request,
                                                 static_cast <const char*> (postData.getData()) + bytesSent,
                                                 (DWORD) bytesToDo, &bytesDone))
                    {
                        break;
                    }

                    if (bytesToDo == 0 || (int) bytesDone < bytesToDo)
                    {
                        if (HttpEndRequest (request, 0, 0, 0))
                            return;

                        break;
                    }

                    bytesSent += bytesDone;

                    if (progressCallback != nullptr
                          && ! progressCallback (progressCallbackContext, bytesSent, (int) postData.getSize()))
                        break;
                }
            }
        }

        close();
    }
コード例 #18
0
void writeDataAsCppLiteral (const MemoryBlock& mb, OutputStream& out)
{
    const int maxCharsOnLine = 250;

    const unsigned char* data = (const unsigned char*) mb.getData();
    int charsOnLine = 0;

    bool canUseStringLiteral = mb.getSize() < 32768; // MS compilers can't handle big string literals..

    if (canUseStringLiteral)
    {
        unsigned int numEscaped = 0;

        for (size_t i = 0; i < mb.getSize(); ++i)
        {
            const unsigned int num = (unsigned int) data[i];
            if (! ((num >= 32 && num < 127) || num == '\t' || num == '\r' || num == '\n'))
            {
                if (++numEscaped > mb.getSize() / 4)
                {
                    canUseStringLiteral = false;
                    break;
                }
            }
        }
    }

    if (! canUseStringLiteral)
    {
        out << "{ ";

        for (size_t i = 0; i < mb.getSize(); ++i)
        {
            const int num = (int) (unsigned int) data[i];
            out << num << ',';

            charsOnLine += 2;
            if (num >= 10)
                ++charsOnLine;
            if (num >= 100)
                ++charsOnLine;

            if (charsOnLine >= maxCharsOnLine)
            {
                charsOnLine = 0;
                out << newLine;
            }
        }

        out << "0,0 };";
    }
    else
    {
        out << "\"";
        writeEscapeChars (out, (const char*) data, (int) mb.getSize(), maxCharsOnLine, true, false);
        out << "\";";
    }
}
コード例 #19
0
ファイル: Jobs.cpp プロジェクト: kushview/ksp1
            void work (const URIs& uris, const lvtk::Atom& atom) override
            {
                const File file (String::fromUTF8 (path.c_str()));
                if (ScopedXml xml = XmlDocument::parse (file))
                {
                    if (ScopedPointer<SamplerSynth> ss = SamplerSynth::create ())
                    {
                        if (ss->loadValueTreeXml (*xml))
                        {
#define compressd_json 1
#if compressd_json

                            var json;
                            const bool haveJson = ss->getNestedVariant (json);
#endif
                            uint8_t buf [2048];
                            getForge()->set_buffer (buf, 2048);
                            ObjectRef synth (*getForge(), uris.ksp1_SamplerSynth, ss.release());
                            respond (synth);

                            if (haveJson)
                            {
                                MemoryBlock block (0, false);
                                MemoryOutputStream stream (block, false);
                                GZIPCompressorOutputStream compressed (&stream, 9);
                                JSON::writeToStream (compressed, json, true);
                                compressed.flush();

                                if (block.getSize() > 0)
                                {
                                    Forge& f = *getForge();
                                    int bufSize = nextPowerOfTwo ((int) block.getSize());
                                    bufSize = nextPowerOfTwo (bufSize);
                                    MemoryBlock buffer ((size_t) bufSize, false);
                                    f.set_buffer ((uint8*) buffer.getData(), buffer.getSize());
                                    lvtk::Atom gzipped (f.write_atom (block.getSize(), 100100));
                                    f.write_raw (block.getData(), block.getSize());
                                    DBG ("SIZE: " << (int)block.getSize());
                                    respond (gzipped);
                                }
                            }
                        }
                    }
                }
            }
コード例 #20
0
void LashManager::saveState (const File& fileToSave)
{
    MemoryBlock fileData;
    filter->getStateInformation (fileData);

    if (fileToSave.replaceWithData (fileData.getData (), fileData.getSize()))
    {
    }
}
コード例 #21
0
ファイル: ProgramListBox.cpp プロジェクト: Sentinel77/dexed
void ProgramListBox::itemDropped(const SourceDetails& dragSourceDetails) {
    dragCandidate = programPosition(dragSourceDetails.localPosition.x, dragSourceDetails.localPosition.y);
    
    MemoryBlock* block = dragSourceDetails.description.getBinaryData();
    if ( listener != nullptr )
        listener->programDragged(this, dragCandidate, (char *)block->getData());
    dragCandidate = -1;
    repaint();
}
コード例 #22
0
    //==============================================================================
    void getStateInformation (MemoryBlock& destData)
    {
        destData.setSize (sizeof (float) * getNumParameters());
        destData.fillWith (0);

        float* const p = (float*) ((char*) destData.getData());
        for (int i = 0; i < getNumParameters(); ++i)
            p[i] = getParameter(i);
    }
コード例 #23
0
MemoryInputStream::MemoryInputStream (const MemoryBlock& sourceData,
                                      const bool keepInternalCopy)
    : data (sourceData.getData()),
      dataSize (sourceData.getSize()),
      position (0)
{
    if (keepInternalCopy)
        createInternalCopy();
}
コード例 #24
0
//==============================================================================
void LashManager::loadState (const File& fileToLoad)
{
    MemoryBlock fileData;

    if (fileToLoad.existsAsFile()
        && fileToLoad.loadFileAsData (fileData))
    {
        filter->setStateInformation (fileData.getData (), fileData.getSize());
    }
}
コード例 #25
0
    //==============================================================================
    static String readResponse (const int socketHandle, const uint32 timeOutTime)
    {
        int bytesRead = 0, numConsecutiveLFs  = 0;
        MemoryBlock buffer (1024, true);

        while (numConsecutiveLFs < 2 && bytesRead < 32768
                && Time::getMillisecondCounter() <= timeOutTime)
        {
            fd_set readbits;
            FD_ZERO (&readbits);
            FD_SET (socketHandle, &readbits);

            struct timeval tv;
            tv.tv_sec = jmax (1, (int) (timeOutTime - Time::getMillisecondCounter()) / 1000);
            tv.tv_usec = 0;

            if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
                return String::empty;  // (timeout)

            buffer.ensureSize (bytesRead + 8, true);
            char* const dest = (char*) buffer.getData() + bytesRead;

            if (recv (socketHandle, dest, 1, 0) == -1)
                return String::empty;

            const char lastByte = *dest;
            ++bytesRead;

            if (lastByte == '\n')
                ++numConsecutiveLFs;
            else if (lastByte != '\r')
                numConsecutiveLFs = 0;
        }

        const String header (CharPointer_UTF8 ((const char*) buffer.getData()));

        if (header.startsWithIgnoreCase ("HTTP/"))
            return header.trimEnd();

        return String::empty;
    }
コード例 #26
0
//==============================================================================
bool InterprocessConnection::sendMessage (const MemoryBlock& message)
{
    uint32 messageHeader[2];
    messageHeader [0] = ByteOrder::swapIfBigEndian (magicMessageHeader);
    messageHeader [1] = ByteOrder::swapIfBigEndian ((uint32) message.getSize());

    MemoryBlock messageData (sizeof (messageHeader) + message.getSize());
    messageData.copyFrom (messageHeader, 0, sizeof (messageHeader));
    messageData.copyFrom (message.getData(), sizeof (messageHeader), message.getSize());

    int bytesWritten = 0;

    const ScopedLock sl (pipeAndSocketLock);

    if (socket != nullptr)
        bytesWritten = socket->write (messageData.getData(), (int) messageData.getSize());
    else if (pipe != nullptr)
        bytesWritten = pipe->write (messageData.getData(), (int) messageData.getSize(), pipeReceiveMessageTimeout);

    return bytesWritten == (int) messageData.getSize();
}
コード例 #27
0
//==============================================================================
bool InterprocessConnection::readNextMessageInt()
{
    uint32 messageHeader[2];
    const int bytes = socket != nullptr ? socket->read (messageHeader, sizeof (messageHeader), true)
                                        : pipe  ->read (messageHeader, sizeof (messageHeader), -1);

    if (bytes == sizeof (messageHeader)
         && ByteOrder::swapIfBigEndian (messageHeader[0]) == magicMessageHeader)
    {
        int bytesInMessage = (int) ByteOrder::swapIfBigEndian (messageHeader[1]);

        if (bytesInMessage > 0)
        {
            MemoryBlock messageData ((size_t) bytesInMessage, true);
            int bytesRead = 0;

            while (bytesInMessage > 0)
            {
                if (threadShouldExit())
                    return false;

                const int numThisTime = jmin (bytesInMessage, 65536);
                void* const data = addBytesToPointer (messageData.getData(), bytesRead);

                const int bytesIn = socket != nullptr ? socket->read (data, numThisTime, true)
                                                      : pipe  ->read (data, numThisTime, -1);

                if (bytesIn <= 0)
                    break;

                bytesRead += bytesIn;
                bytesInMessage -= bytesIn;
            }

            if (bytesRead >= 0)
                deliverDataInt (messageData);
        }
    }
    else if (bytes < 0)
    {
        if (socket != nullptr)
        {
            const ScopedLock sl (pipeAndSocketLock);
            socket = nullptr;
        }

        connectionLostInt();
        return false;
    }

    return true;
}
コード例 #28
0
ファイル: LumaPlug.cpp プロジェクト: georgekrueger/Luma
const String LumaPlug::LumaDocument::loadDocument (const File& file)
{
    FileInputStream* stream = file.createInputStream();
	juce::int64 size = stream->getTotalLength();
	if (size <= 0)
	{
		return String("Input file size is zero!");
	}
	MemoryBlock* buffer = new MemoryBlock(size+1, true);
	int bytesRead = stream->read(buffer->getData(), size);
	if (bytesRead != size)
	{
		return String("Bytes read from file differs from file size!");
	}
	
	String text = String(static_cast<char*>(buffer->getData()));
	plug->newTextLoadedFromFile(text);
	
	delete buffer;

    return String::empty;
}
コード例 #29
0
void WrappedJucePlugin::loadPresetFromXml(XmlElement* element)
{
   if (instance)
   {
      XmlElement* chunk = element->getChildByName (T("juceVSTPluginData"));
      if (chunk)
      {
         MemoryBlock mb;
         mb.fromBase64Encoding (chunk->getAllSubText ());
         instance->setStateInformation (mb.getData(), mb.getSize ());
      }
   }
}
コード例 #30
0
var var::readFromStream (InputStream& input)
{
    const int numBytes = input.readCompressedInt();

    if (numBytes > 0)
    {
        switch (input.readByte())
        {
            case varMarker_Int:         return var (input.readInt());
            case varMarker_Int64:       return var (input.readInt64());
            case varMarker_BoolTrue:    return var (true);
            case varMarker_BoolFalse:   return var (false);
            case varMarker_Double:      return var (input.readDouble());
            case varMarker_String:
            {
                MemoryOutputStream mo;
                mo.writeFromInputStream (input, numBytes - 1);
                return var (mo.toUTF8());
            }

            case varMarker_Binary:
            {
                MemoryBlock mb (numBytes - 1);

                if (numBytes > 1)
                {
                    const int numRead = input.read (mb.getData(), numBytes - 1);
                    mb.setSize (numRead);
                }

                return var (mb);
            }

            case varMarker_Array:
            {
                var v;
                Array<var>* const destArray = v.convertToArray();

                for (int i = input.readCompressedInt(); --i >= 0;)
                    destArray->add (readFromStream (input));

                return v;
            }

            default:
                input.skipNextBytes (numBytes - 1); break;
        }
    }

    return var::null;
}