// hook from javascript into the CPP code. void MoonlightInstance::HandleMessage(const pp::Var& var_message) { // Ignore the message if it is not a string. if (!var_message.is_dictionary()) return; pp::VarDictionary msg(var_message); int32_t callbackId = msg.Get("callbackId").AsInt(); std::string method = msg.Get("method").AsString(); pp::VarArray params(msg.Get("params")); if (strcmp(method.c_str(), MSG_START_REQUEST) == 0) { HandleStartStream(callbackId, params); } else if (strcmp(method.c_str(), MSG_STOP_REQUEST) == 0) { HandleStopStream(callbackId, params); } else if (strcmp(method.c_str(), MSG_OPENURL) == 0) { HandleOpenURL(callbackId, params); } else if (strcmp(method.c_str(), "httpInit") == 0) { NvHTTPInit(callbackId, params); } else if (strcmp(method.c_str(), "makeCert") == 0) { MakeCert(callbackId, params); } else if (strcmp(method.c_str(), "pair") == 0) { HandlePair(callbackId, params); } else { pp::Var response("Unhandled message received: " + method); PostMessage(response); } }
virtual void HandleMessage(const pp::Var& var_message) { if (!var_message.is_dictionary ()) { return; } pp::VarDictionary::VarDictionary dic = pp::VarDictionary::VarDictionary (var_message); pp::Var s_rgba= dic.Get("rgba"); pp::Var s_width = dic.Get("width"); pp::Var s_height = dic.Get("height"); pp::Var s_quality= dic.Get("quality"); pp::Var id = dic.Get("id"); if (!s_rgba.is_array_buffer()) { PostMessage(ErrorMsg("ArrayBuffer no find")); return; } if( !s_width.is_int ()) { PostMessage(ErrorMsg("width is not int")); return; } int width = s_width.AsInt (); if (!s_height.is_int ()) { PostMessage(ErrorMsg("height is not int")); return; } int height = s_height.AsInt (); double quality = 80.0f; bool lossless = false; if (s_quality.is_string()) { if (s_quality.AsString() == "lossless") { lossless = true; } }else if (s_quality.is_number()) { double q = s_quality.AsDouble(); if (q <= 100.0 && q >= 0 ) { quality = (float)q; } } std::unique_ptr<pp::VarArrayBuffer::VarArrayBuffer> array_buffer_var(new pp::VarArrayBuffer::VarArrayBuffer(s_rgba)); uint8_t* data = static_cast<uint8_t *>(array_buffer_var->Map()); int byte_length = static_cast<int>(array_buffer_var->ByteLength()); if (byte_length != (width * height * 4)) { PostMessage(ErrorMsg("ArrayBuffer length error :"+ std::to_string(byte_length))); return; } std::shared_ptr<uint8_t> outdata(new uint8_t[byte_length]()); uint8_t * r_outdata = outdata.get(); size_t ret; if (lossless) { ret = WebPEncodeLosslessRGBA(data,width,height,width*4,&r_outdata); }else{ ret = WebPEncodeRGBA(data,width,height,width*4,quality,&r_outdata); } if (ret == 0) { PostMessage(ErrorMsg("encoder error ")); return; } pp::VarArrayBuffer::VarArrayBuffer data_value = pp::VarArrayBuffer::VarArrayBuffer (ret); uint8_t* r_data_value = static_cast<uint8_t*>(data_value.Map()); for (uint32_t i = 0; i < ret; ++i) { r_data_value[i] = r_outdata[i]; } data_value.Unmap(); pp::VarDictionary::VarDictionary ret_msg = pp::VarDictionary::VarDictionary (); pp::Var id_key = pp::Var::Var("id"); ret_msg.Set (id_key,id); pp::Var data_key = pp::Var::Var("data"); ret_msg.Set (data_key,data_value); PostMessage(ret_msg); }
virtual void dosomething(const pp::Var& var_message) { // std::cout << "HandleMessage... " << std::endl; int point_size(0); // printf( "handler thread id '%p'\n", pthread_self()); pp::VarDictionary dict; pp::Var command_name; if (var_message.is_dictionary()) { dict = pp::VarDictionary(var_message); if (!dict.HasKey("command")) { PostError("broker", "message JSON provided no 'command' member!", "null"); return; } command_name = dict.Get("command"); } else { PostError("broker", "No dictionary object was provided!", "null"); return; } if (!dict.HasKey("id")) { PostError("broker", "message JSON provided no 'id' member!", "null"); return; } if (!dict.Get("id").is_string()) { PostError("broker", "'id' member is not a string!", "null"); return; } std::string id = dict.Get("id").AsString(); if (boost::iequals(command_name.AsString(), "open")) { bool opened = open(var_message); if (!opened) { PostError("open","Unable to open file", id); return; } PostSuccess("open", pp::Var(pp::Var::Null()), id, "File opened successfully"); return; // open has set any errors } if (boost::iequals(command_name.AsString(), "close")) { int res = fclose(fp_); if (res) { std::ostringstream errors; errors << "fclose returned message " << res << " error: '" << strerror(errno) <<"'"; PostError("close", errors.str(), id); return; } header_ = LASHeader(); zip_ = LASzip(); unzipper_ = LASunzipper(); fp_ = NULL; bDidReadHeader_ = 0; pointIndex_ = 0; delete[] point_; point_ = 0; delete[] bytes_; bytes_ = 0; delete buffer_; buffer_ = 0; PostSuccess("close", pp::Var(pp::Var::Null()), id, "File closed successfully"); return; // close has set any errors } if (boost::iequals(command_name.AsString(), "getheader")) { if (!fp_) { PostError("broker", "No file is open!", id); return; } bDidReadHeader_ = readHeader(header_, var_message); if (!bDidReadHeader_) { PostError("getheader", "Header read failed!", id); return; } PostSuccess("getheader", header_.AsVar(), id, "Header read successful"); return; } // std::ostringstream errors; if (boost::iequals(command_name.AsString(), "read")) { if (!fp_) { PostError("read", "No file is open!", id); return; } if (!bDidReadHeader_) { PostError("read", "No header has been fetched!", id); return; } if (pointIndex_ == header_.point_count) { PostError("read", "All done reading. 'close' and 'open' the file again", id); return; } uint32_t count(header_.point_count); if (dict.HasKey("count")) { pp::Var cnt = dict.Get("count"); if (!cnt.is_int()) { PostError("read", "'count' is not an integer object!", id); return; } count = cnt.AsInt(); // std::cout << "Fetched count as " << count << std::endl; } #define MAX_POINT_COUNT 2000000 if (count > MAX_POINT_COUNT) { std::ostringstream errors; errors << "'count' is too large, choose a smaller value"; PostError("read", errors.str(), id); return; } uint32_t skip(0); if (dict.HasKey("skip")) { pp::Var s = dict.Get("skip"); if (!s.is_int()) { PostError("read", "'skip' is not an integer object!", id); return; } skip = s.AsInt(); } uint32_t start(0); if (dict.HasKey("start")) { pp::Var st = dict.Get("start"); if (!st.is_int()) { PostError("read", "'start' is not an integer object!", id); return; } start = st.AsInt(); } uint64_t num_left = (uint64_t)header_.point_count - (uint64_t)pointIndex_; uint64_t total_bytes = (uint64_t)count * (uint64_t)header_.point_record_length; if (!buffer_) { try { buffer_ = new pp::VarArrayBuffer(total_bytes); } catch (...) { std::ostringstream error; error << "Unable to allocate buffer of size " << total_bytes << " to read " << count << " points. please try a smaller buffer size" << std::endl; PostError("read", error.str(), id); return; } // std::cout << "making new VarArrayBuffer of size" << total_bytes << std::endl; } // std::cout << "allocated buffer" << std::endl; if (buffer_->ByteLength() < total_bytes) { delete buffer_; try { buffer_ = new pp::VarArrayBuffer(total_bytes); } catch (std::bad_alloc&) { std::ostringstream error; error << "Unable to allocate buffer of size " << total_bytes << " to read " << count << " points. please try a smaller buffer size" << std::endl; PostError("read", error.str(), id); return; } // std::cout << "buffer was wrong size " << buffer_->ByteLength() << ", making new VarArrayBuffer of size" << total_bytes << std::endl; } // std::cout << "mapping buffer" << std::endl; unsigned char* array_start; try { array_start = static_cast<unsigned char*>(buffer_->Map()); } catch (std::bad_alloc&) { std::ostringstream error; error << "Unable to allocate Map of size " << total_bytes << " to read " << count << " points. please try a smaller buffer size" << std::endl; PostError("read", error.str(), id); return; } // std::cout << "skip value: " << skip << std::endl; // std::cout << "start value: " << start << std::endl; unsigned char* data = array_start; uint32_t howManyToRead(count); uint32_t howManyRead(0); bool bHasMoreData(true); int i(0); while ( howManyRead != howManyToRead) // for (int i = howManyToRead; i != 0; --i) { bool bDoKeep(false); // fills in bytes_ bool ok = unzipper_.read(point_); if (!ok) { std::ostringstream error; error << "Unable to read point at index " << i << std::endl; error << "error msg: " << unzipper_.get_error() << std::endl; PostError("read", error.str(), id); return; } if (skip != 0) { if ((skip != 0) && ((pointIndex_ + start) % skip == 0) ) { bDoKeep = true; // std::cout << "keeping " << i <<"th point" << std::endl; } else { // std::cout << "skipping " << i << "th point" << std::endl; } } else { // No skip or start is set, we copy it all bDoKeep = true; } if (start != 0) { if (pointIndex_ < start) { bDoKeep = false; // std::cout << "reskipping " << i << "th point" << std::endl; } } if (bDoKeep) // if skip is 0, just copy all the time { std::copy(bytes_, bytes_ + header_.point_record_length, data); data += header_.point_record_length; howManyRead++; // std::cout << "keeping " << i <<"th point" << std::endl; } pointIndex_++; if (pointIndex_ == header_.point_count) { bHasMoreData = false; break; } i += 1; } // std::cout << "done reading" << std::endl; pp::VarDictionary dict; dict.Set("status", true); dict.Set("hasMoreData", bHasMoreData); dict.Set("message", "Done reading data"); try { dict.Set("result", *buffer_); } catch (std::bad_alloc&) { std::ostringstream error; error << "Unable to return ArrayBuffer of size " << total_bytes << " to read " << count << " points. please try a smaller buffer size" << std::endl; PostError("read", error.str(), id); return; } // PostSuccess("read", dict, id); dict.Set("error", false); dict.Set("method", "read"); dict.Set("id", id); dict.Set("count", (int32_t)howManyRead); dict.Set("skip", (int32_t)skip); dict.Set("start", (int32_t)start); try { // std::cout << "Posting message" << std::endl; PostMessage(dict); // std::cout << "Posted message" << std::endl; } catch (std::bad_alloc&) { std::ostringstream error; error << "Unable to post ArrayBuffer of size " << total_bytes << " to read " << count << " points. please try a smaller buffer size" << std::endl; PostError("read", error.str(), id); return; } // std::cout << "posted message" << std::endl; return; // int32_t x = *(int32_t*)&start[0]; // int32_t y = *(int32_t*)&start[4]; // int32_t z = *(int32_t*)&start[8]; // // double xs = applyScaling(x, header_.scale[0], header_.offset[0]); // double ys = applyScaling(y, header_.scale[1], header_.offset[1]); // double zs = applyScaling(z, header_.scale[2], header_.offset[2]); // // std::ostringstream oss; // oss << "scale[0]: " << header_.scale[0] <<std::endl; // oss << "scale[1]: " << header_.scale[1] <<std::endl; // oss << "scale[2]: " << header_.scale[2] <<std::endl; // oss << "offset[0]: " << header_.offset[0] <<std::endl; // oss << "offset[1]: " << header_.offset[1] <<std::endl; // oss << "offset[2]: " << header_.offset[2] <<std::endl; // oss << "min[0]: " << header_.mins[0] <<std::endl; // oss << "min[1]: " << header_.mins[1] <<std::endl; // oss << "min[2]: " << header_.mins[2] <<std::endl; // oss << "max[0]: " << header_.maxs[0] <<std::endl; // oss << "max[1]: " << header_.maxs[1] <<std::endl; // oss << "max[2]: " << header_.maxs[2] <<std::endl; // // oss << "x: " << x << std::endl; // oss << "y: " << y << std::endl; // oss << "z: " << z << std::endl; // // oss << "x: " << xs << std::endl; // oss << "y: " << ys << std::endl; // oss << "z: " << zs << std::endl; // PostMessage(oss.str()); // PostMessage(header_.AsVar()); // PostMessage(status(true, "Done reading data")); // return; } PostError("broker", "Command not found", id); return; // unsigned char** point; // bool ok = unzipper_.read(point_); // if (!ok) // { // errors << "Unable to read point!" << std::endl; // errors << "error msg: " << unzipper_.get_error() << std::endl; // PostError(errors.str()); // return; // } // // int32_t x = *(int32_t*)&bytes_[0]; // int32_t y = *(int32_t*)&bytes_[4]; // int32_t z = *(int32_t*)&bytes_[8]; // // double xs = applyScaling(x, header_.scale[0], header_.offset[0]); // double ys = applyScaling(y, header_.scale[1], header_.offset[1]); // double zs = applyScaling(z, header_.scale[2], header_.offset[2]); // // std::ostringstream oss; // oss << "scale[0]: " << header_.scale[0] <<std::endl; // oss << "scale[1]: " << header_.scale[1] <<std::endl; // oss << "scale[2]: " << header_.scale[2] <<std::endl; // oss << "offset[0]: " << header_.offset[0] <<std::endl; // oss << "offset[1]: " << header_.offset[1] <<std::endl; // oss << "offset[2]: " << header_.offset[2] <<std::endl; // oss << "min[0]: " << header_.mins[0] <<std::endl; // oss << "min[1]: " << header_.mins[1] <<std::endl; // oss << "min[2]: " << header_.mins[2] <<std::endl; // oss << "max[0]: " << header_.maxs[0] <<std::endl; // oss << "max[1]: " << header_.maxs[1] <<std::endl; // oss << "max[2]: " << header_.maxs[2] <<std::endl; // // oss << "x: " << x << std::endl; // oss << "y: " << y << std::endl; // oss << "z: " << z << std::endl; // // oss << "x: " << xs << std::endl; // oss << "y: " << ys << std::endl; // oss << "z: " << zs << std::endl; // PostMessage(header_.AsVar()); }