Bitcore payment protocol - bitcore

I'm stuck with the BIP70 documentation. I can't figure out how to translate the repeated fields on that object.
message PaymentDetails {
optional string network = 1 [default = "main"];
repeated Output outputs = 2;
required uint64 time = 3;
optional uint64 expires = 4;
optional string memo = 5;
optional string payment_url = 6;
optional bytes merchant_data = 7;
}
With the bitcore-payment-protocol npm package, here is how they fill the outputs filled in the docs.
var details = new PaymentProtocol().makePaymentDetails();
details.set('network', 'test');
details.set('outputs', outputs);<=== shall ouputs be an array?
details.set('time', now);
details.set('expires', now + 60 * 60 * 24);
details.set('memo', 'A payment request from Ambrosia.');
details.set('payment_url', 'https://localhost/-/pay');
details.set('merchant_data', new Buffer({size: 7}));
Here is my question, I want more than one output, should I fill it with an array of output object?

Related

How can I add NTFS metadata to any file?

Is there a possibility to add information like "Version = 1.2.3.4" to - let's say - a TXT file? Could this be achieved with NTFS metadata? If so, can I set such information by a program?
Thanks in advance for any hint! Bernd
You can use either Alternative Data Stream (ADS), or Extended File Attributes (more e.g. here).
If you are sure your files remain on NTFS, Alternative Data Streams are perfect way how to store any amount of alternative data - but you will lose ADS when such file leaves NTFS.
Another option is to use Extended File Attributes, it's supported cross-platform, cross-FS, but it has limitations (e.g. how much data you can store). If you're going to save just e.g. version information, this is probably the best way to go.
Thank you Robert! I used the Extended File Attributes of NTFS that you proposed. They are called "File Summary Information". Unfortunately the information does not show up for - lets say - a text file in the "Details" tab of the Windows file explorer. I found some tricks for the registry but they didn't work yet. My code is Delphi:
CONST FmtID_SummaryInformation:TGUID= '{F29F85E0-4FF9-1068-AB91-08002B27B3D9}';
// FMTID_DocSummaryInformation:TGUID='{D5CDD502-2E9C-101B-9397-08002B2CF9AE}';
// FMTID_UserDefinedProperties:TGUID='{D5CDD505-2E9C-101B-9397-08002B2CF9AE}';
IID_IPropertySetStorage:TGUID= '{0000013A-0000-0000-C000-000000000046}';
STGFMT_FILE=3; //Indicates that the file must not be a compound file.
//This element is only valid when using the StgCreateStorageEx
//or StgOpenStorageEx functions to access the NTFS file system
//implementation of the IPropertySetStorage interface.
//Therefore, these functions return an error if the riid
//parameter does not specify the IPropertySetStorage interface,
//or if the specified file is not located on an NTFS file system volume.
STGFMT_ANY=4; //Indicates that the system will determine the file type and
//use the appropriate structured storage or property set
//implementation.
//This value cannot be used with the StgCreateStorageEx function.
// Summary Information
PID_TITLE = 2;
PID_SUBJECT = 3;
PID_AUTHOR = 4;
PID_KEYWORDS = 5;
PID_COMMENTS = 6;
PID_TEMPLATE = 7;
PID_LASTAUTHOR = 8;
PID_REVNUMBER = 9;
PID_EDITTIME = 10;
PID_LASTPRINTED = 11;
PID_CREATE_DTM = 12;
PID_LASTSAVE_DTM = 13;
PID_PAGECOUNT = 14;
PID_WORDCOUNT = 15;
PID_CHARCOUNT = 16;
PID_THUMBNAIL = 17;
PID_APPNAME = 18;
PID_SECURITY = 19;
(*
// Document Summary Information
PID_CATEGORY = 2;
PID_PRESFORMAT = 3;
PID_BYTECOUNT = 4;
PID_LINECOUNT = 5;
PID_PARCOUNT = 6;
PID_SLIDECOUNT = 7;
PID_NOTECOUNT = 8;
PID_HIDDENCOUNT = 9;
PID_MMCLIPCOUNT = 10;
PID_SCALE = 11;
PID_HEADINGPAIR = 12;
PID_DOCPARTS = 13;
PID_MANAGER = 14;
PID_COMPANY = 15;
PID_LINKSDIRTY = 16;
PID_CHARCOUNT2 = 17;
*)
FUNCTION IsNTFS(AFileName:AnsiString):Boolean;
VAR fso,drv:OleVariant;
BEGIN
fso:=CreateOleObject('Scripting.FileSystemObject'{=});
drv:=fso.GetDrive(fso.GetDriveName(AFileName));
Result:=drv.FileSystem='NTFS'{=};
END;
FUNCTION StgOpenStorageEx(
CONST pwcsName:POleStr; //Pointer to the path of the
//file containing storage object
grfMode:LongInt; //Specifies the access mode for the object
stgfmt:DWORD; //Specifies the storage file format
grfAttrs:DWORD; //Reserved; must be zero
pStgOptions:Pointer;//Address of STGOPTIONS pointer
reserved2:Pointer; //Reserved; must be zero
riid:PGUID; //Specifies the GUID of the interface pointer
OUT stgOpen:IStorage//Address of an interface pointer
) : HResult; stdcall; external 'ole32.dll'{=};
FUNCTION GetFileSummaryInfo(FileName:AnsiString):AnsiString;
{Read the File Summary Info of a file (NTFS)}
FUNCTION PropertyPIDToCaption(CONST ePID:Cardinal):AnsiString;
BEGIN {PropertyPIDToCaption}
CASE ePID OF
PID_TITLE: Result:='Title';
PID_SUBJECT: Result:='Subject';
PID_AUTHOR: Result:='Author';
PID_KEYWORDS: Result:='Keywords';
PID_COMMENTS: Result:='Comments';
PID_TEMPLATE: Result:='Template';
PID_LASTAUTHOR: Result:='Last Saved By';
PID_REVNUMBER: Result:='Revision Number';
PID_EDITTIME: Result:='Total Editing Time';
PID_LASTPRINTED: Result:='Last Printed';
PID_CREATE_DTM: Result:='Create Time/Date';
PID_LASTSAVE_DTM:Result:='Last Saved Time/Date';
PID_PAGECOUNT: Result:='Number of Pages';
PID_WORDCOUNT: Result:='Number of Words';
PID_CHARCOUNT: Result:='Number of Characters';
PID_THUMBNAIL: Result:='Thumbnail';
PID_APPNAME: Result:='Creating Application';
PID_SECURITY: Result:='Security';
ELSE Result:='$'+IntToHex(ePID,8);
END
END; {PropertyPIDToCaption}
VAR i,k:Integer;
PropSetStg:IPropertySetStorage;
PropSpec:ARRAY OF TPropSpec;
PropStg:IPropertyStorage;
PropVariant:ARRAY OF TPropVariant;
Rslt:HResult;
S:AnsiString;
Stg:IStorage;
PropEnum:IEnumSTATPROPSTG;
HR:HResult;
PropStat:STATPROPSTG;
AHRes:HRESULT;
PFNw,P:PWideChar;
BEGIN {GetFileSummaryInfo}
GetMem(P,257); PFNw:=StringToWideChar(FileName,P,256);
Result := '';
TRY
OleCheck(StgOpenStorageEx(PFNw,STGM_READ OR STGM_SHARE_DENY_WRITE,STGFMT_FILE,0,NIL,NIL,#IID_IPropertySetStorage,Stg));
PropSetStg:=Stg AS IPropertySetStorage;
AHRes:=PropSetStg.Open(FmtID_SummaryInformation,STGM_READ OR STGM_SHARE_EXCLUSIVE,PropStg);
IF AHRes<>S_OK THEN Exit;
OleCheck(AHRes);
OleCheck(PropStg.Enum(PropEnum));
hr:=PropEnum.Next(1,PropStat,NIL);
i:=0;
WHILE hr=S_OK DO BEGIN
inc(i);
SetLength(PropSpec,I);
PropSpec[i-1].ulKind:=PRSPEC_PROPID;
PropSpec[i-1].propid:=PropStat.propid;
hr := PropEnum.Next(1,PropStat, nil);
END;
SetLength(PropVariant,i);
Rslt:=PropStg.ReadMultiple(i,#PropSpec[0],#PropVariant[0]);
IF Rslt=S_FALSE THEN Exit;
FOR k:=0 TO i-1 DO BEGIN
S:='';
IF (PropVariant[k].vt=VT_LPWSTR) AND Assigned(PropVariant[k].pwszVal) THEN
S:=WideCharToString(PropVariant[k].pwszVal);
IF (PropVariant[k].vt=VT_LPSTR) AND Assigned(PropVariant[k].pszVal) THEN
S:=PropVariant[k].pszVal;
S:=PropertyPIDToCaption(PropSpec[k].Propid)+'='+S;
IF S<>'' THEN Result:=Result+S+#13#10;
END;
FINALLY
END;
END; {GetFileSummaryInfo}
PROCEDURE SetFileSummaryInfo(FileName,Author,Title,Subject,Keywords,Comments:AnsiString);
{Write some fields of the File Summary Info of a file (NTFS)}
VAR PropSetStg:IPropertySetStorage;
PropSpec:ARRAY OF TPropSpec;
PropStg:IPropertyStorage;
PropVariant:ARRAY OF TPropVariant;
Stg:IStorage;
PFNw,P:PWideChar;
Anz:LongInt;
BEGIN {SetFileSummaryInfo}
IF NOT IsNTFS(FileName) THEN Exit;
Anz:=5;
GetMem(P,257); PFNw:=StringToWideChar(FileName,P,256);
OleCheck(StgOpenStorageEx(PFNw,STGM_SHARE_EXCLUSIVE OR STGM_READWRITE,STGFMT_ANY,0,NIL,NIL,#IID_IPropertySetStorage,Stg));
PropSetStg:=Stg AS IPropertySetStorage;
OleCheck(PropSetStg.Create(FmtID_SummaryInformation,FmtID_SummaryInformation,PROPSETFLAG_DEFAULT,STGM_CREATE OR STGM_READWRITE OR STGM_SHARE_EXCLUSIVE,PropStg));
Setlength(PropSpec,Anz);
PropSpec[0].ulKind:=PRSPEC_PROPID;
PropSpec[0].propid:=PID_AUTHOR;
PropSpec[1].ulKind:=PRSPEC_PROPID;
PropSpec[1].propid:=PID_TITLE;
PropSpec[2].ulKind:=PRSPEC_PROPID;
PropSpec[2].propid:=PID_SUBJECT;
PropSpec[3].ulKind:=PRSPEC_PROPID;
PropSpec[3].propid:=PID_KEYWORDS;
PropSpec[4].ulKind:=PRSPEC_PROPID;
PropSpec[4].propid:=PID_COMMENTS;
SetLength(PropVariant,Anz);
PropVariant[0].vt:=VT_LPSTR;
PropVariant[0].pszVal:=PChar(Author);
PropVariant[1].vt:=VT_LPSTR;
PropVariant[1].pszVal:=PChar(Title);
PropVariant[2].vt:=VT_LPSTR;
PropVariant[2].pszVal:=PChar(Subject);
PropVariant[3].vt:=VT_LPSTR;
PropVariant[3].pszVal:=PChar(Keywords);
PropVariant[4].vt:=VT_LPSTR;
PropVariant[4].pszVal:=PChar(Comments);
OleCheck(PropStg.WriteMultiple(Anz,#PropSpec[0],#PropVariant[0],2));
PropStg.Commit(STGC_DEFAULT);
FreeMem(P);
END; {SetFileSummaryInfo}

Matlab, AppDesigner-Convert image on a good type and use it in "imread" function

I use AppDesigner inMATLAB to show photos with changed RGB. But there is the problem with character of the photo.
When I switch on my own fuction "changeRGB", finally "choosenImage" has 20bytes, class "char" and size(1x10). OK!
There is no problem in using the "function OpenButtonValueChanged". OK!
There is the problem with "function UploadButtonPushed". OK!
ABOUT THE PROBLEM:
When I click button which callback is "function UploadButtonPushed" I get the error:
"Error using imread>parse_inputs (line 502)
The file name or URL argument must be a character
vector or string scalar."
"Error in imread (line 342)
[source, fmt_s, extraArgs, was_cached_fmt_used] =
parse_inputs(cached_fmt, varargin{:});"
WHY?
Because in the "function UploadButtonPushed" my choosenImage has 1977624bytes, class "uint8" and size(681x968x3). So it's too bug for "imread".
WHAT I TRIED:
When in "function OpenButtonValueChanged" I convert a photo, adding "char": (myimage = char(app.clickedImage)); the class of the photo is changing from uint8 to char but the size.
When I use "num2cell", the claas of the photo is changing on "cell" but size and number of bytes are the same- so big. And I get the Error: "Error using imread>parse_inputs (line 502) The file name or URL argument must be a character vector or string scalar."
In my own function "changeRGB" I used "imread(image)" and here is the problem with the size of the photo. Do you know how to get the correct one?
%my own properties in AppDesigner- to use them in different functions
properties (Access = public)
clickedImage;
addR = 1;
addG = 1;
addB = 1;
end
%first function in AppDeesigner
function OpenButtonValueChanged(app, event)
value = app.OpenButton.Value;
[file, howManyFiles] = chooseImagesFromComputer; %myown function
%I load 3 images which are showed as miniatures
myFile1 = imread(file{1});
imshow(myFile1, 'Parent', app.UIAxes1_1);
myFile2 = imread(file{2});
imshow(myFile2, 'Parent', app.UIAxes1_2);
myFile3 = imread(file{3});
imshow(myFile3, 'Parent', app.UIAxes1_3);
%take values of changed RGB from the slider
app.addR = app.SliderR.Value
app.addG = app.SliderG.Value
app.addB = app.SliderB.Value
%work only on one image to change its colors. app.clickedImage, app.addR, app.addG, app.addB are properties at the beginning of the code
app.clickedImage = file{1};
app.clickedImage = changeRGB(app.clickedImage,app.addR,app.addG,app.addB); %changeRGB- my own function- here is the problem. I add it bottom
imshow(app.clickedImage,'Parent',app.UIAxesMain);
end
%second function in AppDesigner
%here is the button to upload color of the photo
function UploadButtonPushed(app, event)
myimage = app.clickedImage;
myimage = changeRGB(myimage,app.addR,app.addG,app.addB);
imshow(myimage);
end
%here is my own function in matlab, not in AppDesigner, which makes problem:
function [changedImage] = changeRGB(choosenImage, addR, addG, addB)
whos
loadedImage = imread(choosenImage);
R = loadedImage(:,:,1); %extract one of the color channels
G = loadedImage(:,:,2);
B = loadedImage(:,:,3);
RBG = cat(3,R,G,B);
R_adj2 = R + addR;
G_adj2 = G + addG;
B_adj2 = B + addB;
changedImage = cat(3,R_adj2,G_adj2,B_adj2);
end
First, you make unnecessary operations in changeRGB
function [changedImage] = changeRGB(choosenImage, addR, addG, addB)
loadedImage = imread(choosenImage);
loadedImage = bsxfun(#sum, loadedImage, reshape([addR, addG, addB], [1 1 3]);
end
Then this function return an array (the modified image) so in UploadButtonPushed(app, event) when you run myimage = app.clickedImage;, you are passing the modified array instead of the image path, that you set here app.clickedImage = changeRGB(app.clickedImage,app.addR,app.addG,app.addB);
So you have to change the design of your variables, because app.clickedImage is saving either the image path, or the image itself. Consider having 2 different variables.
A good advice also is to use matlab debugger which is really good help to find the source of this kind of problems.

randdusing/ng-cordova-bluetoothle, parsing ble advertisement ionic

using the randdusing bluetoothle plugin for ionic app, need to read the advertisement.
The ble scan returns with Start Scan Success :
{"address":"14::30:c6:60:e8;9f","name":null,"rssi":-50,"advertisement":"AgEGG/9SVgIADSw5YTNlMTQAAAJlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA;=","status":"scanResult"}
query: need to decipher this json data and convert this advertisement data into array containing hex values of advertisement data? The advertisement data seems to be base64 encoded. Please advice.
I made for this purpose a little helper function as shown below. The key is the $cordovaBluetoothLE.encodedStringToBytes as you can see in docs https://github.com/randdusing/ng-cordova-bluetoothle.
var encodedToByteString = function encodedToByteString(input) {
var val = $cordovaBluetoothLE.encodedStringToBytes(input);
var byteStr = "";
for (var i = 0; i < val.length; i++) {
var byte = val[i].toString(16);
if (byte.length == 1) byte = "0" + byte;
byteStr += byte;
}
return byteStr;
};
The same goes for the opposite operation - that is sending data. You first need to get your hex-string into an array of bytes and then encode it via $cordovaBluetoothLE.bytesToEncodedString(value).

Kafka ByteArray

I'm using Kafka to send produce and consume messages.
Producing is fine, working with a <String, ByteArray> producer.
When consuming, I'm using the code below (taken from an example) but I'm getting each record as being just 8 bytes (sample output beneath code).
Is there a way a consumer can simply take a whole message as a byte array?
Code:
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.ByteArrayDeserializer");
KafkaConsumer<String, byte[]> consumer = new KafkaConsumer<String, byte[]>(props);
consumer.subscribe(Arrays.asList(topic));
int i = 0;
while (true) {
ConsumerRecords<String, byte[]> records = consumer.poll(100);
for (ConsumerRecord<String, byte[]> record : records)
System.out.printf("offset = %d, key = %s, value = %s\n", record.offset(), record.key(), record.value());
}
Output of System.out :
offset = 1773133, key = 105906453, value = [B#b8eff39
offset = 1773134, key = 105906453, value = [B#7bb1504
offset = 1773135, key = 105906453, value = [B#67b6c728
offset = 1773136, key = 105906453, value = [B#60b1f9c5
offset = 1773137, key = 105906177, value = [B#1cbab5dd
offset = 1773138, key = 105906177, value = [B#4376907b
offset = 1773139, key = 105906177, value = [B#122880ba
offset = 1773140, key = 105906177, value = [B#7db82ceb
offset = 1773141, key = 105906177, value = [B#34657adc
I'm not looking forward to having to assemble a load of these records to re-create a message as I believe I'm missing something and manual assembly may be error prone.
I think you should use
System.out.printf("offset = %d, key = %s, value = %s\n", record.offset(), record.key(), java.util.Arrays.toString(record.value()));
rather than depending on plain array.toString (which gives you garbage instead of actual content). Arrays are probably coming properly, you just debug it wrong way.

How can I apply a low-shelving filter using Visualdsp++?

I'm very new to DSP. And have to solve the following problem: applying the low shelving filter for an array of data. The original data is displayed in fract16 (VisualDSP++).
I'm writing something as below but not sure it's correct or not.
Does the following code have any problem with overflow?
If 1 is true, how should I do to prevent it?
Any advice on this problem?
fract16 org_data[256]; //original data
float16 ArrayA[],ArrayB[];
long tmp_A0, tmp_A1, tmp_A2, tmp_B1, tmp_B2;
float filter_paraA[3], filter_paraB[3]; // correctness: 0.xxxxx
// For equalizing
// Low-Shelving filter
for ( i=0; i<2; i++)
{
tmp_A1 = ArrayA[i*2];
tmp_A2 = ArrayA[i*2+1];
tmp_B1 = ArrayB[i*2];
tmp_B2 = ArrayB[i*2+1];
for(j=0;j<256;j++){
tmp_A0 = org_data[j];
org_data[j] = filter_paraA[0] * tmp_A0
+ filter_paraA[1] * tmp_A1
+ filter_paraA[2] * tmp_A2
- filter_paraB[1] * tmp_B1
- filter_paraB[2] * tmp_B2;
tmp_A2 = tmp_A1;
tmp_B2 = tmp_B1;
tmp_A1 = tmp_A0;
tmp_B1 = org_data[j];
}
ArrayA[i*2] = tmp_A1;
ArrayA[i*2+1] = tmp_A2;
ArrayB[i*2] = tmp_B1;
ArrayB[i*2+1] = tmp_B2;
}
I don't know what the range is for fract16, just -1 to +1 approx?
The section that stands out to me as possibly generating an overflow is assigning org_data[j] but will be dependent on what you know about your input signal and your filter coefficients. If you can ensure that multiplying filter_paraA[2:0] to signal with values tmp_A2..1 = [1,1,1] is < max(fract16) you should be fine regardless of the 'B' side.
I would recommend adding some checks for overflow in your code. It doesn't necessarily have to fix it, but you would be able to identify an otherwise very tricky bug. Unless you need absolute max performance I would even leave the check code in place but with less output or setting a flag that gets checked.
macA = filter_paraA[0] * tmp_A0 + filter_paraA[1] * tmp_A1 \
+ filter_paraA[2] * tmp_A2;
macB = filter_paraB[1] * tmp_B1 - filter_paraB[2] * tmp_B2;
if((macA-macB)>1){
printf("ERROR! Overflow detected!\n");
printf("tmp_A[] = [%f, %f, %f]\n",tmp_A2,tmp_A1,tmp_A0);
printf("tmp_B[] = [%f, %f]\n",tmp_B1,tmp_B0);
printf(" i = %i, j = %i\n",i,j);
}

Resources