FileDocCategorySizeDatePackage
LogReceiver.javaAPI DocAndroid 1.5 API9891Wed May 06 22:41:08 BST 2009com.android.ddmlib.log

LogReceiver

public 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
mCurrentEntry
Current {@link LogEntry} being read, before sending it to the listener.
private byte[]
mEntryHeaderBuffer
Temp buffer to store partial entry headers.
private int
mEntryHeaderOffset
Offset in the partial header buffer
private int
mEntryDataOffset
Offset in the partial entry data
private ILogListener
mListener
Listener 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.

param
listener the listener to receive new log entries.

    
                                               
       
        mListener = listener;
    
Methods Summary
public voidcancel()
Cancels the current remote service.

        mIsCancelled = true;
    
private com.android.ddmlib.log.LogReceiver$LogEntrycreateEntry(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}.

param
data the data buffer the entry is read from.
param
offset the offset of the first byte from the buffer representing the entry.
return
a new {@link LogEntry} or null if some error happened.

        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 booleanisCancelled()
Returns whether this receiver is canceling the remote service.

        return mIsCancelled;
    
public voidparseNewData(byte[] data, int offset, int length)
Parses new data coming from the log service.

param
data the data buffer
param
offset the offset into the buffer signaling the beginning of the new data.
param
length the length of the new data.

        // 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;
            }
        }