Handle NULL BLOB-s in MFC - visual-c++

I have an old MFC project that I need to expand. For database operations I use a class derived from CRecordSet, and bind Oracle BLOB to CByteArray. When I retrieve a row with null blob, I get an array with size of 1 byte, and value 0xFF. Is there a way to check if a field is actually NULL in database? Or is this 0xFF array actually a value denoting a null BLOB?

OK, I found it. The function is CRecordset::IsFieldNull, the parameter is the address of bound CByteArray object, and the function can be only used between Open() and Close(). Something like this:
void CMySet::DoFieldExchange(CFieldExchange* pFX)
{
...
RFX_Binary(pFX, _T("[THE_BLOB]"), m_TheBlob, MAX_BLOB_SIZE);
}
void CMySet::ReadBlob(CByteArray& theBlob, BOOL& isNull)
{
m_strFilter = ...;
Open();
isNull = IsFieldNull(&m_TheBlob);
if (!isNull)
theBlob.Copy(m_TheBlob);
Close();
}

Related

Solidity mapping not returns an array in a struct

The Solidity's mapping not returns an array inside a struct (when call mapping_data(), the data variable is undefined).
Just be able to read it from read() function.
Does anyone know a reason?
struct structPackage
{
uint256 ui;
string[2] data;
}
// the mapping_data(address) is not includes data variable, undefined.
mapping(address => structPackage) public mapping_data;
constructor()
{
structPackage storage data_package = mapping_data[msg.sender];
data_package.data[0] = "test1";
data_package.data[1] = "test2";
}
// This function shows data as expected, [ 'test1', 'test2' ].
function read() external view
returns (structPackage memory)
{
structPackage storage data_package = mapping_data[msg.sender];
return data_package;
}
Tested on Remix, mapping_data doesn't return the array inside struct
When a struct is used as value inside a mapping, the getter function of the mapping will ignore the mappings or arrays used inside the struct, because there is no easy way to provide keys or indexes to get the specific element from array or mapping. This mechanism exists to avoid high gas costs when returning an entire array or entire mapping.
Hence, if you want to access a complete array or mapping inside a struct (which is used as a value in a mapping which is public) make separate specific getters as required(Similar to as you wrote your read method).
Read Getter Functions docs
Read a similar GitHub issue

Invoking a functions based on string name in java

I need a logic to replace the following code.
void invokeMethod(String action){
if ("echo".equals(action)) {
//call echo
echo();
}
else if ("dump".equals(action)) {
// call dump
dump();
}
... goes on
}
switch case with string parameter won't work in java 1.6.
Can I do it a better way ?
I used a java hashmap with action as key and random integer as value. Whenever perticular action is asked to invoke, fetch the integer from the hashmap and use switch case now (In above problem, string comparison was very operation, replaced the same with integers).

Configuring notification tag for Azure Function

