Skip to content

Instantly share code, notes, and snippets.

@xomachine
Created June 5, 2017 13:47
Show Gist options
  • Save xomachine/ceeb3505e32859ad9434c64b00c1eb5d to your computer and use it in GitHub Desktop.
Save xomachine/ceeb3505e32859ad9434c64b00c1eb5d to your computer and use it in GitHub Desktop.
Little utility to show rtdb fields of NWChem calculation.
from nesm import serializable
from streams import Stream, atEnd
from tables import Table, initTable, `[]`, `[]=`
const cookie* = "hdbm v1.0"
serializable:
type
FileEntry* = object
key_size: int32
val_size: int32
active*: bool
padding: array[3, byte]
key*: string {size: {}.key_size - 1}
endkey: byte
val*: seq[byte] {size: {}.val_size}# required a feature
Header* = tuple
cookie: string {size: cookie.len}
endcookie: byte
type
NotADBError* = object of Exception
Entry* = object
data*: seq[byte]
active*: bool
HDBM* = Table[string, Entry]
proc load*(input: Stream): HDBM =
let head = Header.deserialize(input)
if head.cookie != cookie:
raise newException(NotADBError, "The file is not a database!")
result = initTable[string, Entry]()
while not input.atEnd:
let fentry = FileEntry.deserialize(input)
let entry = Entry(data: fentry.val, active: fentry.active)
result[fentry.key] = entry
from strutils import startsWith, `%`, join
from sequtils import mapIt
from tables import Table
from tables import initTable, pairs, rightSize, `[]`, `[]=`, len, contains
from nesm import serializable
from hdbm import HDBM
const info_header = "!rtdb!"
const MT_BASE = 1000
serializable:
static:
type DataType* = enum
Undefined
Char = MT_BASE
Integer
LongInteger
Float
Double
LongDouble
SPComplex
DPComplex
LongDPComplex
FortByte
FortInteger
FortLogical
FortReal
FortDP
FortSPComplex
FortDPComplex
type InfoStruct = object
ma_type: uint32
#spacer: array[2, byte]
nelements: uint32
date: array[26, char]
type
UndefinedDataError = object of Exception
Element* = object
nelements*: Natural
kind*: DataType
last_changed*: string
data: seq[byte]
RTDB* = Table[string, Element]
proc toRTDB*(hdbm: HDBM): RTDB =
result = initTable[string, Element](rightSize(hdbm.len div 2))
for k, v in hdbm.pairs():
if k.startsWith(info_header):
#echo "Encountered info section: " & k
#echo $v.active
let info = InfoStruct.deserialize(v.data)
#echo "Data: " & $info
let realKey = k[info_header.len..^1]
if realKey notin result:
result[realKey] = Element(nelements: 0, last_changed: "",
kind: Undefined, data: @[])
result[realKey].nelements = info.nelements
result[realKey].kind = DataType(info.ma_type)
#result[realKey].last_changed = newString(info.date.len)
result[realKey].last_changed = $cast[cstring](info.date[0].unsafeAddr)
#copyMem(result[realKey].last_changed[0].addr, info.date[0].unsafeAddr,
# info.date.len - 1)
else:
if k notin result:
result[k] = Element(nelements: 0, last_changed: "",
kind: Undefined, data: @[])
result[k].data = v.data
proc getKeyAs*[T](self: RTDB, key: string): seq[T] =
let element = self[key]
assert((element.data.len == T.sizeof * element.nelements),
"Size of data is not equals size of type expected")
result = newSeq[T](element.nelements)
for i in 0..<element.nelements:
copyMem(result[i].addr, element.data[i*T.sizeof].unsafeAddr, T.sizeof)
proc stringify[T](a: seq[byte], maxnum: Natural): string =
result = ""
for i in 0..<maxnum:
result.add($(cast[ptr T](a[i*sizeof(T)].unsafeAddr)[]) & ", ")
proc `$`*(e: Element): string =
let last = min(e.nelements, 5)
#assert(e.data.len mod e.nelements == 0, "Kind: $1, len: $2, nelem: $3" %
# [$e.kind, $e.data.len, $e.nelements])
if e.nelements == 0:
"Empty"
else:
let esize = e.data.len div e.nelements
case e.kind:
of Char:
$cast[cstring](e.data[0].unsafeAddr)
of Double, FortDP, LongDouble:
assert(float64.sizeof == esize, "Kind: $1, size: $2" % [$e.kind, $esize])
stringify[float64](e.data, last)
of Integer, LongInteger, FortInteger:
assert(int64.sizeof == esize, "Kind: $1, size: $2" % [$e.kind, $esize])
stringify[int64](e.data, last)
of FortReal, Float:
assert(float32.sizeof == esize, "Kind: $1, size: $2" % [$e.kind, $esize])
stringify[float32](e.data, last)
of FortLogical:
stringify[bool](e.data, last)
of FortByte:
cast[cstring](e.data[0].unsafeAddr).repr
else:
"Undefined"
from hdbm import HDBM, load
from rtdb import toRTDB, `$`
from tables import pairs
from streams import newFileStream
let input = newFileStream(stdin)
let db = input.load()
let nwrtdb = toRTDB(db)
for k, v in nwrtdb.pairs:
echo("Key: " & k & " Kind: " & $v.kind & " Count: " & $v.nelements &
" Data: " & $v & " Last changed: " & v.last_changed)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment