View difference between Paste ID: uwGhstyk and bGf8UKr8
SHOW: | | - or go back to the newest paste.
1
// convert a byte into a list of ones and zeros
2
3
def bits(num: Int): List[Int] = (for (i <- Range(0,8)) yield (((num << i) & 0xff) >>> 7)).toList
4
5
// given a list, take the first N bits
6
7
def next(bits: List[Int], numBits: Int) = {
8
9
  val filler = List[Int](8 - numBits) map (_ => 0)
10
  val bitList = filler ++ bits.take(numBits)
11
  
12
  def convert (accumulator: Int, val_pos: Tuple2[Int, Int]) =
13
    accumulator + (val_pos._1 << val_pos._2)
14
15
  bitList.reverse.zipWithIndex.foldLeft(0) { convert }
16
}
17
18
def localStrings(len: Int, data: DataInputStream): List[String] = {
19
20
  // Works for the NDFD data files as I've found them, but doesn't
21
  // account for more than one group of data (say), or bits that
22
  // might be stored as floating point numbers.
23
24
  val numGroups = readInteger(2, data)
25
  val numValues = readInteger(4, data)
26
  val refValue  = data.readFloat()
27
  val scale     = readInteger(2, data)
28
  val recScale10 = 1 / math.pow(10, scale)
29
  val numBits    = data.readUnsignedByte()
30
  val dataType   = data.readUnsignedByte()
31
32
  // TODO: This really needs to be "streamed" in some
33
  // way so we don't have to keep such a massive list
34
  // in memory. Okay for local WX strings, but is
35
  // unusable on huge CONUS data sets.
36
37
  // Convert the data into a list of ones and zeros
38
39
  var packed: List[Int] = List()
40
41
  for (i <- 1 to (len - 14))
42
    packed = packed ++ bits(data.readUnsignedByte)
43
44
  // Expand the packed bit list into bytes
45
46
  var unpacked: List[Char] = List()
47
48
  for (i <- 1 to numValues) {
49
    unpacked = unpacked ++ List(((refValue + next(packed, numBits)) * recScale10).toChar)
50
    packed = packed.drop(numBits)
51
  }
52
53
  // Convert the zero-delimited strings into a list of strings
54
55
  unpacked.mkString.split(0.toChar.toString).toList
56
}