From 8e7b3b15f7a4f888d55f080d3ed61860cd5fab55 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Thu, 31 Jan 2013 18:26:20 -0800 Subject: [PATCH] Support optional values in ProcFileReader. When new values are added to proc files, we need to handle reading them from both old and new kernels. This change supports optionally reading long values. Tests to verify. Bug: 7903145 Change-Id: I9fe250c0486c3cce3cf3d8624f01af01128d1191 --- .../android/internal/util/ProcFileReader.java | 50 ++++++++++++++++--- .../internal/util/ProcFileReaderTest.java | 16 +++++- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/core/java/com/android/internal/util/ProcFileReader.java b/core/java/com/android/internal/util/ProcFileReader.java index 72e1f0ffa2180..81571fe66b5c8 100644 --- a/core/java/com/android/internal/util/ProcFileReader.java +++ b/core/java/com/android/internal/util/ProcFileReader.java @@ -19,6 +19,7 @@ package com.android.internal.util; import java.io.Closeable; import java.io.IOException; import java.io.InputStream; +import java.net.ProtocolException; import java.nio.charset.Charsets; /** @@ -82,12 +83,15 @@ public class ProcFileReader implements Closeable { } /** - * Find buffer index of next token delimiter, usually space or newline. Will - * fill buffer as needed. + * Find buffer index of next token delimiter, usually space or newline. + * Fills buffer as needed. + * + * @return Index of next delimeter, otherwise -1 if no tokens remain on + * current line. */ private int nextTokenIndex() throws IOException { if (mLineFinished) { - throw new IOException("no tokens remaining on current line"); + return -1; } int i = 0; @@ -105,7 +109,7 @@ public class ProcFileReader implements Closeable { } } while (fillBuf() > 0); - throw new IOException("end of stream while looking for token boundary"); + throw new ProtocolException("End of stream while looking for token boundary"); } /** @@ -136,7 +140,7 @@ public class ProcFileReader implements Closeable { } } while (fillBuf() > 0); - throw new IOException("end of stream while looking for line boundary"); + throw new ProtocolException("End of stream while looking for line boundary"); } /** @@ -144,9 +148,11 @@ public class ProcFileReader implements Closeable { */ public String nextString() throws IOException { final int tokenIndex = nextTokenIndex(); - final String s = new String(mBuffer, 0, tokenIndex, Charsets.US_ASCII); - consumeBuf(tokenIndex + 1); - return s; + if (tokenIndex == -1) { + throw new ProtocolException("Missing required string"); + } else { + return parseAndConsumeString(tokenIndex); + } } /** @@ -154,6 +160,33 @@ public class ProcFileReader implements Closeable { */ public long nextLong() throws IOException { final int tokenIndex = nextTokenIndex(); + if (tokenIndex == -1) { + throw new ProtocolException("Missing required long"); + } else { + return parseAndConsumeLong(tokenIndex); + } + } + + /** + * Parse and return next token as base-10 encoded {@code long}, or return + * the given default value if no remaining tokens on current line. + */ + public long nextOptionalLong(long def) throws IOException { + final int tokenIndex = nextTokenIndex(); + if (tokenIndex == -1) { + return def; + } else { + return parseAndConsumeLong(tokenIndex); + } + } + + private String parseAndConsumeString(int tokenIndex) throws IOException { + final String s = new String(mBuffer, 0, tokenIndex, Charsets.US_ASCII); + consumeBuf(tokenIndex + 1); + return s; + } + + private long parseAndConsumeLong(int tokenIndex) throws IOException { final boolean negative = mBuffer[0] == '-'; // TODO: refactor into something like IntegralToString @@ -193,6 +226,7 @@ public class ProcFileReader implements Closeable { return (int) value; } + @Override public void close() throws IOException { mStream.close(); } diff --git a/core/tests/coretests/src/com/android/internal/util/ProcFileReaderTest.java b/core/tests/coretests/src/com/android/internal/util/ProcFileReaderTest.java index 386a78d4cf74f..a81bb4bc7137b 100644 --- a/core/tests/coretests/src/com/android/internal/util/ProcFileReaderTest.java +++ b/core/tests/coretests/src/com/android/internal/util/ProcFileReaderTest.java @@ -134,7 +134,7 @@ public class ProcFileReaderTest extends AndroidTestCase { fail("somehow read a string value?"); } catch (IOException e) { // expected - assertTrue(e.getMessage().contains("end of stream")); + assertTrue(e.getMessage().contains("End of stream")); } } @@ -152,6 +152,20 @@ public class ProcFileReaderTest extends AndroidTestCase { } } + public void testOptionalLongs() throws Exception { + final ProcFileReader reader = buildReader("123 456\n789\n"); + + assertEquals(123L, reader.nextLong()); + assertEquals(456L, reader.nextOptionalLong(-1L)); + assertEquals(-1L, reader.nextOptionalLong(-1L)); + assertEquals(-1L, reader.nextOptionalLong(-1L)); + assertEquals(-1L, reader.nextOptionalLong(-1L)); + reader.finishLine(); + + assertEquals(789L, reader.nextOptionalLong(-1L)); + assertEquals(-1L, reader.nextOptionalLong(-1L)); + } + private static ProcFileReader buildReader(String string) throws IOException { return buildReader(string, 2048); }