Categories
discuss

How to resolve `Raw use of parameterized class ‘Comparable’` warning?

Got to implement the method below for an assignment which it’s subject is “WildCards”, but don’t know where to use wildcards in order to resolve the warning.

static <T extends Comparable> T findMax(T ... items)
{
    T max = items[0];
    for (T item : items)
        if (item.compareTo(max) > 0)
            max = item;
    return max;
}

Any ideas ?

Answer

Comparable is a generic interface, so to use it safely you must always specify the generic type to use. In your case, something like:

<T extends Comparable<T>>

is likely what you’re looking for. Otherwise, the compiler is unable to help you verify that the types are actually compatible in all scenarii.

Categories
discuss

How to handle streaming data using fetch?

I have used async for with great success in handling output streams from processes with node.js, but I’m struggling to get something that I was hoping could “just work” with the browser fetch API.

This works great to async’ly handle chunks of output streaming from a process:

for await (const out of proc.child.stdout) {
  ...
}

(in an async function context here of course)

I tried to do something similar in a browser where I want to gain access to the data while it is being sent to me from the server.

for await (const chunk of (await fetch('/data.jsonl')).body) {
  console.log('got', chunk);
}

This does not work in Chrome (Uncaught TypeError: (intermediate value).body is not async iterable).

For my use case this is not necessary, so I am simply using let data = await (await fetch(datapath)).text(); in my client code for now. This is analogous to the typical use of .json() instead of .text() on the awaited fetch, so no processing can begin until the entire response is received by the browser. This is not ideal for obvious reasons.

I was looking at Oboe.js (I think the relevant impl is somewhere near here) which pretty much deals with this but its internals are fairly ugly so it looks like that might be the only way to do this for now?

If async iteration isn’t implemented (meaning async for cannot be used yet) isn’t there another way to use the ReadableStream in a practical way?

Answer

Unfortunately async iterable support is not yet implemented, despite being in the spec. Instead you can manually iterate, as shown in this example from the spec. (I’ll convert examples to async/await for you in this answer.)

const reader = response.body.getReader();
const { value, done } = await reader.read();

if (done) {
  console.log("The stream was already closed!");
} else {
  console.log(value);
}

You can use recursion or a loop to do this repeatedly, as in this other example:

async function readAllChunks(readableStream) {
  const reader = readableStream.getReader();
  const chunks = [];
  
  let done, value;
  while (!done) {
    ({ value, done } = await reader.read());
    if (done) {
      return chunks;
    }
    chunks.push(value);
  }
}

console.log(await readAllChunks(response.body));
Categories
discuss

Cannot set the value of read-only property ‘classDirectories’ for task ‘…’ of type org.gradle.testing.jacoco.tasks.JacocoReport

I just updated my Android Studio to 4.0 with a new version of Gradle, and I now have an error on my build.

Cannot set the value of read-only property 'classDirectories' for task ':app:testNameOfMyFlavorDebugUnitTestCoverage' of type org.gradle.testing.jacoco.tasks.JacocoReport.

It’s been working fine so far, I don’t know what to change to make it work again.

Answer

Found the response here : https://docs.gradle.org/current/userguide/upgrading_version_5.html#other_deprecated_behaviors_and_apis

And here : Filter JaCoCo coverage reports with Gradle

For example, classDirectories is replaced by classDirectories.from

Categories
discuss

