GP-1981Checkpoint - more Changes

This commit is contained in:
ghidragon 2022-07-28 16:01:12 -04:00
parent 60b1ae8b44
commit 50de9eb7b3
34 changed files with 1297 additions and 419 deletions

View file

@ -382,11 +382,19 @@ public abstract class WebColors {
int red = Integer.parseInt(split[0]);
int green = Integer.parseInt(split[1]);
int blue = Integer.parseInt(split[2]);
float alpha = Float.parseFloat(split[3]);
return new Color(red, green, blue, (int) (alpha * 255 + 0.5));
int alpha = parseAlpha(split[3]);
return new Color(red, green, blue, alpha);
}
catch (IllegalArgumentException e) {
return null;
}
}
private static int parseAlpha(String string) {
if (string.contains(".")) {
float value = Float.parseFloat(string);
return (int) (value * 0xff + 0.5) & 0xff;
}
return Integer.parseInt(string) & 0xff;
}
}

View file

@ -0,0 +1,121 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.util.datastruct;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.*;
/**
* Class for storing weak reference to object instances. Objects of type T can be place
* in this store and they will remain there until there are no references to that object
* remaining. Note that this is not a Set and you can have multiple instances that are
* "equal" in this store.The main purpose of this store is to be able to get all objects
* in the store that are still reference; typically to refresh or "kick" them in some manner.
* Could be useful for a thread safe weak listener list.
*
* @param <T> The type of objects stored in this WeakStore
*/
public class WeakStore<T> {
protected ReferenceQueue<T> refQueue;
private Link<T> first;
private Link<T> last;
private int size = 0;
public WeakStore() {
refQueue = new ReferenceQueue<>();
}
/**
* Returns the number of objects of type T remaining in the store. Those that are remaining
* are either still referenced
* @return the number of objects still in the store that haven't yet been garbage collected
*/
public synchronized int size() {
processQueue();
return size;
}
/**
* returns a list of all the objects in this store
* @return a list of all the objects in this store
*/
public synchronized List<T> getValues() {
processQueue();
List<T> values = new ArrayList<>();
for (Link<T> l = first; l != null; l = l.nextLink) {
T value = l.get();
if (value != null) {
values.add(value);
}
}
return values;
}
/**
* Adds the given value to the store
* @param value the instance being added to the store
*/
public synchronized void add(T value) {
Objects.requireNonNull(value);
processQueue();
Link<T> newLink = new Link<>(last, value, null, refQueue);
if (last == null) {
first = newLink;
}
else {
last.nextLink = newLink;
}
last = newLink;
size++;
}
@SuppressWarnings("unchecked")
private void processQueue() {
Link<T> ref;
while ((ref = (Link<T>) refQueue.poll()) != null) {
remove(ref);
}
}
private void remove(Link<T> link) {
if (link.previousLink == null) {
first = link.nextLink;
}
else {
link.previousLink.nextLink = link.nextLink;
}
if (link.nextLink == null) {
last = link.previousLink;
}
else {
link.nextLink.previousLink = link.previousLink;
}
size--;
}
private static class Link<T> extends WeakReference<T> {
private Link<T> nextLink;
private Link<T> previousLink;
public Link(Link<T> previous, T value, Link<T> next, ReferenceQueue<T> refQueue) {
super(value, refQueue);
this.nextLink = next;
this.previousLink = previous;
}
}
}

View file

@ -35,7 +35,7 @@ public class WebColorsTest {
@Test
public void testColorToStringFromColorWithNoDefinedEntry() {
assertEquals("#0123EF", WebColors.toString(new Color(0x01, 0x23, 0xEF)));
assertEquals("#0123ef", WebColors.toString(new Color(0x01, 0x23, 0xef)));
}
@Test
@ -45,10 +45,20 @@ public class WebColorsTest {
assertEquals(WebColors.NAVY, WebColors.getColor("#000080"));
assertEquals(WebColors.NAVY, WebColors.getColor("rgb(0,0,128)"));
assertEquals(WebColors.NAVY, WebColors.getColor("rgba(0,0,128,1.0)"));
assertEquals(WebColors.NAVY, WebColors.getColor("rgba(0,0,128, 255)"));
assertEquals(new Color(0x123456), WebColors.getColor("0x123456"));
assertEquals(new Color(0x80102030, true), WebColors.getColor("rgba(16, 32, 48, 0.5)"));
assertNull(WebColors.getColor("asdfasdfas"));
}
@Test
public void testColorWithAlphaRoundTrip() {
Color c = new Color(0x44112233, true);
assertEquals(0x44, c.getAlpha());
String string = WebColors.toString(c, false);
Color parsed = WebColors.getColor(string);
assertEquals(c, parsed);
}
}

View file

@ -0,0 +1,62 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.util.datastruct;
import static org.junit.Assert.*;
import java.util.List;
import org.junit.Test;
public class WeakStoreTest {
@Test
public void testStore() throws InterruptedException {
WeakStore<Foo> store = new WeakStore<>();
store.add(new Foo("AAA"));
store.add(new Foo("BBB"));
store.add(new Foo("CCC"));
assertEquals(3, store.size());
List<Foo> values = store.getValues();
assertEquals("AAA", values.get(0).getName());
assertEquals("BBB", values.get(1).getName());
assertEquals("CCC", values.get(2).getName());
values = null;
for (int i = 0; i < 20; i++) {
System.gc();
if (store.size() == 0) {
break;
}
}
assertEquals(0, store.size());
}
static class Foo {
String name;
Foo(String name) {
this.name = name;
}
String getName() {
return name;
}
}
}