1 //          Copyright Yazan Dabain 2014.
2 // Distributed under the Boost Software License, Version 1.0.
3 //    (See accompanying file LICENSE_1_0.txt or copy at
4 //          http://www.boost.org/LICENSE_1_0.txt)
5 
6 module elf.sections.stringtable;
7 
8 import std.exception;
9 import std.conv : to;
10 import elf;
11 
12 static if (__VERSION__ >= 2079)
13 	alias elfEnforce = enforce!ELFException;
14 else
15 	alias elfEnforce = enforceEx!ELFException;
16 
17 struct StringTable {
18 	private ELFSection m_section;
19 
20 	this(ELFSection section) {
21 		this.m_section = section;
22 	}
23 
24 	string getStringAt(size_t index) {
25 		import std.algorithm: countUntil;
26 
27 		elfEnforce(index < m_section.size);
28 		ptrdiff_t len = m_section.contents[index .. $].countUntil('\0');
29 		elfEnforce(len >= 0);
30 
31 		return cast(string) m_section.contents[index .. index + len];
32 	}
33 
34 	auto strings() {
35 		static struct Strings {
36 			private ELFSection m_section;
37 			private size_t m_currentIndex = 0;
38 
39 			@property bool empty() { return m_currentIndex >= m_section.size; }
40 
41 			@property string front() {
42 				elfEnforce(!empty, "out of bounds exception");
43 				ptrdiff_t len = frontLength();
44 				elfEnforce(len >= 0, "invalid data");
45 				return cast(string) m_section.contents[m_currentIndex .. m_currentIndex + len];
46 			}
47 
48 			private auto frontLength() {
49 				import std.algorithm: countUntil;
50 
51 				ptrdiff_t len = m_section.contents[m_currentIndex .. $].countUntil('\0');
52 				return len;
53 			}
54 
55 			void popFront() {
56 				elfEnforce(!empty, "out of bounds exception");
57 				this.m_currentIndex += frontLength() + 1;
58 			}
59 
60 			@property typeof(this) save() {
61 				return this;
62 			}
63 
64 			this(ELFSection section) {
65 				this.m_section = section;
66 			}
67 		}
68 
69 		return Strings(this.m_section);
70 	}
71 }