Difference between revisions of "CPF/Source Code"
From SimsWiki
< CPF
(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 01:42, 21 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])))
}