Skip to content

Commit

Permalink
Change header value reading code to use enum constants and lambdas (#57)
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 10, 2024
1 parent ecd1acc commit c367ac1
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[] value;

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

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

public byte[] getValue() {
return this.value;
}

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

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 c367ac1

Please sign in to comment.