stevedlawrence commented on a change in pull request #12: Revised daffodil-io 
module to require passing in a FormatInfo object.
URL: https://github.com/apache/incubator-daffodil/pull/12#discussion_r158041271
 
 

 ##########
 File path: 
daffodil-runtime1/src/main/scala/edu/illinois/ncsa/daffodil/processors/RuntimeData.scala
 ##########
 @@ -183,9 +191,126 @@ sealed abstract class TermRuntimeData(
     optIgnoreCase
     maybeFillByteEv
     tunable
+    maybeCheckByteAndBitOrderEv
+    maybeCheckBitOrderAndCharsetEv
   }
   @throws(classOf[java.io.IOException])
   final private def writeObject(out: java.io.ObjectOutputStream): Unit = 
serializeObject(out)
+
+  final def checkParseBitOrder(pstate: PState) = {
+    //
+    // TODO: This looks like a lot of overhead for every single parse call.
+    //
+    // We need to check for bitOrder change. If it is changing, we
+    // need to know if it is on a proper byte boundary.
+    //
+    val dis = pstate.dataInputStream.asInstanceOf[ByteBufferDataInputStream]
+    val isChanging = isParseBitOrderChanging(dis, pstate)
+    if (isChanging && !dis.isAligned(8))
+      pstate.SDE("Can only change dfdl:bitOrder on a byte boundary. Bit pos 
(1b) was %s.", dis.bitPos1b)
+  }
+
+  private def isParseBitOrderChanging(dis: ByteBufferDataInputStream, pstate: 
PState): Boolean = {
+    pstate.processor.context match {
+      case ntrd: NonTermRuntimeData => false
+      case _ => {
+        val priorBitOrder = dis.st.priorBitOrder
+        val newBitOrder = pstate.bitOrder
+        if (priorBitOrder eq newBitOrder) false
+        else {
+          //
+          // the bit order is changing. Let's be sure
+          // that it's legal to do so w.r.t. other properties
+          // These checks will have been evaluated at compile time if
+          // all the properties are static, so this is really just
+          // in case the charset or byteOrder are runtime-valued.
+          //
+          pstate.processor.context match {
+            case trd: TermRuntimeData => {
+              val mcboc = trd.maybeCheckBitOrderAndCharsetEv
+              val mcbbo = trd.maybeCheckByteAndBitOrderEv
+              if (mcboc.isDefined) mcboc.get.evaluate(pstate) // Expressions 
must be evaluated on the element, not before it is created.
+              if (mcbbo.isDefined) mcbbo.get.evaluate(pstate)
+            }
+            case _ => // ok
+          }
+
+          dis.st.setPriorBitOrder(newBitOrder)
+          true
+        }
+      }
+    }
+  }
+
+  final def checkUnparseBitOrder(ustate: UState) = {
+    //
+    // Check for bitOrder change. If yes, then unless we know we're byte 
aligned
+    // we must split the DOS until we find out. That way the new buffered DOS
+    // can be assumed to be byte aligned (which will be checked on combining),
+    // and the bytes in it will actually start out byte aligned.
+    //
+    val dos = 
ustate.dataOutputStream.asInstanceOf[DirectOrBufferedDataOutputStream]
+    val isChanging = isUnparseBitOrderChanging(dos, ustate)
+    splitOnBitOrderChange(dos, ustate, isChanging)
+  }
+
+  private def isUnparseBitOrderChanging(dos: DirectOrBufferedDataOutputStream, 
ustate: UState): Boolean = {
+    ustate.processor.context match {
+      case ntrd: NonTermRuntimeData => false
+      case _ => {
+        val priorBitOrder = dos.priorBitOrder
+        val newBitOrder = ustate.bitOrder
+        if (priorBitOrder eq newBitOrder) false
+        else {
+          //
+          // the bit order is changing. Let's be sure
+          // that it's legal to do so w.r.t. other properties
+          // These checks will have been evaluated at compile time if
+          // all the properties are static, so this is really just
+          // in case the charset or byteOrder are runtime-valued.
+          //
+          ustate.processor.context match {
+            case trd: TermRuntimeData => {
+              val mcboc = trd.maybeCheckBitOrderAndCharsetEv
+              val mcbbo = trd.maybeCheckByteAndBitOrderEv
+              if (mcboc.isDefined) mcboc.get.evaluate(ustate)
+              if (mcbbo.isDefined) mcbbo.get.evaluate(ustate)
+            }
+            case _ => // ok
+          }
+
+          dos.setPriorBitOrder(newBitOrder)
+          true
+        }
+      }
+    }
+  }
+
+  private def splitOnBitOrderChange(dos: DirectOrBufferedDataOutputStream, 
ustate: UState, isChanging: Boolean): Unit = {
+    val mabp = dos.maybeAbsBitPos0b
+    val mabpDefined = mabp.isDefined
+    val isSplitForBitOrder: Boolean = {
+      if (mabpDefined && dos.isAligned(8)) false
+      else {
+        if (!isChanging) false
+        else {
+          if (!mabpDefined) true
+          else {
+            // mabp is defined, and we're not on a byte boundary
+            // and the bit order is changing.
+            // Error: bit order change on non-byte boundary
+            val bp1b = mabp.get + 1
+            ustate.SDE("Can only change dfdl:bitOrder on a byte boundary. Bit 
pos (1b) was %s.", bp1b)
+          }
 
 Review comment:
   This might be easier to read by changing new lines, e.g:
   
   ```
   if (foo) false
   else if (bar) false
   else if (baz) true
   else {
     //etc.
   }
   ```

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to