How to set width of Material Components tab bar on iOS with Xamarin - ios

I'm using Material Components in iOS Xamarin app and would like to set width of MDCTabBar indicator to something larger like 8 dp.
As I understand I should supply custom object implementing TabBarIndicatorTemplate to SelectionIndicatorTemplate.
So let's say that I initialize tabbar:
tabBar = new TabBar();
tabBar.Items = new UITabBarItem[] {
new UITabBarItem("One", null, 0),
new UITabBarItem("Two", null, 0)
};
tabBar.Alignment = TabBarAlignment.Justified;
tabBar.ItemAppearance = TabBarItemAppearance.Titles;
tabBar.TitleTextTransform = TabBarTextTransform.None;
And then use my custom CustomTabBarIndicatorTemplate:
tabBar.SelectionIndicatorTemplate = new CustomTabBarIndicatorTemplate();
which is implemented as follows:
private class CustomTabBarIndicatorTemplate : TabBarIndicatorTemplate
{
public override TabBarIndicatorAttributes IndicatorAttributesForContext(ITabBarIndicatorContext context)
{
var bounds = context.Bounds;
var attr = new TabBarIndicatorAttributes();
var frame = new CGRect(bounds.GetMinX(), bounds.GetMaxY() - 8, bounds.Width, 8);
attr.Path = UIBezierPath.FromRect(frame);
return attr;
}
}
Unfortunately this causes native crash on iOS:
=================================================================
Native Crash Reporting
=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================
=================================================================
Native stacktrace:
=================================================================
0x10dc02ae5 - /Users/user/Library/Developer/CoreSimulator/Devices/44BEABB1-FBEC-48AB-8CE3-F04C3969A12A/data/Containers/Bundle/Application/23FCADDC-6D6C-4DCA-8C0F-1D2CCF19D914/MyApp.iOS.app/MyApp.iOS : mono_dump_native_crash_info
0x10dbf6a25 - /Users/user/Library/Developer/CoreSimulator/Devices/44BEABB1-FBEC-48AB-8CE3-F04C3969A12A/data/Containers/Bundle/Application/23FCADDC-6D6C-4DCA-8C0F-1D2CCF19D914/MyApp.iOS.app/MyApp.iOS : mono_handle_native_crash
0x10dc09d61 - /Users/user/Library/Developer/CoreSimulator/Devices/44BEABB1-FBEC-48AB-8CE3-F04C3969A12A/data/Containers/Bundle/Application/23FCADDC-6D6C-4DCA-8C0F-1D2CCF19D914/MyApp.iOS.app/MyApp.iOS : mono_sigsegv_signal_handler_debug
0x11e7c7b5d - /usr/lib/system/libsystem_platform.dylib : _sigtramp
0x10dc820b9 - /Users/user/Library/Developer/CoreSimulator/Devices/44BEABB1-FBEC-48AB-8CE3-F04C3969A12A/data/Containers/Bundle/Application/23FCADDC-6D6C-4DCA-8C0F-1D2CCF19D914/MyApp.iOS.app/MyApp.iOS : mono_de_add_pending_breakpoints
0x14593b306 - Unknown
=================================================================
Basic Fault Address Reporting
=================================================================
Memory around native instruction pointer (0x11d03080a):0x11d0307fa 00 00 00 00 00 90 4c 8b 57 08 48 8b 3f 49 89 f3 ......L.W.H.?I..
0x11d03080a 45 23 5a 18 49 c1 e3 04 4d 03 5a 10 49 3b 33 75 E#Z.I...M.Z.I;3u
0x11d03081a 04 41 ff 63 08 49 83 3b 01 76 0d 49 83 c3 10 49 .A.c.I.;.v.I...I
0x11d03082a 3b 33 75 f1 41 ff 63 08 72 1b 4d 8b 5b 08 eb 0a ;3u.A.c.r.M.[...
=================================================================
Managed Stacktrace:
=================================================================
at <unknown> <0xffffffff>
at ApiDefinition.Messaging:IntPtr_objc_msgSendSuper <0x00135>
at MaterialComponents.TabBarIndicatorTemplate:.ctor <0x00342>
at CustomTabBarIndicatorTemplate:.ctor <0x00072>
at MyApp.iOS.Views.[REDACTED].[REDACTED]ViewController:SetLayout <0x00a32>
at MyApp.iOS.Views.BaseViewController`1:PrepareLayout <0x001b0>
at MyApp.iOS.Views.BaseViewController`1:ViewDidLoad <0x000fa>
at System.Object:runtime_invoke_void__this__ <0x001a5>
at <unknown> <0xffffffff>
at UIKit.UIApplication:UIApplicationMain <0x00251>
at UIKit.UIApplication:Main <0x000b2>
at UIKit.UIApplication:Main <0x00132>
at MyApp.iOS.Application:Main <0x00092>
at <Module>:runtime_invoke_void_object <0x001a8>
=================================================================
How should I correctly implement this?

The solution was to call base constructor base(NSObjectFlag.Empty):
private class CustomTabBarIndicatorTemplate : TabBarIndicatorTemplate
{
public CustomTabBarIndicatorTemplate() : base(NSObjectFlag.Empty)
{
Console.WriteLine("Constructor");
}
public override TabBarIndicatorAttributes IndicatorAttributesForContext(ITabBarIndicatorContext context)
{
var bounds = context.Bounds;
var attr = new TabBarIndicatorAttributes();
var frame = new CGRect(bounds.GetMinX(), bounds.GetMaxY() - 8, bounds.Width, 8);
attr.Path = UIBezierPath.FromRect(frame);
return attr;
}
}

Related

Playing recorded audio results in ACMP4AACBaseDecoder failing

I'm playing around with a really simple audio use case. I'm recording via AVAudioRecorder and playing the recorded audio via AVAudioPlayer. The way I configured it is to set up the AVAudioRecorder once when the view controller is presented and record over the same file whenever record is initiated. Playing will play the url used by the recorder. The first recording and play back work fine. However if I try to record and play again I get the following:
2022-12-30 10:39:09.874066-0800 [40936:5138438] Error deserializing gain control data
2022-12-30 10:39:09.874246-0800 [40936:5138438] Error deserializing right channel stream
2022-12-30 10:39:09.874443-0800 [40936:5138438] Error in deserializing element
2022-12-30 10:39:09.874545-0800 [40936:5138438] Error deserializing packet
2022-12-30 10:39:09.874675-0800 [40936:5138438] [ac] ACMP4AACBaseDecoder.cpp:1438 (0x127850040) Error decoding packet 1: err = -1, packet length: 198
2022-12-30 10:39:09.874781-0800 [40936:5138438] [ac] ACMP4AACBaseDecoder.cpp:1447 '21 4E E5 44 87 E2 FC 62 0A 9B 64 42 80 D5 4E 01 17 D0 9D 47 CF FA E0 91 D2 5C FD 28 8B 3E 04 3A FD 71 F0 43 6D 20 48 52 EB 6C 73 7D 30 98 41 CC 12 F9 27 C3 10 60 4F 67 41 F6 4F 59 F1 A6 45 A4 B4 87 6A 4F 34 9C 26 CF 03 9A 9C 8D 20 14 6E 72 E6 C5 08 A6 BC D7 3B DE 3D 7F 61 1A 23 38 EC 95 1E 71 C8 1A D4 F1 B0 6E ED 9C 53 D3 FD 0E E1 5B AA CD 83 8F D3 0D 40 D7 D1 94 B4 F5 A8 1A 13 4D CE E2 37 69 14 FA E9 01 A2 50 2C AE 9C 75 49 04 06 8B 6F 01 23 20 0D 3E F1 5B 6F 47 D3 F3 F3 8A 06 E9 C5 AB 34 84 28 21 C7 4D DA 47 BE 9E 1A D5 6A B8 74 B2 EA 21 1D 51 0B 2D CE 1C 3F 01 F8 0F C0 7E 10 EB F5 C7'
2022-12-30 10:39:09.876272-0800 [40936:5138438] Too few bits left in input buffer
I'm not very knowledgable about how audio works beneath the hood but I figured this is pretty basic audio stuff.
How I set up the recorder (only done once when VC is loaded):
func setupAudioRecorder() {
// Set the audio file
let audioFileURL = getFileUrl()
// Setup audio session
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(.playAndRecord, mode: .default, options: [])
} catch _ {
}
// Define the recorder setting
let recorderSetting = [AVFormatIDKey: NSNumber(value: kAudioFormatMPEG4AAC as UInt32),
AVSampleRateKey: 44100.0,
AVNumberOfChannelsKey: 2 ]
audioRecorder = try? AVAudioRecorder(url: audioFileURL, settings: recorderSetting)
audioRecorder?.delegate = self
audioRecorder?.isMeteringEnabled = true
audioRecorder?.prepareToRecord()
}
func getDocumentsDirectory() -> URL
{
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
return documentsDirectory
}
func getFileUrl() -> URL
{
let timeInterval = Int(NSDate().timeIntervalSince1970*1000)
let audioFileName = "version_" + String(timeInterval) + ".m4a"
let filePath = getDocumentsDirectory().appendingPathComponent(audioFileName)
return filePath
}
Start recording:
func startRecording() {
if let recorder = audioRecorder {
if !recorder.isRecording {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setActive(true)
} catch _ {
}
// Start recording
recorder.record()
print("RECORD " + recorder.url.absoluteString)
}
}
}
How I set up the player (called every time user hits play):
func setUpPlayer() {
guard let _ = self.audioPlayer else {
self.audioPlayer = try? AVAudioPlayer(contentsOf: self.audioRecorder!.url)
self.audioPlayer?.delegate = self
setAudioPlayerToUseSpeaker()
return
}
}
Toggle player:
func toggleAudioPlayer() {
if let audioPlayer = self.audioPlayer {
if (audioPlayer.isPlaying) {
audioPlayer.stop()
} else {
audioPlayer.play()
}
}
}

ZXing not scanning barcodes on ios

I have a problem building Xamarin Forms app. We need to implement barcode scanner in it where I found several tutorials how to integrate ZXing.Net.Mobile.Platforms which I installed for all project via Nuget - I tried latest stable version (2.4.1) as also latest beta version (3.1.0-beta2)
I read readme file so I added permission request to Info.plist and I also added Init call to AppDeledate.cs
When I call method scanner.Scan(); the scanner opens up and show scanner but it never detects any code.
My code is:
PermissionStatus status = await Permissions.RequestAsync<Permissions.Camera>();
if (status == PermissionStatus.Granted)
{
MobileBarcodeScanner scanner = new MobileBarcodeScanner();
MobileBarcodeScanningOptions mobileBarcodeScanningOptions = new ZXing.Mobile.MobileBarcodeScanningOptions();
mobileBarcodeScanningOptions.TryHarder = true;
mobileBarcodeScanningOptions.AutoRotate = true;
mobileBarcodeScanningOptions.TryInverted = true;
mobileBarcodeScanningOptions.UseNativeScanning = true;
mobileBarcodeScanningOptions.DisableAutofocus = false;
mobileBarcodeScanningOptions.CameraResolutionSelector = (res) => { return res.Last(); };
mobileBarcodeScanningOptions.PossibleFormats = new List<ZXing.BarcodeFormat>
{
ZXing.BarcodeFormat.QR_CODE,
ZXing.BarcodeFormat.EAN_13
};
scanner.ResumeAnalysis();
var result = await scanner.Scan(mobileBarcodeScanningOptions);
if (result != null)
Console.WriteLine("Scanned Barcode: " + result.Text);
}
I tried this on iPhone 13 (iOS 16) and iPhone 11 (iOS 15.4) but it is not working on any of them.
Barcode scanner is working fine on all Android device we have tested but not luck on iOS.
What I noted in output window after starting scanner is:
2022-09-18 20:27:10.905 Xamarin.PreBuilt.iOS[6680:656924] Starting to scan...
2022-09-18 20:27:10.981 Xamarin.PreBuilt.iOS[6680:656924] ZXingScannerView.Setup() took 68.001 ms.
2022-09-18 20:27:10.981 Xamarin.PreBuilt.iOS[6680:656924] StartScanning
Thread started: #9
=================================================================
Native Crash Reporting
Got a segv while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================
Native stacktrace:
0x1044d8288 - /private/var/containers/Bundle/Application/E002FFE8-ADDD-4163-90D0-43B001F6763F/DelovniCas.iOS.app/Xamarin.PreBuilt.iOS : mono_dump_native_crash_info
0x1044cecd8 - /private/var/containers/Bundle/Application/E002FFE8-ADDD-4163-90D0-43B001F6763F/DelovniCas.iOS.app/Xamarin.PreBuilt.iOS : mono_handle_native_crash
0x1044dbc58 - /private/var/containers/Bundle/Application/E002FFE8-ADDD-4163-90D0-43B001F6763F/DelovniCas.iOS.app/Xamarin.PreBuilt.iOS : mono_sigsegv_signal_handler_debug
0x2103cda90 - /usr/lib/system/libsystem_platform.dylib : <redacted>
0x1046651ec - /private/var/containers/Bundle/Application/E002FFE8-ADDD-4163-90D0-43B001F6763F/DelovniCas.iOS.app/Xamarin.PreBuilt.iOS : xamarin_collapse_struct_name
0x10467220c - /private/var/containers/Bundle/Application/E002FFE8-ADDD-4163-90D0-43B001F6763F/DelovniCas.iOS.app/Xamarin.PreBuilt.iOS : _ZL15param_iter_next14IteratorActionPvPKcmS0_PS0_
0x10466af14 - /private/var/containers/Bundle/Application/E002FFE8-ADDD-4163-90D0-43B001F6763F/DelovniCas.iOS.app/Xamarin.PreBuilt.iOS : xamarin_invoke_trampoline
0x1046720d0 - /private/var/containers/Bundle/Application/E002FFE8-ADDD-4163-90D0-43B001F6763F/DelovniCas.iOS.app/Xamarin.PreBuilt.iOS : xamarin_arch_trampoline
0x104672d74 - /private/var/containers/Bundle/Application/E002FFE8-ADDD-4163-90D0-43B001F6763F/DelovniCas.iOS.app/Xamarin.PreBuilt.iOS : xamarin_arm64_common_trampoline
0x1dc86c2d0 - /System/Library/PrivateFrameworks/AVFCapture.framework/AVFCapture : <redacted>
0x1dc86c19c - /System/Library/PrivateFrameworks/AVFCapture.framework/AVFCapture : <redacted>
0x1df91efd0 - /System/Library/PrivateFrameworks/CMCapture.framework/CMCapture : <redacted>
0x1dfae30fc - /System/Library/PrivateFrameworks/CMCapture.framework/CMCapture : <redacted>
0x1cafbdfdc - /usr/lib/system/libdispatch.dylib : <redacted>
0x1cafc146c - /usr/lib/system/libdispatch.dylib : <redacted>
0x1cafd4a58 - /usr/lib/system/libdispatch.dylib : <redacted>
0x1cafc556c - /usr/lib/system/libdispatch.dylib : <redacted>
0x1cafc61e0 - /usr/lib/system/libdispatch.dylib : <redacted>
0x1cafd0e10 - /usr/lib/system/libdispatch.dylib : <redacted>
0x210460df8 - /usr/lib/system/libsystem_pthread.dylib : _pthread_wqthread
0x210460b98 - /usr/lib/system/libsystem_pthread.dylib : start_wqthread
=================================================================
Basic Fault Address Reporting
Memory around native instruction pointer (0x1046650b0):0x1046650a0 a8 83 5e f8 1f 01 00 39 01
00 00 14 a8 03 5f f8 ..^....9.......
0x1046650b0 08 01 40 39 a8 10 00 34 01 00 00 14 a8 03 5f f8 ..#9...4.......
0x1046650c0 08 01 c0 39 08 8d 00 71 e8 13 00 f9 08 69 01 f1 ...9...q.....i..
0x1046650d0 c8 0c 00 54 eb 13 40 f9 0a 00 00 90 4a c1 0c 91 ...T..#.....J...
=================================================================
Managed Stacktrace:
=================================================================
But I do not know how to resolve this problem. Any help will be highly appreciated.

