LogReceiverpublic final class LogReceiver extends Object Receiver able to provide low level parsing for device-side log services. |
Fields Summary |
---|
private static final int | ENTRY_HEADER_SIZE | private LogEntry | mCurrentEntryCurrent {@link LogEntry} being read, before sending it to the listener. | private byte[] | mEntryHeaderBufferTemp buffer to store partial entry headers. | private int | mEntryHeaderOffsetOffset in the partial header buffer | private int | mEntryDataOffsetOffset in the partial entry data | private ILogListener | mListenerListener waiting for receive fully read {@link LogEntry} objects | private boolean | mIsCancelled |
Constructors Summary |
---|
public LogReceiver(ILogListener listener)Creates a {@link LogReceiver} with an {@link ILogListener}.
The {@link ILogListener} will receive new log entries as they are parsed, in the form
of {@link LogEntry} objects.
mListener = listener;
|
Methods Summary |
---|
public void | cancel()Cancels the current remote service.
mIsCancelled = true;
| private com.android.ddmlib.log.LogReceiver$LogEntry | createEntry(byte[] data, int offset)Creates a {@link LogEntry} from the array of bytes. This expects the data buffer size
to be at least offset + {@link #ENTRY_HEADER_SIZE} .
if (data.length < offset + ENTRY_HEADER_SIZE) {
throw new InvalidParameterException(
"Buffer not big enough to hold full LoggerEntry header");
}
// create the new entry and fill it.
LogEntry entry = new LogEntry();
entry.len = ArrayHelper.swapU16bitFromArray(data, offset);
// we've read only 16 bits, but since there's also a 16 bit padding,
// we can skip right over both.
offset += 4;
entry.pid = ArrayHelper.swap32bitFromArray(data, offset);
offset += 4;
entry.tid = ArrayHelper.swap32bitFromArray(data, offset);
offset += 4;
entry.sec = ArrayHelper.swap32bitFromArray(data, offset);
offset += 4;
entry.nsec = ArrayHelper.swap32bitFromArray(data, offset);
offset += 4;
// allocate the data
entry.data = new byte[entry.len];
return entry;
| public boolean | isCancelled()Returns whether this receiver is canceling the remote service.
return mIsCancelled;
| public void | parseNewData(byte[] data, int offset, int length)Parses new data coming from the log service.
// notify the listener of new raw data
if (mListener != null) {
mListener.newData(data, offset, length);
}
// loop while there is still data to be read and the receiver has not be cancelled.
while (length > 0 && mIsCancelled == false) {
// first check if we have no current entry.
if (mCurrentEntry == null) {
if (mEntryHeaderOffset + length < ENTRY_HEADER_SIZE) {
// if we don't have enough data to finish the header, save
// the data we have and return
System.arraycopy(data, offset, mEntryHeaderBuffer, mEntryHeaderOffset, length);
mEntryHeaderOffset += length;
return;
} else {
// we have enough to fill the header, let's do it.
// did we store some part at the beginning of the header?
if (mEntryHeaderOffset != 0) {
// copy the rest of the entry header into the header buffer
int size = ENTRY_HEADER_SIZE - mEntryHeaderOffset;
System.arraycopy(data, offset, mEntryHeaderBuffer, mEntryHeaderOffset,
size);
// create the entry from the header buffer
mCurrentEntry = createEntry(mEntryHeaderBuffer, 0);
// since we used the whole entry header buffer, we reset the offset
mEntryHeaderOffset = 0;
// adjust current offset and remaining length to the beginning
// of the entry data
offset += size;
length -= size;
} else {
// create the entry directly from the data array
mCurrentEntry = createEntry(data, offset);
// adjust current offset and remaining length to the beginning
// of the entry data
offset += ENTRY_HEADER_SIZE;
length -= ENTRY_HEADER_SIZE;
}
}
}
// at this point, we have an entry, and offset/length have been updated to skip
// the entry header.
// if we have enough data for this entry or more, we'll need to end this entry
if (length >= mCurrentEntry.len - mEntryDataOffset) {
// compute and save the size of the data that we have to read for this entry,
// based on how much we may already have read.
int dataSize = mCurrentEntry.len - mEntryDataOffset;
// we only read what we need, and put it in the entry buffer.
System.arraycopy(data, offset, mCurrentEntry.data, mEntryDataOffset, dataSize);
// notify the listener of a new entry
if (mListener != null) {
mListener.newEntry(mCurrentEntry);
}
// reset some flags: we have read 0 data of the current entry.
// and we have no current entry being read.
mEntryDataOffset = 0;
mCurrentEntry = null;
// and update the data buffer info to the end of the current entry / start
// of the next one.
offset += dataSize;
length -= dataSize;
} else {
// we don't have enough data to fill this entry, so we store what we have
// in the entry itself.
System.arraycopy(data, offset, mCurrentEntry.data, mEntryDataOffset, length);
// save the amount read for the data.
mEntryDataOffset += length;
return;
}
}
|
|