1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00
This commit is contained in:
Ben Kuper 2026-01-07 19:49:10 +01:00 committed by GitHub
commit 18df69f6bd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 359 additions and 14 deletions

View file

@ -36,10 +36,15 @@ namespace juce
{
OSCArgument::OSCArgument (int32 v) : type (OSCTypes::int32), intValue (v) {}
OSCArgument::OSCArgument (int64 v) : type (OSCTypes::int64), int64Value (v) {}
OSCArgument::OSCArgument (float v) : type (OSCTypes::float32), floatValue (v) {}
OSCArgument::OSCArgument (double v) : type (OSCTypes::double64),doubleValue (v) {}
OSCArgument::OSCArgument (const String& s) : type (OSCTypes::string), stringValue (s) {}
OSCArgument::OSCArgument (MemoryBlock b) : type (OSCTypes::blob), blob (std::move (b)) {}
OSCArgument::OSCArgument (OSCColour c) : type (OSCTypes::colour), intValue ((int32) c.toInt32()) {}
OSCArgument::OSCArgument (bool b) : type (b ? OSCTypes::T : OSCTypes::F) {}
OSCArgument::OSCArgument (OSCType t) : type (t) {} //for nil and impulse
//==============================================================================
String OSCArgument::getString() const noexcept
@ -60,6 +65,15 @@ int32 OSCArgument::getInt32() const noexcept
return 0;
}
int64 OSCArgument::getInt64() const noexcept
{
if (isInt64())
return int64Value;
jassertfalse; // you must check the type of an argument before attempting to get its value!
return 0;
}
float OSCArgument::getFloat32() const noexcept
{
if (isFloat32())
@ -69,6 +83,15 @@ float OSCArgument::getFloat32() const noexcept
return 0.0f;
}
double OSCArgument::getDouble() const noexcept
{
if (isDouble())
return doubleValue;
jassertfalse; // you must check the type of an argument before attempting to get its value!
return 0.0;
}
const MemoryBlock& OSCArgument::getBlob() const noexcept
{
// you must check the type of an argument before attempting to get its value!
@ -86,6 +109,15 @@ OSCColour OSCArgument::getColour() const noexcept
return { 0, 0, 0, 0 };
}
bool OSCArgument::getBool() const noexcept
{
if (isBool())
return type == OSCTypes::T;
jassertfalse; // you must check the type of an argument before attempting to get its value!
return false;
}
//==============================================================================
//==============================================================================
@ -126,14 +158,40 @@ public:
expect (arg.getType() == OSCTypes::int32);
expect (arg.isInt32());
expect (! arg.isInt64());
expect (! arg.isFloat32());
expect (! arg.isDouble());
expect (! arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (! arg.isNil());
expect (! arg.isImpulse());
expect (! arg.isBool());
expect (arg.getInt32() == value);
}
beginTest("Int64");
{
int64 value = 1234567890123456789;
OSCArgument arg(value);
expect(arg.getType() == OSCTypes::int64);
expect (! arg.isInt32());
expect (arg.isInt64());
expect (! arg.isFloat32());
expect (! arg.isDouble());
expect (! arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (! arg.isNil());
expect (! arg.isImpulse());
expect (! arg.isBool());
expect(arg.getInt64() == value);
}
beginTest ("Float32");
{
float value = 12345.6789f;
@ -142,14 +200,40 @@ public:
expect (arg.getType() == OSCTypes::float32);
expect (! arg.isInt32());
expect (! arg.isInt64());
expect (arg.isFloat32());
expect (! arg.isDouble());
expect (! arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (! arg.isNil());
expect (! arg.isImpulse());
expect (! arg.isBool());
expectEquals (arg.getFloat32(), value);
}
beginTest("Double");
{
double value = 12345.6789;
OSCArgument arg(value);
expect(arg.getType() == OSCTypes::double64);
expect (! arg.isInt32());
expect (! arg.isInt64());
expect (! arg.isFloat32());
expect (arg.isDouble());
expect (! arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (! arg.isNil());
expect (! arg.isImpulse());
expect (! arg.isBool());
expectEquals(arg.getDouble(), value);
}
beginTest ("String");
{
String value = "Hello, World!";
@ -157,10 +241,15 @@ public:
expect (arg.getType() == OSCTypes::string);
expect (! arg.isInt32());
expect (! arg.isInt64());
expect (! arg.isFloat32());
expect (! arg.isDouble());
expect (arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (! arg.isNil());
expect (! arg.isImpulse());
expect (! arg.isBool());
expect (arg.getString() == value);
}
@ -171,10 +260,15 @@ public:
expect (arg.getType() == OSCTypes::string);
expect (! arg.isInt32());
expect (! arg.isInt64());
expect (! arg.isFloat32());
expect (! arg.isDouble());
expect (arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (! arg.isNil());
expect (! arg.isImpulse());
expect (! arg.isBool());
expect (arg.getString() == "Hello, World!");
}
@ -186,10 +280,15 @@ public:
expect (arg.getType() == OSCTypes::blob);
expect (! arg.isInt32());
expect (! arg.isInt64());
expect (! arg.isFloat32());
expect (! arg.isDouble());
expect (! arg.isString());
expect (arg.isBlob());
expect (! arg.isColour());
expect (! arg.isNil());
expect (! arg.isImpulse());
expect (! arg.isBool());
expect (arg.getBlob() == blob);
}
@ -209,15 +308,85 @@ public:
expect (arg.getType() == OSCTypes::colour);
expect (! arg.isInt32());
expect (! arg.isInt64());
expect (! arg.isFloat32());
expect (! arg.isDouble());
expect (! arg.isString());
expect (! arg.isBlob());
expect (arg.isColour());
expect (! arg.isNil());
expect (! arg.isImpulse());
expect (! arg.isBool());
expect (arg.getColour().toInt32() == col.toInt32());
}
}
beginTest ("Nil");
{
OSCArgument arg (OSCTypes::nil);
expect (arg.getType() == OSCTypes::nil);
expect (! arg.isInt32());
expect (! arg.isInt64());
expect (! arg.isFloat32());
expect (! arg.isDouble());
expect (! arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (arg.isNil());
expect (! arg.isImpulse());
expect (! arg.isBool());
}
beginTest("Impulse");
{
OSCArgument arg(OSCTypes::impulse);
expect(arg.getType() == OSCTypes::impulse);
expect (! arg.isInt32());
expect (! arg.isInt64());
expect (! arg.isFloat32());
expect (! arg.isDouble());
expect (! arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (! arg.isNil());
expect (arg.isImpulse());
expect (! arg.isBool());
}
beginTest("True");
{
OSCArgument arg(OSCTypes::T);
expect (! arg.isInt32());
expect (! arg.isInt64());
expect (! arg.isFloat32());
expect (! arg.isDouble());
expect (! arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (! arg.isNil());
expect (! arg.isImpulse());
expect (arg.isBool());
}
beginTest("False");
{
OSCArgument arg(OSCTypes::F);
expect (! arg.isInt32());
expect (! arg.isInt64());
expect (! arg.isFloat32());
expect (! arg.isDouble());
expect (! arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (! arg.isNil());
expect (! arg.isImpulse());
expect (arg.isBool());
}
beginTest ("Copy, move and assignment");
{
{

View file

@ -52,9 +52,15 @@ public:
/** Constructs an OSCArgument with type int32 and a given value. */
OSCArgument (int32 value);
/** Constructs an OSCArgument with type int64 and a given value. */
OSCArgument (int64 value);
/** Constructs an OSCArgument with type float32 and a given value. */
OSCArgument (float value);
/** Constructs an OSCArgument with type double and a given value. */
OSCArgument (double value);
/** Constructs an OSCArgument with type string and a given value */
OSCArgument (const String& value);
@ -69,6 +75,14 @@ public:
/** Constructs an OSCArgument with type colour and a given colour value */
OSCArgument (OSCColour colour);
/** Constructs an OSCArgument with type T or F depending on the given boolean value */
OSCArgument (bool value);
/** Constructs an OSCArgument with the given OSC type tag.
This constructor is intended for creating OSCArgument objects with type nil or impulse.
*/
OSCArgument (OSCType type);
/** Returns the type of the OSCArgument as an OSCType.
OSCType is a char type, and its value will be the OSC type tag of the type.
*/
@ -77,9 +91,15 @@ public:
/** Returns whether the type of the OSCArgument is int32. */
bool isInt32() const noexcept { return type == OSCTypes::int32; }
/** Returns whether the type of the OSCArgument is int64. */
bool isInt64() const noexcept { return type == OSCTypes::int64; }
/** Returns whether the type of the OSCArgument is float. */
bool isFloat32() const noexcept { return type == OSCTypes::float32; }
/** Returns whether the type of the OSCArgument is double. */
bool isDouble() const noexcept { return type == OSCTypes::double64; }
/** Returns whether the type of the OSCArgument is string. */
bool isString() const noexcept { return type == OSCTypes::string; }
@ -89,16 +109,35 @@ public:
/** Returns whether the type of the OSCArgument is colour. */
bool isColour() const noexcept { return type == OSCTypes::colour; }
/** Returns whether the type of the OSCArgument is nil. */
bool isNil() const noexcept { return type == OSCTypes::nil; }
/** Returns whether the type of the OSCArgument is impulse. */
bool isImpulse() const noexcept { return type == OSCTypes::impulse; }
/** Returns whether the type of the OSCArgument is T or F. */
bool isBool() const noexcept { return type == OSCTypes::T || type == OSCTypes::F; }
/** Returns the value of the OSCArgument as an int32.
If the type of the OSCArgument is not int32, the behaviour is undefined.
*/
int32 getInt32() const noexcept;
/** Returns the value of the OSCArgument as an int64.
If the type of the OSCArgument is not int64, the behaviour is undefined.
*/
int64 getInt64() const noexcept;
/** Returns the value of the OSCArgument as a float32.
If the type of the OSCArgument is not float32, the behaviour is undefined.
*/
float getFloat32() const noexcept;
/** Returns the value of the OSCArgument as a double.
If the type of the OSCArgument is not double, the behaviour is undefined.
*/
double getDouble() const noexcept;
/** Returns the value of the OSCArgument as a string.
If the type of the OSCArgument is not string, the behaviour is undefined.
*/
@ -116,6 +155,11 @@ public:
*/
OSCColour getColour() const noexcept;
/** Returns the value of the OSCArgument as a boolean.
If the type of the OSCArgument is not T or F, the behaviour is undefined.
*/
bool getBool() const noexcept;
private:
//==============================================================================
OSCType type;
@ -126,6 +170,12 @@ private:
float floatValue;
};
union
{
int64 int64Value;
double doubleValue;
};
String stringValue;
MemoryBlock blob;
};

View file

@ -98,10 +98,15 @@ void OSCMessage::clear()
//==============================================================================
void OSCMessage::addInt32 (int32 value) { arguments.add (OSCArgument (value)); }
void OSCMessage::addInt64 (int64 value) { arguments.add (OSCArgument (value)); }
void OSCMessage::addFloat32 (float value) { arguments.add (OSCArgument (value)); }
void OSCMessage::addDouble (double value) { arguments.add (OSCArgument (value)); }
void OSCMessage::addString (const String& value) { arguments.add (OSCArgument (value)); }
void OSCMessage::addBlob (MemoryBlock blob) { arguments.add (OSCArgument (std::move (blob))); }
void OSCMessage::addColour (OSCColour colour) { arguments.add (OSCArgument (colour)); }
void OSCMessage::addNil() { arguments.add (OSCArgument (OSCTypes::nil)); }
void OSCMessage::addImpulse() { arguments.add (OSCArgument (OSCTypes::impulse)); }
void OSCMessage::addBool (bool value) { arguments.add (OSCArgument (value)); }
void OSCMessage::addArgument (OSCArgument arg) { arguments.add (arg); }
@ -124,41 +129,72 @@ public:
expectEquals (msg.size(), 0);
expect (msg.getAddressPattern().toString() == "/test/param0");
const int numTestArgs = 5;
const int numTestArgs = 11;
const int testInt = 42;
const int64 testInt64 = 64;
const float testFloat = 3.14159f;
const double testDouble = 6.28;
const String testString = "Hello, World!";
const OSCColour testColour = { 10, 20, 150, 200 };
const bool testTrue = true;
const bool testFalse = false;
const uint8 testBlobData[5] = { 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
const MemoryBlock testBlob (testBlobData, sizeof (testBlobData));
msg.addInt32 (testInt);
msg.addInt64 (testInt64);
msg.addFloat32 (testFloat);
msg.addDouble (testDouble);
msg.addString (testString);
msg.addBlob (testBlob);
msg.addColour (testColour);
msg.addNil ();
msg.addImpulse ();
msg.addBool (testTrue);
msg.addBool (testFalse);
expectEquals (msg.size(), numTestArgs);
expectEquals (msg[0].getType(), OSCTypes::int32);
expectEquals (msg[1].getType(), OSCTypes::float32);
expectEquals (msg[2].getType(), OSCTypes::string);
expectEquals (msg[3].getType(), OSCTypes::blob);
expectEquals (msg[4].getType(), OSCTypes::colour);
expectEquals (msg[1].getType(), OSCTypes::int64);
expectEquals (msg[2].getType(), OSCTypes::float32);
expectEquals (msg[3].getType(), OSCTypes::double64);
expectEquals (msg[4].getType(), OSCTypes::string);
expectEquals (msg[5].getType(), OSCTypes::blob);
expectEquals (msg[6].getType(), OSCTypes::colour);
expectEquals (msg[7].getType(), OSCTypes::nil);
expectEquals (msg[8].getType(), OSCTypes::impulse);
expectEquals (msg[9].getType(), OSCTypes::T);
expectEquals (msg[10].getType(), OSCTypes::F);
expect (msg[0].isInt32());
expect (msg[1].isFloat32());
expect (msg[2].isString());
expect (msg[3].isBlob());
expect (msg[4].isColour());
expect (msg[1].isInt64());
expect (msg[2].isFloat32());
expect (msg[3].isDouble());
expect (msg[4].isString());
expect (msg[5].isBlob());
expect (msg[6].isColour());
expect (msg[7].isNil());
expect (msg[8].isImpulse());
expect (msg[9].isBool());
expect (msg[10].isBool());
expectEquals (msg[0].getInt32(), testInt);
expectEquals (msg[1].getFloat32(), testFloat);
expectEquals (msg[2].getString(), testString);
expect (msg[3].getBlob() == testBlob);
expect (msg[4].getColour().toInt32() == testColour.toInt32());
expectEquals (msg[1].getInt64(), testInt64);
expectEquals (msg[2].getFloat32(), testFloat);
expectEquals (msg[3].getDouble(), testDouble);
expectEquals (msg[4].getString(), testString);
expect (msg[5].getBlob() == testBlob);
expect (msg[6].getColour().toInt32() == testColour.toInt32());
expectEquals (msg[9].getBool(), testTrue);
expectEquals (msg[10].getBool(), testFalse);
expect (msg.begin() + numTestArgs == msg.end());
@ -166,9 +202,15 @@ public:
expect (arg->isInt32());
expectEquals (arg->getInt32(), testInt);
++arg;
expect (arg->isInt64());
expectEquals (arg->getInt64(), testInt64);
++arg;
expect (arg->isFloat32());
expectEquals (arg->getFloat32(), testFloat);
++arg;
expect (arg->isDouble());
expectEquals (arg->getDouble(), testDouble);
++arg;
expect (arg->isString());
expectEquals (arg->getString(), testString);
++arg;
@ -178,6 +220,17 @@ public:
expect (arg->isColour());
expect (arg->getColour().toInt32() == testColour.toInt32());
++arg;
expect (arg->isNil());
++arg;
expect(arg->isImpulse());
++arg;
expect(arg->isBool());
expectEquals(arg->getBool(), testTrue);
++arg;
expect(arg->isBool());
expectEquals(arg->getBool(), testFalse);
++arg;
expect (arg == msg.end());
}

View file

@ -133,11 +133,21 @@ public:
*/
void addInt32 (int32 value);
/** Creates a new OSCArgument of type int64 with the given value,
and adds it to the OSCMessage object.
*/
void addInt64(int64 value);
/** Creates a new OSCArgument of type float32 with the given value,
and adds it to the OSCMessage object.
*/
void addFloat32 (float value);
/** Creates a new OSCArgument of type double with the given value,
and adds it to the OSCMessage object.
*/
void addDouble (double value);
/** Creates a new OSCArgument of type string with the given value,
and adds it to the OSCMessage object.
*/
@ -155,6 +165,17 @@ public:
*/
void addColour (OSCColour colour);
/** Creates a new OSCArgument of type nil and adds it to the OSCMessage object. */
void addNil();
/** Creates a new OSCArgument of type impulse and adds it to the OSCMessage object. */
void addImpulse();
/** Creates a new OSCArgument of type T or F with the given value,
and adds it to the OSCMessage object.
*/
void addBool (bool value);
/** Adds the OSCArgument argument to the OSCMessage object.
Note: This method will result in a copy of the OSCArgument object if it is passed

View file

@ -86,6 +86,12 @@ namespace
return input.readIntBigEndian();
}
int64 readInt64()
{
checkBytesAvailable(8, "OSC input stream exhausted while reading int64");
return input.readInt64BigEndian();
}
uint64 readUint64()
{
checkBytesAvailable (8, "OSC input stream exhausted while reading uint64");
@ -98,6 +104,12 @@ namespace
return input.readFloatBigEndian();
}
double readDouble64()
{
checkBytesAvailable(8, "OSC input stream exhausted while reading double");
return input.readDoubleBigEndian();
}
String readString()
{
checkBytesAvailable (4, "OSC input stream exhausted while reading string");
@ -189,10 +201,16 @@ namespace
switch (type)
{
case OSCTypes::int32: return OSCArgument (readInt32());
case OSCTypes::int64: return OSCArgument (readInt64());
case OSCTypes::float32: return OSCArgument (readFloat32());
case OSCTypes::double64: return OSCArgument (readDouble64());
case OSCTypes::string: return OSCArgument (readString());
case OSCTypes::blob: return OSCArgument (readBlob());
case OSCTypes::colour: return OSCArgument (readColour());
case OSCTypes::nil: return OSCArgument (OSCTypes::nil);
case OSCTypes::impulse: return OSCArgument (OSCTypes::impulse);
case OSCTypes::T: return OSCArgument (true);
case OSCTypes::F: return OSCArgument (false);
default:
// You supplied an invalid OSCType when calling readArgument! This should never happen.

View file

@ -62,6 +62,11 @@ namespace
return output.writeIntBigEndian (value);
}
bool writeInt64(int64 value)
{
return output.writeInt64BigEndian(value);
}
bool writeUint64 (uint64 value)
{
return output.writeInt64BigEndian (int64 (value));
@ -72,6 +77,11 @@ namespace
return output.writeFloatBigEndian (value);
}
bool writeDouble(double value)
{
return output.writeDoubleBigEndian(value);
}
bool writeString (const String& value)
{
if (! output.writeString (value))
@ -133,10 +143,16 @@ namespace
switch (arg.getType())
{
case OSCTypes::int32: return writeInt32 (arg.getInt32());
case OSCTypes::int64: return writeInt64 (arg.getInt64());
case OSCTypes::float32: return writeFloat32 (arg.getFloat32());
case OSCTypes::double64: return writeDouble (arg.getDouble());
case OSCTypes::string: return writeString (arg.getString());
case OSCTypes::blob: return writeBlob (arg.getBlob());
case OSCTypes::colour: return writeColour (arg.getColour());
case OSCTypes::nil: return true;
case OSCTypes::impulse: return true;
case OSCTypes::T: return true;
case OSCTypes::F: return true;
default:
// In this very unlikely case you supplied an invalid OSCType!

View file

@ -36,10 +36,16 @@ namespace juce
{
const OSCType OSCTypes::int32 = 'i';
const OSCType OSCTypes::int64 = 'h';
const OSCType OSCTypes::float32 = 'f';
const OSCType OSCTypes::double64= 'd';
const OSCType OSCTypes::string = 's';
const OSCType OSCTypes::blob = 'b';
const OSCType OSCTypes::colour = 'r';
const OSCType OSCTypes::nil = 'N';
const OSCType OSCTypes::impulse = 'I';
const OSCType OSCTypes::T = 'T';
const OSCType OSCTypes::F = 'F';
uint32 OSCColour::toInt32() const
{

View file

@ -56,18 +56,30 @@ class JUCE_API OSCTypes
{
public:
static const OSCType int32;
static const OSCType int64;
static const OSCType float32;
static const OSCType double64;
static const OSCType string;
static const OSCType blob;
static const OSCType colour;
static const OSCType nil;
static const OSCType impulse;
static const OSCType T;
static const OSCType F;
static bool isSupportedType (OSCType type) noexcept
{
return type == OSCTypes::int32
|| type == OSCTypes::int64
|| type == OSCTypes::float32
|| type == OSCTypes::double64
|| type == OSCTypes::string
|| type == OSCTypes::blob
|| type == OSCTypes::colour;
|| type == OSCTypes::colour
|| type == OSCTypes::nil
|| type == OSCTypes::impulse
|| type == OSCTypes::T
|| type == OSCTypes::F;
}
};