GraphicsMagick .toBuffer() creates empty buffer stream

I have a Firebase Cloud Function that converts a buffer (from PDF) to a PNG using GraphcisMagick. When I attempt to write this PNG buffer to Firebase Storage, I get a file stub but no content (empty file). My conversion to PNG is failing...
async function createThumbnail(newthumbname, mimetype, filebuffer) {
const file = bucket.file(newthumbname)
const thumbstream = file.createWriteStream({metadata:{contentType:mimetype}})
const gm = require('gm').subClass({imageMagick: true})
gm(filebuffer)
.toBuffer('png', (err, thumbbuffer)=>{
console.log(filebuffer)
console.log(thumbbuffer)
thumbstream.end(thumbbuffer)
})
}
The filebuffer passed into the createThumbnail() has content,
<Buffer 25 50 44 46 2d 31 2e 33 0a 25 c4 e5 f2 e5 eb a7 f3 a0 d0 c4 c6 0a 33 20 30 20 6f 62 6a 0a 3c 3c 20 2f 46 69 6c 74 65 72 20 2f 46 6c 61 74 65 44 65 63 ... 6464 more bytes>
But the gm(filebuffer).toBuffer() is producing and empty thumbbuffer with Error: Stream yields empty buffer
What am I doing wrong here?
This appears to be a png issue, as jpg seems to work with both, .stream() and .toBuffer().
I'll settle for jpg until I can figure out what's wrong with png.
async function createThumbnail(newthumbname, mimetype, filebuffer) {
const file = bucket.file(newthumbname)
const thumbstream = file.createWriteStream({metadata:{contentType:mimetype}})
const gm = require('gm').subClass({imageMagick: true})
gm(filebuffer)
// .setFormat("jpg")
// .stream()
// .pipe(thumbstream)
.toBuffer('jpg', (err, thumbbuffer)=>{
thumbstream.end(thumbbuffer)
})
}

