@@ -109,6 +109,44 @@ macro typeGetter*(body: typed): untyped =
109109 # # Helper macro to get the return type of custom parsers
110110 body.getTypeImpl[0 ][1 ][0 ][0 ]
111111
112+ template writeDataBE * (stream: Stream , buffer: pointer , size: int ) =
113+ for i in 0 ..< size:
114+ let tmp = cast [pointer ](cast [int ](buffer) + ((size- 1 )- i))
115+ stream.writeData (tmp, 1 )
116+
117+ template writeDataLE * (stream: Stream , buffer: pointer , size: int ) =
118+ for i in 0 ..< size:
119+ let tmp = cast [pointer ](cast [int ](buffer) + i)
120+ stream.writeData (tmp, 1 )
121+
122+ template readDataBE * (stream: Stream , buffer: pointer , size: int ) =
123+ for i in 0 ..< size:
124+ let tmp = cast [pointer ](cast [int ](buffer) + ((size- 1 )- i))
125+ if stream.readData (tmp, 1 ) != 1 :
126+ raise newException (IOError ,
127+ " Unable to read the requested amount of bytes from file" )
128+
129+ template readDataLE * (stream: Stream , buffer: pointer , size: int ) =
130+ for i in 0 ..< size:
131+ let tmp = cast [pointer ](cast [int ](buffer) + i)
132+ if stream.readData (tmp, 1 ) != 1 :
133+ raise newException (IOError ,
134+ " Unable to read the requested amount of bytes from file" )
135+
136+ template peekDataBE * (stream: Stream , buffer: pointer , size: int ) =
137+ for i in 0 ..< size:
138+ let tmp = cast [pointer ](cast [int ](buffer) + ((size- 1 )- i))
139+ if stream.peekData (tmp, 1 ) != 1 :
140+ raise newException (IOError ,
141+ " Unable to peek the requested amount of bytes from file" )
142+
143+ template peekDataLE * (stream: Stream , buffer: pointer , size: int ) =
144+ for i in 0 ..< size:
145+ let tmp = cast [pointer ](cast [int ](buffer) + i)
146+ if stream.peekData (tmp, 1 ) != 1 :
147+ raise newException (IOError ,
148+ " Unable to peek the requested amount of bytes from file" )
149+
112150proc replace (node: var NimNode , seenFields: seq [string ]) =
113151 if node.kind == nnkIdent:
114152 if $ node.ident in seenFields:
@@ -305,9 +343,17 @@ proc createWriteStatement(
305343 result = newStmtList ()
306344 if info.size mod 8 == 0 :
307345 result .add (quote do :
308- `stream`.writeData (`field`.addr , `write`)
346+ `stream`.writeDataLE (`field`.addr , `write`)
309347 )
310348 else :
349+ if tmpVar == nil :
350+ raise newException (AssertionError , " tmpVar cannot be nil when size mod" &
351+ " 8 != 0 and info.kind = " & $ info.kind)
352+ if tmpVar != nil and skip != 0 and skip != size div 8 :
353+ let addspace = (size div 8 ) * 8
354+ result .add (quote do :
355+ `tmpVar` = `tmpVar` shl `addspace`
356+ )
311357 if shift > 0 :
312358 result .add (quote do :
313359 `tmpVar` = `tmpVar` or (`field` and `mask`) shl `shift`
@@ -319,16 +365,19 @@ proc createWriteStatement(
319365 if skip != 0 :
320366 if tmpVar != nil :
321367 result .add (quote do :
322- `stream`.writeData (`tmpVar`.addr , `skip`)
368+ `stream`.writeDataLE (`tmpVar`.addr , `skip`)
369+ `tmpVar` = 0
323370 )
324371 else :
325372 result .add (quote do :
326- `stream`.writeData (`field`.addr , `skip`)
373+ `stream`.writeDataLE (`field`.addr , `skip`)
327374 )
375+ #[
328376 if offset + size > (offset + size) mod 8:
329377 result.add(quote do:
330378 `tmpVar` = (`field` and `mask`) shl (8 + `shift`)
331379 )
380+ ]#
332381 offset += size
333382 offset = offset mod 8
334383
@@ -345,14 +394,16 @@ macro createParser*(name: untyped, paramsAndDef: varargs[untyped]): untyped =
345394 res = newIdentNode (" result" )
346395 stream = newIdentNode (" stream" )
347396 input = newIdentNode (" input" )
397+ tmpVar = genSym (nskVar)
348398 # input = genSym(nskParam)
349399 var
350400 inner = newStmtList ()
351401 writer = newStmtList ()
352402 tupleMeat = nnkTupleTy.newNimNode
353403 i = 0
354404 field = 0
355- offset: BiggestInt = 0
405+ readOffset: BiggestInt = 0
406+ writeOffset: BiggestInt = 0
356407 seenFields = newSeq [string ]()
357408 extraParams = newSeq [NimNode ]()
358409 while i < paramsAndDef.len - 1 :
@@ -402,8 +453,8 @@ macro createParser*(name: untyped, paramsAndDef: varargs[untyped]): untyped =
402453 tupleMeat.add (nnkIdentDefs.newTree (resfield, kind, newEmptyNode ()))
403454 if $ info.kind == " string" :
404455 info.size = ($ magic).len
405- inner.add (createReadStatement (sym, info, offset , stream))
406- writer.add (createWriteStatement (writeSym, info, offset , stream))
456+ inner.add (createReadStatement (sym, info, readOffset , stream))
457+ writer.add (createWriteStatement (writeSym, info, writeOffset , stream))
407458 inner.add (quote do :
408459 if `sym` != `magic`:
409460 raise newException (MagicError ,
@@ -424,27 +475,28 @@ macro createParser*(name: untyped, paramsAndDef: varargs[untyped]): untyped =
424475 )
425476 let
426477 ii = genSym (nskVar)
427- tmpVar = genSym (nskVar)
428- startOffset = offset
478+ # tmpVar = genSym(nskVar)
479+ startReadOffset = readOffset
480+ startWriteOffset = writeOffset
429481 var
430482 readFieldOps = @ [
431483 createReadStatement (
432- (quote do : `res`[`field`][`ii`]), info, offset , stream
484+ (quote do : `res`[`field`][`ii`]), info, readOffset , stream
433485 )
434486 ]
435- while startOffset != offset :
487+ while startReadOffset != readOffset :
436488 readFieldOps.add createReadStatement (
437- (quote do : `res`[`field`][`ii`]), info, offset , stream
489+ (quote do : `res`[`field`][`ii`]), info, readOffset , stream
438490 )
439491 var
440492 writeFieldOps = @ [
441493 createWriteStatement (
442- (quote do : `input`[`field`][`ii`]), info, offset , stream, tmpVar
494+ (quote do : `input`[`field`][`ii`]), info, writeOffset , stream, tmpVar
443495 )
444496 ]
445- while startOffset != offset :
497+ while startWriteOffset != writeOffset :
446498 writeFieldOps.add createWriteStatement (
447- (quote do : `input`[`field`][`ii`]), info, offset , stream, tmpVar
499+ (quote do : `input`[`field`][`ii`]), info, writeOffset , stream, tmpVar
448500 )
449501 let
450502 readFieldCount = readFieldOps.len
@@ -523,7 +575,7 @@ macro createParser*(name: untyped, paramsAndDef: varargs[untyped]): untyped =
523575 magic = endMagic[1 ][0 ][1 ]
524576 endKind = endInfo.kind
525577 peek = newIdentNode (" peek" & $ endInfo.kind)
526- bitInfo = getBitInfo (endInfo.size, offset )
578+ bitInfo = getBitInfo (endInfo.size, readOffset )
527579 shift = bitInfo.shift
528580 mask = bitInfo.mask
529581 inner.add (quote do :
@@ -548,7 +600,8 @@ macro createParser*(name: untyped, paramsAndDef: varargs[untyped]): untyped =
548600 `readField`
549601 inc `ii`
550602 )
551- offset = 0
603+ readOffset = 0
604+ writeOffset = 0
552605 of nnkIdent:
553606 if $ def[1 ][0 ].ident == " _" :
554607 if def[0 ].kind == nnkIdent and $ def[0 ].ident == " s" :
@@ -560,20 +613,28 @@ macro createParser*(name: untyped, paramsAndDef: varargs[untyped]): untyped =
560613 )
561614 dec field
562615 else :
563- let jump =
564- if size mod 8 != 0 :
565- if (offset+ size) mod 8 < offset+ size: 1 else : 0
566- else :
567- 0
616+ let
617+ readJump =
618+ if size mod 8 != 0 :
619+ if (readOffset+ size) mod 8 < readOffset+ size: 1 else : 0
620+ else :
621+ 0
622+ writeJump =
623+ if size mod 8 != 0 :
624+ if (writeOffset+ size) mod 8 < writeOffset+ size: 1 else : 0
625+ else :
626+ 0
568627 writer.add (quote do :
569- for i in 0 ..< (`size` div 8 + `jump `):
628+ for i in 0 ..< (`size` div 8 + `writeJump `):
570629 `stream`.write (0 'u8 )
571630 )
572631 inner.add (quote do :
573- `stream`.setPosition (`stream`.getPosition ()+ `size` div 8 + `jump `)
632+ `stream`.setPosition (`stream`.getPosition ()+ `size` div 8 + `readJump `)
574633 )
575- offset += size
576- offset = offset mod 8
634+ readOffset += size
635+ readOffset = readOffset mod 8
636+ writeOffset += size
637+ writeOffset = writeOffset mod 8
577638 dec field
578639 else :
579640 let
@@ -583,12 +644,14 @@ macro createParser*(name: untyped, paramsAndDef: varargs[untyped]): untyped =
583644 tupleMeat.add (nnkIdentDefs.newTree (resfield, kind, newEmptyNode ()))
584645 inner.add (
585646 createReadStatement (
586- (quote do : `res`[`field`]), info, offset , stream
647+ (quote do : `res`[`field`]), info, readOffset , stream
587648 )
588649 )
650+ echo $ sym
651+ echo " (" & $ info.size & " , " & $ writeOffset & " ) -> " & $ getBitInfo (info.size, writeOffset)
589652 writer.add (
590653 createWriteStatement (
591- (quote do : `input`[`field`]), info, offset , stream
654+ (quote do : `input`[`field`]), info, writeOffset , stream, tmpVar
592655 )
593656 )
594657 else :
@@ -611,6 +674,7 @@ macro createParser*(name: untyped, paramsAndDef: varargs[untyped]): untyped =
611674 proc `readerName` (`stream`: Stream ): `tupleMeat` =
612675 `inner`
613676 proc `writerName` (`stream`: Stream , `input`: var `tupleMeat`) =
677+ var `tmpVar`: int64 = 0
614678 `writer`
615679 let `name` = (get: `readerName`, put: `writerName`)
616680 for p in extraParams:
@@ -636,6 +700,12 @@ when isMainModule:
636700 createParser (tert):
637701 3 : test[8 ]
638702
703+ createParser (ccsds_header):
704+ u3: version
705+ u1: packet_type
706+ u1: secondary_header
707+ u11: apid
708+
639709 block parse:
640710 var fs = newFileStream (" data.hex" , fmRead)
641711 defer : fs.close ()
@@ -651,3 +721,22 @@ when isMainModule:
651721 var data: typeGetter (tert)
652722 data.test = @ [1 'i8 , 2 , 3 , 4 , 5 , 6 , 7 , 0 ]
653723 tert.put (fs2, data)
724+ var fs3 = newFileStream (" ccsds.hex" , fmReadWrite)
725+ defer : fs3.close ()
726+ if not fs3.isNil:
727+ var data: typeGetter (ccsds_header)
728+ data.version = 0
729+ data.packet_type = 0
730+ data.secondary_header = 1
731+ data.apid = 6
732+ ccsds_header.put (fs3, data)
733+ var test: int64 = 0x 31_32_33_34_35_36_37_38
734+ var test2: int64 = 0
735+ echo test
736+ echo test.toHex
737+ fs3.writeDataBE (test.addr , 8 )
738+ fs3.setPosition (2 )
739+ fs3.readDataLE (test2.addr , 8 )
740+ echo test2
741+ echo test2.toHex
742+
0 commit comments