I'm using an Azure function to pick up messages from an event hub and send out notifications via the Azure notification hub. Works great! Now I wanted to see whether I could add tags to those messages in order to allow user targeting via those tags.
The output for the notification hub has a "tag expression" parameter which you can configure. But this seems to be a static text. I need to dynamically set these tags based on the message received from the event hub instead. I'm not sure whether you can somehow put dynamic content in there?
I also found that the constructor of the GcmNotification object that I'm using has an overload which allows a tag string to be used. But when I try that I get a warning on compile time stating this is deprecated and when the function fires it shows an error because the Tag property should be empty.
So I'm not clear on a) whether this is at all possible and b) how to do it when it is. Any ideas?
Update: as suggested I tried creating a POCO object to map to my input string. The string is as follows:
[{"deviceid":"repsaj-neptune-win10pi","readingtype":"temperature1","reading":22.031614503139451,"threshold":23.0,"time":"2016-06-22T09:38:54.1900000Z"}]
The POCO object:
public class RuleMessage
{
public string deviceid;
public string readingtype;
public object reading;
public double threshold;
public DateTime time;
}
For the function I now tried both RuleMessage[] and List<RuleMessage> as parameter types, but the function complains it cannot convert the input:
2016-06-24T18:25:16.830 Exception while executing function: Functions.submerged-function-ruleout. Microsoft.Azure.WebJobs.Host: Exception binding parameter 'inputMessage'. Microsoft.Azure.WebJobs.Host: Binding parameters to complex objects (such as 'RuleMessage') uses Json.NET serialization.
1. Bind the parameter type as 'string' instead of 'RuleMessage' to get the raw values and avoid JSON deserialization, or
2. Change the queue payload to be valid json. The JSON parser failed: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Submission#0+RuleMessage' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Function code:
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Microsoft.Azure.NotificationHubs;
public static void Run(List<RuleMessage> inputEventMessage, string inputBlob, out Notification notification, out string outputBlob, TraceWriter log)
{
if (inputEventMessage == null || inputEventMessage.Count != 1)
{
log.Info($"The inputEventMessage array was null or didn't contain exactly one item.");
notification = null;
outputBlob = inputBlob;
return;
}
log.Info($"C# Event Hub trigger function processed a message: {inputEventMessage[0]}");
if (String.IsNullOrEmpty(inputBlob))
inputBlob = DateTime.MinValue.ToString();
DateTime lastEvent = DateTime.Parse(inputBlob);
TimeSpan duration = DateTime.Now - lastEvent;
if (duration.TotalMinutes >= 0) {
notification = GetGcmMessage(inputMessage.First());
log.Info($"Sending notification message: {notification.Body}");
outputBlob = DateTime.Now.ToString();
}
else {
log.Info($"Not sending notification message because of timer ({(int)duration.TotalMinutes} minutes ago).");
notification = null;
outputBlob = inputBlob;
}
}
private static Notification GetGcmMessage(RuleMessage input)
{
string message;
if (input.readingtype == "leakage")
message = String.Format("[FUNCTION GCM] Leakage detected! Sensor {0} has detected a possible leak.", input.reading);
else
message = String.Format("[FUNCTION GCM] Sensor {0} is reading {1:0.0}, threshold is {2:0.0}.", input.readingtype, input.reading, input.threshold);
message = "{\"data\":{\"message\":\""+message+"\"}}";
return new GcmNotification(message);
}
public class RuleMessage
{
public string deviceid;
public string readingtype;
public object reading;
public double threshold;
public DateTime time;
}
Update 28-6-2016: I've not managed to get it working by switching ASA output to line seperated to that it doesn't generate a JSON array any more. This is a temp. fix because the Function binding now fails as soon as there is more than one line in the output (which can happen).
Anyways, I now proceeded to set the tagExpression, as per instruction I changed it to:
{
"type": "notificationHub",
"name": "notification",
"hubName": "repsaj-neptune-notifications",
"connection": "repsaj-neptune-notifications_NOTIFICATIONHUB",
"direction": "out",
"tagExpression": "deviceId:{deviceid}"
}
Where {deviceid} equals the deviceid property on my RuleMessage POCO. Unfortunately this doesn't work, when I call the function it outputs:
Exception while executing function: Functions.submerged-function-ruleout. Microsoft.Azure.WebJobs.Host: Exception binding parameter 'notification'. Microsoft.Azure.WebJobs.Host: No value for named parameter 'deviceid'.
Which is not true, I know for sure the property has been set as I've logged it to the ouput window. I also tried something like {inputEventMessage.deviceid}, but that doesn't work either (as I didn't get how the runtime would map {deviceid} to the correct input object when there's more than one.
The tagExpression binding property supports binding parameters coming from trigger input properties. For example, assume your incoming Event Hub event has properties A and B. You can use these properties in your tagExpression using the parens syntax, e.g.: My Tag {A}-{B}.
In general, most of the properties across all the binding types support binding parameters in this way.

Default values for properties in Azure Table Storage

I am using Azure table storage and have questions about how nulls and default values for entities work.
Specifically, I have a class that extends TableServiceEntity. The default constructor for this class is setting default values for various properties like so:
public class MyEntity: TableServiceEntry
{
public MyEntity() : MyEntity("invalid", "invalid") {}
public MyEntity(string f1, string f2)
{
Field1 = f1;
Field2 = f2;
}
public string Field1 { get; set; }
public string Field2 { get; set; }
}
I tested this class locally (on the emulator) by constructing the following entity:
MyEntity e = new MyEntity("hello", null);
I uploaded the entity and then retrieved it locally and the two fields were set to "hello" and null, respectively, as expected.
However, when I uploaded the same entity to the Azure cloud, what I received back was "hello" and "invalid", respectively, for the two properties.
My code that saves the entity is below:
public class MyTable : TableServiceContext
{
...
public void AddEntry(MyEntity e)
{
this.AddObject("MyTable", e);
this.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate);
}
}
I was able to fix this by making the default constructor take no arguments, but now I feel like I have a fundamental misunderstanding of how table storage works. Is it true that when you specify defaults for properties of a TableServiceEntry, those become the defaults for each row in the table in the cloud but not in the emulator (i.e. cloud vs. SQL Express)? If so, why can't I override those defaults with null in the cloud? Is there any documentation that explains how default constructors and nulls work in Azure table storage?
Yes, there is a difference between how table storage behaves in the emulator and in the cloud. The emulator implemented in SQL server, returns all columns defined for a table, even if not defined for a row, irrespective of the columns value (null / non-null). In the cloud, a property set to null is neither stored nor returned in the REST call.
A quick fix would be to check for null in property set, and only mutate the property if the value passed in, is not null.
Devstorage and real storage behave differently in some cases, but I've never seen them handle NULL values differently. And I've certainly never seen it change a value from NULL to "invalid", as you seem to be implying. Are you sure you didn't accidentally upload the wrong values to the cloud? You may want to try again, and use Fiddler to look at the actual request and response values.

