diff --git a/doc/lib-issues.txt b/doc/lib-issues.txt index 82a9568ca..3a8c87120 100644 --- a/doc/lib-issues.txt +++ b/doc/lib-issues.txt @@ -28,6 +28,7 @@ Datastructures: - List - HashMap - Arrays + - Ranges - BitMatrix - BitVector - Vector @@ -43,14 +44,13 @@ Strings/render - Utf8 Parsing + - Parsed - Symbol - Tokens - Lexing utils - Parsing utils IO - - ByteBuffer - - CharBuffer underlies StringBuilder? - ByteStream - DataReader - DataWriter diff --git a/lib/util/DataReader.v3 b/lib/util/DataReader.v3 index 5a50393e0..29ab0aca4 100644 --- a/lib/util/DataReader.v3 +++ b/lib/util/DataReader.v3 @@ -13,7 +13,7 @@ class DataReader { def var data: Range; // array containing data def var pos: int; // current position def var limit: int = data.length; // read limit within array - def var pos_offset: int; // address of pos = 0 + var startAddr: u64; // address of pos = 0 def var ok: bool = true; // true if no error def var error_pos: int = int.max; // first error position @@ -50,21 +50,17 @@ class DataReader { pos = npos; limit = nlimit; } - // Calculate the absolute offset of the current position. - def abspos() -> int { - return pos + pos_offset; + // Calculate the address of the current position. + def addr() -> u64 { + return u64.!(pos) + startAddr; } - // Calculate the absolute offset of a position {pos}. - def abs_of(pos: int) -> int { - return pos + pos_offset; - } - // Set the position offset to be {npos_offset}. - def atoffset(npos_offset: int) -> this { - pos_offset = npos_offset; + // Calculate the address of a position {pos}. + def addr_of(pos: int) -> u64 { + return u64.!(pos) + startAddr; } // Reset the current data, position, and limit. def reset(ndata: Range, npos: int, nlimit: int) -> this { - pos_offset = 0; + startAddr = 0; data = ndata; pos = npos; limit = nlimit; @@ -75,11 +71,11 @@ class DataReader { } // Record an error at {pos} with the specified message {msg}. def fail_at(pos: int, msg: string) -> this { - onError(this, pos + pos_offset, msg); + onError(this, pos, msg); } // Record end-of-file for a read beginning at the position {pos}, with message {msg}. def eof_at(pos: int, size: int, msg: string) -> this { - onEOF(this, pos + pos_offset, size, Strings.format1(msg, size)); + onEOF(this, pos, size, Strings.format1(msg, size)); } // Peek a single byte, if available, or {-1} if EOF. def peek1() -> int { @@ -279,22 +275,7 @@ class DataReader { pos = 0; limit = combined; } - pos_offset += diff; - } - // Divest from the given buffer {alias} so that this data reader no longer - // aliases it. Callers should use this method if they have previously - // provided {alias} to this data reader through the constructor or - // {append()} but now need to reuse {alias}. - def divest(expecting: int, alias: Range) -> this { - if (alias != data) return; // nothing to do - var avail = available(); - var nlength = if(expecting > avail, expecting, avail); - var nbuf = Array.new(nlength); - for (i < avail) nbuf[i] = data[pos + i]; - data = nbuf; - pos_offset += pos; - limit = avail; - pos = 0; + startAddr += u64.view(diff); } // Populate the given reader {d} with the range of bytes from {this.pos} to // {this.pos + length}. @@ -307,17 +288,17 @@ class DataReader { d.data = data; d.pos = this.pos; d.limit = this.pos + length; - d.pos_offset = this.pos_offset; + d.startAddr = this.startAddr; this.pos += length; } // Set an error on EOF. - def setEOFError(abspos: int, size: int, msg: string) { - onError(this, abspos, msg); + def setEOFError(pos: int, size: int, msg: string) { + onError(this, pos, msg); } // Record the first error for this reader. - def setFirstError(abspos: int, msg: string) { - if (abspos < error_pos) { - error_pos = abspos; + def setFirstError(pos: int, msg: string) { + if (pos < error_pos) { + error_pos = pos; error_msg = msg; ok = false; } diff --git a/test/lib/DataReaderTest.v3 b/test/lib/DataReaderTest.v3 index ce410248a..6a86d20a9 100644 --- a/test/lib/DataReaderTest.v3 +++ b/test/lib/DataReaderTest.v3 @@ -5,7 +5,6 @@ def T = LibTests.register("DataReader", _, _); def X = [ T("putk", test_putk), T("putk_err", test_putk_err), - T("divest", test_divest), T("sleb32", test_i32), T("uleb32", test_u32), T("sleb32ext", test_i32ext), @@ -26,20 +25,21 @@ def X = [ def test_putk(t: LibTest) { // initial buffer = [] def T = t.asserteq; + def L = t.asserteq; def D = t.asserteq>; def B = t.assert_bytes; var x1: Array = []; var d = DataReader.new(x1); T(0, d.pos); T(0, d.limit); - T(0, d.pos_offset); + L(0, d.startAddr); // first putk of [0x99] var x2: Array = [0x99]; d.putk(0, x2, 0, x2.length); T(0, d.pos); T(1, d.limit); - T(0, d.pos_offset); + L(0, d.startAddr); D(x2, d.data); // putk [0x88, 0x99], should copy into new buffer @@ -47,7 +47,7 @@ def test_putk(t: LibTest) { d.putk(0, x3, 0, x3.length); T(0, d.pos); T(3, d.limit); - T(0, d.pos_offset); + L(0, d.startAddr); t.assertne(x1, d.data); t.assertne(x2, d.data); t.assertne(x3, d.data); @@ -61,7 +61,7 @@ def test_putk(t: LibTest) { d.putk(0, x4, 0, x4.length); T(0, d.pos); T(3, d.limit); - T(0, d.pos_offset); + L(0, d.startAddr); D(d3, d.data); B([0x99, 0x33, 0x44], d.data); @@ -72,7 +72,7 @@ def test_putk(t: LibTest) { d.putk(7, x5, 1, 2); T(0, d.pos); T(4, d.limit); - T(1, d.pos_offset); + L(1, d.startAddr); T(7, d.data.length); // hint should be utilized B([0x33, 0x44, 0x11, 0x22, 0, 0, 0], d.data); @@ -83,12 +83,13 @@ def test_putk(t: LibTest) { d.putk(0, x6, 3, 1); T(3, d.pos); T(4, d.limit); - T(5, d.pos_offset); + L(5, d.startAddr); D(x6, d.data); } def test_putk_err(t: LibTest) { def T = t.asserteq; + def L = t.asserteq; var x1: Array = [0x33, 0x44, 0x11, 0x22, 0, 0, 0]; var d = DataReader.new(x1); d.atl(2, 6); @@ -97,43 +98,12 @@ def test_putk_err(t: LibTest) { d.putk(0, [0x77, 0x66], 0, 2); T(0, d.pos); T(6, d.limit); - T(2, d.pos_offset); + L(2, d.startAddr); T(1, d.error_pos); d.putk(0, [0x33], 0, 1); } -def test_divest(t: LibTest) { - def T = t.asserteq; - var x1: Array = [0x33, 0x44]; - var d = DataReader.new(x1); - - d.divest(0, x1); - var d1 = d.data; - t.assertne(x1, d1); - t.assert_bytes(x1, d1); - - d.divest(0, x1); - t.asserteq(d1, d.data); - - d.divest(7, d1); - var d2 = d.data; - t.assertne(d1, d2); - T(7, d2.length); - T(0, d.pos); - T(0, d.pos_offset); - T(2, d.limit); - t.assert_bytes([0x33, 0x44, 0, 0, 0, 0, 0], d2); - - d.atl(3, 5); - d.divest(0, d2); - T(0, d.pos); - T(3, d.pos_offset); - T(2, d.limit); - var d3 = d.data; - t.assert_bytes([0, 0], d3); -} - def assertOk(t: LibTest, f: DataReader -> I, bytes: Array, expected_len: int, expected_val: I) { var d = DataReader.new(bytes);