Equivalent version of SHA256 ComputeHash (from C#) for React Native/JS

I’m trying to build an equivalent version of SHA256 ComputeHash (from C#, the EXACT same output from the below sample), to React Native/JavaScript. This is the following C#:

public static string Hash(string input)
{
    if (string.IsNullOrWhiteSpace(input)) return "";

    using (SHA256 hasher = SHA256.Create())
    {
        // Convert the input string to a byte array and compute the hash.
        byte[] data = hasher.ComputeHash(Encoding.Unicode.GetBytes(input));

        // Create a new Stringbuilder to collect the bytes
        // and create a string.
        StringBuilder sBuilder = new StringBuilder();

        // Loop through each byte of the hashed data 
        // and format each one as a hexadecimal string.
        for (int i = 0; i < data.Length; i++)
        {
            sBuilder.Append(data[i].ToString("X2"));
        }

        // Return the hexadecimal string.
        return $"0x{sBuilder.ToString().ToLower()}";
    }
}

I tried the following, but it doesn’t generate the same Hash:

import * as Crypto from 'expo-crypto';

const hash = await Crypto.digestStringAsync(
    Crypto.CryptoDigestAlgorithm.SHA256,
    "StringIWantToHash"
);

Would anyone know, either what’s wrong with the JavaScript, or if there is an exact equivalent version of the C# one?

Answer

Solution 1: Use UTF8 instead of Unicode

Well, this is an Encoding problem.

Encoding.Unicode is Microsoft’s misleading name for UTF-16 (a double-wide encoding, used in the Windows world for historical reasons but not used by anyone else). http://msdn.microsoft.com/en-us/library/system.text.encoding.unicode.aspx (see this answer)

You should be using Encoding.UTF8.GetBytes instead.

Using js-sha256 library like this:

const jssha = require('js-sha256')

function hash(input)
{
    const hashString = "0x" + jssha.sha256(input)
    return hashString;
}

const hashResult = hash("StringIWantToHash")
// Output: 0x29c506d0d69a16e413d63921b7de79525c43715931d8d93127dbeb46eacda2f9

We can achieve pretty similar in C# just using UTF8 encoding:

public static string Hash(string input)
{
    if (string.IsNullOrWhiteSpace(input)) return "";

    using (SHA256 hasher = SHA256.Create())
    {
        // Convert the input string to a byte array and compute the hash.
        byte[] data = hasher.ComputeHash(Encoding.UTF8.GetBytes(input)); // Note that UTF8 here

        // Create a new Stringbuilder to collect the bytes
        // and create a string.
        StringBuilder sBuilder = new StringBuilder();

        // Loop through each byte of the hashed data 
        // and format each one as a hexadecimal string.
        for (int i = 0; i < data.Length; i++)
        {
            sBuilder.Append(data[i].ToString("X2"));
        }

        // Return the hexadecimal string.
        return $"0x{sBuilder.ToString().ToLower()}"; 
    }
}

static void Main()
{
    var hashResult = Hash("StringIWantToHash");
    // Output: 0x29c506d0d69a16e413d63921b7de79525c43715931d8d93127dbeb46eacda2f9
}

Also, I believe that other JS/React Native libraries that help to compute SHA256 hash use UTF8 encoding too, so I think you can use any other crypto libraries for that.

Solution 2: What if you need to use Unicode?

In that case, you need to manually represent C# encoding in JS code.
While you are using Unicode encoding, after every single byte in the string goes ‘0’ byte if it is a plain Latin character. For other symbols (with more than 255 number) Unicode required 2 bytes for that.

var input = "StringIWantToHash";
var encodedInput = Encoding.Unicode.GetBytes(input);
// Output: [83, 0, 116, 0, 114, 0, 105, 0, 110, 0, ...]

So we need to represent that in our JS code:

const jssha = require('js-sha256')

function hash(input)
{
    var bytes = [];
    for (var i = 0; i < input.length; i++)
    {
        const code = input.charCodeAt(i);
        bytes = bytes.concat([code & 0xff, code / 256 >>> 0]);
    }

    const hashString = "0x" + jssha.sha256(bytes)
    return hashString;
}

const hashResult = hash("StringIWantToHash")
// Output: 0x029dbc4b54b39bed6d684175b2d76cc5622c60fe91f0bde9865b977d0d9a531d
Categories
discuss

How can I make the corners of my bottom sheet dialog rounded?

I’m trying to make the top corners of my BottomSheetDialog rounded, but I haven’t had any luck with anything online. This is what I would like for it to look like:

Rounded Modal Bottom Sheet

No matter what I’ve tried, I keep getting this:

Not rounded Modal Bottom Sheet

I’ve tried the method here and using shapeAppearanceLargeComponent (what I’m using now).

Here is my code:

styles.xml

 <style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    ...
    <item name="shapeAppearanceLargeComponent">@style/CustomShapeAppearanceBottomSheetDialog</item>
</style>

<style name="CustomShapeAppearanceBottomSheetDialog" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSizeTopRight">16dp</item>
    <item name="cornerSizeTopLeft">16dp</item>
</style>

BottomNavMenuFragment:

public class BottomNavMenuFragment extends BottomSheetDialogFragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_bottom_nav_drawer, container, false);
    }
}

And this is how I’m showing the fragment:

BottomNavMenuFragment navFragment = new BottomNavMenuFragment();
navFragment.show(getSupportFragmentManager(), navFragment.getTag());

Nothing I seem to do works. Could someone point me in the right direction?

Answer

After messing around with the possible solutions people posted, I figured out that my code was working fine, but the corners of my NavigationView were obscuring the rounded corners of the drawer. After adding some padding, the rounded corners are displaying correctly.

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..