AREXPORT bool ArServerClient::sendPacketUdp(ArNetPacket *packet)
{
  if (myTcpOnly || getForceTcpFlag())
    return sendPacketTcp(packet);
  
  if (!setupPacket(packet))
  {
    if (myDebugLogging && packet->getCommand() <= 255)
      ArLog::log(ArLog::Normal, 
		 "%s sendPacket: could not set up udp command %d",
		 myLogPrefix.c_str(), packet->getCommand());
    return false;
  }
  else if (mySendUdpCB != NULL)
  {
    trackPacketSent(packet, false);
    if (myDebugLogging && packet->getCommand() <= 255)
      ArLog::log(ArLog::Normal, "%sSending udp command %d", 
		 myLogPrefix.c_str(), packet->getCommand());
    return mySendUdpCB->invokeR(packet, &mySin);
  }
  else
  {
    if (myDebugLogging && packet->getCommand() <= 255)
      ArLog::log(ArLog::Normal, "%sCould not send udp command %d", 
		 myLogPrefix.c_str(), packet->getCommand());
    return false;
  }
}
AREXPORT bool ArServerClient::sendPacketTcp(ArNetPacket *packet)
{
  if (!setupPacket(packet))
  {
    if (myDebugLogging && packet->getCommand() <= 255)
      ArLog::log(ArLog::Normal, 
		 "%s sendPacket: could not set up tcp command %d",
		 myLogPrefix.c_str(), packet->getCommand());
    return false;
  }
  else
  {
    trackPacketSent(packet, true);

    if (myDebugLogging && packet->getCommand() <= 255)
      ArLog::log(ArLog::Normal, "%sSending tcp command %d", 
		 myLogPrefix.c_str(), packet->getCommand());

    myTcpSender.sendPacket(packet, myLogPrefix.c_str());
    return true;
  }
}
Example #3
0
Common::SeekableReadStream *WwRIFFVorbisStream::generateHeaderSetup() {
	Common::MemoryWriteStreamDynamic header(true);
	Common::BitStreamWriter8LSB bits(header);

	putVorbisHeader(bits, 5);

	Packet setupPacket(*_inStream, _dataOffset + _setupPacketOffset, _noGranule);

	_inStream->seek(setupPacket.offset());

	if (setupPacket.granule() != 0)
		throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
		                        "Setup packet granule != 0");

	const size_t startPos = _inStream->pos() * 8;
	Common::BitStream8LSB in(*_inStream);

	// Codebook count
	const size_t codebookCount = in.getBits(8) + 1;
	bits.putBits(codebookCount - 1, 8);

	if (!_codebooks) {
		CodebookLibrary cbl;

		for (size_t i = 0; i < codebookCount; i++) {
			if (_fullSetup)
				cbl.copy(in, bits);
			else
				cbl.rebuild(in, 0, bits);
		}

	} else {
		CodebookLibrary cbl(*_codebooks);

		for (size_t i = 0; i < codebookCount; i++) {
			const uint16 codebookID = in.getBits(10);

			cbl.rebuild(codebookID, bits);
		}
	}

	// Time-domain transforms (placeholder)
	bits.putBits(0, 6);
	bits.putBits(0, 16);

	if (_fullSetup) {
		while (in.pos() < (setupPacket.size() * 8))
			bits.putBit(in.getBit());

	} else {
		const size_t floorCount = in.getBits(6) + 1;
		bits.putBits(floorCount - 1, 6);

		for (size_t i = 0; i < floorCount; i++) {
			bits.putBits(1, 16); // Floor type

			const size_t floor1Partitions = in.getBits(5);
			bits.putBits(floor1Partitions, 5);

			Common::ScopedArray<uint8> floor1PartitionClassList(new uint8[floor1Partitions]);
			uint8 maxClass = 0;

			for (size_t j = 0; j < floor1Partitions; j++) {
				floor1PartitionClassList[j] = in.getBits(4);
				bits.putBits(floor1PartitionClassList[j], 4);

				maxClass = MAX(maxClass, floor1PartitionClassList[j]);
			}

			Common::ScopedArray<uint8> floor1ClassDimensionsList(new uint8[maxClass + 1]);
			for (size_t j = 0; j <= maxClass; j++) {
				floor1ClassDimensionsList[j] = in.getBits(3) + 1;
				bits.putBits(floor1ClassDimensionsList[j] - 1, 3);

				const uint8 subClasses = in.getBits(2);
				bits.putBits(subClasses, 2);

				if (subClasses != 0) {
					const uint8 masterbook = in.getBits(8);
					bits.putBits(masterbook, 8);

					if (masterbook >= codebookCount)
						throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
						                        "Invalid floor1 masterbook");
				}

				for (size_t k = 0; k < (1U << subClasses); k++) {
					const int16 subClassBook = static_cast<int16>(in.getBits(8)) - 1;
					bits.putBits(static_cast<uint16>(subClassBook + 1), 8);

					if (subClassBook >= 0 && (static_cast<size_t>(subClassBook) >= codebookCount))
						throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
						                        "Invalid floor1 subclass book");
				}
			}

			const uint8 floor1Multiplier = in.getBits(2) + 1;
			bits.putBits(floor1Multiplier - 1, 2);

			const uint8 rangeBits = in.getBits(4);
			bits.putBits(rangeBits, 4);

			for (size_t j = 0; j < floor1Partitions; j++) {
				const uint8 currentClassNumber = floor1PartitionClassList[j];

				for (size_t k = 0; k < floor1ClassDimensionsList[currentClassNumber]; k++)
					bits.putBits(in.getBits(rangeBits), rangeBits);

			}
		}

		const size_t residueCount = in.getBits(6) + 1;
		bits.putBits(residueCount - 1, 6);

		for (size_t i = 0; i < residueCount; i++) {
			const uint8 residueType = in.getBits(2);
			bits.putBits(residueType, 16);

			if (residueType > 2)
				throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
				                        "Invalid residue type");

			// Residues: begin, end, partition size
			bits.putBits(in.getBits(24), 24);
			bits.putBits(in.getBits(24), 24);
			bits.putBits(in.getBits(24), 24);

			const size_t residueClassifications = in.getBits(6) + 1;
			bits.putBits(residueClassifications - 1, 6);

			const uint8 residueClassbook = in.getBits(8);
			bits.putBits(residueClassbook, 8);

			if (residueClassbook >= codebookCount)
				throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
				                        "Invalid residue classbook");

			Common::ScopedArray<uint16> residueCascade(new uint16[residueClassifications]);
			for (size_t j = 0; j < residueClassifications; j++) {
				const uint8 lowBits = in.getBits(3);
				bits.putBits(lowBits, 3);

				const uint8 bitFlag = in.getBit();
				bits.putBit(bitFlag);

				uint8 highBits = 0;
				if (bitFlag) {
					highBits = in.getBits(5);
					bits.putBits(highBits, 5);
				}

				residueCascade[j] = highBits * 8 + lowBits;
			}

			for (size_t j = 0; j < residueClassifications; j++) {
				for (uint8 k = 0; k < 8; k++) {
					if (residueCascade[j] & (1 << k)) {
						const size_t residueBook = in.getBits(8);
						bits.putBits(residueBook, 8);

						if (residueBook >= codebookCount)
							throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
							                        "Invalid residue book");
					}
				}
			}
		}

		const size_t mappingCount = in.getBits(6) + 1;
		bits.putBits(mappingCount - 1, 6);

		for (size_t i = 0; i < mappingCount; i++) {
			bits.putBits(0, 16); // Mapping type

			const uint8 subMapsFlag = in.getBit();
			bits.putBit(subMapsFlag);

			uint8 subMaps = 1;
			if (subMapsFlag) {
				subMaps = in.getBits(4) + 1;
				bits.putBits(subMaps - 1, 4);
			}

			const uint8 squarePolarFlag = in.getBit();
			bits.putBit(squarePolarFlag);

			if (squarePolarFlag) {
				const size_t couplingSteps = in.getBits(8) + 1;
				bits.putBits(couplingSteps - 1, 8);

				for (size_t j = 0; j < couplingSteps; j++) {
					const size_t bitCount = Common::intLog2(_channels - 1) + 1;

					const uint32 magnitude = in.getBits(bitCount);
					const uint32 angle = in.getBits(bitCount);

					bits.putBits(magnitude, bitCount);
					bits.putBits(angle, bitCount);

					if ((angle == magnitude) || (magnitude >= _channels) || (angle >= _channels))
						throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
						                        "Invalid coupling");
				}
			}

			const uint8 mappingReserved = in.getBits(2);
			bits.putBits(mappingReserved, 2);

			if (mappingReserved != 0)
				throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
				                        "Mapping reserved field nonzero");

			if (subMaps > 1) {
				for (size_t j = 0; j < _channels; j++) {
					const uint8 MappingMux = in.getBits(4);
					bits.putBits(MappingMux, 4);

					if (MappingMux >= subMaps)
						throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
						                        "MappingMux >= subMaps");
				}
			}

			for (size_t j = 0; j < subMaps; j++) {
				const uint8 timeConfig    = in.getBits(8);
				const uint8 floorNumber   = in.getBits(8);
				const uint8 residueNumber = in.getBits(8);

				bits.putBits(timeConfig   , 8);
				bits.putBits(floorNumber  , 8);
				bits.putBits(residueNumber, 8);

				if (floorNumber >= floorCount)
					throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
					                        "Invalid floor mapping");
				if (residueNumber >= residueCount)
					throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
					                        "Invalid residue mapping");
			}
		}

		const size_t modeCount = in.getBits(6) + 1;
		bits.putBits(modeCount - 1, 6);

		_modeBlockFlags.reset(new bool[modeCount]);
		_modeBits = Common::intLog2(modeCount - 1) + 1;

		for (size_t i = 0; i < modeCount; i++) {
			_modeBlockFlags[i] = in.getBit();
			bits.putBit(_modeBlockFlags[i]);

			bits.putBits(0, 16); // Window type
			bits.putBits(0, 16); // Transform type

			const uint8 mapping = in.getBits(8);
			bits.putBits(mapping, 8);

			if (mapping >= mappingCount)
				throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
				                        "Invalid mode mapping");
		}

	}

	bits.putBits(1, 1); // Framing

	bits.flush();

	if (((in.pos() - startPos + 7) / 8) != setupPacket.size())
		throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
		                        "Didn't read the exact size of the setup packet");

	if (setupPacket.nextOffset() != (_dataOffset + static_cast<size_t>(_firstAudioPacketOffset)))
		throw Common::Exception("WwRIFFVorbisStream::generateHeaderSetup(): "
		                        "First audio packet doesn't follow setup packet");

	header.setDisposable(false);
	return new Common::MemoryReadStream(header.getData(), header.size(), true);
}