Difference between revisions of "CPF/Source Code"

From SimsWiki
< CPF
Jump to: navigation, search
(First version, shamelessly copied from the DBPF/Source Code page)
 
m (Source)
Line 8: Line 8:
  
 
<pre>
 
<pre>
<?
 
  
 
#
 
#
Line 67: Line 66:
 
}
 
}
  
 
?>
 
  
 
</pre>
 
</pre>

Revision as of 20:42, 20 January 2007

Overview

This page contains a sample R function to read a CPF and extract information about it.

Use at your own risk. Any comments please use the Talk:CPF/Source Code page.

Source


#
# raw is a list of bytes (raw format). They
# should have been read by readBin(f, "raw", n) or
# using a decompressing routine
#
# The return value is a list, with "human" as a human-readable
# list of things in the CPF.
#
convert_cpf <- function(raw)
{
  cpf <- NULL
  cpf$id <- "CPF"
  cpf$version <- get_little_endian(raw, 2)
  n <- get_little_endian(raw[3:6], 4) # number of entries
  cpf$data <- NULL
  pos <- 7  # first 6 bytes are version and number of fields
  # start decoding at position 7
  for (i in 1:n) {
    xtype <- get_little_endian(raw[pos:(pos+3)], 4)
    # xtype is the type of the data, in a crazy hex code
    pos <- pos + 4
    # after each interpretation of raw bytes, we should move pos
    nlen <- get_little_endian(raw[pos:(pos+3)], 4)  # len of field name
    pos <- pos + 4
    name <- rawToChar(raw[pos:(pos+nlen-1)])
    pos <- pos + nlen
    if (xtype == 0xEB61E4F7 || xtype == 0x0C264712 || xtype == 0xABC78708) {  # integer or float
# Nota Bene: I didn't care for float data, I just read and ignore
      data <- get_little_endian(raw[pos:(pos+3)], 4)
      pos <- pos + 4
      cpf[[name]] <- data
    }
    else if (xtype == 0x0B8BEA18) { # string
# get string length
      slen <- get_little_endian(raw[pos:(pos+3)], 4)
      pos <- pos + 4
      str <- rawToChar(raw[pos:(pos+slen-1)])
      pos <- pos + slen
      cpf[[name]] <- str
    }
    else if (xtype == 0xCBA908E1) { # boolean
      cpf[[name]] <- raw[pos]
      pos <- pos + 1
    }
  }
  return(cpf)
}

#
# get_little_endian converts n bytes in little-endian
# format. It means that the first byte is the less significant
#
get_little_endian <- function(bytes, n)
{
  return(sum(256^(0:(n-1)) * as.integer(bytes[1:n])))
}


See Also

Personal tools
Namespaces

Variants
Actions
Navigation
game select
Toolbox