static void create (MemoryBlock& block, const StringPairArray& values)
        {
            auto numNotes = values.getValue ("NumCueNotes", "0").getIntValue();

            if (numNotes > 0)
            {
                MemoryOutputStream out (block, false);
                out.writeShortBigEndian ((short) numNotes);

                for (int i = 0; i < numNotes; ++i)
                {
                    auto prefix = "CueNote" + String (i);

                    out.writeIntBigEndian (values.getValue (prefix + "TimeStamp", "0").getIntValue());
                    out.writeShortBigEndian ((short) values.getValue (prefix + "Identifier", "0").getIntValue());

                    auto comment = values.getValue (prefix + "Text", String());
                    auto commentLength = jmin (comment.getNumBytesAsUTF8(), (size_t) 65534);

                    out.writeShortBigEndian ((short) commentLength + 1);
                    out.write (comment.toUTF8(), commentLength);
                    out.writeByte (0);

                    if ((out.getDataSize() & 1) != 0)
                        out.writeByte (0);
                }
            }
        }
Beispiel #2
0
    void runTest() override
    {
        beginTest ("Basics");
        Random r = getRandom();

        int randomInt = r.nextInt();
        int64 randomInt64 = r.nextInt64();
        double randomDouble = r.nextDouble();
        String randomString (createRandomWideCharString (r));

        MemoryOutputStream mo;
        mo.writeInt (randomInt);
        mo.writeIntBigEndian (randomInt);
        mo.writeCompressedInt (randomInt);
        mo.writeString (randomString);
        mo.writeInt64 (randomInt64);
        mo.writeInt64BigEndian (randomInt64);
        mo.writeDouble (randomDouble);
        mo.writeDoubleBigEndian (randomDouble);

        MemoryInputStream mi (mo.getData(), mo.getDataSize(), false);
        expect (mi.readInt() == randomInt);
        expect (mi.readIntBigEndian() == randomInt);
        expect (mi.readCompressedInt() == randomInt);
        expectEquals (mi.readString(), randomString);
        expect (mi.readInt64() == randomInt64);
        expect (mi.readInt64BigEndian() == randomInt64);
        expect (mi.readDouble() == randomDouble);
        expect (mi.readDoubleBigEndian() == randomDouble);
    }
void ValueTreeSynchroniser::sendFullSyncCallback()
{
    MemoryOutputStream m;
    writeHeader (m, ValueTreeSynchroniserHelpers::fullSync);
    valueTree.writeToStream (m);
    stateChanged (m.getData(), m.getDataSize());
}
void ValueTreeSynchroniser::valueTreeChildRemoved (ValueTree& parentTree, ValueTree&, int oldIndex)
{
    MemoryOutputStream m;
    ValueTreeSynchroniserHelpers::writeHeader (*this, m, ValueTreeSynchroniserHelpers::childRemoved, parentTree);
    m.writeCompressedInt (oldIndex);
    stateChanged (m.getData(), m.getDataSize());
}
Beispiel #5
0
Drawable* Drawable::createFromImageDataStream (InputStream& dataSource)
{
    MemoryOutputStream mo;
    mo.writeFromInputStream (dataSource, -1);

    return createFromImageData (mo.getData(), mo.getDataSize());
}
    static void findTempoEvents (MidiFile& midiFile, StringPairArray& midiMetadata)
    {
        MidiMessageSequence tempoEvents;
        midiFile.findAllTempoEvents (tempoEvents);

        const int numTempoEvents = tempoEvents.getNumEvents();
        MemoryOutputStream tempoSequence;

        for (int i = 0; i < numTempoEvents; ++i)
        {
            const double tempo = getTempoFromTempoMetaEvent (tempoEvents.getEventPointer (i));

            if (tempo > 0.0)
            {
                if (i == 0)
                    midiMetadata.set (CoreAudioFormat::tempo, String (tempo));

                if (numTempoEvents > 1)
                    tempoSequence << String (tempo) << ',' << tempoEvents.getEventTime (i) << ';';
            }
        }

        if (tempoSequence.getDataSize() > 0)
            midiMetadata.set ("tempo sequence", tempoSequence.toUTF8());
    }
