Merge branch 'development' into LTS_development

This commit is contained in:
Thulinma 2017-02-02 11:30:05 +01:00
commit 28106cf396
5 changed files with 116 additions and 37 deletions

View file

@ -162,9 +162,34 @@ static inline char hex2c(char c) {
return '0'; return '0';
} }
static std::string UTF8(uint32_t c){
std::string r;
if (c <= 0x7F){
r.append(1, c);
return r;
}
if (c <= 0x7FF){
r.append(1, 0xC0 | (c >> 6));
r.append(1, 0x80 | (c & 0x3F));
return r;
}
if (c <= 0x7FF){
r.append(1, 0xC0 | (c >> 12));
r.append(1, 0x80 | ((c >> 6) & 0x3F));
r.append(1, 0x80 | (c & 0x3F));
return r;
}
r.append(1, 0xC0 | (c >> 18));
r.append(1, 0x80 | ((c >> 12) & 0x3F));
r.append(1, 0x80 | ((c >> 6) & 0x3F));
r.append(1, 0x80 | (c & 0x3F));
return r;
}
static std::string read_string(int separator, std::istream & fromstream) { static std::string read_string(int separator, std::istream & fromstream) {
std::string out; std::string out;
bool escaped = false; bool escaped = false;
uint32_t fullChar = 0;
while (fromstream.good()) { while (fromstream.good()) {
char c; char c;
fromstream.get(c); fromstream.get(c);
@ -173,6 +198,10 @@ static std::string read_string(int separator, std::istream & fromstream) {
continue; continue;
} }
if (escaped) { if (escaped) {
if (fullChar && c != 'u'){
out += UTF8(fullChar >> 16);
fullChar = 0;
}
switch (c) { switch (c) {
case 'b': case 'b':
out += '\b'; out += '\b';
@ -189,15 +218,32 @@ static std::string read_string(int separator, std::istream & fromstream) {
case 't': case 't':
out += '\t'; out += '\t';
break; break;
case 'x':
char d1, d2;
fromstream.get(d1);
fromstream.get(d2);
out.append(1, (c2hex(d2) + (c2hex(d1) << 4)));
break;
case 'u': { case 'u': {
char d1, d2, d3, d4; char d1, d2, d3, d4;
fromstream.get(d1); fromstream.get(d1);
fromstream.get(d2); fromstream.get(d2);
fromstream.get(d3); fromstream.get(d3);
fromstream.get(d4); fromstream.get(d4);
out.append(1, (c2hex(d4) + (c2hex(d3) << 4))); uint32_t tmpChar = (c2hex(d4) + (c2hex(d3) << 4) + (c2hex(d2) << 8) + (c2hex(d1) << 16));
//We ignore the upper two characters. if (fullChar && (tmpChar < 0xDC00 || tmpChar > 0xDFFF)){
// + (c2hex(d2) << 8) + (c2hex(d1) << 16) //not a low surrogate - handle high surrogate separately!
out += UTF8(fullChar >> 16);
fullChar = 0;
}
fullChar |= tmpChar;
if (fullChar >= 0xD800 && fullChar <= 0xDBFF){
//possibly high surrogate! Read next characters before handling...
fullChar <<= 16;//save as high surrogate
}else{
out += UTF8(fullChar);
fullChar = 0;
}
break; break;
} }
default: default:
@ -206,6 +252,10 @@ static std::string read_string(int separator, std::istream & fromstream) {
} }
escaped = false; escaped = false;
} else { } else {
if (fullChar){
out += UTF8(fullChar >> 16);
fullChar = 0;
}
if (c == separator) { if (c == separator) {
return out; return out;
} else { } else {
@ -213,13 +263,32 @@ static std::string read_string(int separator, std::istream & fromstream) {
} }
} }
} }
if (fullChar){
out += UTF8(fullChar >> 16);
fullChar = 0;
}
return out; return out;
} }
static std::string UTF16(uint32_t c){
if (c > 0xFFFF){
c -= 0x010000;
return UTF16(0xD800 + ((c >> 10) & 0x3FF)) + UTF16(0xDC00 + (c & 0x3FF));
}else{
std::string ret = "\\u";
ret += hex2c((c >> 12) & 0xf);
ret += hex2c((c >> 8) & 0xf);
ret += hex2c((c >> 4) & 0xf);
ret += hex2c(c & 0xf);
return ret;
}
}
static std::string string_escape(const std::string val) { static std::string string_escape(const std::string val) {
std::string out = "\""; std::string out = "\"";
for (unsigned int i = 0; i < val.size(); ++i) { for (unsigned int i = 0; i < val.size(); ++i) {
switch (val.data()[i]) { const char & c = val.data()[i];
switch (c) {
case '"': case '"':
out += "\\\""; out += "\\\"";
break; break;
@ -242,7 +311,35 @@ static std::string string_escape(const std::string val) {
out += "\\t"; out += "\\t";
break; break;
default: default:
if (val.data()[i] < 32 || val.data()[i] > 126) { if (c < 32 || c > 126) {
//we assume our data is UTF-8 encoded internally.
//JavaScript expects UTF-16, so if we recognize a valid UTF-8 sequence, we turn it into UTF-16 for JavaScript.
//Anything else is escaped as a single character UTF-16 escape.
if ((c & 0xC0) == 0xC0){
//possible UTF-8 sequence
//check for 2-byte sequence
if (((c & 0xE0) == 0XC0) && (i+1 < val.size()) && ((val.data()[i+1] & 0xC0) == 0x80)){
//valid 2-byte sequence
out += UTF16(((c & 0x1F) << 6) | (val.data()[i+1] & 0x3F));
i += 1;
break;
}
//check for 3-byte sequence
if (((c & 0xF0) == 0XE0) && (i+2 < val.size()) && ((val.data()[i+1] & 0xC0) == 0x80) && ((val.data()[i+2] & 0xC0) == 0x80)){
//valid 3-byte sequence
out += UTF16(((c & 0x1F) << 12) | ((val.data()[i+1] & 0x3F) << 6) | (val.data()[i+2] & 0x3F));
i += 2;
break;
}
//check for 4-byte sequence
if (((c & 0xF8) == 0XF0) && (i+3 < val.size()) && ((val.data()[i+1] & 0xC0) == 0x80) && ((val.data()[i+2] & 0xC0) == 0x80) && ((val.data()[i+3] & 0xC0) == 0x80)){
//valid 4-byte sequence
out += UTF16(((c & 0x1F) << 18) | ((val.data()[i+1] & 0x3F) << 12) | ((val.data()[i+2] & 0x3F) << 6) | (val.data()[i+3] & 0x3F));
i += 3;
break;
}
}
//Anything else, we encode as a single UTF-16 character.
out += "\\u00"; out += "\\u00";
out += hex2c((val.data()[i] >> 4) & 0xf); out += hex2c((val.data()[i] >> 4) & 0xf);
out += hex2c(val.data()[i] & 0xf); out += hex2c(val.data()[i] & 0xf);

View file

@ -237,6 +237,14 @@ void Socket::Connection::resetCounter(){
down = 0; down = 0;
} }
void Socket::Connection::addUp(const uint32_t i){
up += i;
}
void Socket::Connection::addDown(const uint32_t i){
down += i;
}
/// Internally used call to make an file descriptor blocking or not. /// Internally used call to make an file descriptor blocking or not.
void setFDBlocking(int FD, bool blocking){ void setFDBlocking(int FD, bool blocking){
int flags = fcntl(FD, F_GETFL, 0); int flags = fcntl(FD, F_GETFL, 0);

View file

@ -94,6 +94,8 @@ namespace Socket{
uint64_t dataUp(); ///< Returns total amount of bytes sent. uint64_t dataUp(); ///< Returns total amount of bytes sent.
uint64_t dataDown(); ///< Returns total amount of bytes received. uint64_t dataDown(); ///< Returns total amount of bytes received.
void resetCounter(); ///< Resets the up/down bytes counter to zero. void resetCounter(); ///< Resets the up/down bytes counter to zero.
void addUp(const uint32_t i);
void addDown(const uint32_t i);
std::string getStats(std::string C); ///< Returns a std::string of stats, ended by a newline. std::string getStats(std::string C); ///< Returns a std::string of stats, ended by a newline.
friend class Server; friend class Server;
bool Error; ///< Set to true if a socket error happened. bool Error; ///< Set to true if a socket error happened.

View file

@ -459,39 +459,11 @@ namespace Mist{
selected << (*it); selected << (*it);
} }
} }
DEBUG_MSG(DLVL_MEDIUM, "Selected tracks: %s (%lu)", selected.str().c_str(), selectedTracks.size()); MEDIUM_MSG("Selected tracks: %s (%lu)", selected.str().c_str(), selectedTracks.size());
} }
if (selectedTracks.size() == 0){ if (!selectedTracks.size() && myMeta.tracks.size()){
INSANE_MSG("We didn't find any tracks which that we can use. selectedTrack.size() is 0."); WARN_MSG("No tracks selected (%u total) for stream %s!", myMeta.tracks.size(), streamName.c_str());
for (std::map<unsigned int,DTSC::Track>::iterator trit = myMeta.tracks.begin(); trit != myMeta.tracks.end(); trit++){
INSANE_MSG("Found track/codec: %s", trit->second.codec.c_str());
}
static std::string source;
if (!myMeta.tracks.size() && !source.size()){
IPC::sharedPage serverCfg(SHM_CONF, DEFAULT_CONF_PAGE_SIZE, false, false); ///< Contains server configuration and capabilities
IPC::semaphore configLock(SEM_CONF, O_CREAT | O_RDWR, ACCESSPERMS, 1);
configLock.wait();
std::string smp = streamName.substr(0, streamName.find_first_of("+ "));
//check if smp (everything before + or space) exists
DTSC::Scan streamCfg = DTSC::Scan(serverCfg.mapped, serverCfg.len).getMember("streams").getMember(smp);
if (streamCfg){
source = streamCfg.getMember("source").asString();
}
configLock.post();
configLock.close();
}
if (!myMeta.tracks.size() && (source.find("dtsc://") == 0)){
//Wait 5 seconds and try again. Keep a counter, try at most 3 times
static int counter = 0;
if (counter++ < 10){
Util::wait(1000);
nProxy.userClient.keepAlive();
stats();
updateMeta();
selectDefaultTracks();
}
}
} }
} }

View file

@ -26,7 +26,7 @@ namespace Mist {
void parseChunk(Socket::Buffer & inputBuffer); void parseChunk(Socket::Buffer & inputBuffer);
void parseAMFCommand(AMF::Object & amfData, int messageType, int streamId); void parseAMFCommand(AMF::Object & amfData, int messageType, int streamId);
void sendCommand(AMF::Object & amfReply, int messageType, int streamId); void sendCommand(AMF::Object & amfReply, int messageType, int streamId);
virtual std::string getStatsName(); std::string getStatsName();
}; };
} }