bool BinTreeNodeReader::readString(int token, QByteArray& s, QDataStream& in) { int size; if (token == -1) { qDebug() << "-1 token in readString"; //socket->disconnectFromHost(); Q_EMIT socketBroken(); } if (token > 2 && token < 0xf5) return getToken(token, s, in); switch (token) { case 0: return false; case 0xfc: size = readInt8(in); fillArray(s,size,in); return true; case 0xfd: size = readInt24(in); fillArray(s,size,in); return true; case 0xfe: in >> token; return getToken(0xf5 + token, s, in); case 0xfa: QByteArray user,server; bool usr = readString(user,in); bool srv = readString(server,in); if (usr & srv) { s = user + "@" + server; return true; } if (srv) { s = server; return true; } qDebug() << "readString couldn't reconstruct jid."; //socket->disconnectFromHost(); Q_EMIT socketBroken(); } qDebug() << "readString invalid token" << QString::number(token); //socket->disconnectFromHost(); Q_EMIT socketBroken(); return false; }
bool BinTreeNodeReader::readString(int token, QByteArray& s) { if (token == -1) { throw ProtocolException("-1 token in readString."); } if (token > 2 && token < 0xf5) return getToken(token, s); //no default value. switch (token) { case 0: return false; case 0xfc: quint8 size8; if (!readInt8(size8)) return false; return fillArray(s,size8); case 0xfd: qint32 size24; if (!readInt24(size24)) return false; return fillArray(s,size24); case 0xfe: quint8 token8; if (!readInt8(token8)) return false; return getToken(0xf5 + token8, s); case 0xfa: QByteArray user,server; bool usr = readString(user); bool srv = readString(server); if (usr & srv) { s = user + "@" + server; return true; } if (srv) { s = server; return true; } throw ProtocolException("readString couldn't reconstruct jid."); } throw ProtocolException("readString invalid token " + QString::number(token)); }
int BinTreeNodeReader::getOneToplevelStream() { qint32 bufferSize = readInt24(); qint8 flags = (bufferSize & 0xff0000) >> 20; bufferSize &= 0xffff; fillBuffer(bufferSize); //qDebug() << "[[ " + readBuffer.toHex(); decodeStream(flags, 0, bufferSize); return bufferSize + 3; }
void BinTreeNodeReader::getTopLevelStream() { int stanzaSize = readInt24(this->rawIn); int flags = (stanzaSize >> 20); stanzaSize &= 0x0FFFFF; if (this->buf.size() < (size_t)stanzaSize) { int newsize = max((int)(this->buf.size() * 3 / 2), stanzaSize); this->buf.resize(newsize); } fillArray(this->buf, stanzaSize, this->rawIn); this->decodeStream(flags, 0, stanzaSize); }
bool BinTreeNodeReader::readString(int token, QByteArray& s, QDataStream& in) { int size; if (token == -1) throw ProtocolException("-1 token in readString."); if (token > 4 && token < 0xf5) return getToken(token,s); switch (token) { case 0: return false; case 0xfc: size = readInt8(in); fillArray(s,size,in); return true; case 0xfd: size = readInt24(in); fillArray(s,size,in); return true; case 0xfe: in >> token; return getToken(245 + token,s); case 0xfa: QByteArray user,server; bool usr = readString(user,in); bool srv = readString(server,in); if (usr & srv) { s = user + "@" + server; return true; } if (srv) { s = server; return true; } throw ProtocolException("readString couldn't reconstruct jid."); } throw ProtocolException("readString invalid token " + QString::number(token)); }
MidiEvent* parseEvent(uint8_t const*& dataStart, uint8_t lastEventTypeByte) { uint8_t eventTypeByte = *dataStart++; if ((eventTypeByte & 0xf0) == 0xf0) { /* system / meta event */ if (eventTypeByte == 0xff) { /* meta event */ uint8_t subtypeByte = *dataStart++; int length = readVarInt(dataStart); switch(subtypeByte) { case 0x00: { if (length != 2) throw "Expected length for sequenceNumber event is 2"; SequenceNumberEvent* event = new SequenceNumberEvent(); event->number = * (uint16_t*) dataStart; dataStart += 2; return event; } case 0x01: { TextEvent* event = new TextEvent(); event->text.assign((char*) dataStart, length); dataStart += length; return event; } case 0x02: { CopyrightNoticeEvent* event = new CopyrightNoticeEvent(); event->text.assign((char*) dataStart, length); dataStart += length; return event; } case 0x03: { TrackNameEvent* event = new TrackNameEvent(); event->text.assign((char*) dataStart, length); dataStart += length; return event; } case 0x04: { InstrumentNameEvent* event = new InstrumentNameEvent(); event->text.assign((char*) dataStart, length); dataStart += length; return event; } case 0x05: { LyricsEvent* event = new LyricsEvent(); event->text.assign((char*) dataStart, length); dataStart += length; return event; } case 0x06: { MarkerEvent* event = new MarkerEvent(); event->text.assign((char*) dataStart, length); dataStart += length; return event; } case 0x07: { CuePointEvent* event = new CuePointEvent(); event->text.assign((char*) dataStart, length); dataStart += length; return event; } case 0x20: { if (length != 1) throw "Expected length for midiChannelPrefix event is 1"; MidiChannelPrefixEvent* event = new MidiChannelPrefixEvent(); event->channel = *(uint8_t*) dataStart; ++dataStart; return event; } case 0x2f: { if (length != 0) throw "Expected length for endOfTrack event is 0"; EndOfTrackEvent* event = new EndOfTrackEvent(); return event; } case 0x51: { if (length != 3) throw "Expected length for setTempo event is 3"; SetTempoEvent* event = new SetTempoEvent(); event->microsecondsPerBeat = readInt24(dataStart); return event; } case 0x54: { if (length != 5) throw "Expected length for smpteOffset event is 5"; SmpteOffsetEvent* event = new SmpteOffsetEvent(); uint8_t hourByte = *dataStart++; switch (hourByte & 0x60) { case 0x00: event->framerate = 24; break; case 0x20: event->framerate = 25; break; case 0x40: event->framerate = 29; break; case 0x60: event->framerate = 30; break; } event->hour = hourByte & 0x1f; event->min = int(*dataStart++); event->sec = int(*dataStart++); event->frame = int(*dataStart++); event->subframe = int(*dataStart++); return event; } case 0x58: { if (length != 4) throw "Expected length for timeSignature event is 4"; TimeSignatureEvent* event = new TimeSignatureEvent(); event->numerator = int(*dataStart++); event->denominator = int(powf(2.0f, float(*dataStart++))); event->metronome = int(*dataStart++); event->thirtyseconds = int(*dataStart++); return event; } case 0x59: { if (length != 2) throw "Expected length for keySignature event is 2"; KeySignatureEvent* event = new KeySignatureEvent(); event->key = int(*dataStart++); event->scale = int(*dataStart++); return event; } case 0x7f: { SequencerSpecificEvent* event = new SequencerSpecificEvent(); event->data = new uint8_t[length]; memcpy(event->data, dataStart, length); dataStart += length; return event; } } // console.log("Unrecognised meta event subtype: " + subtypeByte); UnknownEvent* event = new UnknownEvent(); event->data = new uint8_t[length]; memcpy(event->data, dataStart, length); dataStart += length; return event; } else if (eventTypeByte == 0xf0) { int length = readVarInt(dataStart); SysExEvent* event = new SysExEvent(); event->data = new uint8_t[length]; memcpy(event->data, dataStart, length); dataStart += length; return event; } else if (eventTypeByte == 0xf7) { int length = readVarInt(dataStart); DividedSysExEvent* event = new DividedSysExEvent(); event->data = new uint8_t[length]; memcpy(event->data, dataStart, length); dataStart += length; return event; } else { throw "Unrecognised MIDI event type byte"; // eventTypeByte; } } else { /* channel event */ ChannelEvent* event = new ChannelEvent(); int param1; if ((eventTypeByte & 0x80) == 0) { // Running status is described here: // http://home.roadrunner.com/~jgglatt/tech/midispec/run.htm // running status - reuse lastEventTypeByte as the event type. // eventTypeByte is actually the first parameter // param1 = eventTypeByte; eventTypeByte = lastEventTypeByte; } else { param1 = int(*dataStart++); lastEventTypeByte = eventTypeByte; } event->midiCommand = eventTypeByte; event->param1 = param1; event->param2 = 0xff; // don't transmit this value switch (eventTypeByte & 0xf0) { case 0x80: // note off event->param2 = int(*dataStart++); return event; case 0x90: // note on event->param2 = int(*dataStart++); // velocity return event; case 0xa0: // after touch event->param2 = int(*dataStart++); // amount return event; case 0xb0: // controller event->param2 = int(*dataStart++); // amount return event; case 0xc0: // program change return event; case 0xd0: // channel after touch return event; case 0xe0: // pitch bend event->param2 = int(*dataStart++); return event; default: throw "Unrecognised MIDI event type"; } } throw "Unparsed event"; }
ReadData* BinTreeNodeReader::readString(int token) { if (token == -1) throw WAException("-1 token in readString", WAException::CORRUPT_STREAM_EX, -1); int bSize; ReadData *ret = new ReadData(); if (token > 2 && token <= 236) { if (token != 236) ret->data = new std::string(dictionary[token]); else { token = readInt8(this->in); ret->data = new std::string(extended_dict[token]); } ret->type = STRING; return ret; } switch (token) { case 0: delete ret; return NULL; case 252: bSize = readInt8(this->in); { std::vector<unsigned char>* buf8 = new std::vector<unsigned char>(bSize); fillArray(*buf8, bSize, this->in); ret->type = ARRAY; ret->data = buf8; } return ret; case 253: bSize = readInt24(this->in); { std::vector<unsigned char>* buf24 = new std::vector<unsigned char>(bSize); fillArray(*buf24, bSize, this->in); ret->type = ARRAY; ret->data = buf24; } return ret; case 255: bSize = readInt8(this->in); { int size = bSize & 0x7f; int numnibbles = size * 2 - ((bSize & 0x80) ? 1 : 0); std::vector<unsigned char> tmp(size); fillArray(tmp, size, this->in); std::string s; for (int i = 0; i < numnibbles; i++) { char c = (tmp[i / 2] >> (4 - ((i & 1) << 2))) & 0xF; if (c < 10) s += (c + '0'); else s += (c - 10 + '-'); } ret->type = STRING; ret->data = new std::string(s); } return ret; case 250: std::string* user = readStringAsString(); std::string* server = readStringAsString(); if ((user != NULL) && (server != NULL)) { std::string* result = new std::string(*user + "@" + *server); delete user; delete server; ret->type = STRING; ret->data = result; return ret; } if (server != NULL) { ret->type = STRING; ret->data = server; return ret; } throw WAException("readString couldn't reconstruct jid", WAException::CORRUPT_STREAM_EX, -1); } throw WAException("readString couldn't match token" + (int)token, WAException::CORRUPT_STREAM_EX, -1); }
bool BinTreeNodeReader::readString(int token, QByteArray& s) { if (token == -1) { throw ProtocolException("-1 token in readString."); } if (token > 0 && token < 0xf5) return getToken(token, s); QByteArray user,server; bool usr, srv; //no default value. switch (token) { case 0: return false; case 0xfc: quint8 size8; if (!readInt8(size8)) return false; return fillArray(s,size8); case 0xfd: qint32 size24; if (!readInt24(size24)) return false; return fillArray(s,size24); case 0xfe: quint8 token8; if (!readInt8(token8)) return false; return getToken(0xf5 + token8, s); case 0xfa: usr = readString(user); srv = readString(server); if (usr & srv) { s = user + "@" + server; return true; } if (srv) { s = server; return true; } throw ProtocolException("readString couldn't reconstruct jid."); case 0xff: { quint8 nbyte; if (!readInt8(nbyte)) return false; int size = nbyte & 0x7f; int numnibbles = size * 2 - ((nbyte & 0x80) ? 1 : 0); QByteArray res; if (!fillArray(res, size)) return false; res = res.toHex().left(numnibbles); res = res.replace('a', '-').replace('b', '.'); s = res; return true; } } throw ProtocolException("readString invalid token " + QString::number(token)); }