mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
GP-1981Checkpoint - more Changes
This commit is contained in:
parent
60b1ae8b44
commit
50de9eb7b3
34 changed files with 1297 additions and 419 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue