1616
1717package com .android .server ;
1818
19+ import android .util .Slog ;
1920import com .google .android .collect .Lists ;
2021
2122import java .util .ArrayList ;
@@ -32,12 +33,14 @@ public class NativeDaemonEvent {
3233 private final int mCode ;
3334 private final String mMessage ;
3435 private final String mRawEvent ;
36+ private String [] mParsed ;
3537
3638 private NativeDaemonEvent (int cmdNumber , int code , String message , String rawEvent ) {
3739 mCmdNumber = cmdNumber ;
3840 mCode = code ;
3941 mMessage = message ;
4042 mRawEvent = rawEvent ;
43+ mParsed = null ;
4144 }
4245
4346 public int getCmdNumber () {
@@ -166,4 +169,86 @@ public static String[] filterMessageList(NativeDaemonEvent[] events, int matchCo
166169 }
167170 return result .toArray (new String [result .size ()]);
168171 }
172+
173+ /**
174+ * Find the Nth field of the event.
175+ *
176+ * This ignores and code or cmdNum, the first return value is given for N=0.
177+ * Also understands "\"quoted\" multiword responses" and tries them as a single field
178+ */
179+ public String getField (int n ) {
180+ if (mParsed == null ) {
181+ mParsed = unescapeArgs (mRawEvent );
182+ }
183+ n += 2 ; // skip code and command#
184+ if (n > mParsed .length ) return null ;
185+ return mParsed [n ];
186+ }
187+
188+ public static String [] unescapeArgs (String rawEvent ) {
189+ final boolean DEBUG_ROUTINE = false ;
190+ final String LOGTAG = "unescapeArgs" ;
191+ final ArrayList <String > parsed = new ArrayList <String >();
192+ final int length = rawEvent .length ();
193+ int current = 0 ;
194+ int wordEnd = -1 ;
195+ boolean quoted = false ;
196+
197+ if (DEBUG_ROUTINE ) Slog .e (LOGTAG , "parsing '" + rawEvent + "'" );
198+ if (rawEvent .charAt (current ) == '\"' ) {
199+ quoted = true ;
200+ current ++;
201+ }
202+ while (current < length ) {
203+ // find the end of the word
204+ if (quoted ) {
205+ wordEnd = current ;
206+ while ((wordEnd = rawEvent .indexOf ('\"' , wordEnd )) != -1 ) {
207+ if (rawEvent .charAt (wordEnd - 1 ) != '\\' ) {
208+ break ;
209+ } else {
210+ wordEnd ++; // skip this escaped quote and keep looking
211+ }
212+ }
213+ } else {
214+ wordEnd = rawEvent .indexOf (' ' , current );
215+ }
216+ // if we didn't find the end-o-word token, take the rest of the string
217+ if (wordEnd == -1 ) wordEnd = length ;
218+ String word = rawEvent .substring (current , wordEnd );
219+ current += word .length ();
220+ if (!quoted ) {
221+ word = word .trim ();
222+ } else {
223+ current ++; // skip the trailing quote
224+ }
225+ // unescape stuff within the word
226+ word .replace ("\\ \\ " , "\\ " );
227+ word .replace ("\\ \" " , "\" " );
228+
229+ if (DEBUG_ROUTINE ) Slog .e (LOGTAG , "found '" + word + "'" );
230+ parsed .add (word );
231+
232+ // find the beginning of the next word - either of these options
233+ int nextSpace = rawEvent .indexOf (' ' , current );
234+ int nextQuote = rawEvent .indexOf (" \" " , current );
235+ if (DEBUG_ROUTINE ) {
236+ Slog .e (LOGTAG , "nextSpace=" + nextSpace + ", nextQuote=" + nextQuote );
237+ }
238+ if (nextQuote > -1 && nextQuote <= nextSpace ) {
239+ quoted = true ;
240+ current = nextQuote + 2 ;
241+ } else {
242+ quoted = false ;
243+ if (nextSpace > -1 ) {
244+ current = nextSpace + 1 ;
245+ }
246+ } // else we just start the next word after the current and read til the end
247+ if (DEBUG_ROUTINE ) {
248+ Slog .e (LOGTAG , "next loop - current=" + current +
249+ ", length=" + length + ", quoted=" + quoted );
250+ }
251+ }
252+ return parsed .toArray (new String [parsed .size ()]);
253+ }
169254}
0 commit comments