Rev 7747 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
asBitwiseValue =function(val, defValues, className, prefix = NA){if(is.character(val)) {i = pmatch(val, names(defValues))if(!is.na(prefix) && any(is.na(i))) {i[is.na(i)] = pmatch(paste(prefix, val[i], sep = ""), names(defValues))}} else {# check for a single scalar valuei = match(val, defValues)# we didn't get a match, check for a combinationif(any(is.na(i))) {tmp = sapply(defValues, function(x) bitAnd(val, x))i = which(tmp != 0)if(length(i) == 0)stop("can't match ", val, " to elements of bitwise enumeration: ", paste(names(defValues), collapse = ", "))}}if(any(is.na(i)))stop("unmatched name(s) ", val[is.na(i)])value = bitlist(defValues[i])# if className = NA, the we return the number. This is useful# to avoid the expense of creating a new instance only to# take the value to pass to C/C++ code.if(is.na(className))return(value)# Create a new instance of the given class.id = paste(names(defValues)[i], collapse = " | ")ans = new(className, value)names(ans) = idans}BitwiseValue =## create one or more bitwise values.#function(val, name = names(val),class = if(is(val, "BitwiseValue")) class(val) else "BitwiseValue",asVector = TRUE, S3 = FALSE,defValues = getEnumValues(class, name)){if(length(val) > 1 && !asVector) {lapply(seq(along = val), function(i) BitwiseValue(val[i], name[i], class))} else {if(FALSE && S3) {ans = structure(val, names = name, class = unique(c(class, "BitwiseValue")))} else {if(is(val, "character")) {if(missing(name))name = vali = match(val, names(defValues))if(any(is.na(i)))raiseEnumError(val, defValues, TRUE, FALSE, index = i)val = defValues[i]}if(!is.integer(val) && is.na(as.integer(val))) {# the value is too big for an integer in R.warning("BitwiseValue ", val, " doesn't fit into integer value")}ans = new(class, val)names(ans) = name}ans}}getEnumValues =function(class = NA, ids = character()){if(!is.na(class)) {var = sprintf("%sValues", class)if(exists(var))return(get(var))}structure(sapply(ids, get), names = ids)}setAs("BitwiseValue", "numeric",function(from) {ans = bitlist(from)names(ans) = paste(names(from), collapse = " | ")ans})setMethod("|", c("BitwiseValue", "BitwiseValue"),function(e1, e2) {if(class(e1) != class(e2) &&!( is(e1, class(e2)) || is(e2, class(e1))))warning("OR'ing two BitwiseValue objects of different class")v = bitlist(e1, e2)# if these are of different classes, we should decide what class the result# should be.BitwiseValue(v, paste(names(e1), names(e2), sep = " | "), class = class(e1))})setMethod("&", c("BitwiseValue", "BitwiseValue"),function(e1, e2) {if(class(e1) != class(e2) &&!( is(e1, class(e2)) || is(e2, class(e1))))warning("OR'ing two BitwiseValue objects of different class")v = bitAnd(e1, e2) # from package bitops# if these are of different classes, we should decide what class the result# should be.BitwiseValue(v, paste(names(e1), names(e2), sep = " & "), class = class(e1))})# Should this return a vector with the same number of elements as x# a single value?# Version of# Perhaps introduce a BitwiseValueVector to represent more than one element.if(FALSE) {setMethod("c", c("BitwiseValue"),function(x, ..., recursive = FALSE) {val = callNextMethod()val = val[ - grep("\\.\\.\\.[0-9]+", names(val)) ]names(val)[1] = gsub("^x\\.", "", names(val)[1])val = structure(unlist(val), names = names(val))BitwiseValue(val, class = class(x))})}setMethod("c", c("BitwiseValue"),function(x, ..., recursive = FALSE) {els = c(as(x, "numeric"), sapply(list(...), as, "numeric"))defValues = get(paste(class(x), "Values", sep = ""))return(asBitwiseValue(unlist(els), defValues, class(x)))})