Beispiel #7
0
void Robot::timerCallback() {
  MemoryOutputStream * out = messageBuffer.getReader();
  if (out != nullptr) {
    send(out->getData(), out->getDataSize());
    messageBuffer.readDone();
  }
}
    static void findTimeSigEvents (MidiFile& midiFile, StringPairArray& midiMetadata)
    {
        MidiMessageSequence timeSigEvents;
        midiFile.findAllTimeSigEvents (timeSigEvents);
        const int numTimeSigEvents = timeSigEvents.getNumEvents();

        MemoryOutputStream timeSigSequence;

        for (int i = 0; i < numTimeSigEvents; ++i)
        {
            int numerator, denominator;
            timeSigEvents.getEventPointer(i)->message.getTimeSignatureInfo (numerator, denominator);

            String timeSigString;
            timeSigString << numerator << '/' << denominator;

            if (i == 0)
                midiMetadata.set (CoreAudioFormat::timeSig, timeSigString);

            if (numTimeSigEvents > 1)
                timeSigSequence << timeSigString << ',' << timeSigEvents.getEventTime (i) << ';';
        }

        if (timeSigSequence.getDataSize() > 0)
            midiMetadata.set ("time signature sequence", timeSigSequence.toUTF8());
    }
Beispiel #9
0
void create (MemoryBlock& block, const StringPairArray& values)
{
    const int numNotes = values.getValue ("NumCueNotes", "0").getIntValue();

    if (numNotes > 0)
    {
        MemoryOutputStream out (block, false);
        out.writeShortBigEndian ((short) numNotes);

        for (int i = 0; i < numNotes; ++i)
        {
            const String prefix ("CueNote" + String (i));

            out.writeIntBigEndian (values.getValue (prefix + "TimeStamp", "0").getIntValue());
            out.writeShortBigEndian ((short) values.getValue (prefix + "Identifier", "0").getIntValue());

            const String comment (values.getValue (prefix + "Text", String::empty));
            out.write (comment.toUTF8(), jmin (comment.getNumBytesAsUTF8(), 65534));
            out.writeByte (0);

            if ((out.getDataSize() & 1) != 0)
                out.writeByte (0);
        }
    }
}
Beispiel #10
0
void HelmPlugin::getStateInformation(MemoryBlock& dest_data) {
  var state = LoadSave::stateToVar(&synth_, gui_state_, getCallbackLock());
  String data_string = JSON::toString(state);
  MemoryOutputStream stream;
  stream.writeString(data_string);
  dest_data.append(stream.getData(), stream.getDataSize());
}
    static void findKeySigEvents (MidiFile& midiFile, StringPairArray& midiMetadata)
    {
        MidiMessageSequence keySigEvents;
        midiFile.findAllKeySigEvents (keySigEvents);
        const int numKeySigEvents = keySigEvents.getNumEvents();

        MemoryOutputStream keySigSequence;

        for (int i = 0; i < numKeySigEvents; ++i)
        {
            const MidiMessage& message (keySigEvents.getEventPointer (i)->message);
            const int key = jlimit (0, 14, message.getKeySignatureNumberOfSharpsOrFlats() + 7);
            const bool isMajor = message.isKeySignatureMajorKey();

            static const char* majorKeys[] = { "Cb", "Gb", "Db", "Ab", "Eb", "Bb", "F", "C", "G", "D", "A", "E", "B", "F#", "C#" };
            static const char* minorKeys[] = { "Ab", "Eb", "Bb", "F", "C", "G", "D", "A", "E", "B", "F#", "C#", "G#", "D#", "A#" };

            String keySigString (isMajor ? majorKeys[key]
                                         : minorKeys[key]);

            if (! isMajor)
                keySigString << 'm';

            if (i == 0)
                midiMetadata.set (CoreAudioFormat::keySig, keySigString);

            if (numKeySigEvents > 1)
                keySigSequence << keySigString << ',' << keySigEvents.getEventTime (i) << ';';
        }

        if (keySigSequence.getDataSize() > 0)
            midiMetadata.set ("key signature sequence", keySigSequence.toUTF8());
    }
OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryOutputStream& streamToRead)
{
    const size_t dataSize = streamToRead.getDataSize();

    if (dataSize > 0)
        stream.write (streamToRead.getData(), dataSize);

    return stream;
}
Beispiel #13
0
void create (MemoryBlock& block, const StringPairArray& values)
{
    const int numCues = values.getValue ("NumCuePoints", "0").getIntValue();

    if (numCues > 0)
    {
        MemoryOutputStream out (block, false);

        out.writeShortBigEndian ((short) numCues);

        const int numCueLabels = values.getValue ("NumCueLabels", "0").getIntValue();
        const int idOffset = metaDataContainsZeroIdentifiers (values) ? 1 : 0; // can't have zero IDs in AIFF

#if JUCE_DEBUG
        Array<int> identifiers;
#endif

        for (int i = 0; i < numCues; ++i)
        {
            const String prefixCue ("Cue" + String (i));
            const int identifier = idOffset + values.getValue (prefixCue + "Identifier", "1").getIntValue();

#if JUCE_DEBUG
            jassert (! identifiers.contains (identifier));
            identifiers.add (identifier);
#endif

            const int offset = values.getValue (prefixCue + "Offset", "0").getIntValue();
            String label ("CueLabel" + String (i));

            for (int labelIndex = 0; labelIndex < numCueLabels; ++labelIndex)
            {
                const String prefixLabel ("CueLabel" + String (labelIndex));
                const int labelIdentifier = idOffset + values.getValue (prefixLabel + "Identifier", "1").getIntValue();

                if (labelIdentifier == identifier)
                {
                    label = values.getValue (prefixLabel + "Text", label);
                    break;
                }
            }

            out.writeShortBigEndian ((short) identifier);
            out.writeIntBigEndian (offset);

            const int labelLength = jmin (254, label.getNumBytesAsUTF8()); // seems to need null terminator even though it's a pstring
            out.writeByte ((char) labelLength + 1);
            out.write (label.toUTF8(), labelLength);
            out.writeByte (0);
        }

        if ((out.getDataSize() & 1) != 0)
            out.writeByte (0);
    }
}
Beispiel #14
0
void URL::createHeadersAndPostData (String& headers, MemoryBlock& postDataToWrite) const
{
    MemoryOutputStream data (postDataToWrite, false);

    if (filesToUpload.size() > 0)
    {
        // (this doesn't currently support mixing custom post-data with uploads..)
        jassert (postData.getSize() == 0);

        auto boundary = String::toHexString (Random::getSystemRandom().nextInt64());

        headers << "Content-Type: multipart/form-data; boundary=" << boundary << "\r\n";

        data << "--" << boundary;

        for (int i = 0; i < parameterNames.size(); ++i)
        {
            data << "\r\nContent-Disposition: form-data; name=\"" << parameterNames[i]
                 << "\"\r\n\r\n" << parameterValues[i]
                 << "\r\n--" << boundary;
        }

        for (auto* f : filesToUpload)
        {
            data << "\r\nContent-Disposition: form-data; name=\"" << f->parameterName
                 << "\"; filename=\"" << f->filename << "\"\r\n";

            if (f->mimeType.isNotEmpty())
                data << "Content-Type: " << f->mimeType << "\r\n";

            data << "Content-Transfer-Encoding: binary\r\n\r\n";

            if (f->data != nullptr)
                data << *f->data;
            else
                data << f->file;

            data << "\r\n--" << boundary;
        }

        data << "--\r\n";
    }
    else
    {
        data << URLHelpers::getMangledParameters (*this)
             << postData;

        // if the user-supplied headers didn't contain a content-type, add one now..
        if (! headers.containsIgnoreCase ("Content-Type"))
            headers << "Content-Type: application/x-www-form-urlencoded\r\n";

        headers << "Content-length: " << (int) data.getDataSize() << "\r\n";
    }
}
void ValueTreeSynchroniser::valueTreeChildAdded (ValueTree& parentTree, ValueTree& childTree)
{
    const int index = parentTree.indexOf (childTree);
    jassert (index >= 0);

    MemoryOutputStream m;
    ValueTreeSynchroniserHelpers::writeHeader (*this, m, ValueTreeSynchroniserHelpers::childAdded, parentTree);
    m.writeCompressedInt (index);
    childTree.writeToStream (m);
    stateChanged (m.getData(), m.getDataSize());
}
Beispiel #16
0
void jojo_write (t_jojo *x, const File& aFile)
{
    MemoryOutputStream myText;
    GZIPCompressorOutputStream zipper (&myText);
    
    zipper << "Stately, plump Buck Mulligan came from the stairhead, " << newLine
           << "bearing a bowl of lather on which a mirror and a razor lay crossed." << newLine;

    zipper.flush();
    
    aFile.replaceWithData (myText.getData(), myText.getDataSize());
}
    void writeToStream (const ValueUnion& data, OutputStream& output) const
    {
        MemoryOutputStream buffer (512);
        const int numItems = data.arrayValue->size();
        buffer.writeCompressedInt (numItems);

        for (int i = 0; i < numItems; ++i)
            data.arrayValue->getReference(i).writeToStream (buffer);

        output.writeCompressedInt (1 + (int) buffer.getDataSize());
        output.writeByte (varMarker_Array);
        output << buffer;
    }
