Read Bytes data from fetch response - arrays

I want to convert an Android-Kotlin project to React Native, and I have a problem:
The Kotlin project handle data fetch from api like that:
import java.net.URL
import java.nio.ByteBuffer
import java.nio.ByteOrder
fun getData() {
val bytes = try {
URL(address).readBytes()
} catch (e: Exception) {
return emptySet()
}
val arrayBuffer = ByteBuffer
.wrap(bytes)
.order(ByteOrder.BIG_ENDIAN)
}
return arrayBuffer
}
fun URL.readBytes(settings: HeaderSetter? = null): ByteArray {
val request = Request.Builder()
.url(this).let {
settings?.invoke(it) ?: it
}.build()
return client.newCall(request).execute().also { if (it.code() != 200) throw IOException("CODE ${it.code()}") }.body()?.use { it.bytes() } ?: throw IOException()
}
var clientHolder: OkHttpClient? = null
val client: OkHttpClient
get() = clientHolder ?: clientBuilder.build().also {
clientHolder = it
}
How I do it in react-native ?

For people arriving from search engines and looking to get an answer to the question as written in the title, the way to read bytes from a fetch response is to use Response.arrayBuffer or Response.blob.
More information can be found here: https://developer.mozilla.org/en-US/docs/Web/API/Response
Some unsolicited tips for working with array buffers:
To access individual bytes use Uint8Array - i.e. new Uint8Array(array)
To view bytes as a (a.k.a primitive hexdump) decode them as iso-8859-1 using TextDecoder - i.e. new TextDecoder("iso-8859-1")
To convert bytes to normal strings, also use TextDecoder.

Related

Parsing a JSON to convert some parameters into HEX/String

I have the following problem, I'm new in Dart, and I'm using a Future to construct a list view from a JSON response of an API, once I do this request, I receive the following response:
REQUEST:
Future<List<Job>> _fetchJobs() async {
final response = await http.get(
Uri.parse('http://10.10.10.254/httpapi.asp?command=wlanGetApListEx'));
if (response.statusCode == 200) {
final List jsonResponse = json.decode(response.body)['aplist'] as List;
print(jsonResponse);
return jsonResponse.map((job) => new Job.fromJson(job)).toList();
} else {
throw Exception('Failed to load jobs from API');
}
}
[
{
"ssid":444A446F626C65615F322E34,
"bssid":"80":"3f":"5d":"ed":"cd":f9,
"rssi":42,
"channel":8,
"auth":WPA2PSK,
"encry":"AES",
"extch":0
},
{
"ssid":426172696369632D322E3447,
"bssid":"b0":"76":"1b":"f4":"55":80,
"rssi":18,
"channel":1,
"auth":WPA2PSK,
"encry":"AES",
"extch":0
},
{
"ssid":46616D696C69615F65737061727A61,
"bssid":"60":"32":"b1":"71":"ce":46,
"rssi":0,
"channel":5,
"auth":WPA2PSK,
"encry":"AES",
"extch":0
},
{
"ssid":43617361204C756369616E61,
"bssid":"20":"ab":"48":"86":"17":58,
"rssi":0,
"channel":11,
"auth":WPA2PSK,
"encry":"AES",
"extch":0
}
]
As you can see, the SSID values are in HEX and I need it in UTF-16 or UTF-8
I was trying to implement the hex package, but I can not find how to implement it on a JSON array like this.
The hex codex is in the convert package (not to be confused with the dart built in convert library).
If you need to convert the string you have to its ascii/utf8 form use both convert libraries like this:
import 'dart:convert';
import 'package:convert/convert.dart';
void main() {
final h = '444A446F626C65615F322E34';
final u = utf8.decode(hex.decode(h));
print(u); // prints DJDoblea_2.4
}
The more troubling issue seems to be that the data excerpt you provide is not valid JSON, so you cannot, of course, decode it with json.decode.
Try the following code:
import 'dart:convert';
import 'package:convert/convert.dart';
class Job {
Job({required this.ssid, required this.auth, required this.encry});
final String ssid;
final String auth;
final String encry;
factory Job.fromJson(Map<String, dynamic> json) {
return Job(
ssid: utf8.decode(hex.decode(json['ssid'])),
auth: json['auth'],
encry: json['encry'],
);
}
Map<String, dynamic> toMap() {
return {
'ssid': ssid,
'auth': auth,
'encry': encry,
};
}
}
final List<Map<String, dynamic>> jsonResponse = (json.decode(response.body)['aplist'] as List).map((e) => Job.fromJson(e)).map((e) => e.toMap()).toList();

