Skip to content

Commit

Permalink
Change header value reading code to use enum constants and lambdas
Browse files Browse the repository at this point in the history
Instead of using magic constants in `HeaderValue`, use the types already defined in `Type`.
  • Loading branch information
dwalluck committed Apr 5, 2024
1 parent 6f67a52 commit 06e6f75
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 35 deletions.
12 changes: 11 additions & 1 deletion rpm/src/main/java/org/eclipse/packager/rpm/header/Type.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public enum Type {
BLOB(7, 1), //
STRING_ARRAY(8, 1), //
I18N_STRING(9, 1), //
;
UNKNOWN(Integer.MAX_VALUE, 0);

private final int type;

Expand All @@ -42,4 +42,14 @@ public int type() {
public int align() {
return this.align;
}

public static Type fromType(final int type) {
for (final Type t : values()) {
if (t.type == type) {
return t;
}
}

return UNKNOWN;
}
}
92 changes: 58 additions & 34 deletions rpm/src/main/java/org/eclipse/packager/rpm/parse/HeaderValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,36 +13,58 @@

package org.eclipse.packager.rpm.parse;

import static com.google.common.io.BaseEncoding.base16;
import static org.eclipse.packager.rpm.header.Type.UNKNOWN;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.function.Function;

import org.eclipse.packager.rpm.Rpms;
import org.eclipse.packager.rpm.header.Type;

public class HeaderValue {
private static final class Unknown {
static final class Unknown {
private final int type;

private final byte[] data;

public Unknown(int type, byte[] data) {
this.type = type;
this.data = data;
}

public int getType() {
return this.type;
}

public byte[] getData() {
return this.data;
}

@Override
public String toString() {
return "UNKNOWN";
return "UNKNOWN: type: " + this.type + ", data: " + base16().encode(this.data);
}
}

public static final Unknown UNKNOWN = new Unknown();

private final int tag;

private Object value;

private final int type;
private final int originalType;

private final Type type;

private final int index;

private final int count;

public HeaderValue(final int tag, final int type, final int index, final int count) {
this.tag = tag;
this.type = type;
this.originalType = type;
this.type = Type.fromType(type);
this.index = index;
this.count = count;
}
Expand All @@ -55,7 +77,7 @@ public Object getValue() {
return this.value;
}

public int getType() {
public Type getType() {
return this.type;
}

Expand All @@ -69,50 +91,52 @@ public int getIndex() {

void fillFromStore(final ByteBuffer storeData) throws IOException {
switch (this.type) {
case 0: // null value
case NULL:
break;
case 1: // character
this.value = getFromStore(storeData, true, buf -> (char) storeData.get(), size -> new Character[size]);
case CHAR:
this.value = getFromStore(storeData, true, buf -> (char) storeData.get(), Character[]::new);
break;
case 2: // byte
this.value = getFromStore(storeData, true, buf -> buf.get(), size -> new Byte[size]);
case BYTE:
this.value = getFromStore(storeData, true, ByteBuffer::get, Byte[]::new);
break;
case 3: // 16bit integer
this.value = getFromStore(storeData, true, buf -> buf.getShort(), size -> new Short[size]);
case SHORT:
this.value = getFromStore(storeData, true, ByteBuffer::getShort, Short[]::new);
break;
case 4: // 32bit integer
this.value = getFromStore(storeData, true, buf -> buf.getInt(), size -> new Integer[size]);
case INT:
this.value = getFromStore(storeData, true, ByteBuffer::getInt, Integer[]::new);
break;
case 5: // 64bit integer
this.value = getFromStore(storeData, true, buf -> buf.getLong(), size -> new Long[size]);
case LONG:
this.value = getFromStore(storeData, true, ByteBuffer::getLong, Long[]::new);
break;
case 6: // one string
case STRING:
{
// only one allowed
storeData.position(this.index);
this.value = makeString(storeData);
}
break;
case 7: // blob
case BLOB:
{
final byte[] data = new byte[this.count];
storeData.position(this.index);
storeData.get(data);
this.value = data;
this.value = getBlob(storeData);
}
break;
case 8: // string array
this.value = getFromStore(storeData, false, buf -> makeString(buf), size -> new String[size]);
break;
case 9: // i18n string array
this.value = getFromStore(storeData, false, buf -> makeString(buf), size -> new String[size]);
case STRING_ARRAY:
case I18N_STRING:
this.value = getFromStore(storeData, false, HeaderValue::makeString, String[]::new);
break;
default:
this.value = UNKNOWN;
case UNKNOWN:
this.value = new Unknown(this.originalType, getBlob(storeData));
break;
}
}

private byte[] getBlob(ByteBuffer storeData) {
final byte[] data = new byte[this.count];
storeData.position(this.index);
storeData.get(data);
return data;
}

@FunctionalInterface
public static interface IOFunction<T, R> {
public R apply(T t) throws IOException;
Expand Down Expand Up @@ -158,10 +182,10 @@ public String toString() {
sb.append(" - ").append(this.type).append(" = ");

if (this.value != null) {
if (this.value != UNKNOWN) {
sb.append(this.value.getClass().getName());
} else {
if (this.type == UNKNOWN) {
sb.append(this.type);
} else {
sb.append(this.value.getClass().getName());
}
} else {
sb.append("NULL");
Expand Down

0 comments on commit 06e6f75

Please sign in to comment.