• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ddmlib;
18 
19 import java.io.UnsupportedEncodingException;
20 import java.util.ArrayList;
21 
22 /**
23  * Base implementation of {@link IShellOutputReceiver}, that takes the raw data coming from the
24  * socket, and convert it into {@link String} objects.
25  * <p/>Additionally, it splits the string by lines.
26  * <p/>Classes extending it must implement {@link #processNewLines(String[])} which receives
27  * new parsed lines as they become available.
28  */
29 public abstract class MultiLineReceiver implements IShellOutputReceiver {
30 
31     private boolean mTrimLines = true;
32 
33     /** unfinished message line, stored for next packet */
34     private String mUnfinishedLine = null;
35 
36     private final ArrayList<String> mArray = new ArrayList<String>();
37 
38     /**
39      * Set the trim lines flag.
40      * @param trim hether the lines are trimmed, or not.
41      */
setTrimLine(boolean trim)42     public void setTrimLine(boolean trim) {
43         mTrimLines = trim;
44     }
45 
46     /* (non-Javadoc)
47      * @see com.android.ddmlib.adb.IShellOutputReceiver#addOutput(
48      *      byte[], int, int)
49      */
addOutput(byte[] data, int offset, int length)50     public final void addOutput(byte[] data, int offset, int length) {
51         if (isCancelled() == false) {
52             String s = null;
53             try {
54                 s = new String(data, offset, length, "UTF-8"); //$NON-NLS-1$
55             } catch (UnsupportedEncodingException e) {
56                 // normal encoding didn't work, try the default one
57                 s = new String(data, offset,length);
58             }
59 
60             // ok we've got a string
61             if (s != null) {
62                 // if we had an unfinished line we add it.
63                 if (mUnfinishedLine != null) {
64                     s = mUnfinishedLine + s;
65                     mUnfinishedLine = null;
66                 }
67 
68                 // now we split the lines
69                 mArray.clear();
70                 int start = 0;
71                 do {
72                     int index = s.indexOf("\r\n", start); //$NON-NLS-1$
73 
74                     // if \r\n was not found, this is an unfinished line
75                     // and we store it to be processed for the next packet
76                     if (index == -1) {
77                         mUnfinishedLine = s.substring(start);
78                         break;
79                     }
80 
81                     // so we found a \r\n;
82                     // extract the line
83                     String line = s.substring(start, index);
84                     if (mTrimLines) {
85                         line = line.trim();
86                     }
87                     mArray.add(line);
88 
89                     // move start to after the \r\n we found
90                     start = index + 2;
91                 } while (true);
92 
93                 if (mArray.size() > 0) {
94                     // at this point we've split all the lines.
95                     // make the array
96                     String[] lines = mArray.toArray(new String[mArray.size()]);
97 
98                     // send it for final processing
99                     processNewLines(lines);
100                 }
101             }
102         }
103     }
104 
105     /* (non-Javadoc)
106      * @see com.android.ddmlib.adb.IShellOutputReceiver#flush()
107      */
flush()108     public final void flush() {
109         if (mUnfinishedLine != null) {
110             processNewLines(new String[] { mUnfinishedLine });
111         }
112 
113         done();
114     }
115 
116     /**
117      * Terminates the process. This is called after the last lines have been through
118      * {@link #processNewLines(String[])}.
119      */
done()120     public void done() {
121         // do nothing.
122     }
123 
124     /**
125      * Called when new lines are being received by the remote process.
126      * <p/>It is guaranteed that the lines are complete when they are given to this method.
127      * @param lines The array containing the new lines.
128      */
processNewLines(String[] lines)129     public abstract void processNewLines(String[] lines);
130 }
131