# # # The Nim Compiler # (c) Copyright 2020 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # from typetraits import supportsCopyMem type RodSection* = enum versionSection configSection stringsSection checkSumsSection depsSection integersSection floatsSection topLevelSection bodiesSection symsSection typesSection RodFileError* = enum ok, tooBig, ioFailure, wrongHeader, wrongSection, configMismatch, includeFileChanged RodFile* = object f*: File currentSection*: RodSection # for error checking err*: RodFileError # little experiment to see if this works # better than exceptions. const RodVersion = 1 cookie = [byte(0), byte('R'), byte('O'), byte('D'), byte(0), byte(0), byte(0), byte(RodVersion)] proc storePrim*(f: var RodFile; s: string) = if f.err != ok: return if s.len >= high(int32): f.err = tooBig return var lenPrefix = int32(s.len) if writeBuffer(f.f, addr lenPrefix, sizeof(lenPrefix)) != sizeof(lenPrefix): f.err = ioFailure else: if s.len != 0: if writeBuffer(f.f, unsafeAddr(s[0]), s.len) != s.len: f.err = ioFailure proc storePrim*[T](f: var RodFile; x: T) = if f.err != ok: return when supportsCopyMem(T): if writeBuffer(f.f, unsafeAddr(x), sizeof(x)) != sizeof(x): f.err = ioFailure elif T is tuple: for y in fields(x): storePrim(f, y) else: {.error: "unsupported type for 'storePrim'".} proc storeSeq*[T](f: var RodFile; s: seq[T]) = if f.err != ok: return if s.len >= high(int32): f.err = tooBig return var lenPrefix = int32(s.len) if writeBuffer(f.f, addr lenPrefix, sizeof(lenPrefix)) != sizeof(lenPrefix): f.err = ioFailure else: for i in 0.. 0: if readBuffer(f.f, unsafeAddr(s[0]), s.len) != s.len: f.err = ioFailure proc loadPrim*[T](f: var RodFile; x: var T) = if f.err != ok: return when supportsCopyMem(T): if readBuffer(f.f, unsafeAddr(x), sizeof(x)) != sizeof(x): f.err = ioFailure elif T is tuple: for y in fields(x): loadPrim(f, y) else: {.error: "unsupported type for 'loadPrim'".} proc loadSeq*[T](f: var RodFile; s: var seq[T]) = if f.err != ok: return var lenPrefix = int32(0) if readBuffer(f.f, addr lenPrefix, sizeof(lenPrefix)) != sizeof(lenPrefix): f.err = ioFailure else: s = newSeq[T](lenPrefix) for i in 0..