1 module utils.io; 2 import utils; 3 import std.bitmanip; 4 import std..string; 5 6 public import std.file; 7 public import std.stdio; 8 9 /** 10 Reads file value in big endian fashion 11 */ 12 T readValue(T)(ref File file) { 13 size_t currPos = file.tell(); 14 T value = bigEndianToNative!T(file.rawRead(new ubyte[T.sizeof])[0 .. T.sizeof]); 15 16 // HACK: For some reason rawRead *sometimes* 17 // reads an extra byte without any warning 18 // this ensures we don't do that. 19 if (file.tell() != currPos+T.sizeof) file.seek(currPos+T.sizeof); 20 return value; 21 } 22 23 /** 24 Reads file value in big endian fashion 25 */ 26 T peekValue(T)(ref File file) { 27 T val = file.readValue!T; 28 file.skip(-cast(ptrdiff_t)T.sizeof); 29 return val; 30 } 31 32 /** 33 Reads a string 34 */ 35 string readStr(ref File file, uint length) { 36 return cast(string) file.rawRead(new ubyte[length]); 37 } 38 39 /** 40 Peeks a string 41 */ 42 string peekStr(ref File file, uint length) { 43 string val = file.readStr(length); 44 file.seek(-(cast(int)length), SEEK_CUR); 45 return val; 46 } 47 48 /** 49 Reads a pascal string 50 */ 51 string readPascalStr(ref File file, uint readTo = 0) { 52 uint length = file.readValue!ubyte; 53 uint extra = readTo > 0 ? readTo-length : 0; 54 if (length == 0) { 55 file.skip(1); 56 return ""; 57 } 58 59 string str = file.readStr(length); 60 if (extra > 0) file.skip(extra); 61 return str[0..length]; 62 } 63 64 /** 65 Reads values 66 */ 67 ubyte[] read(ref File file, size_t length) { 68 return file.rawRead(new ubyte[length]); 69 } 70 71 /** 72 Peeks values 73 */ 74 ubyte[] peek(ref File file, ptrdiff_t length) { 75 ubyte[] result = file.read(length); 76 file.seek(-cast(ptrdiff_t)length, SEEK_CUR); 77 return result; 78 } 79 80 /** 81 Skips bytes 82 */ 83 void skip(ref File file, ptrdiff_t length) { 84 file.seek(cast(ptrdiff_t)length, SEEK_CUR); 85 }