stevedlawrence commented on a change in pull request #225: Implement 
daf:lookAhead
URL: https://github.com/apache/incubator-daffodil/pull/225#discussion_r290271477
 
 

 ##########
 File path: 
daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DAFFunctions.scala
 ##########
 @@ -72,3 +78,63 @@ case object DAFError extends RecipeOp {
     }
   }
 }
+
+case class DAFLookAhead(recipes: List[CompiledDPath])
+  extends FNTwoArgs(recipes) {
+
+  def computeValue(arg1: AnyRef, arg2: AnyRef, dstate: DState): AnyRef = {
+    val offset = arg1.asInstanceOf[JLong]
+    val lBitSize = arg2.asInstanceOf[JLong]
+
+    /*
+     * Since daf:lookAhead is defined to take unsigned arguements, the DPath 
interperater
+     * will error out on the cast if a negative arguement is supplied, so we 
do not need to SDE here.
+     */
+
+    Assert.invariant(offset >= 0)
+    Assert.invariant(lBitSize >= 0)
+
+    val totalLookahead = offset + lBitSize
+    if (totalLookahead > 512) {
+      dstate.SDE("Look-ahead distance of %s bits exceeds implementation 
defined limit of 512 bits", totalLookahead)
+    }
+    //Safe since we guard on totalLookahead
+    val bitSize = lBitSize.toInt
+
+    if (!dstate.parseOrUnparseState.isDefined) {
+      Assert.invariant(dstate.isCompile)
+      /*
+        * This is an expected code path.
+        * Throwing an exception is how we indicated that this expression does
+        * cannot be reduced to a constant at compile time.
+        */
+      throw new IllegalStateException("No input stream at compile time")
+    }
+    if (dstate.parseOrUnparseState.get.isInstanceOf[PState]) {
+      val pstate = dstate.parseOrUnparseState.get.asInstanceOf[PState]
+      val dis = pstate.dataInputStream
+      if (!dis.isDefinedForLength(totalLookahead)) {
+        val maybeSFL =
+          if (dstate.runtimeData.isDefined) 
One(dstate.runtimeData.get.schemaFileLocation)
+          else Nope
+        throw new ParseError(maybeSFL, dstate.contextLocation, Nope,
+          One("Insufficient bits available to satisfy daf:lookAhead(%s,%s)."),
+          offset, bitSize, totalLookahead)
+      }
+      val mark = dis.markPos
+      dis.skip(offset, pstate)
+      val ans: AnyRef = if (bitSize > 63) {
+        dis.getUnsignedBigInt(bitSize, pstate)
+      } else if (bitSize == 0) {
+        Long.box(0)
+      } else {
+        Long.box(dis.getUnsignedLong(bitSize, pstate).longValue)
+      }
+      dis.resetPos(mark)
+      ans
+    } else {
+      Assert.invariant(dstate.parseOrUnparseState.get.isInstanceOf[UState])
+      dstate.SDE("Cannot call daf:lookAhead() during unparse")
+    }
 
 Review comment:
   Does anyone know if there's information in the compilation process about 
what property an expression is being compiled for? It would be nice to throw 
this SDE at schema compilation time if it' ever used in a expression that could 
be evaluated at unparse, instead of only evaluating at runtime. I would think 
we would have that information, but I can't find it, so maybe not.
   

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


With regards,
Apache Git Services

Reply via email to