Merge "Initialize BitInputStream with rule input stream"
This commit is contained in:
committed by
Android (Google) Code Review
commit
4324208bfa
@@ -16,15 +16,29 @@
|
||||
|
||||
package com.android.server.integrity.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/** A wrapper class for reading a stream of bits. */
|
||||
public class BitInputStream {
|
||||
|
||||
private byte[] mRuleBytes;
|
||||
private long mBitPointer;
|
||||
private boolean mReadFromStream;
|
||||
|
||||
private byte[] mRuleBytes;
|
||||
private InputStream mRuleInputStream;
|
||||
|
||||
private byte mCurrentRuleByte;
|
||||
|
||||
public BitInputStream(byte[] ruleBytes) {
|
||||
this.mRuleBytes = ruleBytes;
|
||||
this.mBitPointer = 0;
|
||||
this.mReadFromStream = false;
|
||||
}
|
||||
|
||||
public BitInputStream(InputStream ruleInputStream) {
|
||||
this.mRuleInputStream = ruleInputStream;
|
||||
this.mReadFromStream = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,34 +47,43 @@ public class BitInputStream {
|
||||
* @param numOfBits The number of bits to read.
|
||||
* @return The value read from the stream.
|
||||
*/
|
||||
public int getNext(int numOfBits) {
|
||||
public int getNext(int numOfBits) throws IOException {
|
||||
int component = 0;
|
||||
int count = 0;
|
||||
|
||||
int idx = (int) (mBitPointer / 8);
|
||||
int offset = 7 - (int) (mBitPointer % 8);
|
||||
|
||||
while (count++ < numOfBits) {
|
||||
if (idx >= mRuleBytes.length) {
|
||||
throw new IllegalArgumentException(String.format("Invalid byte index: %d", idx));
|
||||
if (mBitPointer % 8 == 0) {
|
||||
mCurrentRuleByte = getNextByte();
|
||||
}
|
||||
int offset = 7 - (int) (mBitPointer % 8);
|
||||
|
||||
component <<= 1;
|
||||
component |= (mRuleBytes[idx] >>> offset) & 1;
|
||||
component |= (mCurrentRuleByte >>> offset) & 1;
|
||||
|
||||
offset--;
|
||||
if (offset == -1) {
|
||||
idx++;
|
||||
offset = 7;
|
||||
}
|
||||
mBitPointer++;
|
||||
}
|
||||
|
||||
mBitPointer += numOfBits;
|
||||
return component;
|
||||
}
|
||||
|
||||
/** Check if there are bits left in the stream. */
|
||||
public boolean hasNext() {
|
||||
return mBitPointer / 8 < mRuleBytes.length;
|
||||
public boolean hasNext() throws IOException {
|
||||
if (mReadFromStream) {
|
||||
return mRuleInputStream.available() > 0;
|
||||
} else {
|
||||
return mBitPointer / 8 < mRuleBytes.length;
|
||||
}
|
||||
}
|
||||
|
||||
private byte getNextByte() throws IOException {
|
||||
if (mReadFromStream) {
|
||||
return (byte) mRuleInputStream.read();
|
||||
} else {
|
||||
int idx = (int) (mBitPointer / 8);
|
||||
if (idx >= mRuleBytes.length) {
|
||||
throw new IllegalArgumentException(String.format("Invalid byte index: %d", idx));
|
||||
}
|
||||
return mRuleBytes[idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.content.integrity.Rule;
|
||||
|
||||
import com.android.server.integrity.model.BitInputStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -56,15 +57,14 @@ public class RuleBinaryParser implements RuleParser {
|
||||
@Override
|
||||
public List<Rule> parse(InputStream inputStream) throws RuleParseException {
|
||||
try {
|
||||
byte[] ruleBytes = new byte[inputStream.available()];
|
||||
inputStream.read(ruleBytes);
|
||||
return parse(ruleBytes);
|
||||
BitInputStream bitInputStream = new BitInputStream(inputStream);
|
||||
return parseRules(bitInputStream);
|
||||
} catch (Exception e) {
|
||||
throw new RuleParseException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Rule> parseRules(BitInputStream bitInputStream) {
|
||||
private List<Rule> parseRules(BitInputStream bitInputStream) throws IOException {
|
||||
List<Rule> parsedRules = new ArrayList<>();
|
||||
|
||||
// Read the rule binary file format version.
|
||||
@@ -79,7 +79,7 @@ public class RuleBinaryParser implements RuleParser {
|
||||
return parsedRules;
|
||||
}
|
||||
|
||||
private Rule parseRule(BitInputStream bitInputStream) {
|
||||
private Rule parseRule(BitInputStream bitInputStream) throws IOException {
|
||||
Formula formula = parseFormula(bitInputStream);
|
||||
int effect = bitInputStream.getNext(EFFECT_BITS);
|
||||
|
||||
@@ -90,7 +90,7 @@ public class RuleBinaryParser implements RuleParser {
|
||||
return new Rule(formula, effect);
|
||||
}
|
||||
|
||||
private Formula parseFormula(BitInputStream bitInputStream) {
|
||||
private Formula parseFormula(BitInputStream bitInputStream) throws IOException {
|
||||
int separator = bitInputStream.getNext(SEPARATOR_BITS);
|
||||
switch (separator) {
|
||||
case ATOMIC_FORMULA_START:
|
||||
@@ -105,7 +105,7 @@ public class RuleBinaryParser implements RuleParser {
|
||||
}
|
||||
}
|
||||
|
||||
private CompoundFormula parseCompoundFormula(BitInputStream bitInputStream) {
|
||||
private CompoundFormula parseCompoundFormula(BitInputStream bitInputStream) throws IOException {
|
||||
int connector = bitInputStream.getNext(CONNECTOR_BITS);
|
||||
List<Formula> formulas = new ArrayList<>();
|
||||
|
||||
@@ -118,7 +118,7 @@ public class RuleBinaryParser implements RuleParser {
|
||||
return new CompoundFormula(connector, formulas);
|
||||
}
|
||||
|
||||
private AtomicFormula parseAtomicFormula(BitInputStream bitInputStream) {
|
||||
private AtomicFormula parseAtomicFormula(BitInputStream bitInputStream) throws IOException {
|
||||
int key = bitInputStream.getNext(KEY_BITS);
|
||||
int operator = bitInputStream.getNext(OPERATOR_BITS);
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ public class RuleBinarySerializer implements RuleSerializer {
|
||||
|
||||
bitOutputStream.setNext(SEPARATOR_BITS, ATOMIC_FORMULA_START);
|
||||
bitOutputStream.setNext(KEY_BITS, atomicFormula.getKey());
|
||||
if (atomicFormula instanceof AtomicFormula.StringAtomicFormula) {
|
||||
if (atomicFormula.getTag() == AtomicFormula.STRING_ATOMIC_FORMULA_TAG) {
|
||||
AtomicFormula.StringAtomicFormula stringAtomicFormula =
|
||||
(AtomicFormula.StringAtomicFormula) atomicFormula;
|
||||
bitOutputStream.setNext(OPERATOR_BITS, AtomicFormula.EQ);
|
||||
@@ -135,7 +135,7 @@ public class RuleBinarySerializer implements RuleSerializer {
|
||||
stringAtomicFormula.getValue(),
|
||||
stringAtomicFormula.getIsHashedValue(),
|
||||
bitOutputStream);
|
||||
} else if (atomicFormula instanceof AtomicFormula.IntAtomicFormula) {
|
||||
} else if (atomicFormula.getTag() == AtomicFormula.INT_ATOMIC_FORMULA_TAG) {
|
||||
AtomicFormula.IntAtomicFormula intAtomicFormula =
|
||||
(AtomicFormula.IntAtomicFormula) atomicFormula;
|
||||
bitOutputStream.setNext(OPERATOR_BITS, intAtomicFormula.getOperator());
|
||||
@@ -143,7 +143,7 @@ public class RuleBinarySerializer implements RuleSerializer {
|
||||
String.valueOf(intAtomicFormula.getValue()),
|
||||
/* isHashedValue= */ false,
|
||||
bitOutputStream);
|
||||
} else if (atomicFormula instanceof AtomicFormula.BooleanAtomicFormula) {
|
||||
} else if (atomicFormula.getTag() == AtomicFormula.BOOLEAN_ATOMIC_FORMULA_TAG) {
|
||||
AtomicFormula.BooleanAtomicFormula booleanAtomicFormula =
|
||||
(AtomicFormula.BooleanAtomicFormula) atomicFormula;
|
||||
bitOutputStream.setNext(OPERATOR_BITS, AtomicFormula.EQ);
|
||||
|
||||
@@ -127,7 +127,7 @@ public class RuleXmlSerializer implements RuleSerializer {
|
||||
xmlSerializer.startTag(NAMESPACE, ATOMIC_FORMULA_TAG);
|
||||
serializeAttributeValue(
|
||||
KEY_ATTRIBUTE, String.valueOf(atomicFormula.getKey()), xmlSerializer);
|
||||
if (atomicFormula instanceof AtomicFormula.StringAtomicFormula) {
|
||||
if (atomicFormula.getTag() == AtomicFormula.STRING_ATOMIC_FORMULA_TAG) {
|
||||
serializeAttributeValue(
|
||||
VALUE_ATTRIBUTE,
|
||||
((AtomicFormula.StringAtomicFormula) atomicFormula).getValue(),
|
||||
@@ -137,7 +137,7 @@ public class RuleXmlSerializer implements RuleSerializer {
|
||||
String.valueOf(
|
||||
((AtomicFormula.StringAtomicFormula) atomicFormula).getIsHashedValue()),
|
||||
xmlSerializer);
|
||||
} else if (atomicFormula instanceof AtomicFormula.IntAtomicFormula) {
|
||||
} else if (atomicFormula.getTag() == AtomicFormula.INT_ATOMIC_FORMULA_TAG) {
|
||||
serializeAttributeValue(
|
||||
OPERATOR_ATTRIBUTE,
|
||||
String.valueOf(((AtomicFormula.IntAtomicFormula) atomicFormula).getOperator()),
|
||||
@@ -146,7 +146,7 @@ public class RuleXmlSerializer implements RuleSerializer {
|
||||
VALUE_ATTRIBUTE,
|
||||
String.valueOf(((AtomicFormula.IntAtomicFormula) atomicFormula).getValue()),
|
||||
xmlSerializer);
|
||||
} else if (atomicFormula instanceof AtomicFormula.BooleanAtomicFormula) {
|
||||
} else if (atomicFormula.getTag() == AtomicFormula.BOOLEAN_ATOMIC_FORMULA_TAG) {
|
||||
serializeAttributeValue(
|
||||
VALUE_ATTRIBUTE,
|
||||
String.valueOf(((AtomicFormula.BooleanAtomicFormula) atomicFormula).getValue()),
|
||||
|
||||
Reference in New Issue
Block a user