ianmonge/Javascript equivalent for PHP's print_r ( JavaScript)
function print_r( array, return_val ) {
// http://kevin.vanzonneveld.net
// + original by: Michael White (http://crestidg.com)
// + improved by: Ben Bryan
// * example 1: print_r(1, true);
// * returns 1: 1
var output = "", pad_char = " ", pad_val = 4;
var formatArray = function (obj, cur_depth, pad_val, pad_char) {
if (cur_depth > 0) {
cur_depth++;
}
var base_pad = repeat_char(pad_val*cur_depth, pad_char);
var thick_pad = repeat_char(pad_val*(cur_depth+1), pad_char);
var str = "";
if (obj instanceof Array || obj instanceof Object) {
str += "Array\n" + base_pad + "(\n";
for (var key in obj) {
if (obj[key] instanceof Array) {
str += thick_pad + "["+key+"] => "+formatArray(obj[key], cur_depth+1, pad_val, pad_char);
} else {
str += thick_pad + "["+key+"] => " + obj[key] + "\n";
}
}
str += base_pad + ")\n";
} else if(obj == null || obj == undefined) {
str = '';
} else {
str = obj.toString();
}
return str;
};
var repeat_char = function (len, pad_char) {
var str = "";
for(var i=0; i < len; i++) {
str += pad_char;
};
return str;
};
output = formatArray(array, 0, pad_val, pad_char);
if (return_val !== true) {
document.write("<pre>" + output + "</pre>");
return true;
} else {
return output;
}
}
Description
print_r - Prints human-readable information about a variable
mixed print_r( mixed expression [, bool return] )
print_r() displays information about a variable in a way that's readable by humans. Parameters
* expression
The expression to be printed.
* return
If you would like to capture the output of print_r(), use the return parameter. If this parameter is set to TRUE, print_r() will return its output, instead of printing it (which it does by default).
Return Values
If given a string, integer or float, the value itself will be printed. If given an array, values will be presented in a format that shows keys and elements. Similar notation is used for objects.
benjaminpearson/PHP HTTP POST images & files ( PHP)
<?php
$url = ''; // the url of the file processing script (ie, http://example.com/upload)
// Iterate through each file, check it has been stored in a tmp location, then post to another url
foreach ($_FILES as $file) {
// tmp_name will look something like this /private/var/tmp/phpRDJDT92
if ($file['tmp_name'] > '') {
$params['file'] = '@'.$file['tmp_name']; // Its this @ symbol thats the key.
$response = post($url, $params);
}
}
function post($url, $params = array()) {
try {
$response = http_post($url, $params);
return $response;
} catch (Exception $e) {
return null;
}
}
// More REST methods available at http://snipplr.com/view/19781/php-rest/
// Nothing special about this cURL POST. You dont have to set any special headers for file uploading.
function http_post($url, $data) {
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $url);
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($c, CURLOPT_POSTFIELDS, $data);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($c);
curl_close($c);
return $output;
}
?>
The following are instructions to "re-post" files that have been already been POSTed to your php script. This can help if you want to have a form (with file upload) that POSTs its data to your own script where the text elements can be handled and then the script POSTs the file for processing/storage on another system.
Basically the key is that you only POST the $_FILES['tmp_name'] with an "@" symbol prepended.
Spent a good hour trying to figure this out. Thanks to gordon who posted on 08-Sep-2004 10:08 at http://theserverpages.com/php/manual/en/ref.curl.php
samclarke/Classic ASP (basic) implementation of PHP's sprintf() function ( ASP)
<%
Function SPrintF(sLine, aReplacements)
aLines = Split(sLine, "%s")
sFormatted = ""
For i = 0 To UBound(aLines)
If UBound(aReplacements) >= i Then
sFormatted = sFormatted & aLines(i) & aReplacements(i)
End If
Next
sFormatted = sFormatted & aLines(UBound(aLines))
SPrintF = sFormatted
End Function
' example usage
Response.Write SPrintF("There are %s monkeys in the %s, but only %s lions in the %s.", _
Array("five", "tree", "two", "grass"))
Response.Write SPrintF("Click here to visit <a href=""%s"">%s</a>!", _
Array("http://www.google.com", Server.HTMLEncode("Google")))
Response.Write SPrintF("SELECT id, name FROM users WHERE username = '%s' AND password = MD5('%s');", _
Array(Replace("sammy", "'", "''"), Replace("letmein", "'", "''")))
%>
This is a basic implementation of PHP's handy sprintf() written in Classic ASP/VBScript. It's not as extensive as PHP's version as it doesn't support numbered parameters, and only works with %s placeholders, but it's better than nothing, right?
Makes for nice clean, understandable code as you can avoid concatenated strings containing function calls mid-string.
Vaibhav Bhatia/exception handling using decorators ( python)
import functools
def ExpHandler(*pargs):
""" An exception handling idiom using decorators"""
def wrapper(f):
if pargs:
(handler,li) = pargs
t = [(ex, handler)
for ex in li ]
t.reverse()
else:
t = [(Exception,None)]
def newfunc(t,*args, **kwargs):
ex, handler = t[0]
try:
if len(t) == 1:
f(*args, **kwargs)
else:
newfunc(t[1:],*args,**kwargs)
except ex,e:
if handler:
handler(e)
else:
print e.__class__.__name__, ':', e
return functools.partial(newfunc,t)
return wrapper
def myhandler(e):
print 'Caught exception!', e
# Examples
# Specify exceptions in order, first one is handled first
# last one last.
@ExpHandler(myhandler,(ZeroDivisionError,))
@ExpHandler(None,(AttributeError, ValueError))
def f1():
1/0
@ExpHandler()
def f3(*pargs):
l = pargs
return l.index(10)
if __name__=="__main__":
f1()
f3()
The logic of the code is a rewrite of http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/408937, however partial is used here and default Exception class is added when no input is given. I have also made some modifications in the way handlers and exception classes are passed to the decorator. (it was earlier posted in comments for the same receipe)
tomer filiba/Real Mixins ( python)
import inspect
def mixin(cls):
"""
mixes-in a class (or a module) into another class. must be called from within
a class definition. `cls` is the class/module to mix-in
"""
locals = inspect.stack()[1][0].f_locals
if "__module__" not in locals:
raise TypeError("mixin() must be called from within a class definition")
# copy the class's dict aside and perform some tweaking
dict = cls.__dict__.copy()
dict.pop("__doc__", None)
dict.pop("__module__", None)
# __slots__ hell
slots = dict.pop("__slots__", [])
if slots and "__slots__" not in locals:
locals["__slots__"] = ["__dict__"]
for name in slots:
if name.startswith("__") and not name.endswith("__"):
name = "_%s%s" % (cls.__name__, name)
dict.pop(name)
locals["__slots__"].append(name)
# mix the namesapces
locals.update(dict)
#
# example
#
>>> class SomeMixin(object):
... def f(self, x):
... return self.y + x
...
>>> class AnotherMixin(object):
... def g(self):
... print "g"
...
>>>
>>> class Foo(object):
... mixin(SomeMixin)
... mixin(AnotherMixin)
...
... def h(self):
... print "h"
...
This code here creates real mixed-in classes: it actually merges one class into another (c-python specific), taking care of name-mangling, some complications with __slots__, and everything else. As a side-effect, you can also use it to mix modules into classes. Similar to ruby's include statement.
Ori Peleg/"once" decorator ( python)
def func_once(func):
"A decorator that runs a function only once."
def decorated(*args, **kwargs):
try:
return decorated._once_result
except AttributeError:
decorated._once_result = func(*args, **kwargs)
return decorated._once_result
return decorated
def method_once(method):
"A decorator that runs a method only once."
attrname = "_%s_once_result" % id(method)
def decorated(self, *args, **kwargs):
try:
return getattr(self, attrname)
except AttributeError:
setattr(self, attrname, method(self, *args, **kwargs))
return getattr(self, attrname)
return decorated
# Example, will only parse the document once
@func_once
def get_document():
import xml.dom.minidom
return xml.dom.minidom.parse("document.xml")
This decorator runs a function or method once and caches the result.
It offers minimal memory use and high speed (only one extra function call). It is _not_ a memoization implementation, the result is cached for all future arguments as well.
This code is used in the TestOOB testing framework (http://testoob.sourceforge.net).
devnull69/Hash history hack ( JavaScript)
var currHash = "#";
window.onload = function() {
if(window.location.hash) {
checkHash();
}
};
function getContent(descr) {
// simple example, please change according to your needs!!!
switch(descr) {
case "inhalt1" :
document.getElementById('content').innerHTML = "<h2>Inhalt 1</h2>";
break;
case "inhalt2" :
document.getElementById('content').innerHTML = "<h2>Inhalt 2</h2>";
default: break;
}
window.location.hash = descr;
currHash = "#" + descr;
}
setInterval(checkHash, 500);
function checkHash() {
if(window.location.hash && currHash != "#" && window.location.hash != currHash) {
currHash = window.location.hash;
getContent(window.location.hash.substring(1));
}
}
Include the following code into the global scope of your page. It will make sure that by navigating using the browser back/forward buttons you will see the correct dynamic content. It will also make the dynamic content bookmarkable.
You'll have to change getContent() according to what content you want to load depending on the "descr" paramter describing the content. descr will be the text that will be added to the URL as hash
Steven Cummings/General dispatching mechanism for C#-style events ( python)
# dispatch.py
# definitions:
import threading
class Dispatcher(object):
def __init__(self, targets=None, nonBlocking=True):
if not targets or targets is None:
self._targets = []
else:
self._targets = targets
self._nonBlocking = nonBlocking
def __iadd__(self, target):
self._targets.append(target)
return self
def __isub__(self, target):
self._targets.remove(target)
return self
def isNonBlocking(self):
return self._nonBlocking
nonBlocking = property(isNonBlocking)
def __call__(self, *listArgs, **kwArgs):
def invokeTargets():
for target in self._targets:
target(*listArgs, **kwArgs)
if self.nonBlocking:
threading.Timer(0, invokeTargets).start()
else:
invokeTargets()
# demos:
def Test1():
"""
A simple example demonstrating most functionality.
"""
def m1():
print 'm1 invoked'
def m2():
print 'm2 invoked'
e = Dispatcher()
e += m1
e += m2
e += m2
print 'Dispatching:'
e()
e -= m1
print 'Dispatching:'
e()
e -= m2
print 'Dispatching:'
e()
def Test2():
"""
A more realistic example for the OO programmer.
"""
class Sprite(object):
def __init__(self, location):
self._location = location
locationChanged = Dispatcher()
def getLocation(self):
return self._location
def setLocation(self, newLocation):
oldLocation = self._location
self._location = newLocation
# Dispatch a "property change event"
self.locationChanged(oldLocation, newLocation)
location = property(getLocation, setLocation)
s = Sprite((2,4))
def SpriteLocationChanged(oldLocation, newLocation):
print 'oldLocation =', oldLocation
print 'newLocation =', newLocation
s.locationChanged += SpriteLocationChanged
s.location = (3,4)
s.location = (4,4)
if __name__ == '__main__':
Test1()
Test2()
This is an dynamic dispatching approach inspired by C#-style events. The approach allows for the dispatch of an event to a series of chained methods through the use of a Dispatcher. The Dispatcher can be defined either as part of a class or merely as a variable in some code. When the Dispatcher is invoked the methods that are chained to it (i.e. handlers) are invoked. The dispatch can be either blocking or non-blocking, and is non-blocking by default.
webonomic/Create a new data set for each BY-Group in a data set ( SAS)
/*Sample 2640 of the SAS Knowledge Base*/
/*http://support.sas.com/kb/26/140.html*/
/* Example 1 - Use macro logic to create a new data set for each BY-Group in */
/* an existing data set. */
/* Create sample data */
data test;
input color $ num;
datalines;
blue 1
blue 2
blue 3
green 4
green 5
red 6
red 7
red 8
;
/* Create a new macro variable, VARn, for each BY-Group and a */
/* counter of the number of new macro variables created. */
data _null_;
set test end=eof;
by color;
/* On the first member of the BY-Group, create a new macro variable VARn */
/* and increment the counter FLAG. */
if first.color then do;
flag+1;
call symput('var'||put(flag,8. -L),color);
end;
/* On the last observation of the data set, create a macro variable to */
/* contain the final value of FLAG. */
if eof then call symput('tot',put(flag,8. -L));
run;
/* Create a macro to generate the new data sets. Dynamically produce data set names */
/* on the DATA statement, using subsetting criteria to create the new data sets */
/* based upon the value of the BY variable. */
%macro groups(dsn,byvar);
data %do i=1 %to &tot;
&&var&i
%end;;
set &dsn;
%do i=1 %to &tot;
if &byvar="&&var&i" then output &&var&i;
%end;
run;
%mend groups;
/* Call the macro GROUPS. Specify the name of the data set to be split */
/* in the first macro parameter and the name of the BY variable in the */
/* second parameter. */
%groups(test,color)
proc print data=blue;
title 'Blue';
run;
proc print data=green;
title 'Green';
run;
proc print data=red;
title 'Red';
run;
/* Example 2 - Use CALL EXECUTE to pass a parameter to a macro in order to */
/* create a new data set for each BY-Group in an existing data */
/* set. The output is identical to the output created by */
/* Example 1 above. */
/* Compile the macro BREAK. The parameter BYVAL will be generated below in */
/* the CALL EXECUTE. */
%macro break(byval);
data &byval;
set test(where=(color="&byval"));
run;
%mend;
/* Use the same TEST data set created for Example 1. */
data _null_;
set test;
by color;
if first.color then
call execute(%nrstr('%break('||trim(color)||')'));
run;
This sample uses macro logic to determine the number of unique values of a variable (the BY variable) and creates a new data set for each. The resulting data set names will be the BY variable value.
Limitations:
The sample code does not allow for BY values of longer than 32 positions, numeric BY values or BY values that contain characters that are not permitted in SAS data set names.
If your data contains any of the above, you must add program statements to convert your BY values into valid SAS data set names.
Shamaoke/Scope chain ( Ruby)
# encoding: utf-8
#####################
# The Example Class #
#####################
class Example
def self.execute(&block)
class_eval(&block)
end
def self.some_code(&block)
new.instance_eval(&block)
end
end
#####################
# Object Extensions #
#####################
module ObjectExtensions
def execute(&block)
Example.execute(&block)
end
end
###################################
# Instance Extensions for Example #
###################################
module ExampleInstanceExtensions
def one
'one'
end
def two
'two'
end
def three
'three'
end
end
########################
# Macroses for Example #
########################
module ExampleClassExtensions
def do_one
some_code do
"do #{one}"
end
end
def do_two
some_code do
"do #{two}"
end
end
def do_three
some_code do
"do #{three}"
end
end
def the_macros
yield
end
end
Object.__send__(:include, ObjectExtensions)
Example.__send__(:extend, ExampleClassExtensions)
Example.__send__(:include, ExampleInstanceExtensions)
#####################
# The Demonstration #
#####################
puts "The #{self} scope." #=> main
some_code rescue puts 'some_code boom!' #=> some_code boom!
one rescue puts 'one boom!' #=> one boom!
two rescue puts 'two boom!' #=> two boom!
three rescue puts 'three boom!' #=> three boom!
execute do
the_macros do
puts "The #{self} scope." #=> the Example class
puts do_one, #=> do one
do_two, #=> do two
do_three #=> do three
end
some_code do
puts "The #{self} scope." #=> an Example instance
puts one, #=> one
two, #=> two
three #=> three
end
execute do
some_code do
puts "The #{self} scope." #=> an Example instance.
puts one, #=> one
two, #=> two
three #=> three
end
end
puts "The #{self} scope." #=> the Example class
one rescue puts 'one again boom!' #=> one again boom!
two rescue puts 'two again boom!' #=> two again boom!
three rescue puts 'three again boom!' #=> three again boom!
end
Execute an instance method of Object, call in its block class methods of another object and call in the blocks of that methods class or instance methods of the object depending on if the block applies to a macros or to a simple class method.
jimfred/C# Cypress EEPROM Utility with interop calls to deviceIoControl for access to USB driver. ( C#)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq; // for SequenceEqual (array comparison).
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices; // for DllImport
using System.Diagnostics; // for Assert
using System.Threading; // for Thread.Sleep
namespace CypressEepromUtility
{
public partial class MainForm : Form
{
// This is the main form for a utility to read, write, verify and erase the EEPROM on a Cypress FX2 processor board.
// Some of the code was taken from the EzMr (CyConsole) utility which used the EzUsb driver.
// Calls are made to deviceIoControl to access the EzUsb driver.
#region Vend_AX firmware array.
// This array was generated from C:\Cypress\USB\Examples\FX2LP\Vend_ax\Vend_Ax.hex.
// The .hex was was reconstituted into a binary buffer and then written to a text file and its contents included here.
// The code used to create the text file is testIntelHexToByteArray().
// The AA bytes are gaps that are untouched by the .hex contents.
// The original VendAx array taken from Vend_Ax.h in the EzMr project
// caused random Windows driver errors, crashes and PC lock-ups when coming out of reset.
// It would fail about 1 out of 5 startups and would otherwise run normally.
public static byte[] VendAxCode = new byte[]
{
#region fwCode
0x02, 0x07, 0xF3, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x02, 0x0D, 0x60, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x02, 0x08, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0x02, 0x08, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0x90, 0xE6, 0xB9, 0xE0, 0x24, 0x5E, 0xB4, 0x0B, 0x00, 0x40, 0x03, 0x02,
0x03, 0x98, 0x90, 0x00, 0x9C, 0x75, 0xF0, 0x03, 0xA4, 0xC5, 0x83, 0x25, 0xF0, 0xC5, 0x83, 0x73, 0x02, 0x01, 0x92, 0x02,
0x01, 0x92, 0x02, 0x01, 0x0D, 0x02, 0x00, 0xBD, 0x02, 0x00, 0xD7, 0x02, 0x00, 0xF3, 0x02, 0x01, 0x3C, 0x02, 0x01, 0x8C,
0x02, 0x01, 0x16, 0x02, 0x01, 0x29, 0x02, 0x01, 0x62, 0x90, 0xE7, 0x40, 0xE5, 0x19, 0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0,
0x90, 0xE6, 0x8B, 0x04, 0xF0, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x80, 0xF0, 0x02, 0x03, 0x98, 0x90, 0xE6, 0x0A, 0xE0, 0x90,
0xE7, 0x40, 0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x04, 0xF0, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x80, 0xF0,
0x02, 0x03, 0x98, 0x90, 0xE7, 0x40, 0x74, 0x0F, 0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x04, 0xF0, 0x90,
0xE6, 0xA0, 0xE0, 0x44, 0x80, 0xF0, 0x02, 0x03, 0x98, 0x90, 0xE6, 0xBA, 0xE0, 0xF5, 0x17, 0x02, 0x03, 0x98, 0x90, 0xE6,
0x7A, 0xE0, 0x54, 0xFE, 0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0xF0, 0x02, 0x03, 0x98, 0x90, 0xE6, 0x7A,
0xE0, 0x44, 0x01, 0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0xF0, 0x02, 0x03, 0x98, 0x90, 0xE7, 0x40, 0x74,
0x07, 0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x04, 0xF0, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x80, 0xF0, 0x7F,
0xE8, 0x7E, 0x03, 0x12, 0x07, 0xAD, 0xD2, 0x04, 0x12, 0x0B, 0x87, 0x02, 0x03, 0x98, 0x90, 0xE6, 0xB5, 0xE0, 0x54, 0xFE,
0xF0, 0x90, 0xE6, 0xBF, 0xE0, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0xBE, 0xE0, 0x90, 0xE6, 0x8B, 0xF0, 0x90, 0xE6, 0xBB,
0xE0, 0x90, 0xE6, 0xB3, 0xF0, 0x90, 0xE6, 0xBA, 0xE0, 0x90, 0xE6, 0xB4, 0xF0, 0x02, 0x03, 0x98, 0x75, 0x19, 0x01, 0x43,
0x17, 0x01, 0x90, 0xE6, 0xBA, 0xE0, 0x75, 0x31, 0x00, 0xF5, 0x32, 0xA3, 0xE0, 0xFE, 0xE4, 0xEE, 0x42, 0x31, 0x90, 0xE6,
0xBE, 0xE0, 0x75, 0x33, 0x00, 0xF5, 0x34, 0xA3, 0xE0, 0xFE, 0xE4, 0xEE, 0x42, 0x33, 0x90, 0xE6, 0xB8, 0xE0, 0x64, 0xC0,
0x60, 0x03, 0x02, 0x02, 0x82, 0xE5, 0x34, 0x45, 0x33, 0x70, 0x03, 0x02, 0x03, 0x98, 0x90, 0xE6, 0xA0, 0xE0, 0x20, 0xE1,
0xF9, 0xC3, 0xE5, 0x34, 0x94, 0x40, 0xE5, 0x33, 0x94, 0x00, 0x50, 0x08, 0x85, 0x33, 0x35, 0x85, 0x34, 0x36, 0x80, 0x06,
0x75, 0x35, 0x00, 0x75, 0x36, 0x40, 0x90, 0xE6, 0xB9, 0xE0, 0xB4, 0xA3, 0x35, 0xE4, 0xF5, 0x37, 0xF5, 0x38, 0xC3, 0xE5,
0x38, 0x95, 0x36, 0xE5, 0x37, 0x95, 0x35, 0x50, 0x60, 0xE5, 0x32, 0x25, 0x38, 0xF5, 0x82, 0xE5, 0x31, 0x35, 0x37, 0xF5,
0x83, 0xE0, 0xFF, 0x74, 0x40, 0x25, 0x38, 0xF5, 0x82, 0xE4, 0x34, 0xE7, 0xF5, 0x83, 0xEF, 0xF0, 0x05, 0x38, 0xE5, 0x38,
0x70, 0x02, 0x05, 0x37, 0x80, 0xD0, 0xE4, 0xF5, 0x37, 0xF5, 0x38, 0xC3, 0xE5, 0x38, 0x95, 0x36, 0xE5, 0x37, 0x95, 0x35,
0x50, 0x18, 0x74, 0x40, 0x25, 0x38, 0xF5, 0x82, 0xE4, 0x34, 0xE7, 0xF5, 0x83, 0x74, 0xCD, 0xF0, 0x05, 0x38, 0xE5, 0x38,
0x70, 0x02, 0x05, 0x37, 0x80, 0xDD, 0xAD, 0x36, 0x7A, 0xE7, 0x79, 0x40, 0x7E, 0xE7, 0x7F, 0x40, 0xAB, 0x07, 0xAF, 0x32,
0xAE, 0x31, 0x12, 0x08, 0xB8, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0xE5, 0x36, 0xF0, 0x25, 0x32, 0xF5, 0x32,
0xE5, 0x35, 0x35, 0x31, 0xF5, 0x31, 0xC3, 0xE5, 0x34, 0x95, 0x36, 0xF5, 0x34, 0xE5, 0x33, 0x95, 0x35, 0xF5, 0x33, 0x02,
0x01, 0xBD, 0x90, 0xE6, 0xB8, 0xE0, 0x64, 0x40, 0x60, 0x03, 0x02, 0x03, 0x98, 0xE5, 0x1A, 0x70, 0x05, 0x12, 0x09, 0x67,
0x8F, 0x1A, 0xE5, 0x34, 0x45, 0x33, 0x70, 0x03, 0x02, 0x03, 0x98, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0xF0,
0x90, 0xE6, 0xA0, 0xE0, 0x20, 0xE1, 0xF9, 0x90, 0xE6, 0x8B, 0xE0, 0x75, 0x35, 0x00, 0xF5, 0x36, 0x90, 0xE6, 0xB9, 0xE0,
0xB4, 0xA3, 0x38, 0xE4, 0xF5, 0x37, 0xF5, 0x38, 0xC3, 0xE5, 0x38, 0x95, 0x36, 0xE5, 0x37, 0x95, 0x35, 0x40, 0x03, 0x02,
0x03, 0x7C, 0x74, 0x40, 0x25, 0x38, 0xF5, 0x82, 0xE4, 0x34, 0xE7, 0xF5, 0x83, 0xE0, 0xFF, 0xE5, 0x32, 0x25, 0x38, 0xF5,
0x82, 0xE5, 0x31, 0x35, 0x37, 0xF5, 0x83, 0xEF, 0xF0, 0x05, 0x38, 0xE5, 0x38, 0x70, 0x02, 0x05, 0x37, 0x80, 0xCD, 0xE4,
0xF5, 0x37, 0xF5, 0x38, 0xC3, 0xE5, 0x38, 0x95, 0x36, 0xE5, 0x37, 0x95, 0x35, 0x50, 0x75, 0x85, 0x1A, 0x39, 0xE5, 0x1A,
0x64, 0x01, 0x60, 0x44, 0xE5, 0x32, 0x25, 0x38, 0xFF, 0xE5, 0x31, 0x35, 0x37, 0xFE, 0xE5, 0x1A, 0x24, 0xFF, 0xFD, 0xE4,
0x34, 0xFF, 0x5E, 0xFE, 0xEF, 0x5D, 0x4E, 0x60, 0x10, 0xE5, 0x32, 0x25, 0x38, 0xFF, 0xE5, 0x1A, 0x14, 0x5F, 0xFF, 0xC3,
0xE5, 0x1A, 0x9F, 0xF5, 0x39, 0xC3, 0xE5, 0x36, 0x95, 0x38, 0xFF, 0xE5, 0x35, 0x95, 0x37, 0xFE, 0xC3, 0xEF, 0x95, 0x39,
0xEE, 0x94, 0x00, 0x50, 0x07, 0xC3, 0xE5, 0x36, 0x95, 0x38, 0xF5, 0x39, 0xE5, 0x32, 0x25, 0x38, 0xFF, 0xE5, 0x31, 0x35,
0x37, 0xFE, 0x74, 0x40, 0x25, 0x38, 0xF5, 0x82, 0xE4, 0x34, 0xE7, 0xAD, 0x82, 0xFC, 0xAB, 0x39, 0x12, 0x0A, 0x9C, 0xE5,
0x39, 0x25, 0x38, 0xF5, 0x38, 0xE4, 0x35, 0x37, 0xF5, 0x37, 0x80, 0x80, 0xE5, 0x36, 0x25, 0x32, 0xF5, 0x32, 0xE5, 0x35,
0x35, 0x31, 0xF5, 0x31, 0xC3, 0xE5, 0x34, 0x95, 0x36, 0xF5, 0x34, 0xE5, 0x33, 0x95, 0x35, 0xF5, 0x33, 0x02, 0x02, 0x96,
0xC3, 0x22, 0x90, 0xE6, 0xB9, 0xE0, 0x70, 0x03, 0x02, 0x04, 0x85, 0x14, 0x70, 0x03, 0x02, 0x05, 0x2E, 0x24, 0xFE, 0x70,
0x03, 0x02, 0x05, 0xC4, 0x24, 0xFB, 0x70, 0x03, 0x02, 0x04, 0x7F, 0x14, 0x70, 0x03, 0x02, 0x04, 0x79, 0x14, 0x70, 0x03,
0x02, 0x04, 0x6D, 0x14, 0x70, 0x03, 0x02, 0x04, 0x73, 0x24, 0x05, 0x60, 0x03, 0x02, 0x06, 0x39, 0x12, 0x0D, 0x68, 0x40,
0x03, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xBB, 0xE0, 0x24, 0xFE, 0x60, 0x3B, 0x14, 0x60, 0x56, 0x24, 0xFD, 0x60, 0x16, 0x14,
0x60, 0x40, 0x24, 0x06, 0x70, 0x75, 0xE5, 0x0A, 0x90, 0xE6, 0xB3, 0xF0, 0xE5, 0x0B, 0x90, 0xE6, 0xB4, 0xF0, 0x02, 0x06,
0x45, 0x12, 0x0D, 0x33, 0x50, 0x0F, 0xE5, 0x12, 0x90, 0xE6, 0xB3, 0xF0, 0xE5, 0x13, 0x90, 0xE6, 0xB4, 0xF0, 0x02, 0x06,
0x45, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x02, 0x06, 0x45, 0xE5, 0x0C, 0x90, 0xE6, 0xB3, 0xF0, 0xE5, 0x0D, 0x90,
0xE6, 0xB4, 0xF0, 0x02, 0x06, 0x45, 0xE5, 0x0E, 0x90, 0xE6, 0xB3, 0xF0, 0xE5, 0x0F, 0x90, 0xE6, 0xB4, 0xF0, 0x02, 0x06,
0x45, 0x90, 0xE6, 0xBA, 0xE0, 0xFF, 0x12, 0x0B, 0xE2, 0xAA, 0x06, 0xA9, 0x07, 0x7B, 0x01, 0xEA, 0x49, 0x4B, 0x60, 0x0D,
0xEE, 0x90, 0xE6, 0xB3, 0xF0, 0xEF, 0x90, 0xE6, 0xB4, 0xF0, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0,
0x02, 0x06, 0x45, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x02, 0x06, 0x45, 0x12, 0x0C, 0xF1, 0x02, 0x06, 0x45, 0x12,
0x0D, 0x50, 0x02, 0x06, 0x45, 0x12, 0x0D, 0x48, 0x02, 0x06, 0x45, 0x12, 0x0C, 0xDF, 0x02, 0x06, 0x45, 0x12, 0x0D, 0x6A,
0x40, 0x03, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xB8, 0xE0, 0x24, 0x7F, 0x60, 0x2B, 0x14, 0x60, 0x3C, 0x24, 0x02, 0x60, 0x03,
0x02, 0x05, 0x24, 0xA2, 0x00, 0xE4, 0x33, 0xFF, 0x25, 0xE0, 0xFF, 0xA2, 0x02, 0xE4, 0x33, 0x4F, 0x90, 0xE7, 0x40, 0xF0,
0xE4, 0xA3, 0xF0, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x74, 0x02, 0xF0, 0x02, 0x06, 0x45, 0xE4, 0x90, 0xE7, 0x40,
0xF0, 0xA3, 0xF0, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x74, 0x02, 0xF0, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xBC, 0xE0,
0x54, 0x7E, 0xFF, 0x7E, 0x00, 0xE0, 0xD3, 0x94, 0x80, 0x40, 0x06, 0x7C, 0x00, 0x7D, 0x01, 0x80, 0x04, 0x7C, 0x00, 0x7D,
0x00, 0xEC, 0x4E, 0xFE, 0xED, 0x4F, 0x24, 0x3E, 0xF5, 0x82, 0x74, 0x0D, 0x3E, 0xF5, 0x83, 0xE4, 0x93, 0xFF, 0x33, 0x95,
0xE0, 0xFE, 0xEF, 0x24, 0xA1, 0xFF, 0xEE, 0x34, 0xE6, 0x8F, 0x82, 0xF5, 0x83, 0xE0, 0x54, 0x01, 0x90, 0xE7, 0x40, 0xF0,
0xE4, 0xA3, 0xF0, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x74, 0x02, 0xF0, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xA0, 0xE0,
0x44, 0x01, 0xF0, 0x02, 0x06, 0x45, 0x12, 0x0D, 0x6C, 0x40, 0x03, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xB8, 0xE0, 0x24, 0xFE,
0x60, 0x1D, 0x24, 0x02, 0x60, 0x03, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xBA, 0xE0, 0xB4, 0x01, 0x05, 0xC2, 0x00, 0x02, 0x06,
0x45, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xBA, 0xE0, 0x70, 0x59, 0x90, 0xE6, 0xBC,
0xE0, 0x54, 0x7E, 0xFF, 0x7E, 0x00, 0xE0, 0xD3, 0x94, 0x80, 0x40, 0x06, 0x7C, 0x00, 0x7D, 0x01, 0x80, 0x04, 0x7C, 0x00,
0x7D, 0x00, 0xEC, 0x4E, 0xFE, 0xED, 0x4F, 0x24, 0x3E, 0xF5, 0x82, 0x74, 0x0D, 0x3E, 0xF5, 0x83, 0xE4, 0x93, 0xFF, 0x33,
0x95, 0xE0, 0xFE, 0xEF, 0x24, 0xA1, 0xFF, 0xEE, 0x34, 0xE6, 0x8F, 0x82, 0xF5, 0x83, 0xE0, 0x54, 0xFE, 0xF0, 0x90, 0xE6,
0xBC, 0xE0, 0x54, 0x80, 0xFF, 0x13, 0x13, 0x13, 0x54, 0x1F, 0xFF, 0xE0, 0x54, 0x0F, 0x2F, 0x90, 0xE6, 0x83, 0xF0, 0xE0,
0x44, 0x20, 0xF0, 0x02, 0x06, 0x45, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x02, 0x06, 0x45, 0x12, 0x0D, 0x6E, 0x50,
0x7C, 0x90, 0xE6, 0xB8, 0xE0, 0x24, 0xFE, 0x60, 0x20, 0x24, 0x02, 0x70, 0x5B, 0x90, 0xE6, 0xBA, 0xE0, 0xB4, 0x01, 0x04,
0xD2, 0x00, 0x80, 0x65, 0x90, 0xE6, 0xBA, 0xE0, 0x64, 0x02, 0x60, 0x5D, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x80,
0x54, 0x90, 0xE6, 0xBC, 0xE0, 0x54, 0x7E, 0xFF, 0x7E, 0x00, 0xE0, 0xD3, 0x94, 0x80, 0x40, 0x06, 0x7C, 0x00, 0x7D, 0x01,
0x80, 0x04, 0x7C, 0x00, 0x7D, 0x00, 0xEC, 0x4E, 0xFE, 0xED, 0x4F, 0x24, 0x3E, 0xF5, 0x82, 0x74, 0x0D, 0x3E, 0xF5, 0x83,
0xE4, 0x93, 0xFF, 0x33, 0x95, 0xE0, 0xFE, 0xEF, 0x24, 0xA1, 0xFF, 0xEE, 0x34, 0xE6, 0x8F, 0x82, 0xF5, 0x83, 0xE0, 0x44,
0x01, 0xF0, 0x80, 0x15, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x80, 0x0C, 0x12, 0x00, 0x80, 0x50, 0x07, 0x90, 0xE6,
0xA0, 0xE0, 0x44, 0x01, 0xF0, 0x90, 0xE6, 0xA0, 0xE0, 0x44, 0x80, 0xF0, 0x22, 0xE4, 0xF5, 0x2C, 0xF5, 0x2B, 0xF5, 0x2A,
0xF5, 0x29, 0xC2, 0x03, 0xC2, 0x00, 0xC2, 0x02, 0xC2, 0x01, 0x12, 0x0C, 0x6C, 0x7E, 0x0A, 0x7F, 0x00, 0x8E, 0x0A, 0x8F,
0x0B, 0x75, 0x12, 0x0A, 0x75, 0x13, 0x12, 0x75, 0x08, 0x0A, 0x75, 0x09, 0x1C, 0x75, 0x10, 0x0A, 0x75, 0x11, 0x4A, 0x75,
0x14, 0x0A, 0x75, 0x15, 0x78, 0xEE, 0x54, 0xC0, 0x70, 0x03, 0x02, 0x07, 0x52, 0x75, 0x2D, 0x00, 0x75, 0x2E, 0x80, 0x8E,
0x2F, 0x8F, 0x30, 0xC3, 0x74, 0x9A, 0x9F, 0xFF, 0x74, 0x0A, 0x9E, 0xCF, 0x24, 0x02, 0xCF, 0x34, 0x00, 0xFE, 0xE4, 0x8F,
0x28, 0x8E, 0x27, 0xF5, 0x26, 0xF5, 0x25, 0xF5, 0x24, 0xF5, 0x23, 0xF5, 0x22, 0xF5, 0x21, 0xAF, 0x28, 0xAE, 0x27, 0xAD,
0x26, 0xAC, 0x25, 0xAB, 0x24, 0xAA, 0x23, 0xA9, 0x22, 0xA8, 0x21, 0xC3, 0x12, 0x0D, 0x03, 0x50, 0x37, 0xE5, 0x30, 0x25,
0x24, 0xF5, 0x82, 0xE5, 0x2F, 0x35, 0x23, 0xF5, 0x83, 0xE0, 0xFF, 0xE5, 0x2E, 0x25, 0x24, 0xF5, 0x82, 0xE5, 0x2D, 0x35,
0x23, 0xF5, 0x83, 0xEF, 0xF0, 0xE4, 0xFA, 0xF9, 0xF8, 0xE5, 0x24, 0x24, 0x01, 0xF5, 0x24, 0xEA, 0x35, 0x23, 0xF5, 0x23,
0xE9, 0x35, 0x22, 0xF5, 0x22, 0xE8, 0x35, 0x21, 0xF5, 0x21, 0x80, 0xB3, 0x85, 0x2D, 0x0A, 0x85, 0x2E, 0x0B, 0x74, 0x00,
0x24, 0x80, 0xFF, 0x74, 0x0A, 0x34, 0xFF, 0xFE, 0xC3, 0xE5, 0x13, 0x9F, 0xF5, 0x13, 0xE5, 0x12, 0x9E, 0xF5, 0x12, 0xC3,
0xE5, 0x0D, 0x9F, 0xF5, 0x0D, 0xE5, 0x0C, 0x9E, 0xF5, 0x0C, 0xC3, 0xE5, 0x0F, 0x9F, 0xF5, 0x0F, 0xE5, 0x0E, 0x9E, 0xF5,
0x0E, 0xC3, 0xE5, 0x09, 0x9F, 0xF5, 0x09, 0xE5, 0x08, 0x9E, 0xF5, 0x08, 0xC3, 0xE5, 0x11, 0x9F, 0xF5, 0x11, 0xE5, 0x10,
0x9E, 0xF5, 0x10, 0xC3, 0xE5, 0x15, 0x9F, 0xF5, 0x15, 0xE5, 0x14, 0x9E, 0xF5, 0x14, 0xD2, 0xE8, 0x43, 0xD8, 0x20, 0x90,
0xE6, 0x68, 0xE0, 0x44, 0x09, 0xF0, 0x90, 0xE6, 0x5C, 0xE0, 0x44, 0x3D, 0xF0, 0xD2, 0xAF, 0x90, 0xE6, 0x80, 0xE0, 0x54,
0xF7, 0xF0, 0x53, 0x8E, 0xF8, 0xC2, 0x03, 0x12, 0x07, 0xFF, 0x30, 0x01, 0x05, 0x12, 0x03, 0x9A, 0xC2, 0x01, 0x30, 0x03,
0xF2, 0x12, 0x0D, 0x64, 0x50, 0xED, 0xC2, 0x03, 0x12, 0x0C, 0x0D, 0x20, 0x00, 0x16, 0x90, 0xE6, 0x82, 0xE0, 0x30, 0xE7,
0x04, 0xE0, 0x20, 0xE1, 0xEF, 0x90, 0xE6, 0x82, 0xE0, 0x30, 0xE6, 0x04, 0xE0, 0x20, 0xE0, 0xE4, 0x12, 0x0B, 0xB6, 0x12,
0x0D, 0x66, 0x80, 0xC7, 0x22, 0x8E, 0x3A, 0x8F, 0x3B, 0x90, 0xE6, 0x00, 0xE0, 0x54, 0x18, 0x70, 0x12, 0xE5, 0x3B, 0x24,
0x01, 0xFF, 0xE4, 0x35, 0x3A, 0xC3, 0x13, 0xF5, 0x3A, 0xEF, 0x13, 0xF5, 0x3B, 0x80, 0x15, 0x90, 0xE6, 0x00, 0xE0, 0x54,
0x18, 0xFF, 0xBF, 0x10, 0x0B, 0xE5, 0x3B, 0x25, 0xE0, 0xF5, 0x3B, 0xE5, 0x3A, 0x33, 0xF5, 0x3A, 0xE5, 0x3B, 0x15, 0x3B,
0xAE, 0x3A, 0x70, 0x02, 0x15, 0x3A, 0x4E, 0x60, 0x05, 0x12, 0x0C, 0x21, 0x80, 0xEE, 0x22, 0x78, 0x7F, 0xE4, 0xF6, 0xD8,
0xFD, 0x75, 0x81, 0x41, 0x02, 0x06, 0x4D, 0x22, 0x02, 0x0C, 0x32, 0x00, 0x02, 0x0C, 0xB3, 0x00, 0x02, 0x0C, 0x9D, 0x00,
0x02, 0x0C, 0x85, 0x00, 0x02, 0x0B, 0x19, 0x00, 0x02, 0x0B, 0x50, 0x00, 0x02, 0x09, 0xFF, 0x00, 0x02, 0x0D, 0x70, 0x00,
0x02, 0x0D, 0x71, 0x00, 0x02, 0x0D, 0x72, 0x00, 0x02, 0x0D, 0x73, 0x00, 0x02, 0x0D, 0x74, 0x00, 0x02, 0x0D, 0x75, 0x00,
0x02, 0x0D, 0x76, 0x00, 0x02, 0x0D, 0x77, 0x00, 0x02, 0x0D, 0x78, 0x00, 0x02, 0x0D, 0x79, 0x00, 0x02, 0x0D, 0x70, 0x00,
0x02, 0x0D, 0x7A, 0x00, 0x02, 0x0D, 0x7B, 0x00, 0x02, 0x0D, 0x7C, 0x00, 0x02, 0x0D, 0x7D, 0x00, 0x02, 0x0D, 0x7E, 0x00,
0x02, 0x0D, 0x7F, 0x00, 0x02, 0x0D, 0x80, 0x00, 0x02, 0x0D, 0x70, 0x00, 0x02, 0x0D, 0x70, 0x00, 0x02, 0x0D, 0x70, 0x00,
0x02, 0x0D, 0x81, 0x00, 0x02, 0x0D, 0x82, 0x00, 0x02, 0x0D, 0x83, 0x00, 0x02, 0x0D, 0x84, 0x00, 0x02, 0x0D, 0x85, 0x00,
0x02, 0x0D, 0x86, 0x00, 0x02, 0x0D, 0x87, 0x00, 0x02, 0x0D, 0x88, 0x00, 0x02, 0x0D, 0x89, 0x00, 0x02, 0x0D, 0x8A, 0x00,
0x02, 0x0D, 0x8B, 0x00, 0x02, 0x0D, 0x8C, 0x00, 0x02, 0x0D, 0x8D, 0x00, 0x02, 0x0D, 0x8E, 0x00, 0x02, 0x0D, 0x8F, 0x00,
0x02, 0x0D, 0x90, 0x00, 0x02, 0x0D, 0x91, 0x00, 0x02, 0x0D, 0x92, 0x00, 0x8E, 0x3C, 0x8F, 0x3D, 0x8D, 0x3E, 0x8A, 0x3F,
0x8B, 0x40, 0x12, 0x0D, 0x58, 0x12, 0x0D, 0x24, 0x12, 0x0C, 0xC9, 0x50, 0x01, 0x22, 0xE5, 0x19, 0x60, 0x0C, 0xE5, 0x3C,
0x90, 0xE6, 0x79, 0xF0, 0x12, 0x0C, 0xC9, 0x50, 0x01, 0x22, 0xE5, 0x3D, 0x90, 0xE6, 0x79, 0xF0, 0x12, 0x0C, 0xC9, 0x50,
0x01, 0x22, 0x90, 0xE6, 0x78, 0x74, 0x80, 0xF0, 0xE5, 0x17, 0x25, 0xE0, 0x44, 0x01, 0x90, 0xE6, 0x79, 0xF0, 0x12, 0x0D,
0x14, 0x50, 0x01, 0x22, 0x90, 0xE6, 0x79, 0xE0, 0xF5, 0x41, 0x12, 0x0D, 0x14, 0x50, 0x01, 0x22, 0xE4, 0xF5, 0x41, 0xE5,
0x3E, 0x14, 0xFF, 0xE5, 0x41, 0xC3, 0x9F, 0x50, 0x1C, 0x90, 0xE6, 0x79, 0xE0, 0xFF, 0xE5, 0x40, 0x25, 0x41, 0xF5, 0x82,
0xE4, 0x35, 0x3F, 0xF5, 0x83, 0xEF, 0xF0, 0x12, 0x0D, 0x14, 0x50, 0x01, 0x22, 0x05, 0x41, 0x80, 0xDA, 0x90, 0xE6, 0x78,
0x74, 0x20, 0xF0, 0x12, 0x0D, 0x14, 0x50, 0x01, 0x22, 0x90, 0xE6, 0x79, 0xE0, 0xFF, 0xE5, 0x40, 0x25, 0x41, 0xF5, 0x82,
0xE4, 0x35, 0x3F, 0xF5, 0x83, 0xEF, 0xF0, 0x12, 0x0D, 0x14, 0x50, 0x01, 0x22, 0x90, 0xE6, 0x78, 0x74, 0x40, 0xF0, 0x90,
0xE6, 0x79, 0xE0, 0xF5, 0x41, 0xC3, 0x22, 0xE5, 0x19, 0x70, 0x03, 0x7F, 0x01, 0x22, 0x7A, 0x10, 0x7B, 0x40, 0x7D, 0x40,
0xE4, 0xFF, 0xFE, 0x12, 0x08, 0xB8, 0xE4, 0xF5, 0x3A, 0x74, 0x00, 0x25, 0x3A, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83,
0xE5, 0x3A, 0xF0, 0x05, 0x3A, 0xE5, 0x3A, 0xB4, 0x40, 0xEB, 0x7C, 0x10, 0x7D, 0x00, 0x7B, 0x40, 0xE4, 0xFF, 0xFE, 0x12,
0x0A, 0x9C, 0xE4, 0xF5, 0x3A, 0xE5, 0x3A, 0xF4, 0xFF, 0x74, 0x00, 0x25, 0x3A, 0xF5, 0x82, 0xE4, 0x34, 0x10, 0xF5, 0x83,
0xEF, 0xF0, 0x05, 0x3A, 0xE5, 0x3A, 0xB4, 0x40, 0xE8, 0x7A, 0x10, 0x7B, 0x00, 0x7D, 0x40, 0xE4, 0xFF, 0xFE, 0x12, 0x08,
0xB8, 0x90, 0x10, 0x00, 0xE0, 0xF5, 0x3A, 0xE5, 0x3A, 0x30, 0xE0, 0x05, 0x75, 0x3B, 0x01, 0x80, 0x08, 0x63, 0x3A, 0x3F,
0x05, 0x3A, 0x85, 0x3A, 0x3B, 0xE4, 0xF5, 0x3A, 0xE5, 0x3A, 0xC3, 0x94, 0x40, 0x50, 0x15, 0xAF, 0x3A, 0x7E, 0x00, 0x7C,
0x10, 0x7D, 0x40, 0xAB, 0x3B, 0x12, 0x0A, 0x9C, 0xE5, 0x3B, 0x25, 0x3A, 0xF5, 0x3A, 0x80, 0xE4, 0xAF, 0x3B, 0x22, 0x32,
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0xB4, 0x04, 0x04, 0x10, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x0A, 0x06,
0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x09, 0x02, 0x2E, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32, 0x09, 0x04, 0x00,
0x00, 0x04, 0xFF, 0x00, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x04, 0x02, 0x00, 0x02, 0x00,
0x07, 0x05, 0x86, 0x02, 0x00, 0x02, 0x00, 0x07, 0x05, 0x88, 0x02, 0x00, 0x02, 0x00, 0x09, 0x02, 0x2E, 0x00, 0x01, 0x01,
0x00, 0x80, 0x32, 0x09, 0x04, 0x00, 0x00, 0x04, 0xFF, 0x00, 0x00, 0x00, 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, 0x07,
0x05, 0x04, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x86, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x88, 0x02, 0x40, 0x00, 0x00,
0x04, 0x03, 0x09, 0x04, 0x10, 0x03, 0x43, 0x00, 0x79, 0x00, 0x70, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00,
0x0E, 0x03, 0x45, 0x00, 0x5A, 0x00, 0x2D, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42, 0x00, 0x00, 0x00, 0x8E, 0x3C, 0x8F, 0x3D,
0x8C, 0x3E, 0x8D, 0x3F, 0x8B, 0x40, 0xC2, 0x87, 0x43, 0xB2, 0x80, 0x12, 0x0D, 0x58, 0x12, 0x0D, 0x24, 0x12, 0x0C, 0xC9,
0x50, 0x04, 0xD2, 0x04, 0x80, 0x59, 0xE5, 0x19, 0x60, 0x0F, 0xE5, 0x3C, 0x90, 0xE6, 0x79, 0xF0, 0x12, 0x0C, 0xC9, 0x50,
0x04, 0xD2, 0x04, 0x80, 0x46, 0xE5, 0x3D, 0x90, 0xE6, 0x79, 0xF0, 0x12, 0x0C, 0xC9, 0x50, 0x04, 0xD2, 0x04, 0x80, 0x37,
0xE4, 0xF5, 0x41, 0xE5, 0x41, 0xC3, 0x95, 0x40, 0x50, 0x21, 0x05, 0x3F, 0xE5, 0x3F, 0xAE, 0x3E, 0x70, 0x02, 0x05, 0x3E,
0x14, 0xF5, 0x82, 0x8E, 0x83, 0xE0, 0x90, 0xE6, 0x79, 0xF0, 0x12, 0x0D, 0x14, 0x50, 0x04, 0xD2, 0x04, 0x80, 0x10, 0x05,
0x41, 0x80, 0xD8, 0x90, 0xE6, 0x78, 0xE0, 0x44, 0x40, 0xF0, 0x12, 0x0C, 0x51, 0xC2, 0x04, 0x53, 0xB2, 0x7F, 0xA2, 0x04,
0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0x90, 0xE6, 0x80, 0xE0, 0x30, 0xE7, 0x0E, 0x85, 0x08, 0x0C, 0x85, 0x09, 0x0D,
0x85, 0x10, 0x0E, 0x85, 0x11, 0x0F, 0x80, 0x0C, 0x85, 0x10, 0x0C, 0x85, 0x11, 0x0D, 0x85, 0x08, 0x0E, 0x85, 0x09, 0x0F,
0x53, 0x91, 0xEF, 0x90, 0xE6, 0x5D, 0x74, 0x10, 0xF0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xC0, 0xE0, 0xC0, 0x83,
0xC0, 0x82, 0x90, 0xE6, 0x80, 0xE0, 0x30, 0xE7, 0x0E, 0x85, 0x08, 0x0C, 0x85, 0x09, 0x0D, 0x85, 0x10, 0x0E, 0x85, 0x11,
0x0F, 0x80, 0x0C, 0x85, 0x10, 0x0C, 0x85, 0x11, 0x0D, 0x85, 0x08, 0x0E, 0x85, 0x09, 0x0F, 0x53, 0x91, 0xEF, 0x90, 0xE6,
0x5D, 0x74, 0x20, 0xF0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0x30, 0x04, 0x09, 0x90, 0xE6, 0x80, 0xE0, 0x44, 0x0A,
0xF0, 0x80, 0x07, 0x90, 0xE6, 0x80, 0xE0, 0x44, 0x08, 0xF0, 0x7F, 0xDC, 0x7E, 0x05, 0x12, 0x07, 0xAD, 0x90, 0xE6, 0x5D,
0x74, 0xFF, 0xF0, 0x90, 0xE6, 0x5F, 0xF0, 0x53, 0x91, 0xEF, 0x90, 0xE6, 0x80, 0xE0, 0x54, 0xF7, 0xF0, 0x22, 0x90, 0xE6,
0x82, 0xE0, 0x30, 0xE0, 0x04, 0xE0, 0x20, 0xE6, 0x0B, 0x90, 0xE6, 0x82, 0xE0, 0x30, 0xE1, 0x19, 0xE0, 0x30, 0xE7, 0x15,
0x90, 0xE6, 0x80, 0xE0, 0x44, 0x01, 0xF0, 0x7F, 0x14, 0x7E, 0x00, 0x12, 0x07, 0xAD, 0x90, 0xE6, 0x80, 0xE0, 0x54, 0xFE,
0xF0, 0x22, 0xA9, 0x07, 0xAE, 0x14, 0xAF, 0x15, 0x8F, 0x82, 0x8E, 0x83, 0xA3, 0xE0, 0x64, 0x03, 0x70, 0x17, 0xAD, 0x01,
0x19, 0xED, 0x70, 0x01, 0x22, 0x8F, 0x82, 0x8E, 0x83, 0xE0, 0x7C, 0x00, 0x2F, 0xFD, 0xEC, 0x3E, 0xFE, 0xAF, 0x05, 0x80,
0xDF, 0xE4, 0xFE, 0xFF, 0x22, 0x90, 0xE6, 0x82, 0xE0, 0x44, 0xC0, 0xF0, 0x90, 0xE6, 0x81, 0xF0, 0x43, 0x87, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x22, 0x74, 0x00, 0xF5, 0x86, 0x90, 0xFD, 0xA5, 0x7C, 0x05, 0xA3, 0xE5, 0x82, 0x45, 0x83, 0x70,
0xF9, 0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0x90, 0xE6, 0xB5, 0xE0, 0x44, 0x01, 0xF0, 0xD2, 0x01, 0x53, 0x91, 0xEF,
0x90, 0xE6, 0x5D, 0x74, 0x01, 0xF0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0x12, 0x0D, 0x58, 0x12, 0x0D, 0x24, 0x12,
0x0D, 0x14, 0x90, 0xE6, 0x78, 0xE0, 0x44, 0x40, 0xF0, 0x12, 0x0D, 0x58, 0x90, 0xE6, 0x78, 0xE0, 0x30, 0xE1, 0xE9, 0x22,
0xD2, 0x00, 0xE4, 0xF5, 0x1A, 0x90, 0xE6, 0x78, 0xE0, 0x54, 0x10, 0xFF, 0xC4, 0x54, 0x0F, 0x44, 0x50, 0xF5, 0x17, 0x13,
0xE4, 0x33, 0xF5, 0x19, 0x22, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0xD2, 0x03, 0x53, 0x91, 0xEF, 0x90, 0xE6, 0x5D, 0x74,
0x08, 0xF0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0x53, 0x91, 0xEF, 0x90, 0xE6,
0x5D, 0x74, 0x04, 0xF0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0xC0, 0xE0, 0xC0, 0x83, 0xC0, 0x82, 0x53, 0x91, 0xEF,
0x90, 0xE6, 0x5D, 0x74, 0x02, 0xF0, 0xD0, 0x82, 0xD0, 0x83, 0xD0, 0xE0, 0x32, 0x90, 0xE6, 0x78, 0xE0, 0xFF, 0x30, 0xE0,
0xF8, 0xEF, 0x30, 0xE2, 0x02, 0xD3, 0x22, 0xEF, 0x20, 0xE1, 0x02, 0xD3, 0x22, 0xC3, 0x22, 0x90, 0xE7, 0x40, 0xE5, 0x18,
0xF0, 0xE4, 0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x04, 0xF0, 0xD3, 0x22, 0x90, 0xE7, 0x40, 0xE5, 0x16, 0xF0, 0xE4,
0x90, 0xE6, 0x8A, 0xF0, 0x90, 0xE6, 0x8B, 0x04, 0xF0, 0xD3, 0x22, 0xEB, 0x9F, 0xF5, 0xF0, 0xEA, 0x9E, 0x42, 0xF0, 0xE9,
0x9D, 0x42, 0xF0, 0xE8, 0x9C, 0x45, 0xF0, 0x22, 0x90, 0xE6, 0x78, 0xE0, 0xFF, 0x30, 0xE0, 0xF8, 0xEF, 0x30, 0xE2, 0x02,
0xD3, 0x22, 0xC3, 0x22, 0x90, 0xE6, 0x78, 0x74, 0x80, 0xF0, 0xE5, 0x17, 0x25, 0xE0, 0x90, 0xE6, 0x79, 0xF0, 0x22, 0x90,
0xE5, 0x0D, 0xE0, 0x30, 0xE4, 0x02, 0xC3, 0x22, 0xD3, 0x22, 0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05,
0x90, 0xE6, 0xBA, 0xE0, 0xF5, 0x18, 0xD3, 0x22, 0x90, 0xE6, 0xBA, 0xE0, 0xF5, 0x16, 0xD3, 0x22, 0x90, 0xE6, 0x78, 0xE0,
0x20, 0xE6, 0xF9, 0x22, 0x53, 0xD8, 0xEF, 0x32, 0xD3, 0x22, 0xD3, 0x22, 0xD3, 0x22, 0xD3, 0x22, 0xD3, 0x22, 0xD3, 0x22,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0xAA,
// The original array was padded to a size divisible by 16 but apparently that is not required.
#endregion
};
#endregion
#region DLL APIs
// CreateFile - Used to get access to a USB device
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern Microsoft.Win32.SafeHandles.SafeFileHandle CreateFile(
string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr SecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile
);
// public const uint FILE_ATTRIBUTE_NORMAL = 0x80; // not used
// public const uint FILE_INVALID_HANDLE_VALUE = -1; // not used
// Taken from WinNt.h. These could be enum-ized for type-safety.
public const uint FILE_GENERIC_READ = 0x80000000;
public const uint FILE_GENERIC_WRITE = 0x40000000;
public const uint FILE_SHARE_WRITE = 0x00000002;
public const uint FILE_CREATE_NEW = 1;
public const uint FILE_CREATE_ALWAYS = 2;
public const uint FILE_OPEN_EXISTING = 3;
#region multiple DeviceIoControl definitions
// DeviceIoControl. outbuf as IntPtr
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("Kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool DeviceIoControl(
[In] Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
[In] uint dwIoControlCode, // EIOControlCode
ref EzUsbSys.VENDOR_REQUEST_IN lpInBuffer,
[In] int nInBufferSize,
IntPtr lpOutBuffer,
int nOutBufferSize,
ref int pBytesReturned,
IntPtr Overlapped
);
// DeviceIoControl. outbuf as byte []
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("Kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool DeviceIoControl(
[In] Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
[In] uint dwIoControlCode, // EIOControlCode
ref EzUsbSys.VENDOR_REQUEST_IN lpInBuffer,
[In] int nInBufferSize,
byte[] lpOutBuffer,
int nOutBufferSize,
ref int pBytesReturned,
IntPtr Overlapped
);
// DeviceIoControl. outbuf as byte []
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("Kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool DeviceIoControl(
[In] Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
[In] uint dwIoControlCode, // EIOControlCode
ref EzUsbSys.ANCHOR_DOWNLOAD_CONTROL lpInBuffer,
[In] int nInBufferSize,
byte[] lpOutBuffer,
int nOutBufferSize,
ref int pBytesReturned,
IntPtr Overlapped
);
// DeviceIoControl. outbuf as byte []
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("Kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool DeviceIoControl(
[In] Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
[In] uint dwIoControlCode, // EIOControlCode
ref EzUsbSys.VENDOR_OR_CLASS_REQUEST_CONTROL lpInBuffer,
[In] int nInBufferSize,
byte[] lpOutBuffer,
int nOutBufferSize,
ref int pBytesReturned,
IntPtr Overlapped
);
// DeviceIoControl. intbuf and outbuf as Usb_Device_Descriptor
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("Kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool DeviceIoControl(
[In] Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
[In] uint dwIoControlCode, // EIOControlCode
ref EzUsbSys.Usb_Device_Descriptor lpInBuffer,
[In] int nInBufferSize,
ref EzUsbSys.Usb_Device_Descriptor lpOutBuffer,
int nOutBufferSize,
ref int pBytesReturned,
IntPtr Overlapped
);
// DeviceIoControl. outbuf as byte []
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("Kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool DeviceIoControl(
[In] Microsoft.Win32.SafeHandles.SafeFileHandle hDevice,
[In] uint dwIoControlCode, // EIOControlCode
byte[] lpInBuffer,
[In] int nInBufferSize,
byte[] lpOutBuffer,
int nOutBufferSize,
ref int pBytesReturned,
IntPtr Overlapped
);
#endregion
/*
// since I'm using SafeFileHandle, don't call CloseHandle(hOut);
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(Microsoft.Win32.SafeHandles.SafeFileHandle hObject);
*/
#endregion
#region Other Interop defines
// Taken from EzUsbSys.h
public class EzUsbSys
{
// These values were taken from EzUsbSys.h which were defined using the CTL_CODE macro defined in WinIoCtl.h
// lic static uint IOCTL_Ezusb_GET_PIPE_INFO = CTL_CODE(FileDevice.UNKNOWN, Ezusb_IOCTL_INDEX + 0, Method.BUFFERED, FileAccess.ANY );
public static uint IOCTL_Ezusb_GET_DEVICE_DESCRIPTOR = CTL_CODE(FileDevice.UNKNOWN, Ezusb_IOCTL_INDEX + 1, Method.BUFFERED, FileAccess.ANY );
public static uint IOCTL_Ezusb_VENDOR_REQUEST = CTL_CODE(FileDevice.UNKNOWN, Ezusb_IOCTL_INDEX + 5, Method.BUFFERED, FileAccess.ANY );
// lic static uint IOCTL_Ezusb_ANCHOR_DOWNLOAD = CTL_CODE(FileDevice.UNKNOWN, Ezusb_IOCTL_INDEX + 7, Method.BUFFERED, FileAccess.ANY );
public static uint IOCTL_EZUSB_ANCHOR_DOWNLOAD = CTL_CODE(FileDevice.UNKNOWN, Ezusb_IOCTL_INDEX + 27, Method.IN_DIRECT, FileAccess.ANY );
public static uint IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST = CTL_CODE(FileDevice.UNKNOWN, Ezusb_IOCTL_INDEX + 22, Method.IN_DIRECT, FileAccess.ANY );
enum FileDevice : uint
{
UNKNOWN = 0x00000022, // taken from FILE_DEVICE_UNKNOWN in WinIoCtl.h
};
enum Method : uint
{
BUFFERED = 0, // METHOD_BUFFERED in WinIoCtl.h
IN_DIRECT = 1,
OUT_DIRECT = 2,
NEITHER = 3,
};
enum FileAccess : uint
{
ANY = 0, // FILE_ANY_ACCESS in WinIoCtl.h
};
// CTL_CODE macro defined in WinIoCtl.h
// c# does not allow macros with parameters therefore this function was created.
// For improved type-safety, the parameters are defined as enums based on uint.
private static uint CTL_CODE(FileDevice deviceType, uint function, Method method, FileAccess access)
{
return ((uint)deviceType << 16) | ((uint)access << 14) | ((uint)function << 2) | (uint)method;
}
private const uint Ezusb_IOCTL_INDEX = 0x0800; // taken from Ezusb_IOCTL_INDEX in EzUsbSys.h.
private static bool testOk = TestOk(); // Run test at startup.
static bool TestOk()
{
// Make sure that this implementation results in the same values seen in EzUsb.
Debug.Assert(
IOCTL_Ezusb_VENDOR_REQUEST == 0x00222014 &&
IOCTL_EZUSB_ANCHOR_DOWNLOAD == 0x0022206D &&
IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST == 0x00222059
);
return true;
}
public enum VendAxCmd : byte
{
ANCHOR_LOAD_INTERNAL = 0xA0, // ANCHOR_LOAD_INTERNAL in EzUsbSys.h. R+W internal memory. Executed by USB core rather than firmware.
RwEepromSmall = 0xA2, // Couldn't find A2 in EzUsbSys.h. It R&W small EEPROM.
ANCHOR_LOAD_EXTERNAL = 0xA3, // ANCHOR_LOAD_EXTERNAL
GetEepromSize = 0xA5, // Couldn't find this in EzUsbSys.h. Consider using this to check EEPROM size.
RwEepromBig = 0xA9, // R&W a 'large' EEPROM. I'm assuming that we'll use only the large EEPROM.
};
public enum RequestType : byte
{
Class = 1,
Vendor = 2
};
public enum Recipient : byte
{
Device = 0,
Interface = 1,
Endpoint = 2,
Other = 3
};
public enum Direction : byte
{
HostToDevice = 0,
DeviceToHost = 1
}
// structs taken from EzUsbSys.h
// I'll keep the structure definitions as close as possible to the original definitions.
// A constructor is added for better type-safety.
public struct VENDOR_REQUEST_IN // from EzUsbSys.h
{
public byte bRequest;
public UInt16 wValue;
public UInt16 wIndex;
public UInt16 wLength;
public byte direction;
public byte bData;
public VENDOR_REQUEST_IN(
VendAxCmd bRequest,
int offset,
UInt16 wIndex,
int wLength,
Direction direction,
byte bData)
{
this.bRequest = (byte)bRequest;
this.wValue = (UInt16)offset;
this.wIndex = wIndex;
this.wLength = (UInt16)wLength;
this.direction = (byte)direction;
this.bData = bData;
}
};
// Structure used with IOCTL_EZUSB_ANCHOR_DOWNLOAD (but not IOCTL_Ezusb_ANCHOR_DOWNLOAD).
public struct ANCHOR_DOWNLOAD_CONTROL // From EzUsbSys.h
{
UInt16 offset;
public ANCHOR_DOWNLOAD_CONTROL(UInt16 offset)
{
this.offset = offset;
}
};
public struct VENDOR_OR_CLASS_REQUEST_CONTROL // From EzUsbSys.h
{
public byte direction; // transfer direction (0=host to device, 1=device to host)
public byte requestType; // request type (1=class, 2=vendor)
public byte recepient; // recipient (0=device,1=interface,2=endpoint,3=other)
public byte requestTypeReservedBits;
public byte request;
public UInt16 value;
public UInt16 index;
public VENDOR_OR_CLASS_REQUEST_CONTROL(
Direction direction,
RequestType requestType,
Recipient recepient,
VendAxCmd request,
int value,
UInt16 index)
{
Debug.Assert(value < 0x100000);
this.direction = (byte)direction;
this.requestType = (byte)requestType;
this.recepient = (byte)recepient;
this.request = (byte)request;
this.value = (UInt16)value;
this.index = index;
this.requestTypeReservedBits = 0;
}
};
public struct Usb_Device_Descriptor // Taken from usb100.h
{
public byte bLength;
public byte bDescriptorType;
public ushort bcdUSB;
public byte bDeviceClass;
public byte bDeviceSubClass;
public byte bDeviceProtocol;
public byte bMaxPacketSize0;
public ushort idVendor;
public ushort idProduct;
public ushort bcdDevice;
public byte iManufacturer;
public byte iProduct;
public byte iSerialNumber;
public byte bNumConfigurations;
};
} // EzUsbSys
#endregion
public const int EepromSizeBytes = 0x8000; // The size of a 32 kB EEPROM.
public const int UsbMaxPacketSize = 0x1000;
static Microsoft.Win32.SafeHandles.SafeFileHandle hDevice;
string iicFilename;
EzUsbSys.Usb_Device_Descriptor deviceDescriptor = new EzUsbSys.Usb_Device_Descriptor();
bool deviceOnline = false;
bool vendAxLoaded = false;
public MainForm()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
try
{
timer1.Stop();
// This should be modififed to dynamically update a list of devices.
if (txtDeviceName.Text.Length==0)
{
string[] list = GetUnopenedDevices();
cmboDeviceList.Items.Clear();
cmboDeviceList.Items.AddRange(list);
txtQtyDevices.Text = string.Format("{0} device{1} available", list.Length, list.Length != 1 ? "s" : "");
if (list.Length == 1)
{
cmboDeviceList.SelectedIndex = 0;
}
}
ping();
}
finally
{
timer1.Start();
}
}
private void ping()
{
bool deviceOnlineNow = false;
byte [] eeFirst8Bytes = null;
try
{
Open();
GetDeviceDescriptorDevIoCtl(ref deviceDescriptor);
deviceOnlineNow = true;
if (vendAxLoaded)
{
eeFirst8Bytes = EepromRead(8);
}
hDevice.Close();
if (!vendAxLoaded)
{
downloadVendAx(); // FirmwareDownloadDevIoCtl(VendAxCode);
}
}
catch
{
deviceOnlineNow = false;
}
// change in status.
if (deviceOnline != deviceOnlineNow)
{
deviceOnline = deviceOnlineNow;
txtIdVendor.Text = !deviceOnline ? "" :
deviceDescriptor.idVendor.ToString("X04") + ( deviceDescriptor.idVendor==0x04B4 ?
" (Cypress default)" : deviceDescriptor.idVendor==0x08b1 ? " (DCT)" : "" )
;
txtDeviceName.Text = deviceOnline ? cmboDeviceList.Text : "";
txtProductId.Text = deviceOnline ? deviceDescriptor.idProduct.ToString("X04") : "";
txtDeviceId.Text = deviceOnline ? deviceDescriptor.bcdDevice.ToString("X04") : "";
ProgressDone(deviceOnline ? "Connected" : "Disconnected");
}
if (!deviceOnline)
{
vendAxLoaded = false;
}
txtVendAxLoaded.Text = vendAxLoaded ? "Yes" : "No";
if (deviceOnline && vendAxLoaded && eeFirst8Bytes != null)
{
txtEeFirst8Bytes.Text = BitConverter.ToString(eeFirst8Bytes).Replace("-", " "); ;
}
else
{
txtEeFirst8Bytes.Text = "";
}
btnDeviceToIicFile.Enabled = deviceOnline;
btnEraseEeAfter8.Enabled = deviceOnline;
IicDownload.Enabled = deviceOnline;
btnVerifyIicFile.Enabled = deviceOnline;
btnEraseEeprom.Enabled = deviceOnline;
cmboDeviceToIicFileSize.Enabled = deviceOnline;
cmboDeviceList.Visible = cmboDeviceList.Items.Count > 1;
}
void GetDeviceDescriptorDevIoCtl(ref EzUsbSys.Usb_Device_Descriptor arg)
{
Debug.Assert(hDevice != null);
int pBytesReturned = 0;
bool bOk;
bOk = DeviceIoControl(
hDevice,
(uint)EzUsbSys.IOCTL_Ezusb_GET_DEVICE_DESCRIPTOR,
ref arg,
Marshal.SizeOf(arg),
ref arg,
Marshal.SizeOf(arg),
ref pBytesReturned,
IntPtr.Zero);
if (!bOk || pBytesReturned != Marshal.SizeOf(arg)) { throw new Exception(); }
}
// taken from CEzMrView::Ezusb_DownloadIntelHex in EzMrView
void downloadVendAx()
{
try
{
// EzMr had some sleeps that apparently are not necessary.
// I'll parameterize the duration as a reminder that it might need to be revisited.
int sleepDuration = 0; // 400
ProgressInit(3, "Downloading FW");
Open();
SendOpReset();
hDevice.Close();
ProgressUpdate(1);
Thread.Sleep(sleepDuration); // Sleep durations may not be necessary.
Debug.Assert(VendAxCode.Length == 3476);
ProgressUpdate(2);
Open();
vendAxLoaded = VendAxCode.SequenceEqual(IntRamRead(0, VendAxCode.Length));
if (!vendAxLoaded)
{
FirmwareDownloadDevIoCtl(VendAxCode);
vendAxLoaded = VendAxCode.SequenceEqual(IntRamRead(0, VendAxCode.Length));
if (!vendAxLoaded) { throw new Exception("VendAx Verify Failed"); }
}
Thread.Sleep(sleepDuration);
SendOpRun();
hDevice.Close();
ProgressUpdate(3);
Thread.Sleep(sleepDuration);
ProgressDone( "FW downloaded and verified" );
}
catch ( Exception ex )
{
ProgressDone( "FW downloaded Failed" );
}
}
// Open a handle for the Cypress device.
// The result is stored in this->hDevice.
void Open()
{
hDevice = CreateFile(
cmboDeviceList.Text,
FILE_GENERIC_WRITE,
FILE_SHARE_WRITE,
IntPtr.Zero,
FILE_OPEN_EXISTING,
0,
IntPtr.Zero);
if (hDevice.IsInvalid ) throw( new Exception( "Open failed") );
}
byte[] EepromRead( int qty)
{
Debug.Assert(qty <= EepromSizeBytes);
if (qty <= UsbMaxPacketSize)
{
return EepromReadDevIoCtl(0, qty);
}
byte[] buffer = new byte[qty];
ProgressInit(buffer.Length, "Reading EEPROM");
for (int remaining = qty, offset=0; remaining>0; )
{
int len = Math.Min(remaining, UsbMaxPacketSize);
// Append smaller buffer onto larger buffer.
Array.Copy(EepromReadDevIoCtl(offset, len), 0, buffer, offset, len);
ProgressUpdate(offset);
offset += len;
remaining -= len;
} // for
ProgressDone("Done reading");
return buffer;
} // EepromRead
byte[] EepromReadDevIoCtl(int offset, int qty)
{
Debug.Assert(qty <= UsbMaxPacketSize);
Debug.Assert(offset <= EepromSizeBytes);
byte[] buffer = new byte[qty];
EzUsbSys.VENDOR_OR_CLASS_REQUEST_CONTROL myRequest = new EzUsbSys.VENDOR_OR_CLASS_REQUEST_CONTROL(
EzUsbSys.Direction.DeviceToHost,
EzUsbSys.RequestType.Vendor,
EzUsbSys.Recipient.Device,
EzUsbSys.VendAxCmd.RwEepromBig,
offset,
0 );
Debug.Assert(hDevice != null);
int pBytesReturned = 0;
bool bOk = DeviceIoControl(
hDevice,
(uint)EzUsbSys.IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST,
ref myRequest,
Marshal.SizeOf(myRequest),
buffer,
buffer.Length,
ref pBytesReturned,
IntPtr.Zero);
if (!bOk) { throw new Exception("DeviceIoControl failed"); }
if (!(pBytesReturned == qty)) { throw new Exception("DeviceIoControl failed"); }
return buffer;
} // EepromReadDevIoCtl
void EepromWrite( byte[] buffer)
{
EepromWriteDevIoCtl(0, buffer);
}
void EepromWriteDevIoCtl(int offset, byte[] buffer )
{
Debug.Assert(offset <= EepromSizeBytes );
Debug.Assert(buffer.Length <= UsbMaxPacketSize);
EzUsbSys.VENDOR_OR_CLASS_REQUEST_CONTROL myRequest = new EzUsbSys.VENDOR_OR_CLASS_REQUEST_CONTROL(
EzUsbSys.Direction.HostToDevice,
EzUsbSys.RequestType.Vendor,
EzUsbSys.Recipient.Device,
EzUsbSys.VendAxCmd.RwEepromBig,
offset,
0);
Debug.Assert(hDevice != null);
int pBytesReturned = 0;
bool bOk = DeviceIoControl(
hDevice,
(uint)EzUsbSys.IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST,
ref myRequest,
Marshal.SizeOf(myRequest),
buffer,
buffer.Length,
ref pBytesReturned,
IntPtr.Zero);
if (!bOk) { throw new Exception("DeviceIoControl failed"); }
if (!(pBytesReturned == buffer.Length)) { throw new Exception("DeviceIoControl failed"); }
if (!buffer.SequenceEqual(EepromReadDevIoCtl(offset, buffer.Length))) { throw new Exception("Verify failed"); }
}
// Write a single byte to ram location specified.
// To download firmware, see FirmwareDownloadDevIoCtl
// Typical usage:
// IntRamWrite(0xE600, 1); // write a 1 to address 0xE600 to enter reset.
// IntRamWrite(0xE600, 0); // write a 1 to address 0xE600 to enter reset.
void IntRamWriteByteDevIoCtl(UInt16 offset, byte data)
{
EzUsbSys.VENDOR_REQUEST_IN myRequest = new EzUsbSys.VENDOR_REQUEST_IN(
EzUsbSys.VendAxCmd.ANCHOR_LOAD_INTERNAL,
offset,
0x00,
0x01, // length of data.
EzUsbSys.Direction.HostToDevice,
data);
Debug.Assert(hDevice != null);
int pBytesReturned = 0;
bool bOk = DeviceIoControl(
hDevice,
(uint)EzUsbSys.IOCTL_Ezusb_VENDOR_REQUEST,
ref myRequest,
Marshal.SizeOf(myRequest),
IntPtr.Zero,
0,
ref pBytesReturned,
IntPtr.Zero);
if (!bOk) { throw new Exception("DeviceIoControl failed"); }
if (!(pBytesReturned == 0)) { throw new Exception("DeviceIoControl failed"); }
} // IntRamWriteByteDevIoCtl
// Read internal memory. Used to determine if Vend_Ax is downloaded.
byte[] IntRamRead(int offset, int qty)
{
byte data=0;
EzUsbSys.VENDOR_REQUEST_IN myRequest = new EzUsbSys.VENDOR_REQUEST_IN(
EzUsbSys.VendAxCmd.ANCHOR_LOAD_INTERNAL,
offset,
0x00,
qty, // length of data.
EzUsbSys.Direction.DeviceToHost,
data);
Debug.Assert(hDevice != null);
byte[] buffer = new byte[qty];
int pBytesReturned = 0;
bool bOk = DeviceIoControl(
hDevice,
(uint)EzUsbSys.IOCTL_Ezusb_VENDOR_REQUEST,
ref myRequest,
Marshal.SizeOf(myRequest),
buffer,
buffer.Length,
ref pBytesReturned,
IntPtr.Zero);
if (!bOk) { throw new Exception("DeviceIoControl failed"); }
Debug.Assert(pBytesReturned == qty);
return buffer;
}
// Hold CPU in reset.
void SendOpReset()
{
IntRamWriteByteDevIoCtl(0xE600, 1); // write a 1 to address 0xE600 to enter reset.
return;
}
// Let CPU run.
void SendOpRun()
{
IntRamWriteByteDevIoCtl(0xE600, 0); // write a 1 to address 0xE600 to enter reset.
return;
}
// Download firmware.
// See downloadVendAx for usage.
// Typical usage:
// SendOpReset();
// FirmwareDownload(VendAxCode);
// SendOpRun();
void FirmwareDownloadDevIoCtl( byte [] buffer )
{
Debug.Assert(buffer.Length < 7 * 1024); // The driver spec says the size must be less than 7 kB.
EzUsbSys.ANCHOR_DOWNLOAD_CONTROL myRequest = new EzUsbSys.ANCHOR_DOWNLOAD_CONTROL(0);
Debug.Assert(hDevice != null);
int pBytesReturned = 0;
bool bOk;
bOk = DeviceIoControl(
hDevice,
(uint)EzUsbSys.IOCTL_EZUSB_ANCHOR_DOWNLOAD,
ref myRequest,
Marshal.SizeOf(myRequest),
buffer,
buffer.Length,
ref pBytesReturned,
IntPtr.Zero);
if (!bOk) { throw new Exception("DeviceIoControl failed"); }
Debug.Assert(pBytesReturned == 0);
}
// Find all un-opened devices.
// Check the ezusb driver, and the TsUsb.sys driver, for a list of available devices.
// Typically, there would be a qty of 0 or 1. Rarely, there would be more.
// It's assumed that there would be few devices.
static string[] GetUnopenedDevices()
{
string [] driverList = new string[]{ "Tsusb2", "ezusb" };
List<string> deviceList = new List<string>();
foreach (string driverName in driverList)
{
// I didn't test this fully with the ezusb driver.
// The Tsusb driver used 'funny' characters and didn't seem to work with character '\'.
// I might be able to use characters > '\' but didn't think this would be very common.
for (char c = '0'; c < '\\'; c++)
{
string deviceName = @"\\.\" + driverName + "-" + c;
Microsoft.Win32.SafeHandles.SafeFileHandle hOut = CreateFile(
deviceName,
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
0,
IntPtr.Zero,
FILE_OPEN_EXISTING,
0,
IntPtr.Zero);
if (hOut.IsInvalid)
{
hOut.Close();
continue;
}
else
{
deviceList.Add(deviceName);
hOut.Close();
// if using SafeFileHandle, don't call CloseHandle(hOut);
// Why? hOut was getting closed 'safely' yet again which resulted in odd behavior.
}
} // for each device letter
} // for each device driver
return deviceList.ToArray();
}
// Download a .IIC file.
// Prompt for the file to download.
private void IicDownload_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.FileName = iicFilename;
dlg.Title = "Select .IIC file to load into EEPROM";
dlg.CheckFileExists = true;
dlg.Filter = "IIC files (*.iic)|*.iic|All files (*.*)|*.*";
DialogResult result = dlg.ShowDialog();
if (result != DialogResult.OK)
{
return;
}
iicFilename = dlg.FileName;
byte [] buffer = System.IO.File.ReadAllBytes(iicFilename);
const int packetSize = 0x100;
ProgressInit( buffer.Length, "Writing EEPROM");
Open();
for ( int offset=0, remaining=buffer.Length; remaining>0; )
{
int length = Math.Min( packetSize, remaining );
byte [] x = new byte[length];
ProgressUpdate(buffer.Length - remaining);
// extract smaller buffer from large buffer
Array.Copy( buffer, offset, x, 0, length );
EepromWriteDevIoCtl( offset, x );
remaining -= length;
offset += length;
}
Debug.Assert(buffer.SequenceEqual(EepromRead( buffer.Length)));
hDevice.Close();
ProgressDone( string.Format( "{0} bytes downloaded and verified", buffer.Length ));
}
catch (Exception ex)
{
ProgressDone( string.Format( "Download Error" ));
}
}
private void btnEraseEeprom_Click(object sender, EventArgs e)
{
EraseEe( false );
}
private void btnDeviceToIicFile_Click(object sender, EventArgs e)
{
int size = 0;
try
{
string s = cmboDeviceToIicFileSize.Text;
s = s.Split(' ')[0];
size = ( s.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) ?
Int32.Parse(s.Substring(2), System.Globalization.NumberStyles.HexNumber):
Int32.Parse(s);
size = Math.Min(size, EepromSizeBytes);
}
catch
{
MessageBox.Show("Invalid file size");
return; // TODO:
}
SaveFileDialog dlg = new SaveFileDialog();
dlg.Title = "Select .IIC file to write from EEPROM";
dlg.RestoreDirectory = true;
dlg.FileName = iicFilename;
dlg.Filter = "IIC files (*.iic)|*.iic|All files (*.*)|*.*";
DialogResult result = dlg.ShowDialog();
if (result != DialogResult.OK)
{
return;
}
iicFilename = dlg.FileName;
byte [] buffer = new byte[size];
Open();
ProgressInit(size, "Reading EEPROM");
for ( int offset = 0; offset < size; offset += Math.Min( size, UsbMaxPacketSize))
{
ProgressUpdate(offset);
byte[] x = EepromReadDevIoCtl(offset, Math.Min(size, UsbMaxPacketSize));
x.CopyTo(buffer, offset);
}
hDevice.Close();
ProgressDone( string.Format( "{0} bytes saved", size ) );
System.IO.File.WriteAllBytes(iicFilename, buffer);
}
private void EraseEe( bool keepFirst8Bytes )
{
try
{
const int eraseSize = 0x100;
const int eraseSizeTotal = EepromSizeBytes;
byte[] buffer = new byte[eraseSize];
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] = 0xFF;
}
Open();
ProgressInit(eraseSizeTotal, "Erasing EEPROM");
for (int offset = 0; offset < eraseSizeTotal; offset += eraseSize)
{
ProgressUpdate(offset);
EepromWriteDevIoCtl(offset == 0 && keepFirst8Bytes ? 8 : offset, buffer);
}
hDevice.Close();
ProgressDone("EEPROM erased");
}
catch (Exception ex)
{
ProgressDone("EEPROM erase failed");
}
}
private void btnEraseEeAfter8_Click(object sender, EventArgs e)
{
EraseEe( true );
}
private void ProgressInit(int maxArg, string txtArg)
{
// Initialize the progress bar on the statusbar for operations that might take a long time.
toolStripStatusLabel1.Text = txtArg;
toolStripStatusLabel1.Visible = true;
toolStripProgressBar1.Maximum = maxArg; //
toolStripProgressBar1.Visible = true;
}
private void ProgressUpdate(int offsetArg )
{
toolStripProgressBar1.Value = offsetArg;
statusStrip1.Update();
}
private void ProgressDone( string txt )
{
toolStripProgressBar1.Visible = false;
toolStripStatusLabel1.Text = txt;
}
private void cmboDeviceList_SelectedIndexChanged(object sender, EventArgs e)
{
// If there a multiple devices found, and the selection changes, disconnect the current device.
deviceOnline = false;
}
private void btnVerifyIicFile_Click(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.FileName = iicFilename;
dlg.Title = "Select .IIC file to compare with EEPROM";
dlg.CheckFileExists = true;
dlg.Filter = "IIC files (*.iic)|*.iic|All files (*.*)|*.*";
DialogResult result = dlg.ShowDialog();
if (result != DialogResult.OK)
{
return;
}
iicFilename = dlg.FileName;
byte[] buffer = System.IO.File.ReadAllBytes(iicFilename);
try
{
Open();
if (!buffer.SequenceEqual(EepromRead(buffer.Length)))
{
throw new Exception();
}
hDevice.Close();
ProgressDone("Verify OK");
}
catch
{
ProgressDone("Verify failed");
}
}
private void MainForm_Load(object sender, EventArgs e)
{
//testIntelHexToByteArray();
timer1.Start();
cmboDeviceToIicFileSize.SelectedIndex = 0;
} // btnVerifyIicFile_Click
/*
// Test/development code used to generate data to initialize the VendAxCode array.
// It has one-time usage during development and isn't expected to be used unless the Vend_AX firmware should change.
// This leaves a trail to re-create the data and is commented-out to reduce program size.
void testIntelHexToByteArray()
{
// See http://en.wikipedia.org/wiki/.hex for .HEX record structure.
// I'm assuming that the .hex file is simple, loads internal memory only.
string[] hex = System.IO.File.ReadAllLines("vend_ax.hex");
int maxAddress=0;
// find max memory used.
foreach (string record in hex )
{
Debug.Assert(record[0] == ':');
byte recordType = byte.Parse(record.Substring(7, 2), System.Globalization.NumberStyles.HexNumber);
if (recordType == 1)
{
break;
}
UInt16 recByteCount = UInt16.Parse(record.Substring(1, 2), System.Globalization.NumberStyles.HexNumber);
UInt16 recAddress = UInt16.Parse(record.Substring(3, 4), System.Globalization.NumberStyles.HexNumber);
Debug.Assert(recAddress < 0x2000); // If this fails, re-visit assumptions.
byte checkSum = byte.Parse(record.Substring(9 + recByteCount * 2, 2), System.Globalization.NumberStyles.HexNumber);
Debug.Assert(record.Length == 11 + recByteCount * 2);
maxAddress = Math.Max( maxAddress, recAddress+recByteCount );
}
byte[] bin = new byte[maxAddress+1]; // allocate buffer to reconstitute .hex file into. +1 should result in an extra AA at the end.
for ( int i=0; i<bin.Length; i++ ) { bin[i]=0xAA; } // Initialize buffer with 0xAA, just because the original Vend_Ax array did this.
// For each record read from the .hex file,
foreach (string record in hex)
{
Debug.Assert(record[0] == ':');
byte recordType = byte.Parse(record.Substring(7, 2), System.Globalization.NumberStyles.HexNumber);
if (recordType == 1)
{
break;
}
UInt16 recByteCount = UInt16.Parse(record.Substring(1, 2), System.Globalization.NumberStyles.HexNumber);
UInt16 recAddress = UInt16.Parse(record.Substring(3, 4), System.Globalization.NumberStyles.HexNumber);
byte checkSum = byte.Parse(record.Substring(9 + recByteCount * 2, 2), System.Globalization.NumberStyles.HexNumber);
// TODO: validate checksum.
// In my tests, the firmware ran.
Debug.Assert(record.Length == 11 + recByteCount * 2); // make sure the length is ok.
// For each byte, represented as a 2-character hex number, store the byte in the binary buffer.
for (int i = 0; i < recByteCount; i++)
{
byte b = byte.Parse(record.Substring(9 + i * 2, 2), System.Globalization.NumberStyles.HexNumber);
bin[recAddress + i] = b;
}
} // foreach record in hex.
// write to file
// Create records of the form: 0x02, 0x07, 0xF3, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
// This resulting text will be used to initialize an array.
System.IO.StreamWriter file = new System.IO.StreamWriter("vend_ax.txt");
for (int i = 0; i < bin.Length; i++)
{
string s = string.Format( "0x{0:X02}, {1}", bin[i], i%10==9 ? "
" : "" );
file.Write(s);
}
file.Close();
return;
}
*/
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
// Add a convenience link to the app to start the device manager in the control panel.
System.Diagnostics.Process.Start("devmgmt.msc");
}
private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
// Add a convenience link to open the current working directoy.
System.Diagnostics.Process.Start(System.IO.Directory.GetCurrentDirectory());
}
} // MainForm.
} // namespace CypressEepromUtility
// End of file
Cypress FX2 EEPROM utility implemented in C#.net with interop calls to deviceIoControl for access to the USB driver. This utility reads, writes, verifies and erases the EEPROM. It embeds the vend_ax.hex firmware in a byte array and automatically downloads the firmware if it isn't detected in internal RAM. Some of the code was borrowed from the EzUsb or CyConsole utility. Some code was taken from the EzUsbSys.h file and re-defined for use in c#.
eiger824/Test-Type Exam Correction With Java ( Java)
package com.santi;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
static char [] calif;
static char [] answers = {'a','b','b','c','a','a','d','d','c','b'}; //example1 of right answers
static char [] answers2 = {'b','b','c','a','a','b','d','b','a','c'};//example2 of right answers
int result;
static int cont;
static String cal=null;
public static void main(String[] args) {
int option;
String opt=getInput("Which test model are you correcting? 1-A; 2-B: ");
option=Integer.parseInt(opt);
switch(option){
case 1: cont=0;
cal = checkForTypedLength(cal);
calif=cal.toCharArray();
cont = updateCounters(cont, cal);
System.out.println("Result: "+cont+"/10");
break;
case 2:
cont=0;
cal = checkForTypedLength(cal);
calif=cal.toCharArray();
cont = updateCounters2(cont, cal);
System.out.println("Result: "+cont+"/10");
break;
}
}
public static int updateCounters(int cont, String cal) {
for(int i=0;i<cal.length();i++){
if(calif[i]==answers[i]){
cont++;
}
else if(calif[i]=='0'){
}
else if(calif[i]!=answers[i]){
cont--;
}
}
return cont;
}
public static int updateCounters2(int cont, String cal) {
for(int i=0;i<cal.length();i++){
if(calif[i]==answers2[i]){
cont++;
}
else if(calif[i]=='0'){
}
else if(calif[i]!=answers2[i]){
cont--;
}
}
return cont;
}
public static String checkForTypedLength(String cal) {
boolean go=true;
while(go==true){
cal=getInput("Enter answers (i.e.: acbbaabcddc; 0 if unanswered): ");
if(cal.length()!=10){
System.out.println("There are only 10 questions in the test!" +
" Please enter them correctly.");
}
else{
go=false;
}
}
return cal;
}
private static String getInput(String prompt) {
BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in));
System.out.print(prompt);
System.out.flush();
try {
return stdin.readLine();
} catch (Exception e) {
return "Error: " + e.getMessage();
}
}
}
A simple way of correcting tests with Java. In this piece of code I just defined two possible models or answers, they're all random, but the only thing needed is to update them with valid answers. The length of the test? I just did it for a 10-question test, but it can naturally be extended to the number of answers the teacher may want.
Duncan McGreggor/Authenticating Twisted with Zope/Plone ( python)
import xmlrpclib
from zope.interface import implements
from twisted.internet import defer
from twisted.cred import checkers
from twisted.cred import credentials
class ZopeChecker(object):
'''
A Zope cred checker for twisted applications.
'''
implements(checkers.ICredentialsChecker)
credentialInterfaces = (credentials.IUsernamePassword,)
def __init__(self, host, port=8080, scheme="https", path="/"):
self.scheme = scheme
self.host = host
self.port = port
self.path = path
def requestAvatarId(self, c):
'''
Please, please for the love of all that is holy to you,
make sure that your scheme is 'https'
'''
url = '%s://%s:%s@%s:%s%s' % (self.scheme, c.username, c.password,
self.host, self.port, self.path)
server = xmlrpclib.ServerProxy(url)
info = server.getXMLRPCUserInfo()
if info.get('authenticated'):
return defer.succeed(c.username)
else:
return defer.fail(error.UnauthorizedLogin())
I was writing a custom Twisted XML-RPC server for radio station DJs to use, but one station was managing all of its internal web app users and groups through Zope. Twisted has an amazingly pluggable authentication framework, so the requirement was satisfied with the following.
Note that in this simple example, every time a user executes an XML-RPC method, they are authenticating against Zope. This involves an xmlrpclib.ServerProxy instantiation as well as the overhead of making a network connection to Zope. For this reason, as well as in the event of Zope being down, one might want to implement some form of caching (without passwords), so that application functionality is not impacted by Zope downtime and overhead from authentication is only incurred when necessary.
radix makes a very good point in the comments: the use of xmlrpclib in this recipe is blocking. This means that if you have 10, 20, whatever number of people using the app, and someone new logs in, the twisted reactor can't do it's usual thing and cycle through requests until that user finishes logging in. I will post an update that makes use of the non-blocking t.w.xmlrpc code. The solution will be messier, though, as t.w.xmlrpc is broken in that it doesn't handle scheme://username:pass@host:port URLs. This is due to the fact that t.w.xmlrpc.QueryProtocol doesn't set an Authentication header... and there's no mechanism in t.w.xmlrpc.Proxy and QueryFactory for parsing and setting user and password into from the URL.
Update: see the comments below for how to work around this limitation.
Mayuresh Phadke/Ping Technocrati with your blog URL ( python)
#!/usr/bin/python
#
# Written by Mayuresh at gmail dot com
#
# This program posts a blog URL to the Technorati ping server
import xmlrpclib
import socket
import sys
from optparse import OptionParser
TECHNORATI_RPC_PING_SERVER = 'http://rpc.technorati.com/rpc/ping'
usage = """ %prog Blog_name Blog_URL
Example: %prog YourBlogName http://www.YOURWEBLOGURL.com/
"""
parser = OptionParser(usage=usage)
(options, args) = parser.parse_args()
if len(args) != 2:
parser.error("Invalid options")
print "Submitting the following blog info to %s" % TECHNORATI_RPC_PING_SERVER
print
print "Blog name: %s" % args[0]
print "Blog URL: %s" % args[1]
print
print "Waiting for server response ..."
print
reply = {}
try:
s = xmlrpclib.Server(TECHNORATI_RPC_PING_SERVER)
reply = s.weblogUpdates.ping(args[0], args[1])
except socket.error, msg:
reply['flerror'] = True
errCode, reply['message'] = msg
except xmlrpclib.ProtocolError, inst:
reply['flerror'] = True
reply['message'] = "Error [%s: %s] occured while accesing url %s" %(inst.errcode, inst.errmsg, inst.url)
except xmlrpclib.Fault, inst:
reply['flerror'] = True
reply['message'] = inst.faultString
except:
reply['flerror'] = True
reply['message'] = "Unknown error occured"
if reply['flerror']:
print "The server returned an error"
else:
print "The server returned success"
print
print "Message from the server: %s" % reply['message']
if reply['flerror']:
sys.exit(1)
else:
sys.exit()
Technocrati (http://www.technorati.com/) maintains a list of blogs tagged with user specified tags. People can submit their blogs for inclusion in Technocrati by using their RPC ping service at http://www.technorati.com/ping. This piece of code allows you ping Technocrati with blog details through a script.
Danny Yoo/How to take the "cross product" of two infinite sequences ( python)
# This piece of code is more mathy than normal; it shows that there's a
# correspondance between the positive integers and the positive fractions.
# For example:
###
# >>> two2one(0,0)
# 0
# >>> two2one(1,0)
# 1
# >>> two2one(3,4)
# 32
# >>> one2two(31)
# (4, 3)
# >>> one2two(32)
# (3, 4)
###
# and it's related to the math proof that the rationals are countable.
# It can also be used to take the "cross-product" of two infinite sequences,
# so it's not quite "useless", but it is weird. *grin* Hope you like it.
###
def two2one(x, y):
"""Maps a positive (x,y) to an element in the naturals."""
diag = x + y
bottom = diag * (diag + 1) / 2
return bottom + y
def one2two(k):
"""Inverts the two2one map --- given a natural number, return its
corresponding (x,y) pair."""
diag = int((sqrt(1 + 8*k) - 1) / 2)
offset = k - diag * (diag + 1) / 2
return (diag - offset, offset)
class xcross_inf:
def __init__(self, X, Y):
self.X, self.Y = X, Y
def __getitem__(self, key):
i, j = one2two(key)
return (self.X[i], self.Y[j])
class Evens:
def __getitem__(self, key):
return key * 2
class Odds:
def __getitem__(self, key):
return key * 2 + 1
def test2():
seq = xcross_inf(Evens(), Odds())
for i in range(20): print seq[i]
###
This piece of code takes in two infinite sequences, and, with the help of a cute math function, can cross these two together into another infinite sequence. (This is related to the diagonalization proof that the rationals are countable.) It should guarantee that, given enough time, we can reach any particular element.