Could not parse base64 DER-encoded ASN.1 public key from iOS in Golang

i have a projects in Golang with RSA enryption, so now, i have a Base64 public key format which used for encrypt a message,
i used this code:
publicKeyBase64 = "MIGJAoGBAJJYXgBem1scLKPEjwKrW8+ci3B/YNN3aY2DJ3lc5e2wNc0SmFikDpow1TdYcKl2wdrXX7sMRsyjTk15IECMezyHzaJGQ9TinnkQixJ+YnlNdLC04TNWOg13plyahIXBforYAjYl2wVIA8Yma2bEQFhmAFkEX1A/Q1dIKy6EfQ+xAgMBAAE="
publicKeyBinary, err := base64.StdEncoding.DecodeString(publicKeyBase64)
publicKeyInterface, err := x509.ParsePKIXPublicKey(publicKeyBinary)
if err != nil {
fmt.Println("Could not parse DER encoded public key (encryption key)")
return "","",err
}
publicKey, isRSAPublicKey := publicKeyInterface.(*rsa.PublicKey)
if !isRSAPublicKey {
fmt.Println("Public key parsed is not an RSA public key")
return "","",err
}
encryptedMessage, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, "message")
When i run this code, i got this error:
Could not parse DER encoded public key (encryption key)
asn1: structure error: tags don't match (16 vs {class:0 tag:2 length:129 isCompound:false}) {optional:false explicit:false application:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} AlgorithmIdentifier #3
The error points to publicKeyInterface, it failed to parse from Base64 decoded format to public Key, What's the problem with my code ?
=======updated=====
my publicKeyBase64 is retrieved from my models with Binary Data type
When i store it in my mongoDB from my Rails API, i receive public_key params as Base64 format, but i decode it to binary and then i stored it with this code
def create
params = device_params
public_key = Base64.decode64 device_params[:public_key]
#device_params[:public_key] value is "MIGJAoGBAJJYXgBem1scLKPEjwKrW8+ci3B/YNN3aY2DJ3lc5e2wNc0SmFikDpow1TdYcKl2wdrXX7sMRsyjTk15IECMezyHzaJGQ9TinnkQixJ+YnlNdLC04TNWOg13plyahIXBforYAjYl2wVIA8Yma2bEQFhmAFkEX1A/Q1dIKy6EfQ+xAgMBAAE="
params[:public_key] = BSON::Binary.new(public_key, :generic)
device = Device.find_or_create_by(id: device_params[:id])
render_success device.update_attributes(params), device
end
When i use rails code to convert my Base64 public key string using this code, it succeeded:
rsa_public_key = OpenSSL::PKey::RSA.new(Base64.decode64(public_key))
in my iOS app, i use https://github.com/DigitalLeaves/AsymmetricCrypto
to generate a public Key using this code:
AsymmetricCryptoManager.sharedInstance.createSecureKeyPair({ (success, error) -> Void in
if success {
print("RSA-1024 keypair successfully generated.")
let publicKey = AsymmetricCryptoManager.sharedInstance.getPublicKeyData()?.base64EncodedString()
let url = ENV.BASE_URL + "devices"
let headers = ["Authentication-Token": CurrentUser.getCurrentUser().token] as! HTTPHeaders
let params = ["device[user_id]": CurrentUser.getCurrentUser().id!, "device[id]": instanceID,"device[token]": fcmToken, "device[os]": "ios", "device[public_key]": publicKey!]
Alamofire.request(url, method: .post, parameters: params, encoding: URLEncoding.default, headers: headers)
} else { print("An error happened while generating a keypair: \(error)") }
})
We can dump the ASN.1 contents to see what they look like:
$ echo "MIGJAoGBAJJYXgBem1scLKPEjwKrW8+ci3B/YNN3aY2DJ3lc5e2wNc0SmFikDpow1TdYcKl2wdrXX7sMRsyjTk15IECMezyHzaJGQ9TinnkQixJ+YnlNdLC04TNWOg13plyahIXBforYAjYl2wVIA8Yma2bEQFhmAFkEX1A/Q1dIKy6EfQ+xAgMBAAE=" | \
base64 -d | \
dumpasn1 -
0 137: SEQUENCE {
3 129: INTEGER
: 00 92 58 5E 00 5E 9B 5B 1C 2C A3 C4 8F 02 AB 5B
: CF 9C 8B 70 7F 60 D3 77 69 8D 83 27 79 5C E5 ED
: B0 35 CD 12 98 58 A4 0E 9A 30 D5 37 58 70 A9 76
: C1 DA D7 5F BB 0C 46 CC A3 4E 4D 79 20 40 8C 7B
: 3C 87 CD A2 46 43 D4 E2 9E 79 10 8B 12 7E 62 79
: 4D 74 B0 B4 E1 33 56 3A 0D 77 A6 5C 9A 84 85 C1
: 7E 8A D8 02 36 25 DB 05 48 03 C6 26 6B 66 C4 40
: 58 66 00 59 04 5F 50 3F 43 57 48 2B 2E 84 7D 0F
: B1
135 3: INTEGER 65537
: }
0 warnings, 0 errors.
A well-formatted ASN.1 public key should include the algorithm as well. We should have a line similar to:
5 9: OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
The AsymmetricCryptoManager.getPublicKeyData() returns a very barebones ASN.1 key, without any algorithm information. This makes Go very unhappy as it has no way of knowing what kind of key it is. See more about correctly exporting the key here.
If you can change the iOS code, you should instead use CryptoExportImportManager and use one of exportPublicKeyToPEM or exportPublicKeyToDER. These take the output of getPublicKeyData and generate output usable by other tools. You can find an example of how to use them in the CryptoExportImportManager example.
If you cannot change the key export code, you can instead parse it directly in Go. This assumes that you know for sure that it is a RSA public key:
func main() {
publicKeyBase64 := "MIGJAoGBAJJYXgBem1scLKPEjwKrW8+ci3B/YNN3aY2DJ3lc5e2wNc0SmFikDpow1TdYcKl2wdrXX7sMRsyjTk15IECMezyHzaJGQ9TinnkQixJ+YnlNdLC04TNWOg13plyahIXBforYAjYl2wVIA8Yma2bEQFhmAFkEX1A/Q1dIKy6EfQ+xAgMBAAE="
// Base64 decode.
publicKeyBinary, err := base64.StdEncoding.DecodeString(publicKeyBase64)
if err != nil {
panic(err)
}
// rsa.PublicKey is a big.Int (N: modulus) and an integer (E: exponent).
var pubKey rsa.PublicKey
if rest, err := asn1.Unmarshal(publicKeyBinary, &pubKey); err != nil {
panic(err)
} else if len(rest) != 0 {
panic("rest is not nil")
}
fmt.Printf("key: %+v\n", pubKey)
}
This prints out:
key:
{N:+102767083290202280873554060983826675083148443795791447833515664566475334389364583758312108980110921996262487865832851258326049062353432991986398760705560379825908169063986770245967781444794847106351934016144540466696422397564949226710181429429140226472206572796987719088983654589217713611861345869296293449649
E:65537}
You can now use your public key in package rsa functions.