How to properly store uploaded file from multipartform-data in Rust?

I'm trying to build a web server in Rust, and i'm having a few issues trying to upload file into the server. With text based files it uploads fine, but whenever i try to upload other type of media (images, videos, etc), if the file is small enough, it will save, but corrupted, as showned.
original file raw data
file save on the server raw data
And when the file is too big, multer-rs library panicks with "received with incomplete data".
Error log
async fn parse_body(content_type: Option<&String>, body: String) -> HashMap<String, String> {
match content_type {
Some(content_type) => {
let ct = content_type.as_str();
if ct.contains("application/x-www-form-urlencoded") {
let buffer = body.replace("\r\n\r\n", "");
let _body = from_bytes::<Vec<(String, String)>>(buffer.as_bytes()).unwrap();
return _body.into_iter().collect();
}
if ct.contains("multipart/form-data") {
let boundary = multer::parse_boundary(ct).unwrap();
let data = once(async move { Result::<Bytes, Infallible>::Ok(Bytes::from(body)) });
let mut multipart = multer::Multipart::new(data, boundary);
let mut _body: HashMap<String, String> = HashMap::new();
// Iterate over the fields, use `next_field()` to get the next field.
while let Some(mut field) = multipart.next_field().await.unwrap() {
// Get field name.
let name = field.name().unwrap().to_string();
// Get the field's filename if provided in "Content-Disposition" header.
//
// Process the field data chunks e.g. store them in a file.
while let Some(chunk) = field.chunk().await.unwrap() {
// Do something with field chunk.
if let Some(file_name) = field.file_name() {
let file_dir = format!("src\\static\\temp\\{}", file_name);
let current_dir: &Path = Path::new(&file_dir);
let path = env::current_dir().unwrap().join(current_dir);
if let Ok(mut file) = std::fs::File::create(path) {
file.write_all(&chunk).unwrap();
}
} else {
_body.insert(name.clone(), String::from_utf8(chunk.to_vec()).unwrap());
}
}
}
return _body;
}
},
None => return HashMap::new()
}
HashMap::new()
}

Invalid argument when passing ByteArray to javascript through Rhino

I am using Rhino to evaluate some javascript, where I simply pass a ByteArray from kotlin to a function in Javascript. I know it is in bad taste to say this but I am using the same Js file in Swift, and in .Net Core, without an issue with the line that is failing in this case.
As below, I am passing bytes, a ByteArray, to the JS function decodeByteArray(). The line that fails is the one I have marked with the comment //invalid argument
I have checked the ByteArray contents and they are as expected.
Am I doing something wrong or missing something in this?
Javascript
function decodeByteArray(buf) {
var pbf = new Pbf(buf);
return JSON.stringify(decode(pbf));
}
function Pbf(buf) {
this.buf = ArrayBuffer.isView && ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf);
this.pos = 0;
this.type = 0;
this.length = this.buf.length;
setUp(this);
}
Kotlin
private fun decodePbfBytes(bytes: ByteArray?): Any? {
var jsResult: Any? = null;
var params = arrayOf(bytes)
val rhino = org.mozilla.javascript.Context.enter()
rhino.optimizationLevel = -1
rhino.languageVersion = org.mozilla.javascript.Context.VERSION_ES6
try{
val scope = rhino.initStandardObjects()
val assetManager = MyApp.sharedInstance.assets
val input = assetManager.open("pbfIndex.js") //the js file containing js code
val targetReader = InputStreamReader(input)
rhino.evaluateReader(scope, targetReader, "JavaScript", 1,null)
val obj = scope.get("decodeByteArray", scope)
if (obj is org.mozilla.javascript.Function){
jsResult = obj.call(rhino, scope, scope, params)
jsResult = org.mozilla.javascript.Context.toString(jsResult)
}
}catch (ex: Exception){
Log.e("Error", ex.localizedMessage)
}finally {
org.mozilla.javascript.Context.exit()
}
return jsResult
}
Rhino's TypedArray support is a little lacking (see https://mozilla.github.io/rhino/compat/engines.html#ES2015-built-ins-typed-arrays)
I couldn't get the constructor to take a byte[] directly, but it worked after converting to a javascript array.
I believe it will work to change new Uint8Array(buf); to new Uint8Array(Array.from(buf));
While Uint8Array.from is not implemented, Array.from is.

Check if asset exists

