I can look for services on the network using
std::vector<hstring> propertyKeys = std::vector<hstring>();
propertyKeys.push_back(L"System.Devices.Dnssd.HostName");
propertyKeys.push_back(L"System.Devices.IpAddress");
hstring aqsQueryString = L"System.Devices.AepService.ProtocolId:={4526e8c1-8aac-4153-9b16-55e86ada0e54} AND System.Devices.Dnssd.ServiceName:=\"_http._tcp\" AND System.Devices.Dnssd.Domain:=\"local\"";
auto watcher = DeviceInformation::CreateWatcher(aqsQueryString, propertyKeys, DeviceInformationKind::AssociationEndpointService);
I then set the Updated callback to get information about services.
watcher.Updated([](DeviceWatcher sender, DeviceInformationUpdate info) {
for(auto const& p : info.Properties()){
hstring s = unbox_value_or<hstring>(p.Value(), L""); // This unboxes the Hostname
auto ips = unbox_value_or<???>(p.Value(), ???); // How do I unbox this?
}
}
According to Microsoft Documentation the System.Devices.IpAddress is of type Multivalue String. I've tried with std::vector<hstring> but that doesn't work as the type must be a winrt type.
What type do I put to unbox a multivalue string?
I managed to solve it using Sean Kellys answer from here: Equivalent of Platform::IBoxArray in C++/WinRT
Specifically my implementation for printing the first IP looks like this:
auto prop = info.Properties();
auto ips = prop.Lookup(L"System.Devices.IpAddress").as<Windows::Foundation::IReferenceArray<hstring>>();
winrt::com_array<hstring> arr;
ips.GetStringArray(arr);
std::wcout << arr[0].c_str() << std::endl;
Related
I'm looking to extract form data utilizing textract. I've tested with a PDF in the demo and results are great. Results using the SDK however are far from optimal, actually, completely inaccurate. If I use StartDocumentAnalysisRequest/StartDocumentAnalysisResult (asynchronous), I only get 1 block returned of type PAGE, never KEY_VALUE_SET. If I convert my PDF to an image and use the synchronous methods, I do get KEY_VALUE_SET back but results are completely inaccurate.
Does anyone know how I can utilize the asynchronous analysis functionality to retrieve form values as the documentation indicates?
Sample Code below:
StartDocumentAnalysisResult startDocumentAnalysisResult = amazonTextract.startDocumentAnalysis(req);
String startJobId = startDocumentAnalysisResult.getJobId();
GetDocumentAnalysisResult documentAnalysisResult = null;
String jobStatus = "IN_PROGRESS";
while (jobStatus.equals("IN_PROGRESS")) {
try {
TimeUnit.SECONDS.sleep(10);
GetDocumentAnalysisRequest documentAnalysisRequest = new GetDocumentAnalysisRequest()
.withJobId(startJobId)
.withMaxResults(1);
documentAnalysisResult = amazonTextract.getDocumentAnalysis(documentAnalysisRequest);
jobStatus = documentAnalysisResult.getJobStatus();
} catch (Exception e) {
logger.error(e);
}
}
if (!jobStatus.equals("IN_PROGRESS")) {
List<Block> blocks = documentAnalysisResult.getBlocks();
logger.error("block list size " + blocks.size());
Map<String, Map<String, Block>> keyValueBlockMap = new HashMap<>();
Map<String, Block> keyMap = new HashMap<>();
Map<String, Block> valueMap = new HashMap<>();
Map<String, Block> blockMap = new HashMap<>();
for (Block block : blocks) {
logger.error("Block Type:" + block.getBlockType());
String blockId = block.getId();
blockMap.put(blockId, block);
if (block.getBlockType().equals("KEY_VALUE_SET")) {
if (block.getEntityTypes().contains("KEY")) {
keyMap.put(blockId, block);
} else {
valueMap.put(blockId, block);
}
}
}
keyValueBlockMap.put("keyMap", keyMap);
keyValueBlockMap.put("valueMap", valueMap);
keyValueBlockMap.put("blockMap", blockMap);
Map<String, String> keyValueRelationShip = getKeyValueRelationShip(keyValueBlockMap);
for (String key : keyValueRelationShip.keySet()) {
logger.error("Key: " + key);
logger.error("Value: " + keyValueRelationShip.get(key));
}
}
Synchronous path which results in completely horrible results:
AnalyzeDocumentRequest request = new AnalyzeDocumentRequest() .withFeatureTypes(FeatureType.FORMS) .withDocument(new Document(). withS3Object(new com.amazonaws.services.textract.model.S3Object() .withName(objectName) .withBucket(awsHelper.getS3BucketName())));
AnalyzeDocumentResult result = amazonTextract.analyzeDocument(request);
You are not using the recommended version for the AWS SDK for Java. You are using a old version and not the recommended one.
I have tested the AWS SDK for Java V2 and I am able to get lines and text that lines up with the AWS Management Console.
You can find textTract V2 examples in the repo linked above.
I am able to get to lines and the corresponding text by using software.amazon.awssdk.services.textract.TextractClient.
For example when i debug through the code using the same PNG as I used in the console, i get the proper result.
I am working on a UWP app that depends on available storage space, and would like to have that information prior to a save fail. I have tried the RetrievePropertiesAsync calls on the known folders, but do not get a Freespace or Capacity property in the resultant list. Is there a method available for this?
Code used to access properties:
auto basicProperties = co_await videosFolder->GetBasicPropertiesAsync();
auto retrievedProperties = co_await basicProperties->RetrievePropertiesAsync(propertiesToRetrieve);
unsigned long freeSpace = retrievedProperties->Size;
auto it = retrievedProperties->First();
bool validData = (it != nullptr);
while (validData)
{
String^ text = it->Current->Key;
validData = it->MoveNext();
}
Is it possible to obtain the string equivalent of protobuf enums in C++?
e.g.:
The following is the message description:
package MyPackage;
message MyMessage
{
enum RequestType
{
Login = 0;
Logout = 1;
}
optional RequestType requestType = 1;
}
In my code I wish to do something like this:
MyMessage::RequestType requestType = MyMessage::RequestType::Login;
// requestTypeString will be "Login"
std::string requestTypeString = ProtobufEnumToString(requestType);
The EnumDescriptor and EnumValueDescriptor classes can be used for this kind of manipulation, and the
the generated .pb.h and .pb.cc names are easy enough to read, so you can look through them to get details on the functions they offer.
In this particular case, the following should work (untested):
std::string requestTypeString = MyMessage_RequestType_Name(requestType);
See the answer of Josh Kelley, use the EnumDescriptor and EnumValueDescriptor.
The EnumDescriptor documentation says:
To get a EnumDescriptor
To get the EnumDescriptor for a generated enum type, call
TypeName_descriptor(). Use DescriptorPool to construct your own
descriptors.
To get the string value, use FindValueByNumber(int number)
const EnumValueDescriptor * EnumDescriptor::FindValueByNumber(int number) const
Looks up a value by number.
Returns NULL if no such value exists. If multiple values have this >number,the first one defined is returned.
Example, get the protobuf enum:
enum UserStatus {
AWAY = 0;
ONLINE = 1;
OFFLINE = 2;
}
The code to read the string name from a value and the value from a string name:
const google::protobuf::EnumDescriptor *descriptor = UserStatus_descriptor();
std::string name = descriptor->FindValueByNumber(UserStatus::ONLINE)->name();
int number = descriptor->FindValueByName("ONLINE")->number();
std::cout << "Enum name: " << name << std::endl;
std::cout << "Enum number: " << number << std::endl;
I am trying to update a record in one of my Azure Mobile tables using the “update” function in the azure mobile C++ header. But I get an exception. Below is what my code looks like:
void DBUtils::DBQuestion::UpdateQuestionInTable(std::shared_ptr<azure::mobile::table> table)
{
auto obj = json::value::object();
obj[U("id")] = json::value::string(ID);
obj[U("QuestionText")] = json::value::string(QuestionText);
obj[U("AnswerLatitude")] = json::value::number(AnswerLatitude);
obj[U("AnswerLongitude")] = json::value::number(AnswerLongitude);
table->update(obj);
}
I have verified that the ID above is a valid one actually present in the table. A similar insert operation (which doesn’t specify the ID field) actually succeeds:
void DBUtils::DBQuestion::InsertIntoTable(std::shared_ptr<azure::mobile::table> table)
{
auto obj = json::value::object();
obj[U("QuestionText")] = json::value::string(QuestionText);
obj[U("AnswerLatitude")] = json::value::number(AnswerLatitude);
obj[U("AnswerLongitude")] = json::value::number(AnswerLongitude);
table->insert(obj);
}
What am I doing wrong?
Azure Mobile recently updated its table schema so that the Id field is now a string, which gets filled in by the server with a Guid value if the client doesn’t set it.
This change has introduced a bug in the C++ library. As a workaround, you can try calling the other overload for update, the one that takes the ID string and the object.
void DBUtils::DBQuestion::UpdateQuestionInTable(utility::string_t id, std::shared_ptr<azure::mobile::table> table)
{
auto obj = json::value::object();
obj[U("QuestionText")] = json::value::string(QuestionText);
obj[U("AnswerLatitude")] = json::value::number(AnswerLatitude);
obj[U("AnswerLongitude")] = json::value::number(AnswerLongitude);
ID = id;
table->update(ID, obj);
}
I have created a class and published it as web service. I have created a web method like this:
public void addNewRow(MyObject cob) {
MyAppModule myAppModule = new MyAppModule();
try {
ViewObjectImpl vo = myAppModule.getMyVewObject1();
================> vo object is now null
Row r = vo.createRow();
r.setAttribute("Param1", cob.getParam1());
r.setAttribute("Param2", cob.getParam2());
vo.executeQuery();
getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
}
}
As I have written in code, myAppModule.getMyVewObject1() returns a null object. I do not understand why! As far as I know AppModule has to initialize the object by itself when I call "getMyVewObject1()" but maybe I am wrong, or maybe this is not the way it should be for web methods. Has anyone ever faced this issue? Any help would be very appreciated.
You can check nice tutorial: Building and Using Web Services with JDeveloper
It gives you general idea about how you should build your webservices with ADF.
Another approach is when you need to call existing Application Module from some bean that doesn't have needed environment (servlet, etc), then you can initialize it like this:
String appModuleName = "org.my.package.name.model.AppModule";
String appModuleConfig = "AppModuleLocal";
ApplicationModule am = Configuration.createRootApplicationModule(appModuleName, appModuleConfig);
Don't forget to release it:
Configuration.releaseRootApplicationModule(am, true);
And why you shouldn't really do it like this.
And even more...
Better aproach is to get access to binding layer and do call from there.
Here is a nice article.
Per Our PM : If you don't use it in the context of an ADF application then the following code should be used (sample code is from a project I am involved in). Note the release of the AM at the end of the request
#WebService(serviceName = "LightViewerSoapService")
public class LightViewerSoapService {
private final String amDef = " oracle.demo.lightbox.model.viewer.soap.services.LightBoxViewerService";
private final String config = "LightBoxViewerServiceLocal";
LightBoxViewerServiceImpl service;
public LightViewerSoapService() {
super();
}
#WebMethod
public List<Presentations> getAllUserPresentations(#WebParam(name = "userId") Long userId){
ArrayList<Presentations> al = new ArrayList<Presentations>();
service = (LightBoxViewerServiceImpl)getApplicationModule(amDef,config);
ViewObject vo = service.findViewObject("UserOwnedPresentations");
VariableValueManager vm = vo.ensureVariableManager();
vm.setVariableValue("userIdVariable", userId.toString());
vo.applyViewCriteria(vo.getViewCriteriaManager().getViewCriteria("byUserIdViewCriteria"));
Row rw = vo.first();
if(rw != null){
Presentations p = createPresentationFromRow(rw);
al.add(p);
while(vo.hasNext()){
rw = vo.next();
p = createPresentationFromRow(rw);
al.add(p);
}
}
releaseAm((ApplicationModule)service);
return al;
}
Have a look here too:
http://www.youtube.com/watch?v=jDBd3JuroMQ