virtual void serviceRequest( HttpRequest* request, HttpResponse* response) { // get length param from value after root path, else 0 const char* path = request->getHeader()->getPath(); Url url(path); DynamicObject tokens; url.getTokenizedPath(tokens, mPath.c_str()); int len = 0; if(tokens->length() > 0) { len = tokens[0]->getInt32(); } // send 200 OK response->getHeader()->setStatus(200, "OK"); if(mChunked) { response->getHeader()->setField("Transfer-Encoding", "chunked"); } else { response->getHeader()->setField("Content-Length", len); } response->getHeader()->setField("Content-Type", "text/plain"); response->getHeader()->setField("Connection", "close"); response->sendHeader(); // send const bytes of a specified length ConstByteInputStream cbis(len, mBuffer, mBufsize); response->sendBody(&cbis, NULL); mPingPong->service(len); }
bool SampleService::sendPlayList(BtpAction* action, DynamicObject& fileInfos) { bool rval = false; if(fileInfos->length() > 0) { // FIXME: only support for m3u play lists at this time // FIXME: use query param to select other playlist formats rval = sendm3u(action, fileInfos); } return rval; }
static bool _setDecodedParam( Statement* s, unsigned int index, DynamicObject& param, DynamicObject& value) { bool rval = true; if(param->hasMember("encode")) { // FIXME: could use streams here and handle types other than string, // but the DatabaseClient API might be abandoned before this actually // ever really gets used to that extent // fill byte buffer with initial data ByteBuffer b; b.put(value->getString(), value->length(), true); // apply each decoding // FIXME: optimize this by doing it once and storing it when // defining the schema DynamicObject decode = param["encode"].clone(); decode->reverse(); DynamicObjectIterator i = decode.getIterator(); while(rval && i->hasNext()) { const char* type = i->next()->getString(); // convert hex to binary if(strcmp(type, "hex") == 0) { const char* hex = b.bytes(); unsigned int len = b.length(); unsigned int binLen = (len >> 1) + 1; char bin[binLen]; rval = Convert::hexToBytes(hex, len, bin, binLen); if(rval) { b.clear(); b.put(bin, binLen, true); } } } // only blobs are supported at the moment rval = rval && s->setBlob(index, b.bytes(), b.length()); }
bool SampleService::getSampleMedia( BtpAction* action, DynamicObject& in, DynamicObject& out) { bool rval; DynamicObject fileInfos; rval = getFileInfos(action, in, out, fileInfos); if(rval) { // send the sample file if only one // FIXME: Does it make sense to send sample of first fileinfo? // FIXME: Is first sample representative of a collection? if(fileInfos->length() == 1) { FileInfo& fi = fileInfos[0]; rval = getSampleFileByIds(action, in, out, BM_MEDIA_ID(fi["mediaId"]), BM_FILE_ID(fi["id"])); } } return rval; }
bool JsonLd::normalize(DynamicObject& in, DynamicObject& out) { bool rval = true; // initialize output out->setType(Map); out->clear(); // create map to store subjects DynamicObject subjects; subjects->setType(Map); // initialize context DynamicObject ctx(NULL); if(in->hasMember("#")) { ctx = in["#"]; } // put all subjects in an array for single code path DynamicObject input; input->setType(Array); if(in->hasMember("@") && in["@"]->getType() == Array) { input.merge(in["@"], true); } else { input->append(in); } // do normalization int bnodeId = 0; DynamicObjectIterator i = input.getIterator(); while(rval && i->hasNext()) { rval = _normalize(ctx, i->next(), &subjects, NULL, bnodeId); } // build output if(rval) { // single subject if(subjects->length() == 1) { DynamicObject subject = subjects.first(); out.merge(subject, false); // FIXME: will need to check predicates for blank nodes as well... // and fail if they aren't embeds? // strip blank node '@' if(_isBlankNode(out)) { out->removeMember("@"); } } // multiple subjects else { DynamicObject& array = out["@"]; array->setType(Array); i = subjects.getIterator(); while(i->hasNext()) { DynamicObject& next = i->next(); // FIXME: will need to check predicates for blank nodes as well... // and fail if they aren't embeds? // strip blank node '@' if(_isBlankNode(next)) { next->removeMember("@"); } array->append(next); } } } return rval; }
bool JsonWriter::write(DynamicObject& dyno, OutputStream* os, int level) { bool rval = true; if(level < 0) { level = mIndentLevel; } if(dyno.isNull()) { rval = os->write("null", 4); } else { switch(dyno->getType()) { case String: { const char* temp = dyno->getString(); size_t length = strlen(temp); // Note: UTF-8 has a maximum of 6-bytes per character when // encoded in json format ("\u1234") string encoded; encoded.reserve(length); encoded.push_back('"'); char unicode[6]; for(size_t i = 0; i < length; ++i) { unsigned char c = temp[i]; if((c >= 0x5d /* && c <= 0x10FFFF */) || (c >= 0x23 && c <= 0x5B) || (c == 0x21) || (c == 0x20)) { // TODO: check this handles UTF-* properly encoded.push_back(c); } else { encoded.push_back('\\'); switch(c) { case '"': /* 0x22 */ case '\\': /* 0x5C */ // '/' is in the RFC but not required to be escaped //case '/': /* 0x2F */ encoded.push_back(c); break; case '\b': /* 0x08 */ encoded.push_back('b'); break; case '\f': /* 0x0C */ encoded.push_back('f'); break; case '\n': /* 0x0A */ encoded.push_back('n'); break; case '\r': /* 0x0D */ encoded.push_back('r'); break; case '\t': /* 0x09 */ encoded.push_back('t'); break; default: // produces "u01af" (4 digits of 0-filled hex) snprintf(unicode, 6, "u%04x", c); encoded.append(unicode, 5); break; } } } // end string serialization and write encoded string encoded.push_back('"'); rval = os->write(encoded.c_str(), encoded.length()); break; } case Boolean: case Int32: case UInt32: case Int64: case UInt64: case Double: { const char* temp = dyno->getString(); rval = os->write(temp, strlen(temp)); break; } case Map: { // start map serialization rval = (mCompact || dyno->length() == 0) ? os->write("{", 1) : os->write("{\n", 2); // serialize each map member DynamicObjectIterator i = dyno.getIterator(); while(rval && i->hasNext()) { DynamicObject& next = i->next(); // serialize indentation and start serializing member name if((rval = writeIndentation(os, level + 1) && os->write("\"", 1) && os->write(i->getName(), strlen(i->getName())))) { // end serializing member name, serialize member value rval = ((mCompact) ? os->write("\":", 2) : os->write("\": ", 3)) && write(next, os, level + 1); // serialize delimiter if appropriate if(rval && i->hasNext()) { rval = os->write(",", 1); } // add formatting if appropriate if(rval && !mCompact) { rval = os->write("\n", 1); } } } // end map serialization if(dyno->length() > 0) { rval = rval && writeIndentation(os, level); } rval = rval && os->write("}", 1); break; } case Array: { // start array serialization rval = (mCompact || dyno->length() == 0) ? os->write("[", 1) : os->write("[\n", 2); // serialize each array element DynamicObjectIterator i = dyno.getIterator(); while(rval && i->hasNext()) { // serialize indentation and array value rval = writeIndentation(os, level + 1) && write(i->next(), os, level + 1); // serialize delimiter if appropriate if(rval && i->hasNext()) { rval = os->write(",", 1); } // add formatting if appropriate if(rval && !mCompact) { rval = os->write("\n", 1); } } // end array serialization if(dyno->length() > 0) { rval = rval && writeIndentation(os, level); } rval = rval && os->write("]", 1); break; } } } return rval; }