Is there any way to check if a asset file exists in Flutter before try to load the data?
For now I have the following:
String data;
try {
data = await rootBundle
.loadString('path/to/file.json');
} catch (Exception) {
print('file not found');
}
The problem is, that I have to check for file 1, if this does not exits I have to check for a fallback file (file 2) and if this does also not exist I load a third file.
My complete code would look like this:
try{
//load file 1
} catch (..) {
//file 1 not found
//load file 2
} catch (...) {
//file 2 not found
//load file 3
}
That looks very ugly to me, but I have no better idea...
AssetBundle (as returned by rootBundle) abstracts over different ways of loading assets (local file, network) and there is no general way of checking if it exists.
You can easily wrap your loading code so that it becomes less "ugly".
Future myLoadAsset(String path) async {
try {
return await rootBundle.loadString(path);
} catch(_) {
return null;
}
}
var assetPaths = ['file1path', 'file2path', 'file3path'];
var asset;
for(var assetPath in assetPaths) {
asset = await myLoadAsset(assetPath);
if(asset != null) {
break;
}
}
if(asset == null) {
throw "Asset and fallback assets couldn't be loaded";
}
I believe a better version is the one without the need to try/catch:
import 'dart:convert';
import 'package:flutter/services.dart';
Future<bool> isLocalAsset(final String assetPath) async {
final encoded = utf8.encoder.convert(Uri(path: Uri.encodeFull(assetPath)).path);
final asset = await ServicesBinding.instance.defaultBinaryMessenger.send('flutter/assets', encoded.buffer.asByteData());
return asset != null;
}

Get an image of a vbhtml view as a byte array and save it to an oracle database

I need help on an mvc application in vb.net. In general terms I need to receive an image through the view and get it to work on the controller. I need to do this to convert the image to a byte array and save it to an oracle database. So my idea is to get the image and in the controller to convert it to a byte array or maybe there is some way to get the image already as a byte array and pass that array to the controller to save it to the database.
something like this its my View :
<div class="span11">
<div class="span4" id="depnac">
#Html.LabelFor(Function(m) m.DepNacPER)
#Html.DropDownListFor(Function(m) m.DepNacPER, Model.DepNacPER, New With {.class = "form-control"})
</div>
and this is my Model :
<Display(Name:="Region of birth")>
<Required(ErrorMessage:="you must select a option")>
Property DepNacPER As SelectList
I'm working on an ASP.NET Core app right now that uploads images. The image comes through to the controller via the request as a Stream. I'm then creating an Image object from that Stream but you could just read the data from it directly. That said, you might want to try to create an Image object to confirm that the data does represent a valid image.
Here's some relevant code from the view's script:
function uploadImage()
{
// This is a file upload control in a hidden div.
var image = $("#imageFile");
if (image[0].files.length > 0)
{
var formData = new FormData();
formData.append(image[0].files[0].name, image[0].files[0]);
var xhr = new XMLHttpRequest();
xhr.open("POST", "#Url.Content("~/events/uploadimage")");
xhr.send(formData);
xhr.onreadystatechange = function ()
{
if (xhr.readyState === 4 && xhr.status === 200)
{
var response = JSON.parse(xhr.responseText);
if (response.saveSuccessful)
{
// ...
} else
{
window.location.replace("#Url.Content("~/error")");
}
}
}
xhr.onerror = function(err, result)
{
alert("Error: " + err.responseText);
}
}
}
I'm in the process of replacing that code with some jQuery that does the heavy lifting but haven't got that far yet.
Here's some relevant code from the action:
[HttpPost]
public IActionResult UploadImage()
{
var requestForm = Request.Form;
StringValues tempImageFileNames;
string tempImageFileName = null;
string imageUrl = null;
var saveSuccessful = true;
var requestFiles = requestForm.Files;
if (requestFiles.Count > 0)
{
// A file has been uploaded.
var file = requestFiles[0];
using (var stream = file.OpenReadStream())
{
try
{
using (var originalImage = System.Drawing.Image.FromStream(stream))
{
// Do whatever you like with the Image here.
}
}
catch (Exception)
{
saveSuccessful = false;
}
}
}
if (saveSuccessful)
{
return Json(new {saveSuccessful, tempImageFileName, imageUrl});
}
else
{
return Json(new {saveSuccessful});
}
}
Sorry, it didn't occur to me at first that you're after VB code and this is C#. Hopefully you can still get the idea and I'll take the hit if someone dislikes the answer.

Resources