DynamicMethod code unverifiable in .Net 4.0 (found ref 'this' pointer... expected ref '<>f__AnonymousType1`)

Was using this solution to convert anonymous types to dictionaries using reflection.emit. Was working fine until I changed to .Net 4.0 from 3.5.
Now, I'm getting the "System.Security.VerificationException: Operation could destabilize the runtime." error.
Converted the anonymously loaded dynamic method to one hosted in a dynamic assembly, saved it, then ran peverify.exe on it to find out what was wrong.
Got: [IL]: Error: [DynamicAssemblyExample.dll : MyDynamicType::MyMethod][offs
et 0x0000000D][found ref ('this' ptr) 'MyDynamicType'][expected ref '<>f__AnonymousType1`3[System.String,System.Int32,System.Byte]'] Unexpected type on the stac
k.
[IL]: Error: [DynamicAssemblyExample.dll : MyDynamicType::MyMethod][offs
et 0x0000000D] Method is not visible.
2 Error(s) Verifying DynamicAssemblyExample.dll
The code:
foreach (PropertyInfo property in itemType.GetProperties(attributes).Where(info => info.CanRead))
{
// load Dictionary (prepare for call later)
methIL.Emit(OpCodes.Ldloc_0);
// load key, i.e. name of the property
methIL.Emit(OpCodes.Ldstr, property.Name);
// load value of property to stack
methIL.Emit(OpCodes.Ldarg_0);
methIL.EmitCall(OpCodes.Callvirt, property.GetGetMethod(), null);
// perform boxing if necessary
if (property.PropertyType.IsValueType)
{
methIL.Emit(OpCodes.Box, property.PropertyType);
}
// stack at this point
// 1. string or null (value)
// 2. string (key)
// 3. dictionary
// ready to call dict.Add(key, value)
methIL.EmitCall(OpCodes.Callvirt, addMethod, null);
}
Is there a way to derefence the pointer to the actual property? Or do I have to cast it somehow? Any pointers?
Regards!
Sorry guys, made a mistake, since the actual dynamic method creates a delegate type that acts on the instance of the anonymous (or non-anonymous) type, the Ldarg_0 code is looking for a something that is not there in this debug implementation.
So I, changed it to OpCodes.Ldnull.
var attributes = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy;
foreach (PropertyInfo property in itemType.GetProperties(attributes).Where(info => info.CanRead))
{
// load Dictionary (prepare for call later)
methIL.Emit(OpCodes.Ldloc_0);
// load key, i.e. name of the property
methIL.Emit(OpCodes.Ldstr, property.Name);
// load value of property to stack
methIL.Emit(OpCodes.Ldnull);
//methIL.Emit(OpCodes.Castclass, itemType);
methIL.EmitCall(OpCodes.Callvirt, property.GetGetMethod(), null);
// perform boxing if necessary
if (property.PropertyType.IsValueType)
{
methIL.Emit(OpCodes.Box, property.PropertyType);
}
// stack at this point
// 1. string or null (value)
// 2. string (key)
// 3. dictionary
// ready to call dict.Add(key, value)
methIL.EmitCall(OpCodes.Callvirt, addMethod, null);
}
But I still get a method not visible error after peverifying it. Is it that get methods for properties of anonymous types are not visible via reflection?
Just a suggestion, have you tried to rewrite the code that emits IL to actually write to the dictionary - i.e. no Reflection.Emit ? My bet is that the generated IL is not proper in some way, not the code that accesses the anonymous type.

Resources