Constant TAO CORBA IOR

How to configure TAO corba server so that IOR string of this server generated from object_to_string is constant?
Each time the IOR string generated from object_to_string changes once server restarts. This is inconvenient since client has to update its cached server IOR string via reloading IOR file or namingservice accessing. As a result, it would be useful if server can generate a constant IOR string, no matter how many times it restarts.
My corba server is based on ACE+TAO and i do remember TAO supports constant IOR string: the IOR string each time it generates are same, and the solution is add some configurations for server. But i could not remember these configurations now.
=============================================
UPDATE:
In ACE_wrappers/TAO/tests/POA/Persistent_ID/server.cpp, i added a new function named testUniqe() which is similiar to creatPOA method. And the update file content is:
void testUniqu(CORBA::ORB_ptr orb_, PortableServer::POA_ptr poa_){
CORBA::PolicyList policies (2);
policies.length (2);
//IOR is the same even it is SYSTEM_ID
policies[0] = poa_->create_id_assignment_policy (PortableServer::USER_ID);
policies[1] = poa_->create_lifespan_policy (PortableServer::PERSISTENT);
PortableServer::POAManager_var poa_manager = poa_->the_POAManager ();
PortableServer::POA_ptr child_poa_ = poa_->create_POA ("childPOA", poa_manager.in (), policies);
// Destroy the policies
for (CORBA::ULong i = 0; i < policies.length (); ++i) {
policies[i]->destroy ();
}
test_i *servant = new test_i (orb_, child_poa_);
PortableServer::ObjectId_var oid = PortableServer::string_to_ObjectId("xushijie");
child_poa_->activate_object_with_id (oid, servant);
PortableServer::ObjectId_var id = poa_->activate_object (servant);
CORBA::Object_var object = poa_->id_to_reference (id.in ());
test_var test = test::_narrow (object.in ());
CORBA::String_var ior = orb_->object_to_string(test.in());
std::cout<<ior.in()<<std::endl;
poa_->the_POAManager()->activate();
orb_->run();
}
int
ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
try
{
CORBA::ORB_var orb =
CORBA::ORB_init (argc, argv);
int result = parse_args (argc, argv);
CORBA::Object_var obj =
orb->resolve_initial_references ("RootPOA");
PortableServer::POA_var root_poa =
PortableServer::POA::_narrow (obj.in ());
PortableServer::POAManager_var poa_manager =
root_poa->the_POAManager ();
testUniqu(orb.in(), root_poa.in());
orb->destroy ();
}
catch (const CORBA::Exception& ex)
{
ex._tao_print_exception ("Exception caught");
return -1;
}
return 0;
}
The problem is that the output server IORs are still different once restart. I also compared this code to the one in Page 412(Advance Corba Programming), but still fail..
///////////////////////////////////
UPDATE:
With "server -ORBListenEndpoints iiop://:1234 > /tmp/ior1", the generated two IORs are:
IOR:010000000d00000049444c3a746573743a312e300000000001000000000000007400000001010200150000007368696a69652d5468696e6b5061642d543431300000d2041b00000014010f0052535453f60054c6f80c000000000001000000010000000002000000000000000800000001000000004f41540100000018000000010000000100010001000000010001050901010000000000
IOR:010000000d00000049444c3a746573743a312e300000000001000000000000007400000001010200150000007368696a69652d5468696e6b5061642d543431300000d2041b00000014010f0052535468f60054da280a000000000001000000010000000002000000000000000800000001000000004f41540100000018000000010000000100010001000000010001050901010000000000
The result for tao_catior for ior1 and ior2:
ior1:
The Byte Order: Little Endian
The Type Id: "IDL:test:1.0"
Number of Profiles in IOR: 1
Profile number: 1
IIOP Version: 1.2
Host Name: **
Port Number: 1234
Object Key len: 27
Object Key as hex:
14 01 0f 00 52 53 54 53 f6 00 54 c6 f8 0c 00 00
00 00 00 01 00 00 00 01 00 00 00
The Object Key as string:
....RSTS..T................
The component <1> ID is 00 (TAG_ORB_TYPE)
ORB Type: 0x54414f00 (TAO)
The component <2> ID is 11 (TAG_CODE_SETS)
Component length: 24
Component byte order: Little Endian
Native CodeSet for char: Hex - 10001 Description - ISO8859_1
Number of CCS for char 1
Conversion Codesets for char are:
1) Hex - 5010001 Description - UTF-8
Native CodeSet for wchar: Hex - 10109 Description - UTF-16
Number of CCS for wchar 0
ecoding an IOR:
//ior2
The Byte Order: Little Endian
The Type Id: "IDL:test:1.0"
Number of Profiles in IOR: 1
Profile number: 1
IIOP Version: 1.2
Host Name: **
Port Number: 1234
Object Key len: 27
Object Key as hex:
14 01 0f 00 52 53 54 68 f6 00 54 da 28 0a 00 00
00 00 00 01 00 00 00 01 00 00 00
The Object Key as string:
....RSTh..T.(..............
The component <1> ID is 00 (TAG_ORB_TYPE)
ORB Type: 0x54414f00 (TAO)
The component <2> ID is 11 (TAG_CODE_SETS)
Component length: 24
Component byte order: Little Endian
Native CodeSet for char: Hex - 10001 Description - ISO8859_1
Number of CCS for char 1
Conversion Codesets for char are:
1) Hex - 5010001 Description - UTF-8
Native CodeSet for wchar: Hex - 10109 Description - UTF-16
Number of CCS for wchar 0
The diff result is:
< 14 01 0f 00 52 53 54 53 f6 00 54 c6 f8 0c 00 00
---
> 14 01 0f 00 52 53 54 68 f6 00 54 da 28 0a 00 00
19c19
< ....RSTS..T................
---
> ....RSTh..T.(..............
Similar diff result is:
< 14 01 0f 00 52 53 54 62 fd 00 54 2c 9a 0e 00 00
---
> 14 01 0f 00 52 53 54 02 fd 00 54 f9 a9 09 00 00
19c19
< ....RSTb..T,...............
---
> ....RST...T................
The difference is in ObjectKey.
============================================
update:
Instead of using above code, i find a better solution with helper TAO_ORB_Manager which is used NamingService and TAO/examples/Simple. TAO_ORB_Manager encapsulates API and generate persistent IORs, as example code in Simple.cpp:
if (this->orb_manager_.init_child_poa (argc, argv, "child_poa") == -1){
CORBA::String_var str =
this->orb_manager_.activate_under_child_poa (servant_name,
this->servant_.in ());
}
This is some description for TAO_ORB_Manager:
class TAO_UTILS_Export TAO_ORB_Manager
{
/**
* Creates a child poa under the root poa with PERSISTENT and
* USER_ID policies. Call this if you want a #a child_poa with the
* above policies, otherwise call init.
*
* #retval -1 Failure
* #retval 0 Success
*/
int init_child_poa (int &argc,
ACE_TCHAR *argv[],
const char *poa_name,
const char *orb_name = 0);
/**
* Precondition: init_child_poa has been called. Activate <servant>
* using the POA <activate_object_with_id> created from the string
* <object_name>. Users should call this to activate objects under
* the child_poa.
*
* #param object_name String name which will be used to create
* an Object ID for the servant.
* #param servant The servant to activate under the child POA.
*
* #return 0 on failure, a string representation of the object ID if
* successful. Caller of this method is responsible for
* memory deallocation of the string.
*/
char *activate_under_child_poa (const char *object_name,
PortableServer::Servant servant);
...................
}
After build, I can get what i want with -ORBListenEndpoints iiop://localhost:2809 option. Thanks #Johnny Willemsen help
You have to create the POA with a persistent lifespan policy, see ACE_wrappers/TAO/tests/POA/Persistent_ID as part of the TAO distribution.

Resources