1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00
JUCE/src/io/streams/juce_InputStream.cpp

280 lines
7.1 KiB
C++

/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#include "../../core/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_InputStream.h"
//==============================================================================
char InputStream::readByte()
{
char temp = 0;
read (&temp, 1);
return temp;
}
bool InputStream::readBool()
{
return readByte() != 0;
}
short InputStream::readShort()
{
char temp [2];
if (read (temp, 2) == 2)
return (short) ByteOrder::littleEndianShort (temp);
else
return 0;
}
short InputStream::readShortBigEndian()
{
char temp [2];
if (read (temp, 2) == 2)
return (short) ByteOrder::bigEndianShort (temp);
else
return 0;
}
int InputStream::readInt()
{
char temp [4];
if (read (temp, 4) == 4)
return (int) ByteOrder::littleEndianInt (temp);
else
return 0;
}
int InputStream::readIntBigEndian()
{
char temp [4];
if (read (temp, 4) == 4)
return (int) ByteOrder::bigEndianInt (temp);
else
return 0;
}
int InputStream::readCompressedInt()
{
const unsigned char sizeByte = readByte();
if (sizeByte == 0)
return 0;
const int numBytes = (sizeByte & 0x7f);
if (numBytes > 4)
{
jassertfalse // trying to read corrupt data - this method must only be used
// to read data that was written by OutputStream::writeCompressedInt()
return 0;
}
char bytes[4] = { 0, 0, 0, 0 };
if (read (bytes, numBytes) != numBytes)
return 0;
const int num = (int) ByteOrder::littleEndianInt (bytes);
return (sizeByte >> 7) ? -num : num;
}
int64 InputStream::readInt64()
{
char temp [8];
if (read (temp, 8) == 8)
return (int64) ByteOrder::swapIfBigEndian (*(uint64*) temp);
else
return 0;
}
int64 InputStream::readInt64BigEndian()
{
char temp [8];
if (read (temp, 8) == 8)
return (int64) ByteOrder::swapIfLittleEndian (*(uint64*) temp);
else
return 0;
}
float InputStream::readFloat()
{
union { int asInt; float asFloat; } n;
n.asInt = readInt();
return n.asFloat;
}
float InputStream::readFloatBigEndian()
{
union { int asInt; float asFloat; } n;
n.asInt = readIntBigEndian();
return n.asFloat;
}
double InputStream::readDouble()
{
union { int64 asInt; double asDouble; } n;
n.asInt = readInt64();
return n.asDouble;
}
double InputStream::readDoubleBigEndian()
{
union { int64 asInt; double asDouble; } n;
n.asInt = readInt64BigEndian();
return n.asDouble;
}
const String InputStream::readString()
{
MemoryBlock buffer (256);
uint8* data = (uint8*) buffer.getData();
size_t i = 0;
while ((data[i] = readByte()) != 0)
{
if (++i >= buffer.getSize())
{
buffer.setSize (buffer.getSize() + 512);
data = (uint8*) buffer.getData();
}
}
return String::fromUTF8 (data, (int) i);
}
const String InputStream::readNextLine()
{
MemoryBlock buffer (256);
uint8* data = (uint8*) 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 = (uint8*) buffer.getData();
}
}
return String::fromUTF8 (data, (int) i);
}
int InputStream::readIntoMemoryBlock (MemoryBlock& block,
int numBytes)
{
const int64 totalLength = getTotalLength();
if (totalLength >= 0)
{
const int totalBytesRemaining = (int) jmin ((int64) 0x7fffffff,
totalLength - getPosition());
if (numBytes < 0)
numBytes = totalBytesRemaining;
else if (numBytes > 0)
numBytes = jmin (numBytes, totalBytesRemaining);
else
return 0;
}
const size_t originalBlockSize = block.getSize();
int totalBytesRead = 0;
if (numBytes > 0)
{
// know how many bytes we want, so we can resize the block first..
block.setSize (originalBlockSize + numBytes, false);
totalBytesRead = read (((char*) block.getData()) + originalBlockSize, numBytes);
}
else
{
// read until end of stram..
const int chunkSize = 32768;
for (;;)
{
block.ensureSize (originalBlockSize + totalBytesRead + chunkSize, false);
const int bytesJustIn = read (((char*) block.getData())
+ originalBlockSize
+ totalBytesRead,
chunkSize);
if (bytesJustIn == 0)
break;
totalBytesRead += bytesJustIn;
}
}
// trim off any excess left at the end
block.setSize (originalBlockSize + totalBytesRead, false);
return totalBytesRead;
}
const String InputStream::readEntireStreamAsString()
{
MemoryBlock mb;
const int size = readIntoMemoryBlock (mb);
return String::createStringFromData ((const char*) mb.getData(), size);
}
//==============================================================================
void InputStream::skipNextBytes (int64 numBytesToSkip)
{
if (numBytesToSkip > 0)
{
const int skipBufferSize = (int) jmin (numBytesToSkip, (int64) 16384);
HeapBlock <char> temp (skipBufferSize);
while (numBytesToSkip > 0 && ! isExhausted())
numBytesToSkip -= read (temp, (int) jmin (numBytesToSkip, (int64) skipBufferSize));
}
}
END_JUCE_NAMESPACE