Beispiel #18
0
    void writeToStream (const ValueUnion& data, OutputStream& output) const override
    {
        if (auto* array = toArray (data))
        {
            MemoryOutputStream buffer (512);
            buffer.writeCompressedInt (array->size());

            for (auto& i : *array)
                i.writeToStream (buffer);

            output.writeCompressedInt (1 + (int) buffer.getDataSize());
            output.writeByte (varMarker_Array);
            output << buffer;
        }
    }
Beispiel #19
0
    void writeToStream (const ValueUnion& data, OutputStream& output) const override
    {
        if (const Array<var>* array = toArray (data))
        {
            MemoryOutputStream buffer (512);
            const int numItems = array->size();
            buffer.writeCompressedInt (numItems);

            for (int i = 0; i < numItems; ++i)
                array->getReference(i).writeToStream (buffer);

            output.writeCompressedInt (1 + (int) buffer.getDataSize());
            output.writeByte (varMarker_Array);
            output << buffer;
        }
    }
Beispiel #20
0
END_TEST

BEGIN_TEST(SystemNet_WebClient_CanDownloadStream)
{
	WebClient client;
	try
	{
		MemoryOutputStream stream;
		client.downloadStream("http://www.google.com", stream);
		WIN_ASSERT_TRUE(stream.getDataSize() >= 0);
	}
	catch(Exception & ex)
	{
		String msg = ex.getFullMessage();
		WIN_ASSERT_FAIL(msg.toUTF16());
	}
}
void ValueTreeSynchroniser::valueTreePropertyChanged (ValueTree& vt, const Identifier& property)
{
    MemoryOutputStream m;

    if (auto* value = vt.getPropertyPointer (property))
    {
        ValueTreeSynchroniserHelpers::writeHeader (*this, m, ValueTreeSynchroniserHelpers::propertyChanged, vt);
        m.writeString (property.toString());
        value->writeToStream (m);
    }
    else
    {
        ValueTreeSynchroniserHelpers::writeHeader (*this, m, ValueTreeSynchroniserHelpers::propertyRemoved, vt);
        m.writeString (property.toString());
    }

    stateChanged (m.getData(), m.getDataSize());
}
Beispiel #22
0
XmlElement* XmlDocument::getDocumentElement (const bool onlyReadOuterDocumentElement)
{
    if (originalText.isEmpty() && inputSource != nullptr)
    {
        ScopedPointer<InputStream> in (inputSource->createInputStream());

        if (in != nullptr)
        {
            MemoryOutputStream data;
            data.writeFromInputStream (*in, onlyReadOuterDocumentElement ? 8192 : -1);

           #if JUCE_STRING_UTF_TYPE == 8
            if (data.getDataSize() > 2)
            {
                data.writeByte (0);
                const char* text = static_cast<const char*> (data.getData());

                if (CharPointer_UTF16::isByteOrderMarkBigEndian (text)
                      || CharPointer_UTF16::isByteOrderMarkLittleEndian (text))
                {
                    originalText = data.toString();
                }
                else
                {
                    if (CharPointer_UTF8::isByteOrderMark (text))
                        text += 3;

                    // parse the input buffer directly to avoid copying it all to a string..
                    return parseDocumentElement (String::CharPointerType (text), onlyReadOuterDocumentElement);
                }
            }
           #else
            originalText = data.toString();
           #endif
        }
    }

    return parseDocumentElement (originalText.getCharPointer(), onlyReadOuterDocumentElement);
}
Beispiel #23
0
Image JPEGImageFormat::decodeImage (InputStream& in)
{
#if (JUCE_MAC || JUCE_IOS) && USE_COREGRAPHICS_RENDERING && JUCE_USE_COREIMAGE_LOADER
    return juce_loadWithCoreImage (in);
#else
    using namespace jpeglibNamespace;
    using namespace JPEGHelpers;

    MemoryOutputStream mb;
    mb << in;

    Image image;

    if (mb.getDataSize() > 16)
    {
        struct jpeg_decompress_struct jpegDecompStruct;

        struct jpeg_error_mgr jerr;
        setupSilentErrorHandler (jerr);
        jpegDecompStruct.err = &jerr;

        jpeg_create_decompress (&jpegDecompStruct);

        jpegDecompStruct.src = (jpeg_source_mgr*)(jpegDecompStruct.mem->alloc_small)
            ((j_common_ptr)(&jpegDecompStruct), JPOOL_PERMANENT, sizeof (jpeg_source_mgr));

        jpegDecompStruct.src->init_source       = dummyCallback1;
        jpegDecompStruct.src->fill_input_buffer = jpegFill;
        jpegDecompStruct.src->skip_input_data   = jpegSkip;
        jpegDecompStruct.src->resync_to_restart = jpeg_resync_to_restart;
        jpegDecompStruct.src->term_source       = dummyCallback1;

        jpegDecompStruct.src->next_input_byte   = static_cast <const unsigned char*> (mb.getData());
        jpegDecompStruct.src->bytes_in_buffer   = mb.getDataSize();

        try
        {
            jpeg_read_header (&jpegDecompStruct, TRUE);

            jpeg_calc_output_dimensions (&jpegDecompStruct);

            const int width  = (int) jpegDecompStruct.output_width;
            const int height = (int) jpegDecompStruct.output_height;

            jpegDecompStruct.out_color_space = JCS_RGB;

            JSAMPARRAY buffer
                = (*jpegDecompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegDecompStruct,
                                                         JPOOL_IMAGE,
                                                         (JDIMENSION) width * 3, 1);

            if (jpeg_start_decompress (&jpegDecompStruct))
            {
                image = Image (Image::RGB, width, height, false);
                image.getProperties()->set ("originalImageHadAlpha", false);
                const bool hasAlphaChan = image.hasAlphaChannel(); // (the native image creator may not give back what we expect)

                const Image::BitmapData destData (image, Image::BitmapData::writeOnly);

                for (int y = 0; y < height; ++y)
                {
                    jpeg_read_scanlines (&jpegDecompStruct, buffer, 1);

                    const uint8* src = *buffer;
                    uint8* dest = destData.getLinePointer (y);

                    if (hasAlphaChan)
                    {
                        for (int i = width; --i >= 0;)
                        {
                            ((PixelARGB*) dest)->setARGB (0xff, src[0], src[1], src[2]);
                            ((PixelARGB*) dest)->premultiply();
                            dest += destData.pixelStride;
                            src += 3;
                        }
                    }
                    else
                    {
                        for (int i = width; --i >= 0;)
                        {
                            ((PixelRGB*) dest)->setARGB (0xff, src[0], src[1], src[2]);
                            dest += destData.pixelStride;
                            src += 3;
                        }
                    }
                }

                jpeg_finish_decompress (&jpegDecompStruct);

                in.setPosition (((char*) jpegDecompStruct.src->next_input_byte) - (char*) mb.getData());
            }

            jpeg_destroy_decompress (&jpegDecompStruct);
        }
        catch (...)
        {}
    }

    return image;
#endif
}
Beispiel #24
0
String Path::toString() const
{
    MemoryOutputStream s (2048);
    if (! useNonZeroWinding)
        s << 'a';

    size_t i = 0;
    float lastMarker = 0.0f;

    while (i < numElements)
    {
        const float marker = data.elements [i++];
        char markerChar = 0;
        int numCoords = 0;

        if (marker == moveMarker)
        {
            markerChar = 'm';
            numCoords = 2;
        }
        else if (marker == lineMarker)
        {
            markerChar = 'l';
            numCoords = 2;
        }
        else if (marker == quadMarker)
        {
            markerChar = 'q';
            numCoords = 4;
        }
        else if (marker == cubicMarker)
        {
            markerChar = 'c';
            numCoords = 6;
        }
        else
        {
            jassert (marker == closeSubPathMarker);
            markerChar = 'z';
        }

        if (marker != lastMarker)
        {
            if (s.getDataSize() != 0)
                s << ' ';

            s << markerChar;
            lastMarker = marker;
        }

        while (--numCoords >= 0 && i < numElements)
        {
            String coord (data.elements [i++], 3);

            while (coord.endsWithChar ('0') && coord != "0")
                coord = coord.dropLastCharacters (1);

            if (coord.endsWithChar ('.'))
                coord = coord.dropLastCharacters (1);

            if (s.getDataSize() != 0)
                s << ' ';

            s << coord;
        }
    }

    return s.toUTF8();
}
void BinaryResources::loadFromCpp (const File& cppFileLocation, const String& cppFile)
{
    StringArray cpp;
    cpp.addLines (cppFile);

    clear();

    for (int i = 0; i < cpp.size(); ++i)
    {
        if (cpp[i].contains ("JUCER_RESOURCE:"))
        {
            StringArray tokens;
            tokens.addTokens (cpp[i].fromFirstOccurrenceOf (":", false, false), ",", "\"'");
            tokens.trim();
            tokens.removeEmptyStrings();

            const String resourceName (tokens[0]);
            const int resourceSize = tokens[1].getIntValue();
            const String originalFileName (cppFileLocation.getSiblingFile (tokens[2].unquoted()).getFullPathName());

            jassert (resourceName.isNotEmpty() && resourceSize > 0);

            if (resourceName.isNotEmpty() && resourceSize > 0)
            {
                const int firstLine = i;

                while (i < cpp.size())
                    if (cpp [i++].contains ("}"))
                        break;

                const String dataString (cpp.joinIntoString (" ", firstLine, i - firstLine)
                                            .fromFirstOccurrenceOf ("{", false, false));

                MemoryOutputStream out;
                String::CharPointerType t (dataString.getCharPointer());
                int n = 0;

                while (! t.isEmpty())
                {
                    const juce_wchar c = t.getAndAdvance();

                    if (c >= '0' && c <= '9')
                        n = n * 10 + (c - '0');
                    else if (c == ',')
                    {
                        out.writeByte ((char) n);
                        n = 0;
                    }
                    else if (c == '}')
                        break;
                }

                jassert (resourceSize < (int) out.getDataSize() && resourceSize > (int) out.getDataSize() - 2);

                MemoryBlock mb (out.getData(), out.getDataSize());
                mb.setSize ((size_t) resourceSize);

                add (resourceName, originalFileName, mb);
            }
        }
    }
}
Beispiel #26
0
    int read (void* buffer, int bytesToRead) override
    {
        if (finished || isError())
            return 0;

        if (isChunked && ! readingChunk)
        {
            if (position >= chunkEnd)
            {
                const ScopedValueSetter<bool> setter (readingChunk, true, false);
                MemoryOutputStream chunkLengthBuffer;
                char c = 0;

                if (chunkEnd > 0)
                {
                    if (read (&c, 1) != 1 || c != '\r'
                         || read (&c, 1) != 1 || c != '\n')
                    {
                        finished = true;
                        return 0;
                    }
                }

                while (chunkLengthBuffer.getDataSize() < 512 && ! (finished || isError()))
                {
                    if (read (&c, 1) != 1)
                    {
                        finished = true;
                        return 0;
                    }

                    if (c == '\r')
                        continue;

                    if (c == '\n')
                        break;

                    chunkLengthBuffer.writeByte (c);
                }

                const int64 chunkSize = chunkLengthBuffer.toString().trimStart().getHexValue64();

                if (chunkSize == 0)
                {
                    finished = true;
                    return 0;
                }

                chunkEnd += chunkSize;
            }

            if (bytesToRead > chunkEnd - position)
                bytesToRead = static_cast<int> (chunkEnd - position);
        }

        fd_set readbits;
        FD_ZERO (&readbits);
        FD_SET (socketHandle, &readbits);

        struct timeval tv;
        tv.tv_sec = jmax (1, timeOutMs / 1000);
        tv.tv_usec = 0;

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

        const int bytesRead = jmax (0, (int) recv (socketHandle, buffer, (size_t) bytesToRead, MSG_WAITALL));
        if (bytesRead == 0)
            finished = true;

        if (! readingChunk)
            position += bytesRead;

        return bytesRead;
    }
 bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData)
 {
     return overwriteFileWithNewDataIfDifferent (file, newData.getData(), newData.getDataSize());
 }
OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryOutputStream& streamToRead)
{
    stream.write (streamToRead.getData(), streamToRead.getDataSize());
    return stream;
}