package com.sleepycat.persist.impl;
import com.sleepycat.bind.tuple.TupleInput;
import com.sleepycat.db.DatabaseEntry;
class RecordInput extends TupleInput implements EntityInput {
private Catalog catalog;
private boolean rawAccess;
private VisitedObjects visited;
private DatabaseEntry priKeyEntry;
private int priKeyFormatId;
RecordInput(Catalog catalog,
boolean rawAccess,
DatabaseEntry priKeyEntry,
int priKeyFormatId,
byte[] buffer,
int offset,
int length) {
super(buffer, offset, length);
this.catalog = catalog;
this.rawAccess = rawAccess;
this.priKeyEntry = priKeyEntry;
this.priKeyFormatId = priKeyFormatId;
}
private RecordInput(RecordInput other, int offset) {
this(other.catalog, other.rawAccess, other.priKeyEntry,
other.priKeyFormatId, other.buf, offset, other.len);
visited = other.visited;
}
private RecordInput(RecordInput other, DatabaseEntry entry) {
this(other.catalog, other.rawAccess, other.priKeyEntry,
other.priKeyFormatId, entry.getData(), entry.getOffset(),
entry.getSize());
visited = other.visited;
}
public Catalog getCatalog() {
return catalog;
}
public boolean isRawAccess() {
return rawAccess;
}
public boolean setRawAccess(boolean rawAccessParam) {
boolean original = rawAccess;
rawAccess = rawAccessParam;
return original;
}
public Object readObject() {
int visitedOffset = off;
RecordInput useInput = this;
int formatId = readPackedInt();
Object o = null;
if (formatId == Format.ID_NULL) {
return null;
}
if (formatId < 0) {
int offset = (-(formatId + 1));
if (visited != null) {
o = visited.getObject(offset);
}
if (o == VisitedObjects.PROHIBIT_REF_OBJECT) {
throw new IllegalArgumentException
(VisitedObjects.PROHIBIT_NESTED_REF_MSG);
}
if (o != null) {
return o;
} else {
visitedOffset = offset;
if (offset == VisitedObjects.PRI_KEY_VISITED_OFFSET) {
assert priKeyEntry != null && priKeyFormatId > 0;
useInput = new RecordInput(this, priKeyEntry);
formatId = priKeyFormatId;
} else {
useInput = new RecordInput(this, offset);
formatId = useInput.readPackedInt();
}
}
}
if (visited == null) {
visited = new VisitedObjects();
}
int visitedIndex =
visited.add(VisitedObjects.PROHIBIT_REF_OBJECT, visitedOffset);
Format format = catalog.getFormat(formatId);
Reader reader = format.getReader();
o = reader.newInstance(useInput, rawAccess);
visited.setObject(visitedIndex, o);
Object o2 = reader.readObject(o, useInput, rawAccess);
if (o != o2) {
visited.replaceObject(o, o2);
}
return o2;
}
public Object readKeyObject(Format format) {
Reader reader = format.getReader();
Object o = reader.newInstance(this, rawAccess);
return reader.readObject(o, this, rawAccess);
}
KeyLocation getKeyLocation(Format fieldFormat) {
RecordInput input = this;
if (!fieldFormat.isPrimitive()) {
int formatId = input.readPackedInt();
if (formatId == Format.ID_NULL) {
return null;
}
if (formatId < 0) {
int offset = (-(formatId + 1));
if (offset == VisitedObjects.PRI_KEY_VISITED_OFFSET) {
assert priKeyEntry != null && priKeyFormatId > 0;
input = new RecordInput(this, priKeyEntry);
formatId = priKeyFormatId;
} else {
input = new RecordInput(this, offset);
formatId = input.readPackedInt();
}
}
fieldFormat = catalog.getFormat(formatId);
}
return new KeyLocation(input, fieldFormat);
}
public void registerPriKeyObject(Object o) {
if (visited == null) {
visited = new VisitedObjects();
}
visited.add(o, VisitedObjects.PRI_KEY_VISITED_OFFSET);
}
public void skipField(Format declaredFormat) {
if (declaredFormat != null && declaredFormat.isPrimitive()) {
declaredFormat.skipContents(this);
} else {
int formatId = readPackedInt();
if (formatId > 0) {
Format format = catalog.getFormat(formatId);
format.skipContents(this);
}
}
}
public int readArrayLength() {
return readPackedInt();
}
public int readEnumConstant(String[] names) {
return readPackedInt();
}
}