Levels of abstraction are important in computing. We can look at a computer (and the software it runs) at many levels of abstraction: as quantum devices implementing logical components, as collections of these components implementing digital circuits (described by Boolean formulas), as digital circuits combined into an instruction set architecture (which we'll cover in today's lecture) as an architecture capable of running "translated" computer programs written in a high-level language, as large applications written in high-level programming languages, and as distributed/networked applications running on multiple machines communicating over a network.
It is difficult to hold all these levels of abstraction in our minds while we are exploring and creating computing systems/software. We often focus on just one level of abstraction for our jobs, while knowing some -but less- about the levels directly below and above. We have spent most of ICS 31-33 at the level of discussing computing via the high-level programming language Python. In this lecture we will look down one level, at the architecture into which Python programs are translated and run on: the Python Virtual Machine.
Some programming languages (e.g., C++) are translated into instructions that run directly on hardware. We speak of compiling programs in that language onto a specific hardware architecture. Other programming languages (e.g., Java and Python) are translated to run on a common architecture: interpreters (or virtual machines) for that architecture can be written in a low-level language (like C, which targets most architectures) or in the machine's hardware language itself for maximal speed, so that exactly the same translated programs can run on any architecture that has the virtual machine program implemented on it.
The compiling approach has the advantage of producing programs that execute speedily on real machines. But it is a large undertaking to produce a good compiler for a new architecture, and compiling a program can take a long time. The virtual machine approach is much easier to port to new architectures (it is just one smallish program that must be written to run on the new architecture) but the extra layer of software (even as well as we know how to write interpreters) above the machine reduces performance, often by a factor 2-10 or more. So there is no right way to write language translators: each approach comes with its own advantages and disadvantages, and each can be used/abused in situations.
In fact, hot-spot compilers do a bit of both. They profile programs while interpreting them to find their hots spots (small amounts of code that are executed frequently) and then they compile just those small pieces -all while running the program. Language translation is and has always been an important area in Computer Science. At UCI this topic is covered initially in COMPSCI 142A/B: Language Processor Construction. The computer architectures for real machines (into which compiled programs are compiled) are covered first in ICS-51.
In this lecture we will discuss the code that Python is translated into and how this code is run on the Python Virtual Machine. There is no way to cover this topic fully in one lecture, so my goal is just to introduce this material and show you an interesting vertical slice through it. We will leverage off Python's dis.py module, whose dis function (dis means disassembly) shows us, in a readable form, the Virtual Machine instructions that Python functions, classes, and modules are translated into. At the very end of this lecture we will return to analysis of algorithms by counting the instructions our Python functions are translated into.
Finally, see Section 31.12 in the Python Library documentation for many more details about today's lecture. Once you "get" the big picture, you might find it quite interesting to "dis" a variety of software components. I tried to find information about the Python Virtual Machine on the web, but it is pretty sparse. So I put together this lecture based on general principles and the documentation I could find. There is much more information available for the Java virtual machine.
[top]
Every function object (what we are mostly concerned with in this lecture) is associated with 3 tuples:
(1) its local variable names including parameters (in .__code__.co_varnames) (2) its global names (in .__code__.co_names) (3) it constant (in .__code__.co_consts)
These tuples are built at the time Python defines the function and they are stored in the __code__ object associated with the function.
For example, if we define
def minimum(alist): m = None if len(alist) == 0 else alist[0] for v in alist[1:]: if v < m: m = v return m
Then, minimum.code.covarnames is ('alist', 'm', 'v') minimum.code.conames is ('len', 'None') minimum.code.co_consts is (None, 0, 1)
Load operations (e.g., LOAD_FAST, LOAD_GLOBAL, LOAD_CONST which are all discussed in more detail below) are followed by an integer that indexes these tuples. So for example, in the function addup addup.__code__.co_varnames is the list ('alist', 'sum', 'v'), so the operation LOAD_FAST 0 loads/pushes onto the stack the value the name alist refers to. LOAD_FAST 1 loads/pushes onto the stack the value the name sum refers to. LOAD_FAST 2 loads/pushes onto the stack the value the name v refers to.
[top]
The main data structure in the PVM is the "regular" stack (which is like a restricted a list push=append, pop=pop). A stack's primary operations are load/push and store/pop. We load/push a value on the top of an upwardly-growing stack (incrementing the stackp -stack pointer- that indexes the top); we store/pop a values from the top of a stack (decrementing the stackp).
There is a secondarily important block stack that is used to store information about nested loops, try, and with statements. For example, a break statement is transated into code that uses the block stack to determine which loop to break out of (and how to continue executing at the first statement outside the loop). As loops, try/except, and with statements are started, information about their blocks are pushed onto the block stack; as they terminate, this information is popped off the bock stack. The block stack is too complicated for today's lecture and is not needed to understand it: so when we run across block stack instructions we will point out the fact that we are ignoring them.
Here is an example of a simple sequence of stack operations to perform the calculation d = a+b*c, assuming that a, b, c, and d are local variables inside a function: assume co_varnames is ('a', 'b', 'c', 'd') and the actual values for these names are stored in a parallel tuple (1, 2, 3, None): e.g., the value for 'a' is 1, the value for 'b' is 2, the value for 'c' is 3, and the value for 'd' is None. Generally the value for a name at index i in the co_varnames tuple is stored in index i in the tuple of actual values.
As we will see in more detail below the meaning of
LOAD_FAST N load/push onto the stack the value stored in co_varnames[N], written stackp += 1, stack[stackp] = co_varnames[N] STORE_FAST N store/pop the value on the top of the stack into co_varnames[N], written co_varnames[N] = stack[stackp], and stackp -= 1 BINARY_MULTIPLY load/push onto the stack the * of the two values on the top, written stack[stackp-1] = stack[stackp-1] * stack[stackp]; stackp -= 1 (turns the two values on the top of the stack into their product) BINARY_ADD load/push onto the stack the + of the two values on the top written stack[stackp-1] = stack[stackp-1] + stack[stackp]; stackp -= 1 (turns the two values on the top of the stack into their sum)
The PVM code for d = a+b*c is
LOAD_FAST 0 LOAD_FAST 1 LOAD_FAST 2 BINARY_MULTIPLY BINARY_ADD STORE_FAST 3
Here is what happens step by step.
Initially .... +--------------------+ 3 | | +--------------------+ 2 | | +--------------------+ 1 | | +--------------------+ 0 | | +--------------------+ stack (with stackp = -1, meaning is empty stack)
execute LOAD_FAST 0 .... +--------------------+ 3 | | +--------------------+ 2 | | +--------------------+ 1 | | +--------------------+ 0 | 1: value of a | +--------------------+ stack (with stackp = 0)
execute LOAD_FAST 1 .... +--------------------+ 3 | | +--------------------+ 2 | | +--------------------+ 1 | 2: value of b | +--------------------+ 0 | 1: value of a | +--------------------+ stack (with stackp = 1)
execute LOAD_FAST 2 .... +--------------------+ 3 | | +--------------------+ 2 | 3: value of c | +--------------------+ 1 | 2: value of b | +--------------------+ 0 | 1: value of a | +--------------------+ stack (with stackp = 2)
execute BINARY_MULTIPLY .... +--------------------+ 3 | | +--------------------+ 2 | | +--------------------+ 1 | 6: value of b*c | +--------------------+ 0 | 1: value of a | +--------------------+ stack (with stackp = 1)
execute BINARY_ADD .... +--------------------+ 3 | | +--------------------+ 2 | | +--------------------+ 1 | | +--------------------+ 0 |7: value of a+b*c | +--------------------+ stack (with stackp = 0)
execute STORE_FAST 3 .... +--------------------+ 3 | | +--------------------+ 2 | | +--------------------+ 1 | | +--------------------+ 0 | | +--------------------+ stack (with stackp = -1)
At this point d's value is 7, the value that was at the top of the stack when STORE_FAST was executed. The actual values for these names are stored in the tuple (1, 2, 3, 7).
Problem: show (by drawing what I drew above) how the following instructions compute d = (a+b)*c
LOAD_FAST 0 LOAD_FAST 1 BINARY_ADD LOAD_FAST 2 BINARY_MULTIPLY STORE_FAST 3
Any expression can be translated into similar code for the PVM to evaulate its value.
Control (the fetch/execute cycle) of the PVM
Each instruction (some of which are shown above) in the PVM consists of 1 or 3 bytes of information (a byte is 8 bits, and can represent numbers from 0 to 1. . The first byte is the operation or byte code; the second two bytes are the operand for that byte code (but not all byte codes require operands: LOAD_FAST does; BINARY_ADD doesn't). Two bytes (16 bits) can represent the numbers 0 to 65,536: so it is probably the case that Python function cannot have more than 65,536 different local variable names.
The instructions are stored in memory: think of memory too as a kind of list named m which stores sequential data in one location after the other. We can illustrate this by writing the instruction sequence above as follows:
Memory Instruction Location -------------------------- 0 LOAD_FAST 0 3 LOAD_FAST 1 6 LOAD_FAST 2 9 BINARY_MULTIPLY 10 BINARY_ADD 11 STORE_FAST 3
Note that the first instruction is stored in m[0], and each subsequent instruction is stored in a location that is 3 higher (if the instruction has an explicit operand, as the load/store instructions do; most instructions have implicit operands: stack and pc) or 1 higher (if the instruction has no explicit operands, as the binary operator instructions do).
Technically, the operation name (e.g., LOAD_FAST) represents a one byte value (an integer from 0 to 255). The next two bytes are typically the higher and lower bits in an integer between 0 and 2**16-: 65,535.
Once a program (instruction sequence) is loaded into memory, the PVM executes it according to the following simple rules. This control/execute cycle is what animates computers, allowing then to execute programs. It is fundamental in Computer Science.
(1) Fetch the operation and it operand (if present) starting at m[pc] (2) pc += 3 (if operand is present) or pc += 1 (if no operand is present) (3) Execute operation code (possibly change its operand, stack, stackp, or pc) (4) Go to step 1
Some operations manipulate the stack/stackp and the tuples that store values, others can change the pc (examples of such jump instructions appear in later sections, changing the locus of execution of the code).
So, when the pc is initially 0, the PVM executes the code above as follows
goes back to step 1
fetches the operation a m[3] and the operand at m[4] and m[5]
goes back to step 1
fetches the operation a m[6] and the operand at m[7] and m[8]
goes back to step 1
fetches the operation a m[9]: it has no operand
goes back to step 1
fetches the operation a m[10]: it has no operand
At this point there is no more code to execute. In the next example we will see how the PVM executes more complicated code, specified by full Python functions.
[top]
As described briefly in the intoduction, we can print a symbolic/annotated desciption of any Python function (and module/class too; but in this lecture note we will stick with just functions) by using the dis function in the dis.py module. Here "dis" means "disassemble the code in the function object into a form that is readable by people.
Here is an example function (with line numbers) and the result dis.dis displays for it). All the operation codes and their meanings are covered in detail in the next section; we will look ahead at the relevant ones.
1 def addup(alist): 2 sum = 0 3 for v in alist: 4 sum = sum + v 5 return sum
Actually, I wrote the following simple function to show useful information about any function object (its name, its three tuples, and the dis information:) labelled.
def func_obj(fo): print(fo.__name__) print(' co_varnames:',fo.__code__.co_varnames) print(' co_names :',fo.__code__.co_names) print(' co_consts :',fo.__code__.co_consts,'\n') print('Source Line m operation/byte-code operand (useful name/number)\n'+69*'-') dis.dis(fo)
calling func_obj(addup) prints
addup covarnames: ('alist', 'sum', 'v') conames : () co_consts : (None, 0)
2 0 LOAD_CONST 1 (0) 3 STORE_FAST 1 (sum) 3 6 SETUP_LOOP 24 (to 33) 9 LOAD_FAST 0 (alist) 12 GET_ITER >> 13 FOR_ITER 16 (to 32) 16 STORE_FAST 2 (v) 4 19 LOAD_FAST 1 (sum) 22 LOAD_FAST 2 (v) 25 BINARY_ADD 26 STORE_FAST 1 (sum) 29 JUMP_ABSOLUTE 13 >> 32 POP_BLOCK
5 >> 33 LOAD_FAST 1 (sum) 36 RETURN\_VALUE
Note that any line prefaced by >> means that some other instruction in the function can jump to it (start executing code at it). Jumping in the PVM (by setting pc) is how loops and if statements in Python do their computation.
Here is a high-level description how this function executes. For more details, see the exact description of each instruction in the next section.
Line 2: m[ 0]: loads the value 0 (co_consts[1]) on the stack m[ 3]: stores the value 0 into sum (co_varnames[1])
Line 3: m[ 6]: setup for the loop by pushing the size of the loop onto the block stack (recall that we won't be doing anything with the block stack) m[ 9]: loads the value of alist (covarnames[0]) on the stack m[12]: replaces its value on the stack by its iterator (by popping and pushing) m[13]: loads the next iterator value on the stack, jumping to m[32] if StopIteration raised (code in m[29] jumps back to this location to make the loop) m[16]: stores the next value into v (covarnames[2]), popping it off the stack
Line 4: m[19]: loads the value of sum (co_varnames[1]) on the stack m[22]: loads the value of v (co_varnames[2]) on the stack m[25]: removes from stack/adds two values, pushes the result on the stack m[26]: stores the value into sum (co_varnames[1]), popping it off the stack m[29]: sets pc to 13, so the next instruction executed in at m[13] (jumps back to a previous location to make the loop loop) m[32]: pops what m[6] pushed onto the block stack (recall that we won't be doing anything with the block stack) (code in m[13] jumps here, on StopIteration, terminating the loop)
Line 5: m[33]: load the value of sum (co_varnames[1]) on the stack to return m[36]: return from the function with the result on the top of the stack
[top]
Below is a list of many important operations and how they manipulate the PVM. The complete list is available in section 31.12 of the Python documenation. Recall that many operations manipulate stack, stackp, and pc.
Loading/Storing
LOAD_CONST N stackp += 1, stack[stackp] = co_consts[N] LOAD_FAST N stackp += 1, stack[stackp] = co_varnames[N] LOAD_GLOBAL N stackp += 1, stack[stackp] = co_names[N] STORE_CONST N co_consts[N] = stack[stackp], and stackp -= 1 STORE_FAST N co_varnames[N] = stack[stackp], and stackp -= 1 STORE_GLOBAL N co_names[N] = stack[stackp], and stackp -= 1
There are general Load and Store operations that look up names based on the the LEGB rules, if Python is unsure where these names will be found. Generally it uses the operations above.
Operators UNARYPOSITIVE stack[stackp] = +stack[stackp] UNARYNEGATIVE stack[stackp] = -stack[stackp] UNARYNOT stack[stackp] = not stack[stackp] UNARYINVERT stack[stackp] = ~stack[stackp]
BINARY_ADD stack[stackp-1] = stack[stackp-1] + stack[stackp]; stackp -= 1 BINARY_SUBTRACT stack[stackp-1] = stack[stackp-1] - stack[stackp]; stackp -= 1 BINARY_MULTIPLY stack[stackp-1] = stack[stackp-1] * stack[stackp]; stackp -= 1 BINARY_TRUE_DIVIDE stack[stackp-1] = stack[stackp-1] / stack[stackp]; stackp -= 1 BINARY_FLOOR_DIVIDE stack[stackp-1] = stack[stackp-1] // stack[stackp]; stackp -= 1 BINARY_MODULO stack[stackp-1] = stack[stackp-1] % stack[stackp]; stackp -= 1 BINARY_POWER stack[stackp-1] = stack[stackp-1] ** stack[stackp]; stackp -= 1 BINARY_SUBSCR (indexing) stack[stackp-1] = stack[stackp-1] [ stack[stackp] ]; stackp -= 1 BINARY_LSHIFT stack[stackp-1] = stack[stackp-1] << stack[stackp]; stackp -= 1 BINARY_RSHIFT stack[stackp-1] = stack[stackp-1] >> stack[stackp]; stackp -= 1 BINARY_AND stack[stackp-1] = stack[stackp-1] & stack[stackp]; stackp -= 1 BINARY_OR stack[stackp-1] = stack[stackp-1] | stack[stackp]; stackp -= 1 BINARY_XOR stack[stackp-1] = stack[stackp-1] ^ stack[stackp]; stackp -= 1
There are in-place versions of the binary operators: e.g., x += 1 vs x = x + 1 I will show the meanin of INPLACE_ADD and just list the others here:
INPLACE_ADD stack[stackp-1] += stack[stackp]; stackp -= 1
INPLACE_SUBTRACT, INPLACE_MULTIPLY, INPLACE_FLOOR_DIVIDE, INPLACE_TRUE_DIVIDE, INPLACE_MODULO, INPLACE_POWER, INPLACE_LSHIFT, INPLACE_RSHIFT, INPLACE_AND, INPLACE_XOR, and INPLACE_OR
Iteration:
GET_ITER stack[stackp] = iter(stack[stackp]) FOR_ITER N stackp += 1; stack[stackp] = next(stack[stackp-1]) but if StopIteration exception is raised in part 2: pc += N Jumping (changing the pc from where the next instruction is fetched): JUMP_ABSOLUTE N pc = N JUMP_FORWARD N pc += N POP_JUMP_IF_TRUE N if stack[stackp] is True, pc = N (always stackp =- 1) POP_JUMP_IF_FALSE N if stack[stackp] is False, pc = N (always stackp =- 1)
Calling Functions and Returning/Yielding CALLFUNCTION N The first operand byte is a count of the position arguments: pcount The second operand byte is a count of the keyword arguments: kcount There are kcount values on the top of the stack followed by pcount values followed by the function to call This operation pops all function arguments off the stack to store them into the covarnames tuple, and pops off the the function itself The function should leave its answer on the top of the stack
RETURN_VALUE Return to the location that called this function (its retuned answer on the top of the stack)
YIELD_VALUE
In the Library Reference, they use the notation TOS to mean the location at the top of the stack, and TOSn to mean n down from the top of the stack. So TOS is our stack[stackp] and TOS1 is our stack[stackp-1]
[top] statement (lines 4-5) and a conditional expression (line 6), which translate into a variety of jump instructions. Also note how the tuple assignment in line 2 is translated via the UNPACK_SEQUENCE N instruction (which takes any sequence of values (tuple or list) and pushes N of them onto the stack right to left: so if (0,1) is on the stack, UNPACK_SEQUENCE 2 pops this value off the stack, pushing first 1 then 0 onto the stack (which is why the first value below is stored into sum and the second is stored into count).
1 def average_positive(alist): 2 sum,count = 0,0 3 for v in alist: 4 if v > 0: 5 sum = sum + v 6 count += 1 7 return sum / (1 if count == 0 else count)
average_positive covarnames: ('alist', 'sum', 'count', 'v') conames : () co_consts : (None, 0, 1, (0, 0))
2 0 LOAD_CONST 3 ((0, 0)) 3 UNPACKSEQUENCE 2 6 STOREFAST 1 (sum) 9 STORE_FAST 2 (count)
3 12 SETUP_LOOP 49 (to 64)
15 LOADFAST 0 (alist)
18 GETITER
>> 19 FORITER 41 (to 63)
22 STOREFAST 3 (v)
4 25 LOAD_FAST 3 (v) 28 LOADCONST 1 (0) 31 COMPAREOP 4 (>) 34 POPJUMPIF_FALSE 19
5 37 LOAD_FAST 1 (sum)
40 LOADFAST 3 (v)
43 BINARYADD
44 STORE_FAST 1 (sum)
6 47 LOAD_FAST 2 (count)
50 LOADCONST 2 (1)
53 INPLACEADD
54 STOREFAST 2 (count)
57 JUMPABSOLUTE 19
60 JUMPABSOLUTE 19
>> 63 POPBLOCK
7 >> 64 LOAD_FAST 1 (sum) 67 LOAD_FAST 2 (count) 70 LOAD_CONST 1 (0) 73 COMPARE_OP 2 (==) 76 POP_JUMP_IF_FALSE 85 79 LOAD_CONST 2 (1) 82 JUMP_FORWARD 3 (to 88) >> 85 LOAD_FAST 2 (count) >> 88 BINARY_TRUE_DIVIDE 89 RETURN\_VALUE
Please feel free to type in all sorts of small functions to see how they are translated to run on the PVM. The project folder that you can download includes some simple functions and the func_obj function.
Note that the two simple functions shown did not call functions on their inside: see addup1 in the project folder, which uese range and len to iterate of the list indexes to compute the sum. The relevant line in the function is
for i in range(len(alist)):
The local/global names are
co_varnames: ('alist', 'sum', 'i') co_names : ('range', 'len')
and sequence of instructions is
9 LOAD_GLOBAL 0 (range) 12 LOAD_GLOBAL 1 (len) 15 LOAD_FAST 0 (alist) 18 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 21 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 24 GET_ITER >> 25 FOR_ITER 20 (to 48) 28 STORE_FAST 2 (i)
Here the range function, to call last, is loaded/pushed on the stack; then the len function, to call first, is loaded/pushed on the stack; then the alist variable is pushed on the stack. The stack looks as follows
.... +--------------------+ 3 | | +--------------------+ 2 | alist value | +--------------------+ 1 | len function | +--------------------+ 0 | range function | +--------------------+ stack (with stackp = 2)
The first CALL_FUNCTION 1 says using 1 positional argument (stackp=2), call the function specified at stackp-1 (len) on the stack, leaving the answer on the stack. The stack looks as follows
.... +--------------------+ 3 | | +--------------------+ 2 | | +--------------------+ 1 | len(alist) value | +--------------------+ 0 | range function | +--------------------+ stack (with stackp = 1)
The second CALL_FUNCTION 1 says using 1 positional argument (stackp=1), call the function specified at stackp-1 (range) on the stack, leaving the answer on the stack. The stack looks as follows
.... +--------------------+ 3 | | +--------------------+ 2 | | +--------------------+ 1 | | +--------------------+ 0 | range(len(alist)) | The range iterator +--------------------+ stack (with stackp = 1)
Then GET_ITER is called to do the iteration, which uses FOR_ITER to produce the first value (which is stored in local variable i).
[top]
We can use the result of dis to compute the worst case count of the numnber of instructions executed in a function. Let's return to (and review) the addup function for our analysis.
1 def addup(alist): 2 sum = 0 3 for v in alist: 4 sum = sum + v 5 return sum
addup covarnames: ('alist', 'sum', 'v') conames : () co_consts : (None, 0)
2 0 LOAD_CONST 1 (0) 3 STORE_FAST 1 (sum) 3 6 SETUP_LOOP 24 (to 33) 9 LOAD_FAST 0 (alist) 12 GET_ITER >> 13 FOR_ITER 16 (to 32) 16 STORE_FAST 2 (v) 4 19 LOAD_FAST 1 (sum) 22 LOAD_FAST 2 (v) 25 BINARY_ADD 26 STORE_FAST 1 (sum) 29 JUMP_ABSOLUTE 13 >> 32 POP_BLOCK
5 >> 33 LOAD_FAST 1 (sum) 36 RETURN\_VALUE
Here is how to account for the number of instructions executed when Python runs this function. As always we will assume that the len(alist) is N. Here there are no conditional statements so the worst case always executes all the code in the function (and the loop N times).
Instructions done once (not in the loop proper) 2 for line 2, code before the loop: initialize sum 3 for line 3, setup for the loop; not repeated in the loop proper at m[13] 1 for line 4, at m[32], jumped to when StopIteration exception is raised 2 for line 5, code after the loop: load/push sum on the stack and return
Instructions done in the loop 2 for line 3, m[13] and m[16]; note loop back to m[13] 5 for line 4, sum = sum + v and jump back to m[13] to get next iterator value
Finally, note that the instruction at m[13] is executed N+1 times: N times it continues in the loop body and 1 time it raises StopIteration and jumps to m[32].
So, the I(N) is 8 (instructions done once) + 7N (instructions done in the loop) + 1 (m[13] done on N+1 iteration raising StopInteration) instructions.
I(N) = 7N + 9 instructions


§356D-97 Appeals. An aggrieved party may secure a review of any final judgment of the circuit court under this part by appeal to the appellate courts, subject to chapter 602. The appeal shall be taken in the manner provided in the rules of court. [L 2006, c 180, pt of §2; am L 2007, c 193, §6]


Last days I’ve working in a phonegap/cordova project. The main purpose of the project was taking photos with the device’s camera and sending them to the server. It’s a simple apache cordova project using the camera plugin. According to the documentation we can upload pictures with the following javascript code:
navigator.camera.getPicture(onSuccess, onFail, {
quality: 100,
destinationType: Camera.DestinationType.DATA_URL
});
function onSuccess(imageData) {
// here we can upload imageData to the server
}
function onFail(message) {
alert('Failed because: ' + message);
}
As we can see we our plugin retrieves a base64 encoded version of our image and we can send it to the server, using jQuery for example
function onSuccess(imageData) {
$.post( "upload.php", {data: imageData}, function(data) {
alert("Image uploaded!");
});
}
Our server side is trivial. We only need to read the request variable ‘data’, perform a base64 decode and we have our binary picture ready to be saved.
I test it with an old android smartphone (with a not very good camera) and it’s works, but when I tried to use it with a better android phone (with 8mpx camera) it hangs on and it didn’t work. After property reading the documentation I realized that it isn’t the better way to upload files to the server. It only works if the image file is small. Base64 increases the size of the image and our device can have problems handling the memory. This way Is also slow as hell.
The best way (the way that works, indeed) is, instead of sending the base64 files to the server, to save them into a device’s temporary folder and send them using the file transfer plugin.
var pictureSource; // picture source
var destinationType; // sets the format of returned value
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
pictureSource = navigator.camera.PictureSourceType;
destinationType = navigator.camera.DestinationType;
}
function clearCache() {
navigator.camera.cleanup();
}
var retries = 0;
function onCapturePhoto(fileURI) {
var win = function (r) {
clearCache();
retries = 0;
alert('Done!');
}
var fail = function (error) {
if (retries == 0) {
retries ++
setTimeout(function() {
onCapturePhoto(fileURI)
}, 1000)
} else {
retries = 0;
clearCache();
alert('Ups. Something wrong happens!');
}
}
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1);
options.mimeType = "image/jpeg";
options.params = {}; // if we need to send parameters to the server request
var ft = new FileTransfer();
ft.upload(fileURI, encodeURI("http://host/upload"), win, fail, options);
}
function capturePhoto() {
navigator.camera.getPicture(onCapturePhoto, onFail, {
quality: 100,
destinationType: destinationType.FILE_URI
});
}
function onFail(message) {
alert('Failed because: ' + message);
}
I just realized that sometimes it fails. It looks like a bug of cordova plugin (I cannot assert it), because of that, if you read my code, you can see that if fp.upload fails I retry it (only once). With this little hack it works like a charm (and it’s also fast).
The server part is pretty straightforward. We only need to handle uploaded files. Here a minimalistic example with php
<?php
move_uploaded_file($_FILES["file"]["tmp_name"], '/path/to/file');
And that’s all. We can easily upload our photos from our smartphone using phonegap/cordova.
You can read more articles about cordova here.


Spanning and placing cardio
- Make the grid 10 columns wide, every other taking up twice the free space
- Make the grid have 10 explicit rows, 50px high each
- Whit item 1, start at col 3 and go until 5
- Whit item 2, start at col 5 and go until the end
- Make item 5 double span 2 cols and rows
- Make item 8 two rows high
- Make item 15 span the stire grid with
- Make item 18 span 4 widths but end 9
- Make item 20 start at row 4 and go for 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30


Hi! I’m Sam
I'm an editor and programmer based in New York. I'm currently looking for work! I'm interested in privacy, security, passwords, user education, technical writing, and Rust.
Most recently, I was an editor at CNN Plus, CNN's short-lived streaming service. Before that I spent about ten years as a social media editor. I also write code sometimes.
Here are some things I can do.
You can find me on GitHub, Mastodon, LinkedIn, and Twitter. From time to time I write about passwords, privacy, Rust, books, text editors, code, etc.
Code
Here are some of my favorite coding projects from over the years, organized by language. You can browse my coding blog or GitHub profile for more examples.
Passphrase word list work
- Created the Orchard Street wordlists, one of which is used by the Buttercup password manager and another is available to users of the Strongbox password manager
- Refined and coded a procedure for making a word list uniquely decodable with minimal cuts
- Developed a word list for making better Netflix passwords
Rust command line tools and other projects
- Tidy combines and cleans-up large wordlists, commonly used for generating passphrases or usernames. You can read more about it here.
- Medic checks the passwords of a KeePass database against a list of breached password hashes, like the one offered by HaveIBeenPwned. Here's a blog post I wrote about it.
- QRForge helps users safely handle 32-character TOTP secret keys and their equivalent QR codes.
- I assisted in an analysis of Russian troll Twitter data for CNN, using Rust.
JavaScript games
- Strike 9 is a frustrating little puzzle game. I wrote a blog post about the deceptively tricky functions involved.
- Switch asks you to get the red circles to the right and the blue circles to the left in the fewest number of moves possible.
- Contract Rummy Score Card is an interactive scorecard for a difficult-to-keep-track-of card game.
Ruby and Rails
- Radiation is a blog-publishing engine designed for "Tilde Clubs."
- SquawkBot is a Ruby on Rails web application that surfaces URLs that more than one of your Twitter follows tweeted (sort of like Nuzzel).
Python and Flask
- For Shareablee, I used Python and the Facebook Graph API to analyze how their customers used Facebook and displayed this data using NVD3. I then used the Flask framework to create a web application that allowed potential customers to share their Facebook data and compare their page against the compiled benchmark of the current customers.
Social Media Editing
I was a Social Media Producer at CNN from 2015 to 2021, primarily working with CNN's Facebook account. Our social media team won a Webby and a Murrow Award for our coverage of the 2016 election. I also compiled and analyzed social media analytics and created Slack bots for our teams, using Rust, Ruby and Python. Additionally, I maintained technical documentation for the team, using mdbook.
Before that, I held similar positions at BuzzFeed News and Newsweek & The Daily Beast, where I focused on running both organizations' Twitter and Facebook accounts.
Writing
You can read my most recent, more technical writing on my blog, including guides for enabling two-factor authentication on Mastodon, getting started with Restic, and using KeePassXC password manager. I also wrote an overview of my Vim configuration, and notes on my Linux setup.
While at Newsweek and The Daily Beast, I reported a few articles. Here are some favorites:
- “This is How China Hacks America: Inside the Mandiant Report”
- An interview with Lars Rasmussen of Facebook
- A profile of the media center at Occupy Wall Street
- “7 Things to Do on National Day of Unplugging”
For something a bit more poetic, check out this dreamy travel diary of a trip to Los Angeles in 2011.
Contact
You can reach me via Direct Message on Mastodon or through more secure methods.


| 2021 (Expected) |
University of California, Santa Barbara, California (UCSB) > Degree: PhD Candidate in Geography > Emphasis: Modeling, Measurement, and Computation > Advisor: Dr. Keith C. Clarke > Committee: Dr. Hugo Loaiciga, Dr. Kelly Caylor, David Blogett (USGS) |
| 2019 - Present |
Data Scientist: Urban Flooding Open Knowledge Network |
| 2020 - Present |
Water Resourcees Engineer II*: Lynker Technologies/ NOAA-Affiliate Assigned to the NOAA Next Generation Water Modeling Engine and Framework Prototype development group |
| 2015 |
California Polytechnic State University, San Luis Obispo, California > Degree: B.S. Geography and Anthropology > Honors: Cum Laude > Minors: Water Science (Watershed Management Emphasis) Geographic Information Systems for Agriculture Statistics Environmental Studies Economics |
| Visiting Researcher |
The VU Amsterdam Amsterdam, The Netherlands June - July 2019 Jan - Mar 2018 NCAR Research Applications Laboratory Boulder, CO Aug - Sep 2018 NOAA National Water Center Tuscaloosa, Alabama June - Aug 2017 June - Aug 2016 |
| *Security Clearance (Secret) |


Due to COVID-19, the VLDB Conference 2020 will be held as an online virtual conference. The meeting schedule remains unchanged from August 31st to September 4th, 2020. The conference dates are from August 31st to September 4th, 2020. More details will be posted soon. Please check this website regularly for updates.
Preliminary Conference Timetable


| Opcode | Instruction | 64-Bit Mode | Compat/Leg Mode | Description |
| D9 E1 | FABS | Valid | Valid | Replace ST with its absolute value. |
Clears the sign bit of ST(0) to create the absolute value of the operand. The following table shows the results obtained when creating the absolute value of various classes of numbers.
| ST(0) SRC | ST(0) DEST |
| − ∞ | + ∞ |
| − F | + F |
| − 0 | + 0 |
| + 0 | + 0 |
| + F | + F |
| + ∞ | + ∞ |
| NaN | NaN |
Notes: F Means finite floating-point value.
This instruction’s operation is the same in non-64-bit modes and 64-bit mode.
ST(0) ← |ST(0)|;
| C1 | Set to 0. |
| C0, C2, C3 | Undefined. |
| #IS | Stack underflow occurred. |
| #NM | CR0.EM[bit 2] or CR0.TS[bit 3] = 1. |
| #UD | If the LOCK prefix is used. |
Same exceptions as in protected mode.
Same exceptions as in protected mode.
Same exceptions as in protected mode.
Same exceptions as in protected mode.


--- layout: default title: Passive and Active Clauses ---
Beautiful temples were built by the Greeks.
The Greeks built beautiful temples.
The Athenians built the Parthenon.
The Parthenon was built by the Athenians.
In the 5th century a new temple was built by the people of Ankragas.
In the 5th century the people of Ankragas built a new temple.
The members of the assembly voted on the proposal.
The proposal was voted on by the members of the assembly.
An architect was hired by a building committee.
A building committee hired an architect.
The architect supervised the construction of the temple.
The construction of the temple was supervised by the architect.
The foundation was laid by the construction crew on solid bedrock.
The construction crew laid the foundation on solid bedrock.
They laid the foundation on solid bedrock.
The foundation was laid on solid bedrock.
The foundation was backfilled with soil.
They backfilled the foundation with soil.
They made the platform with squared blocks.
The platform was made with squared blocks.
A simple style of temple was preferred in mainland Greece.
They preferred a simple style of temple in mainland Greece.
They developed the simple Doric style a few decades before the more elaborate Ionic style.
The simple Doric style was developed a few decades before the more elaborate Ionic style.
Greek column styles are used by modern architects.
Modern architects use Greek column styles.
Construction cranes lift steel beams to great heights.
Steel beams are lifted to great heights by construction cranes.
The Doric style is distinguished from the Ionian style by its simplicity.
Its simplicity distinguishes the Doric style from the Ionian style.


Titanic Survival Exploration
In 1912, the ship RMS Titanic hit an iceberg on its maiden voyage and sank. Most of its passengers and crew died, though a number of them did survive. This machine learning (ML) project is to explore passenger manifest of Titanic and find any realtion between surving and any attributes of a passenger. A subset of the manifes was provided as training set for which the outcome of survival, i.e, survied or dead is known. The ML model should learn from this set. A test set was then given with passenger of unkown destiny. The ML model should reliably predict what happened to these test cases.
In the passenger manifest a number of features about the passengers are avaible, including name, age, seating class, ticket number, fare paid, port of embarcation etc. Not all passengers have every piece of information, meaning some of the feature values were missing. The objective of this project is to: (i) identify the features that are highly related to the survival outcome (ii) predict the outcome at least with 80%.
The Jypyter notebook code using Python for this project is found here.
It was found the most significant feature that determined the survival is gender- more female passengers survived than male passengers. The second most important feature was age: younger passengers had survived more than older ones. The third most significant feature was seating class. Passengers from lower classes didnt quite make it as passengers from upper classes.
These findings actually reflect the facts that women and children were given preference in leaving the ship and boarding on lifeboats. It is also a fact that upper-class passengers who stayed in cabin had easy access to lifeboats whereas lower-deck passengers had to clib up to upper level to access them. More of these historical interesting facts are discussed in Nat Geo website.


associate professor @ elon School of Com director @ elon iMedia founder @ hackranch previously fulbright scholar @ UiB infomedia (18-19) associate director @ elon CATL (17-20)


The CrimeWaves Podcast was initiated due to the the inspiration to develop and create a podcast series
based on Canadian criminal events. (Topic selected by students). In order to explore the distinct crimes
witnessed in Canadian history, students are tasked with exploring different aspects of each case, and this
case becomes the focus of a season. The different aspects then becomes the focus of each episode. This podcast
brings to listeners real and raw journalism at an amateur level, helping listeners gain an initial and informed
perspective on significant crimes occurring in Canada. This is a student driven project taken on by the grade 12
Canadian international law class at CPSS
Who Are the Creators?
A grade 12 Law teacher, Justin Schicksneit at Central Peel Secondary School is the moderator of this podcast.
Though he does not create the content himself, he moderates and regulates the episodes along with organizing Seasons
and helps audit each episode. This content is created by grade 12 law students themselves and is also researched by them
in order to put it into a cohesive episode in the end. Each episode is given as a summative project to groups of 4/5 made
by the students. The class then, as a collective, decides which criminal event in Canadian history they would like to research.
The students are required to give credible sources to their findings. These citations have been provided to you by the CrimeWaves
team to acknowledge the importance of credible journalism. These students and teachers work hard to provide to the listeners journalism
of the highest quality.


Solicitation Review Tool (SRT)
FBO is the U.S. government's system of record for opportunities to do business with the government. Each night, the FBO system posts all updated opportunities as a pseudo-xml file that is made publicly available via the File Transfer Protocol (FTP), which is a standard network protocol used for the transfer of computer files between a client and server on a computer network.
This project fetches that solicitation data, parses it, and uses supervised machine learning to determine whether or not the solicitation documents of Information Communications Technology (ICT) notices contain appropriate setion 508 accessibility language.
Following a service-oriented architecture, this project provides the back-end to a UI that GSA policy experts will use to review ICT solicitations for 508 compliance; notify deficient solicitation owners; monitor changes in historical compliance; and validate predictions to improve model performance. This application has been dubbed the Solicitation Review Tool (SRT). This application is designed to be run as a cron daemon within a Docker image on cloud.gov.
Read more about the srt and review the code here: https://github.com/GSA/srt-fbo-scraper/blob/master/README.md


☰
Home
Pages
About Us
About Us 2
Team Members
Services
Services 2
Contact Us
Contact Us 2
Pricing
404
Shortcodes
Accordions
Tabs
Buttons
Progress Bars
Testimonials
Clients
Icon Boxes
Team
Carousel
Google Maps
Pricing tables
Notification
Portfolio
Portfolio 2 Columns
Portfolio 3 Columns
Portfolio 4 Columns
Portfolio Single
Blog
Sidebar Right
Sidebar Left
Full Width
Single Post
Blog Grids
Contact Us
Contact us 1
Contact us 2
Service Page 2
You are Using Free Version!
Purchase Full Version to Get All Pages and Features
Purchase Now


pio
Development environment for embedded boards.
Some subcommands such as `pio run` have their own usage documentation.
More information: home page
- Show help and list subcommands:
pio --help
- Print the version number and exit:
pio --version
- Show help for a specific subcommand:
pio subcommand --help


An option dialog is a modal window that includes a message and one or more buttons which represent actions available to users.
The dialog can be invoked by showOptionDialog()
method of the Frame
interface. This interface is implemented by screen controllers, so these methods can be used directly in the
controller code.
In addition to parameters described for showMessageDialog()
, the method takes an array or a list of
actions. A button is created for each action. After a button is clicked, the dialog closes and invokes the
actionPerform()
method of the corresponding action.
If you need an action with a standard name and icon, use an anonymous class derived from DialogAction
.
Five types of actions are supported: OK
, CANCEL
, YES
, NO
, CLOSE
.
Names of corresponding buttons are extracted from the mаin message pack.


A Division of the SwastikNath Group LLC.
Server Home Page. Employees are permitted to access and login.


Bloomberg Could Become 2020 Heavyweight Immediately, Political Scientist Says
The former New York City mayor is reportedly on the verge of entering the Democratic party's race for the presidential nomination.
Hong Kong Activists Vow to 'Bring Justice' After Student Dies
Activists are demanding an investigation into the death of Chow Tsz-lok, 22, who fell from a car park last weekend under mysterious circumstances.
People Near Coal Plants Could Be Drinking 'Toxic' Water Until 2028
The proposed changes to the coal combustion residual rule won't survive the courts, says Betsy Southerland, who wrote the rule in 2015. But it will delay protections for vulnerable communities.
Bloomberg Could Become 2020 Heavyweight Immediately, Political Scientist Says
The former New York City mayor is reportedly on the verge of entering the Democratic party's race for the presidential nomination.
Hong Kong Activists Vow to 'Bring Justice' After Student Dies
Activists are demanding an investigation into the death of Chow Tsz-lok, 22, who fell from a car park last weekend under mysterious circumstances.
People Near Coal Plants Could Be Drinking 'Toxic' Water Until 2028
The proposed changes to the coal combustion residual rule won't survive the courts, says Betsy Southerland, who wrote the rule in 2015. But it will delay protections for vulnerable communities.
Bloomberg Could Become 2020 Heavyweight Immediately, Political Scientist Says
The former New York City mayor is reportedly on the verge of entering the Democratic party's race for the presidential nomination.
Hong Kong Activists Vow to 'Bring Justice' After Student Dies
Activists are demanding an investigation into the death of Chow Tsz-lok, 22, who fell from a car park last weekend under mysterious circumstances.
People Near Coal Plants Could Be Drinking 'Toxic' Water Until 2028
The proposed changes to the coal combustion residual rule won't survive the courts, says Betsy Southerland, who wrote the rule in 2015. But it will delay protections for vulnerable communities.
Federal Judge Decries Trump's Attacks on Judiciary
"We are in uncharted territory," U.S. District Court Judge Paul Friedman said. "We are witnessing a chief executive who criticizes virtually every judicial decision that doesn't go his way and denigrates judges who rule against him, sometimes on very personal terms."
What Can a Degree in Public Health Do For You?
The field of public health is a powerful draw for those who feel inspired to make a positive difference in their communities. Find out more.
What Can a Degree in Public Health Do For You?
The field of public health is a powerful draw for those who feel inspired to make a positive difference in their communities. Find out more.
IN THE MAGAZINE
EDITOR'S PICK
Bloomberg Could Become 2020 Heavyweight Immediately, Political Scientist Says
The former New York City mayor is reportedly on the verge of entering the Democratic party's race for the presidential nomination.
Bloomberg Could Become 2020 Heavyweight Immediately, Political Scientist Says
The former New York City mayor is reportedly on the verge of entering the Democratic party's race for the presidential nomination.
Bloomberg Could Become 2020 Heavyweight Immediately, Political Scientist Says
The former New York City mayor is reportedly on the verge of entering the Democratic party's race for the presidential nomination.
Bloomberg Could Become 2020 Heavyweight Immediately, Political Scientist Says
The former New York City mayor is reportedly on the verge of entering the Democratic party's race for the presidential nomination.
Bloomberg Could Become 2020 Heavyweight Immediately, Political Scientist Says
The former New York City mayor is reportedly on the verge of entering the Democratic party's race for the presidential nomination.
Bloomberg Could Become 2020 Heavyweight Immediately, Political Scientist Says
The former New York City mayor is reportedly on the verge of entering the Democratic party's race for the presidential nomination.
Bloomberg Could Become 2020 Heavyweight Immediately, Political Scientist Says
The former New York City mayor is reportedly on the verge of entering the Democratic party's race for the presidential nomination.
Bloomberg Could Become 2020 Heavyweight Immediately, Political Scientist Says
The former New York City mayor is reportedly on the verge of entering the Democratic party's race for the presidential nomination.
FEATURED SLIDESHOWS
SUBSCRIBE
In-depth Stories You Don't See Elsewhere About Topics You Want to Read!
All Access + Weekly Delivery.
Choose A Membership
That's Perfect for You!
NEWSLETTER
Daily Briefing
Take back your inbox. Sign up for our newsletter and start making sense of the world around you.
SIGN UP >


Opengl Shading Language
by Randi J. Rost (2nd Edtion, 2006)
I've had a hobbyist interest in computer graphics for years, but had avoided the technology of shaders these last few years, thinking that they were just another layer of complexity which I didn't need to embark upon while I was still getting to grips with the standard OpenGL API.
With hindsight, I was wrong. I was recently cajoled into getting on board after talking to Mike Fletcher (creator of PyOpenGL) after his talk at PyCon, and now I feel as if I should have read this book years ago. Shaders solve many of the problems I've been happily messing with for ages, in ways that are easier to implement, more powerful, and more performant.
I whined about the Red Book, but this "Orange" OpenGL Shading Language book is brill - just what I needed. Incisive without being overly terse, practical, and once it got into the chapters about applications of multidimensional Perlin noise it got me all hot'n'bothered about computer graphics again. Yay my inner geek!
Update: I started this book fascinated by using vertex shaders to transform geometry on the fly, with little interest in the superficial fragment shaders used to decorate the rendered surfaces with pretty images or lighting effects. Since finishing it, this has reversed: I've become obsessed with noise and Fourier transforms and all the paraphernalia of fragment shaders, imagining relatively simple fragment shader that could, I believe, provide a surface with infinite levels of detail. I dreamed about my old university 'Signals & Systems' type lectures. Uncanny.
Update2: Ohdear. Once I started trying to write anything more than the most trivial of my own shaders, I ran into an unexpected problem. My shaders just wouldn't link. I couldn't figure out why. The book was no help. Google was no help. The error messages certainly weren't any help (thanks ATI.) Eventually I realised that the 'built-in' noise functions which are part of the OpenGL shader language are simply not implemented by the vast majority of graphics card manufacturers - you have to roll your own. Which is not a major deal-breaker, but what is disappointing is that the OpenGL Shader Language book makes absolutely no mention of this in any of the chapters plural in which it lovingly describes the built-in noise functions, along with their characteristics and uses. Perhaps I spoke too soon when praising the book. Maybe it is another case of idealistic OpenGL theory that has something of a disconnect with real world development. Maybe the book was written before this situation came to pass - regardless, it's no bloody use to me.
Rating (oh, how I love my new rating system. Check this one out:)
10/10 if you want to learn the theory of how to use the OpenGL shader language.
0/10 if you don't.


Aspiring full Stack Developer. Interested in using coding as a way to solve real world problems and make life easier for everyone.
Worked on creating application integrations between Zoho's Desktop Central and Freshwork's Freshservice.
Worked on Desktop Central, Zoho's enterprise EMS product and implemented features as requested by customers.
Problem setter and tester for HackQuest 2.0, a district wide competitive programming contest.
Lead coder involved in image processing and computer vision for quadcopters using intel's RealSense technology.
Handle : xvetox
Score : 750 / 750
License ID: 846b3cc
Grade : 90.8
Certificate ID : UR45WQ4P58WU
Aggregate : 84.08%
Aggregate : 91.60%
Apart from being an avid learner, I enjoy finding new ways to apply my coding knowledge to solve problems faced everyday.
I also follow a number of technology blogs and shows. I spend a large amount of my free time exploring the latest technolgy advancements in the computer science industry.
In my free time I read, blog and game until it's time to code again.


Part X explores security concepts and examples. This part contains the following chapters:
Chapter 47, "Introduction to Security in the Java EE Platform"
Chapter 48, "Getting Started Securing Web Applications"
Chapter 49, "Getting Started Securing Enterprise Applications"
Chapter 50, "Java EE Security: Advanced Topics"


--- layout: page title: "About" header-img: "img/about-bg.jpg" Order: 5 --- I am someone who studied to become an engineer, am now a quantitative investment analyst by trade, who loves telling stories with data. This page is a collection of basic data explorations and analyses on whatever draws my attention at any given moment.
Aside from data and investments, I also enjoy playing a myriad of guitars, watching every grade of horror movie, and dabbling in some ultimate frisbee and distance running.Me: Clint Howard
What I've done to occupy my weekdays:
2017 - Current: Macquarie Group, Macquarie Investment Management, Systematic Equities, Quantitative Analyst
2016 - 2017: Macquarie Group, Risk Management Group, Risk and Capital Analysis, Analyst
2015 - 2016: University of Sydney, School of Chemical Engineering, Resarch Assistant - Computational Fluid Dynamics
2011-2015: Bachelor of Engineering (Chemical & Biomolecular) Honours Class I and the University Medal / Bachelor of Science (Mathematics), University of Sydney


The smallest Tizen app ever; look at window.W for window load time and window.D for DOM ready time (in ms).


--- layout: post tags: [AutoFixture, Unit Testing] date: 2009-07-23 14:54:45 UTC title: "Disabling AutoProperties In AutoFixture" --- {% include JB/setup %}
Since AutoFixture is a Test Data Builder, one of its most important tasks is to build up graphs of fully populated, yet semantically correct, strongly typed objects. As such, its default behavior is to assign a value to every writable property in the object graph.
While this is sometimes the desired behavior, at other times it is not.
This is particularly the case when you want to test that a newly created object has a property of a particular value. When you want to test the default value of a writable property, AutoFixture's AutoProperty feature is very much in the way.
Let's consider as an example a piece of software that deals with vehicle registration. By default, a vehicle should have four wheels, since this is the most common occurrence. Although I always practice TDD, I'll start by showing you the Vehicle class to illustrate what I mean.
public class Vehicle { public Vehicle() { this.Wheels = 4; } public int Wheels { get; set; } }
Here's a test that ensures that the default number of wheels is 4 - or does it?
In fact the assertion fails because the actual value is 1, not 4.
[TestMethod] public void AnonymousVehicleHasWheelsAssignedByFixture() { // Fixture setup var fixture = new Fixture(); var sut = fixture.CreateAnonymous<Vehicle>(); // Exercise system var result = sut.Wheels; // Verify outcome Assert.AreEqual<int>(4, result, "Wheels"); // Teardown }
Why does the test fail when the value of Wheels is set to 4 in the constructor? It fails because AutoFixture is designed to create populated test data, so it assigns a value to every writable property. Wheels is a writable property, so AutoFixture assigns an integer value to it using its default algorithm for creating anonymous numbers. Since no other numbers are being created during this test, the number assigned to Wheels is 1. This is AutoFixture's AutoProperties feature in effect.
When you want to test constructor logic, or otherwise wish to disable the AutoProperties feature, you can use a customized Builder with the OmitAutoProperties method:
[TestMethod] public void VehicleWithoutAutoPropertiesWillHaveFourWheels() { // Fixture setup var fixture = new Fixture(); var sut = fixture.Build<Vehicle>() .OmitAutoProperties() .CreateAnonymous(); // Exercise system var result = sut.Wheels; // Verify outcome Assert.AreEqual<int>(4, result, "Wheels"); // Teardown }
The OmitAutoProperties method instructs AutoFixture to skip assigning automatic Anonymous Values to all writable properties in the object graph. Any properties specifically assigned by the With method will still be assigned.
The test using OmitAutoProperties succeeds.


Ooh, let's go!
Steve walks warily down the street With the brim pulled way down low
Ain't no sound but the sound of his feet Machine guns ready to go
Are you ready? Hey, are you ready for this?
Are you hanging on the edge of your seat?
 How long can you stand the heat?


|
JavaTM 2 Platform Standard Ed. 5.0 |
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object java.util.prefs.Preferences
public abstract class Preferences
A node in a hierarchical collection of preference data. This class allows applications to store and retrieve user and system preference and configuration data. This data is stored persistently in an implementation-dependent backing store. Typical implementations include flat files, OS-specific registries, directory servers and SQL databases. The user of this class needn't be concerned with details of the backing store.
There are two separate trees of preference nodes, one for user preferences and one for system preferences. Each user has a separate user preference tree, and all users in a given system share the same system preference tree. The precise description of "user" and "system" will vary from implementation to implementation. Typical information stored in the user preference tree might include font choice, color choice, or preferred window location and size for a particular application. Typical information stored in the system preference tree might include installation configuration data for an application.
Nodes in a preference tree are named in a similar fashion to directories in a hierarchical file system. Every node in a preference tree has a node name (which is not necessarily unique), a unique absolute path name, and a path name relative to each ancestor including itself.
The root node has a node name of the empty string (""). Every other node has an arbitrary node name, specified at the time it is created. The only restrictions on this name are that it cannot be the empty string, and it cannot contain the slash character ('/').
The root node has an absolute path name of "/". Children of the root node have absolute path names of "/" + <node name>. All other nodes have absolute path names of <parent's absolute path name> + "/" + <node name>. Note that all absolute path names begin with the slash character.
A node n's path name relative to its ancestor a is simply the string that must be appended to a's absolute path name in order to form n's absolute path name, with the initial slash character (if present) removed. Note that:
Note finally that:
All of the methods that modify preferences data are permitted to operate asynchronously; they may return immediately, and changes will eventually propagate to the persistent backing store with an implementation-dependent delay. The flush method may be used to synchronously force updates to the backing store. Normal termination of the Java Virtual Machine will not result in the loss of pending updates -- an explicit flush invocation is not required upon termination to ensure that pending updates are made persistent.
All of the methods that read preferences from a Preferences
object require the invoker to provide a default value. The default value is
returned if no value has been previously set or if the backing store is
unavailable. The intent is to allow applications to operate, albeit
with slightly degraded functionality, even if the backing store becomes
unavailable. Several methods, like flush, have semantics that
prevent them from operating if the backing store is unavailable. Ordinary
applications should have no need to invoke any of these methods, which can
be identified by the fact that they are declared to throw BackingStoreException
.
The methods in this class may be invoked concurrently by multiple threads in a single JVM without the need for external synchronization, and the results will be equivalent to some serial execution. If this class is used concurrently by multiple JVMs that store their preference data in the same backing store, the data store will not be corrupted, but no other guarantees are made concerning the consistency of the preference data.
This class contains an export/import facility, allowing preferences to be "exported" to an XML document, and XML documents representing preferences to be "imported" back into the system. This facility may be used to back up all or part of a preference tree, and subsequently restore from the backup.
The XML document has the following DOCTYPE declaration:
<!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd">Note that the system URI (http://java.sun.com/dtd/preferences.dtd) is not accessed when exporting or importing preferences; it merely serves as a string to uniquely identify the DTD, which is:
<?xml version="1.0" encoding="UTF-8"?> <!-- DTD for a Preferences tree. --> <!-- The preferences element is at the root of an XML document representing a Preferences tree. --> <!ELEMENT preferences (root)> <!-- The preferences element contains an optional version attribute, which specifies version of DTD. --> <!ATTLIST preferences EXTERNAL_XML_VERSION CDATA "0.0" > <!-- The root element has a map representing the root's preferences (if any), and one node for each child of the root (if any). --> <!ELEMENT root (map, node*) > <!-- Additionally, the root contains a type attribute, which specifies whether it's the system or user root. --> <!ATTLIST root type (system|user) #REQUIRED > <!-- Each node has a map representing its preferences (if any), and one node for each child (if any). --> <!ELEMENT node (map, node*) > <!-- Additionally, each node has a name attribute --> <!ATTLIST node name CDATA #REQUIRED > <!-- A map represents the preferences stored at a node (if any). --> <!ELEMENT map (entry*) > <!-- An entry represents a single preference, which is simply a key-value pair. --> <!ELEMENT entry EMPTY > <!ATTLIST entry key CDATA #REQUIRED value CDATA #REQUIRED >Every Preferences implementation must have an associated
PreferencesFactory
implementation. Every J2SE implementation must provide
some means of specifying which PreferencesFactory implementation
is used to generate the root preferences nodes. This allows the
administrator to replace the default preferences implementation with an
alternative implementation.
Implementation note: In Sun's JRE, the PreferencesFactory implementation is located as follows:
If the system property java.util.prefs.PreferencesFactory is defined, then it is taken to be the fully-qualified name of a class implementing the PreferencesFactory interface. The class is loaded and instantiated; if this process fails then an unspecified error is thrown.
If a PreferencesFactory implementation class file
has been installed in a jar file that is visible to the
system class loader
,
and that jar file contains a provider-configuration file named
java.util.prefs.PreferencesFactory in the resource
directory META-INF/services, then the first class name
specified in that file is taken. If more than one such jar file is
provided, the first one found will be used. The class is loaded
and instantiated; if this process fails then an unspecified error
is thrown.
Finally, if neither the above-mentioned system property nor an extension jar file is provided, then the system-wide default PreferencesFactory implementation for the underlying platform is loaded and instantiated.
| Field Summary | |
|---|---|
static int |
MAX_KEY_LENGTH
Maximum length of string allowed as a key (80 characters). |
static int |
MAX_NAME_LENGTH
Maximum length of a node name (80 characters). |
static int |
MAX_VALUE_LENGTH
Maximum length of string allowed as a value (8192 characters). |
| Constructor Summary | |
|---|---|
protected |
Preferences()
Sole constructor. |
| Method Summary | |
|---|---|
abstract String |
absolutePath()
Returns this preference node's absolute path name. |
abstract void |
addNodeChangeListener(NodeChangeListener ncl)
Registers the specified listener to receive node change events for this node. |
abstract void |
addPreferenceChangeListener(PreferenceChangeListener pcl)
Registers the specified listener to receive preference change events for this preference node. |
abstract String[] |
childrenNames()
Returns the names of the children of this preference node, relative to this node. |
abstract void |
clear()
Removes all of the preferences (key-value associations) in this preference node. |
abstract void |
exportNode(OutputStream os)
Emits on the specified output stream an XML document representing all of the preferences contained in this node (but not its descendants). |
abstract void |
exportSubtree(OutputStream os)
Emits an XML document representing all of the preferences contained in this node and all of its descendants. |
abstract void |
flush()
Forces any changes in the contents of this preference node and its descendants to the persistent store. |
abstract String |
get(String key,
String def)
Returns the value associated with the specified key in this preference node. |
abstract boolean |
getBoolean(String key,
boolean def)
Returns the boolean value represented by the string associated with the specified key in this preference node. |
abstract byte[] |
getByteArray(String key,
byte[] def)
Returns the byte array value represented by the string associated with the specified key in this preference node. |
abstract double |
getDouble(String key,
double def)
Returns the double value represented by the string associated with the specified key in this preference node. |
abstract float |
getFloat(String key,
float def)
Returns the float value represented by the string associated with the specified key in this preference node. |
abstract int |
getInt(String key,
int def)
Returns the int value represented by the string associated with the specified key in this preference node. |
abstract long |
getLong(String key,
long def)
Returns the long value represented by the string associated with the specified key in this preference node. |
static void |
importPreferences(InputStream is)
Imports all of the preferences represented by the XML document on the specified input stream. |
abstract boolean |
isUserNode()
Returns true if this preference node is in the user preference tree, false if it's in the system preference tree. |
abstract String[] |
keys()
Returns all of the keys that have an associated value in this preference node. |
abstract String |
name()
Returns this preference node's name, relative to its parent. |
abstract Preferences |
node(String pathName)
Returns the named preference node in the same tree as this node, creating it and any of its ancestors if they do not already exist. |
abstract boolean |
nodeExists(String pathName)
Returns true if the named preference node exists in the same tree as this node. |
abstract Preferences |
parent()
Returns the parent of this preference node, or null if this is the root. |
abstract void |
put(String key,
String value)
Associates the specified value with the specified key in this preference node. |
abstract void |
putBoolean(String key,
boolean value)
Associates a string representing the specified boolean value with the specified key in this preference node. |
abstract void |
putByteArray(String key,
byte[] value)
Associates a string representing the specified byte array with the specified key in this preference node. |
abstract void |
putDouble(String key,
double value)
Associates a string representing the specified double value with the specified key in this preference node. |
abstract void |
putFloat(String key,
float value)
Associates a string representing the specified float value with the specified key in this preference node. |
abstract void |
putInt(String key,
int value)
Associates a string representing the specified int value with the specified key in this preference node. |
abstract void |
putLong(String key,
long value)
Associates a string representing the specified long value with the specified key in this preference node. |
abstract void |
remove(String key)
Removes the value associated with the specified key in this preference node, if any. |
abstract void |
removeNode()
Removes this preference node and all of its descendants, invalidating any preferences contained in the removed nodes. |
abstract void |
removeNodeChangeListener(NodeChangeListener ncl)
Removes the specified NodeChangeListener, so it no longer receives change events. |
abstract void |
removePreferenceChangeListener(PreferenceChangeListener pcl)
Removes the specified preference change listener, so it no longer receives preference change events. |
abstract void |
sync()
Ensures that future reads from this preference node and its descendants reflect any changes that were committed to the persistent store (from any VM) prior to the sync invocation. |
static Preferences |
systemNodeForPackage(Class<?> c)
Returns the preference node from the system preference tree that is associated (by convention) with the specified class's package. |
static Preferences |
systemRoot()
Returns the root preference node for the system. |
abstract String |
toString()
Returns a string representation of this preferences node, as if computed by the expression:(this.isUserNode() ? "User" : "System") + " Preference Node: " + this.absolutePath(). |
static Preferences |
userNodeForPackage(Class<?> c)
Returns the preference node from the calling user's preference tree that is associated (by convention) with the specified class's package. |
static Preferences |
userRoot()
Returns the root preference node for the calling user. |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
| Field Detail |
|---|
public static final int MAX_KEY_LENGTH
public static final int MAX_VALUE_LENGTH
public static final int MAX_NAME_LENGTH
| Constructor Detail |
|---|
protected Preferences()
| Method Detail |
|---|
public static Preferences userNodeForPackage(Class<?> c)
This convention does not apply to the unnamed package, whose associated preference node is <unnamed>. This node is not intended for long term use, but for convenience in the early development of programs that do not yet belong to a package, and for "throwaway" programs. Valuable data should not be stored at this node as it is shared by all programs that use it.
A class Foo wishing to access preferences pertaining to its package can obtain a preference node as follows:
static Preferences prefs = Preferences.userNodeForPackage(Foo.class);This idiom obviates the need for using a string to describe the preferences node and decreases the likelihood of a run-time failure. (If the class name is misspelled, it will typically result in a compile-time error.)
Invoking this method will result in the creation of the returned node and its ancestors if they do not already exist. If the returned node did not exist prior to this call, this node and any ancestors that were created by this call are not guaranteed to become permanent until the flush method is called on the returned node (or one of its ancestors or descendants).
c
- the class for whose package a user preference node is desired.
NullPointerException
- if c is null.
SecurityException
- if a security manager is present and
it denies RuntimePermission("preferences").RuntimePermission
public static Preferences systemNodeForPackage(Class<?> c)
This convention does not apply to the unnamed package, whose associated preference node is <unnamed>. This node is not intended for long term use, but for convenience in the early development of programs that do not yet belong to a package, and for "throwaway" programs. Valuable data should not be stored at this node as it is shared by all programs that use it.
A class Foo wishing to access preferences pertaining to its package can obtain a preference node as follows:
static Preferences prefs = Preferences.systemNodeForPackage(Foo.class);This idiom obviates the need for using a string to describe the preferences node and decreases the likelihood of a run-time failure. (If the class name is misspelled, it will typically result in a compile-time error.)
Invoking this method will result in the creation of the returned node and its ancestors if they do not already exist. If the returned node did not exist prior to this call, this node and any ancestors that were created by this call are not guaranteed to become permanent until the flush method is called on the returned node (or one of its ancestors or descendants).
c
- the class for whose package a system preference node is desired.
NullPointerException
- if c is null.
SecurityException
- if a security manager is present and
it denies RuntimePermission("preferences").RuntimePermission
public static Preferences userRoot()
SecurityException
- If a security manager is present and
it denies RuntimePermission("preferences").RuntimePermission
public static Preferences systemRoot()
SecurityException
- If a security manager is present and
it denies RuntimePermission("preferences").RuntimePermission
public abstract void put(String key, String value)
key
- key with which the specified value is to be associated.value
- value to be associated with the specified key.
NullPointerException
- if key or value is null.
IllegalArgumentException
- if key.length() exceeds
MAX_KEY_LENGTH or if value.length exceeds
MAX_VALUE_LENGTH.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.public abstract String get(String key, String def)
Some implementations may store default values in their backing stores. If there is no value associated with the specified key but there is such a stored default, it is returned in preference to the specified default.
key
- key whose associated value is to be returned.def
- the value to be returned in the event that this
preference node has no value associated with key.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.
NullPointerException
- if key is null. (A
null value for def is permitted.)public abstract void remove(String key)
If this implementation supports stored defaults, and there is such a default for the specified preference, the stored default will be "exposed" by this call, in the sense that it will be returned by a succeeding call to get.
key
- key whose mapping is to be removed from the preference node.
NullPointerException
- if key is null.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.public abstract void clear() throws BackingStoreException
If this implementation supports stored defaults, and this node in the preferences hierarchy contains any such defaults, the stored defaults will be "exposed" by this call, in the sense that they will be returned by succeeding calls to get.
BackingStoreException
- if this operation cannot be completed
due to a failure in the backing store, or inability to
communicate with it.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.removeNode()
public abstract void putInt(String key, int value)
Integer.toString(int)
. This method is intended for use in
conjunction with getInt(java.lang.String, int)
.
key
- key with which the string form of value is to be associated.value
- value whose string form is to be associated with key.
NullPointerException
- if key is null.
IllegalArgumentException
- if key.length() exceeds
MAX_KEY_LENGTH.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.getInt(String,int)
public abstract int getInt(String key, int def)
Integer.parseInt(String)
. Returns the
specified default if there is no value associated with the key,
the backing store is inaccessible, or if
Integer.parseInt(String) would throw a NumberFormatException
if the associated value were passed. This
method is intended for use in conjunction with putInt(java.lang.String, int)
.
If the implementation supports stored defaults and such a default exists, is accessible, and could be converted to an int with Integer.parseInt, this int is returned in preference to the specified default.
key
- key whose associated value is to be returned as an int.def
- the value to be returned in the event that this
preference node has no value associated with key
or the associated value cannot be interpreted as an int,
or the backing store is inaccessible.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.
NullPointerException
- if key is null.putInt(String,int)
,
get(String,String)
public abstract void putLong(String key, long value)
Long.toString(long)
. This method is intended for use in
conjunction with getLong(java.lang.String, long)
.
key
- key with which the string form of value is to be associated.value
- value whose string form is to be associated with key.
NullPointerException
- if key is null.
IllegalArgumentException
- if key.length() exceeds
MAX_KEY_LENGTH.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.getLong(String,long)
public abstract long getLong(String key, long def)
Long.parseLong(String)
. Returns the
specified default if there is no value associated with the key,
the backing store is inaccessible, or if
Long.parseLong(String) would throw a NumberFormatException
if the associated value were passed. This
method is intended for use in conjunction with putLong(java.lang.String, long)
.
If the implementation supports stored defaults and such a default exists, is accessible, and could be converted to a long with Long.parseLong, this long is returned in preference to the specified default.
key
- key whose associated value is to be returned as a long.def
- the value to be returned in the event that this
preference node has no value associated with key
or the associated value cannot be interpreted as a long,
or the backing store is inaccessible.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.
NullPointerException
- if key is null.putLong(String,long)
,
get(String,String)
public abstract void putBoolean(String key, boolean value)
getBoolean(java.lang.String, boolean)
.
key
- key with which the string form of value is to be associated.value
- value whose string form is to be associated with key.
NullPointerException
- if key is null.
IllegalArgumentException
- if key.length() exceeds
MAX_KEY_LENGTH.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.getBoolean(String,boolean)
,
get(String,String)
public abstract boolean getBoolean(String key, boolean def)
putBoolean(java.lang.String, boolean)
.
Returns the specified default if there is no value associated with the key, the backing store is inaccessible, or if the associated value is something other than "true" or "false", ignoring case.
If the implementation supports stored defaults and such a default exists and is accessible, it is used in preference to the specified default, unless the stored default is something other than "true" or "false", ignoring case, in which case the specified default is used.
key
- key whose associated value is to be returned as a boolean.def
- the value to be returned in the event that this
preference node has no value associated with key
or the associated value cannot be interpreted as a boolean,
or the backing store is inaccessible.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.
NullPointerException
- if key is null.get(String,String)
,
putBoolean(String,boolean)
public abstract void putFloat(String key, float value)
Float.toString(float)
. This method is intended for use in
conjunction with getFloat(java.lang.String, float)
.
key
- key with which the string form of value is to be associated.value
- value whose string form is to be associated with key.
NullPointerException
- if key is null.
IllegalArgumentException
- if key.length() exceeds
MAX_KEY_LENGTH.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.getFloat(String,float)
public abstract float getFloat(String key, float def)
Float.parseFloat(String)
. Returns the specified
default if there is no value associated with the key, the backing store
is inaccessible, or if Float.parseFloat(String) would throw a
NumberFormatException
if the associated value were passed.
This method is intended for use in conjunction with putFloat(java.lang.String, float)
.
If the implementation supports stored defaults and such a default exists, is accessible, and could be converted to a float with Float.parseFloat, this float is returned in preference to the specified default.
key
- key whose associated value is to be returned as a float.def
- the value to be returned in the event that this
preference node has no value associated with key
or the associated value cannot be interpreted as a float,
or the backing store is inaccessible.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.
NullPointerException
- if key is null.putFloat(String,float)
,
get(String,String)
public abstract void putDouble(String key, double value)
Double.toString(double)
. This method is intended for use in
conjunction with getDouble(java.lang.String, double)
.
key
- key with which the string form of value is to be associated.value
- value whose string form is to be associated with key.
NullPointerException
- if key is null.
IllegalArgumentException
- if key.length() exceeds
MAX_KEY_LENGTH.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.getDouble(String,double)
public abstract double getDouble(String key, double def)
Double.parseDouble(String)
. Returns the specified
default if there is no value associated with the key, the backing store
is inaccessible, or if Double.parseDouble(String) would throw a
NumberFormatException
if the associated value were passed.
This method is intended for use in conjunction with putDouble(java.lang.String, double)
.
If the implementation supports stored defaults and such a default exists, is accessible, and could be converted to a double with Double.parseDouble, this double is returned in preference to the specified default.
key
- key whose associated value is to be returned as a double.def
- the value to be returned in the event that this
preference node has no value associated with key
or the associated value cannot be interpreted as a double,
or the backing store is inaccessible.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.
NullPointerException
- if key is null.putDouble(String,double)
,
get(String,String)
public abstract void putByteArray(String key, byte[] value)
getByteArray(java.lang.String, byte[])
.
key
- key with which the string form of value is to be associated.value
- value whose string form is to be associated with key.
NullPointerException
- if key or value is null.
IllegalArgumentException
- if key.length() exceeds MAX_KEY_LENGTH
or if value.length exceeds MAX_VALUE_LENGTH*3/4.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.getByteArray(String,byte[])
,
get(String,String)
public abstract byte[] getByteArray(String key, byte[] def)
putByteArray(java.lang.String, byte[])
.
Returns the specified default if there is no value associated with the key, the backing store is inaccessible, or if the associated value is not a valid Base64 encoded byte array (as defined above).
If the implementation supports stored defaults and such a default exists and is accessible, it is used in preference to the specified default, unless the stored default is not a valid Base64 encoded byte array (as defined above), in which case the specified default is used.
key
- key whose associated value is to be returned as a byte array.def
- the value to be returned in the event that this
preference node has no value associated with key
or the associated value cannot be interpreted as a byte array,
or the backing store is inaccessible.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.
NullPointerException
- if key is null. (A
null value for def is permitted.)get(String,String)
,
putByteArray(String,byte[])
public abstract String[] keys() throws BackingStoreException
If the implementation supports stored defaults and there are any such defaults at this node that have not been overridden, by explicit preferences, the defaults are returned in the array in addition to any explicit preferences.
BackingStoreException
- if this operation cannot be completed
due to a failure in the backing store, or inability to
communicate with it.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.public abstract String[] childrenNames() throws BackingStoreException
BackingStoreException
- if this operation cannot be completed
due to a failure in the backing store, or inability to
communicate with it.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.public abstract Preferences parent()
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.public abstract Preferences node(String pathName)
If the returned node did not exist prior to this call, this node and any ancestors that were created by this call are not guaranteed to become permanent until the flush method is called on the returned node (or one of its ancestors or descendants).
pathName
- the path name of the preference node to return.
IllegalArgumentException
- if the path name is invalid (i.e.,
it contains multiple consecutive slash characters, or ends
with a slash character and is more than one character long).
NullPointerException
- if path name is null.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.flush()
public abstract boolean nodeExists(String pathName) throws BackingStoreException
If this node (or an ancestor) has already been removed with the
removeNode()
method, it is legal to invoke this method,
but only with the path name ""; the invocation will return
false. Thus, the idiom p.nodeExists("") may be
used to test whether p has been removed.
pathName
- the path name of the node whose existence
is to be checked.
BackingStoreException
- if this operation cannot be completed
due to a failure in the backing store, or inability to
communicate with it.
IllegalArgumentException
- if the path name is invalid (i.e.,
it contains multiple consecutive slash characters, or ends
with a slash character and is more than one character long).
NullPointerException
- if path name is null.
s * @throws IllegalStateException if this node (or an ancestor) has been
removed with the removeNode()
method and
pathName is not the empty string ("").public abstract void removeNode() throws BackingStoreException
name()
,
absolutePath()
, isUserNode()
, flush()
or
nodeExists("")
on the corresponding
Preferences instance will fail with an
IllegalStateException. (The methods defined on Object
can still be invoked on a node after it has been removed; they will not
throw IllegalStateException.)
The removal is not guaranteed to be persistent until the flush method is called on this node (or an ancestor).
If this implementation supports stored defaults, removing a node exposes any stored defaults at or below this node. Thus, a subsequent call to nodeExists on this node's path name may return true, and a subsequent call to node on this path name may return a (different) Preferences instance representing a non-empty collection of preferences and/or children.
BackingStoreException
- if this operation cannot be completed
due to a failure in the backing store, or inability to
communicate with it.
IllegalStateException
- if this node (or an ancestor) has already
been removed with the removeNode()
method.
UnsupportedOperationException
- if this method is invoked on
the root node.flush()
public abstract String name()
public abstract String absolutePath()
public abstract boolean isUserNode()
public abstract String toString()
toString
in class Object
public abstract void flush() throws BackingStoreException
Implementations are free to flush changes into the persistent store at any time. They do not need to wait for this method to be called.
When a flush occurs on a newly created node, it is made persistent, as are any ancestors (and descendants) that have yet to be made persistent. Note however that any preference value changes in ancestors are not guaranteed to be made persistent.
If this method is invoked on a node that has been removed with
the removeNode()
method, flushSpi() is invoked on this node,
but not on others.
BackingStoreException
- if this operation cannot be completed
due to a failure in the backing store, or inability to
communicate with it.sync()
public abstract void sync() throws BackingStoreException
BackingStoreException
- if this operation cannot be completed
due to a failure in the backing store, or inability to
communicate with it.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.flush()
public abstract void addPreferenceChangeListener(PreferenceChangeListener pcl)
removeNode()
method, which generates a node change event.
Preference change events are generated by the clear
method.)
Events are only guaranteed for changes made within the same JVM as the registered listener, though some implementations may generate events for changes made outside this JVM. Events may be generated before the changes have been made persistent. Events are not generated when preferences are modified in descendants of this node; a caller desiring such events must register with each descendant.
pcl
- The preference change listener to add.
NullPointerException
- if pcl is null.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.removePreferenceChangeListener(PreferenceChangeListener)
,
addNodeChangeListener(NodeChangeListener)
public abstract void removePreferenceChangeListener(PreferenceChangeListener pcl)
pcl
- The preference change listener to remove.
IllegalArgumentException
- if pcl was not a registered
preference change listener on this node.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.addPreferenceChangeListener(PreferenceChangeListener)
public abstract void addNodeChangeListener(NodeChangeListener ncl)
removeNode()
invocation results in multiple node change events, one for every
node in the subtree rooted at the removed node.)
Events are only guaranteed for changes made within the same JVM as the registered listener, though some implementations may generate events for changes made outside this JVM. Events may be generated before the changes have become permanent. Events are not generated when indirect descendants of this node are added or removed; a caller desiring such events must register with each descendant.
Few guarantees can be made regarding node creation. Because nodes are created implicitly upon access, it may not be feasible for an implementation to determine whether a child node existed in the backing store prior to access (for example, because the backing store is unreachable or cached information is out of date). Under these circumstances, implementations are neither required to generate node change events nor prohibited from doing so.
ncl
- The NodeChangeListener to add.
NullPointerException
- if ncl is null.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.removeNodeChangeListener(NodeChangeListener)
,
addPreferenceChangeListener(PreferenceChangeListener)
public abstract void removeNodeChangeListener(NodeChangeListener ncl)
ncl
- The NodeChangeListener to remove.
IllegalArgumentException
- if ncl was not a registered
NodeChangeListener on this node.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.addNodeChangeListener(NodeChangeListener)
public abstract void exportNode(OutputStream os) throws IOException, BackingStoreException
The XML document will have the following DOCTYPE declaration:
<!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd">The UTF-8 character encoding will be used.
This method is an exception to the general rule that the results of concurrently executing multiple methods in this class yields results equivalent to some serial execution. If the preferences at this node are modified concurrently with an invocation of this method, the exported preferences comprise a "fuzzy snapshot" of the preferences contained in the node; some of the concurrent modifications may be reflected in the exported data while others may not.
os
- the output stream on which to emit the XML document.
IOException
- if writing to the specified output stream
results in an IOException.
BackingStoreException
- if preference data cannot be read from
backing store.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.importPreferences(InputStream)
public abstract void exportSubtree(OutputStream os) throws IOException, BackingStoreException
The XML document will have the following DOCTYPE declaration:
<!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd">The UTF-8 character encoding will be used.
This method is an exception to the general rule that the results of concurrently executing multiple methods in this class yields results equivalent to some serial execution. If the preferences or nodes in the subtree rooted at this node are modified concurrently with an invocation of this method, the exported preferences comprise a "fuzzy snapshot" of the subtree; some of the concurrent modifications may be reflected in the exported data while others may not.
os
- the output stream on which to emit the XML document.
IOException
- if writing to the specified output stream
results in an IOException.
BackingStoreException
- if preference data cannot be read from
backing store.
IllegalStateException
- if this node (or an ancestor) has been
removed with the removeNode()
method.importPreferences(InputStream)
,
exportNode(OutputStream)
public static void importPreferences(InputStream is) throws IOException, InvalidPreferencesFormatException
The XML document must have the following DOCTYPE declaration:
<!DOCTYPE preferences SYSTEM "http://java.sun.com/dtd/preferences.dtd">(This method is designed for use in conjunction with
exportNode(OutputStream)
and
exportSubtree(OutputStream)
.
This method is an exception to the general rule that the results of
concurrently executing multiple methods in this class yields
results equivalent to some serial execution. The method behaves
as if implemented on top of the other public methods in this class,
notably node(String)
and put(String, String)
.
is
- the input stream from which to read the XML document.
IOException
- if reading from the specified output stream
results in an IOException.
InvalidPreferencesFormatException
- Data on input stream does not
constitute a valid XML document with the mandated document type.
SecurityException
- If a security manager is present and
it denies RuntimePermission("preferences").RuntimePermission
|
JavaTM 2 Platform Standard Ed. 5.0 |
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
Copyright © 2004, 2010 Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. Also see the documentation redistribution policy.


Macros | |
| #define | UART_CMD_PEEK (0) |
| Command code used by UART_control() to read the next unsigned char. More... | |
| #define | UART_CMD_ISAVAILABLE (1) |
| Command code used by UART_control() to determine if the read buffer is empty. More... | |
| #define | UART_CMD_GETRXCOUNT (2) |
| Command code used by UART_control() to determine how many unsigned chars are in the read buffer. More... | |
| #define | UART_CMD_RXENABLE (3) |
| Command code used by UART_control() to enable data receive by the UART. More... | |
| #define | UART_CMD_RXDISABLE (4) |
| Command code used by UART_control() to disable data received by the UART. More... | |
UART_CMD_* macros are general command codes for UART_control(). Not all UART driver implementations support these command codes.
UARTMSP432_CMD_* macros are command codes only defined in the UARTMSP432.h driver implementation and need to:
| #define UART_CMD_PEEK (0) |
Command code used by UART_control() to read the next unsigned char.
This command is used to read the next unsigned char from the UART's circular buffer without removing it. With this command code, arg is a pointer to an integer. *arg contains the next unsigned
char
read if data is present, else *arg is set to UART_STATUS_ERROR.
| #define UART_CMD_ISAVAILABLE (1) |
Command code used by UART_control() to determine if the read buffer is empty.
This command is used to determine if there are any unsigned chars available to read from the UART's circular buffer using UART_read(). With this command code, arg is a pointer to a bool
. *arg contains true
if data is available, else false
.
| #define UART_CMD_GETRXCOUNT (2) |
Command code used by UART_control() to determine how many unsigned chars are in the read buffer.
This command is used to determine how many unsigned
chars
are available to read from the UART's circular buffer using UART_read(). With this command code, arg is a pointer to an integer. *arg contains the number of unsigned
chars
available to read.
| #define UART_CMD_RXENABLE (3) |
Command code used by UART_control() to enable data receive by the UART.
This command is used to enable the UART in such a way that it stores received unsigned chars into the circular buffer. For drivers that support power management, this typically means that the UART will set a power constraint while receive is enabled. UART_open() will always have this option enabled. With this command code, arg is don't care.
| #define UART_CMD_RXDISABLE (4) |
Command code used by UART_control() to disable data received by the UART.
This command is used to disable the UART in such a way that ignores the data it receives. For drivers that support power management, this typically means that the driver will release any power constraints, to permit the system to enter low power modes. With this command code, arg is don't care.