Difficulty with rapidjson .11 GetInt(), always returns 0 - rapidjson

Here is the json form:
{"simpleChannels":{"item":[{"channelID":4248,"majorChannelNumber":22,"minorChannelNumber":0,"channelType":"SLL","simpleSchedules":[],"channelKey":"4248_1343210400000","shortName":"KWHY","longName":"A3 Los Angeles 22 KWHY IND","networkAffiliation":["Independent"],"logoID":0,"authCode":"FS","engChlFlag":false,"hasMirror":true,"pgSource":"ACTIVE","hdChlFlag":true,"adultChlFlag":false,"vodProviderId":0,"blackOut":false,"liveStreaming":"N"}]}}
Here is the code that attempts to parse and extract values:
json is a std::string containing the above:
m_guideSlice.Parse<0>(json.c_str());
rapidjson::Value& simpleChannels = m_guideSlice["simpleChannels"];
if (simpleChannels.IsObject()) {
SYSLOG_CRITICAL("simpleChannels.IsObject() == true\n");
rapidjson::Value& channelArray= simpleChannels["item"];
if (channelArray.IsArray()) {
SYSLOG_CRITICAL("channelArray.IsArray() == true\n");
rapidjson::Value& channel = channelArray[0u];
if (channel.IsObject()) {
SYSLOG_CRITICAL("channel.isObject() == true\n");
rapidjson::Value& channelID = channel["channelID"];
if (channelID.IsInt()) {
SYSLOG_CRITICAL("channelID.IsInt() == true, channelID= %d\n", channelID.GetInt());
}
else {
SYSLOG_CRITICAL("channelID.IsInt() == false, type= %X\n", channelID.GetType());
}
rapidjson::Value& majorChannelNumber = channel["majorChannelNumber"];
if (majorChannelNumber.IsInt()) {
SYSLOG_CRITICAL("majorChannelNumber.IsInt() == true, majorChannelNumber= %d\n", majorChannelNumber.GetInt());
}
else {
SYSLOG_CRITICAL("majorChannelNumber.IsInt() == false, type= %X\n", majorChannelNumber.GetType());
}
rapidjson::Value& channelType = channel["channelType"];
if (channelType.IsString()) {
SYSLOG_CRITICAL("channelType.IsString() == true\n")
SYSLOG_CRITICAL("channelType = %s\n", channelType.GetString());
}
else {
SYSLOG_CRITICAL("channelType.IsString() == false, type= %X\n", channelType.GetType());
}
rapidjson::Value& shortName = channel["shortName"];
if (channelType.IsString()) {
SYSLOG_CRITICAL("shortName.IsString() == true\n")
SYSLOG_CRITICAL("shortName = %s\n", shortName.GetString());
}
else {
SYSLOG_CRITICAL("shortName.IsString() == false, type= %X\n", shortName.GetType());
}
}
else {
SYSLOG_CRITICAL("channel.IsObject() == false, type= %X\n", channel.GetType());
}
}
else {
SYSLOG_CRITICAL("channelArray.IsArray() == false, type= %X\n", channelArray.GetType());
}
}
else {
SYSLOG_CRITICAL("simpleChannels.IsObject() == false, type= %X\n", simpleChannels.GetType());
}
Here is the extracted output from syslog:
May 19 01:25:38 [BSP] [30578]: [PGWS-GEN LOG_CRIT tid:30744 pthr:0x7033e4f0]: (PgwsIngest.cpp:78) getGuide(): simpleChannels.IsObject() == true
May 19 01:25:38 [BSP] [30578]: [PGWS-GEN LOG_CRIT tid:30744 pthr:0x7033e4f0]: (PgwsIngest.cpp:81) getGuide(): channelArray.IsArray() == true
May 19 01:25:38 [BSP] [30578]: [PGWS-GEN LOG_CRIT tid:30744 pthr:0x7033e4f0]: (PgwsIngest.cpp:84) getGuide(): channel.isObject() == true
May 19 01:25:38 [BSP] [30578]: [PGWS-GEN LOG_CRIT tid:30744 pthr:0x7033e4f0]: (PgwsIngest.cpp:87) getGuide(): channelID.IsInt() == true, channelID= 0
May 19 01:25:38 [BSP] [30578]: [PGWS-GEN LOG_CRIT tid:30744 pthr:0x7033e4f0]: (PgwsIngest.cpp:94) getGuide(): majorChannelNumber.IsInt() == true, majorChannelNumber= 0
May 19 01:25:38 [BSP] [30578]: [PGWS-GEN LOG_CRIT tid:30744 pthr:0x7033e4f0]: (PgwsIngest.cpp:101) getGuide(): channelType.IsString() == true
May 19 01:25:38 [BSP] [30578]: [PGWS-GEN LOG_CRIT tid:30744 pthr:0x7033e4f0]: (PgwsIngest.cpp:102) getGuide(): channelType = SLL
May 19 01:25:38 [BSP] [30578]: [PGWS-GEN LOG_CRIT tid:30744 pthr:0x7033e4f0]: (PgwsIngest.cpp:109) getGuide(): shortName.IsString() == true
May 19 01:25:38 [BSP] [30578]: [PGWS-GEN LOG_CRIT tid:30744 pthr:0x7033e4f0]: (PgwsIngest.cpp:110) getGuide(): shortName = KWHY
The char json values are extracted correctly but the int ones are always 0. I'm a first time rapidjson user so I'm sure there is a simple error I am making but I don't see it right off.
Thanks all,
Btw, the json form passes on http://www.freeformatter.com/json-validator.html so I think it is correct. It is machine generated anyway.

I am on a big endian machine and the compiler must not be passing the appropriate flag to indicate endianness.
Explicitly setting the flag:
define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
in rapidsjon.h should fix this.

We have improved the endian detection in this pull request.
It will detect more platform defined macros. If it cannot detect successfully, it generates a preprocessor error and then you must define RAPIDJSON_ENDIAN.
You may merge this diff to your version to see if it helps.

Related

How can this code to compare version information be improved?

I have a problem with my logic to compare version information.
Take this method:
bool CPTSDatabase::IsInstalledPublicTalksVersionSupported()
{
CSettingsStore store(TRUE, TRUE);
CString strPath, strVersion;
VS_FIXEDFILEINFO* pVerInfo = nullptr;
bool bOK = false;
if (store.Open(_T("Software\\Community Talks\\Public Talks")))
{
if (store.Read(_T("AppPath"), strPath))
{
//yes, but is the path still valid
if (PathFileExists(strPath))
{
pVerInfo = theApp.ExtractVersionInformation(strPath, strVersion);
if (pVerInfo != nullptr)
{
if (HIWORD(pVerInfo->dwFileVersionMS) >= 20 &&
LOWORD(pVerInfo->dwFileVersionMS) >= 0 &&
HIWORD(pVerInfo->dwFileVersionLS) >= 3)
{
bOK = true;
}
}
}
}
}
return bOK;
}
The issue is this bit:
if (HIWORD(pVerInfo->dwFileVersionMS) >= 20 &&
LOWORD(pVerInfo->dwFileVersionMS) >= 0 &&
HIWORD(pVerInfo->dwFileVersionLS) >= 3)
{
bOK = true;
}
The executable in question is now 21.0.1 and ofcourse the pVerInfo->dwFileVersionLS test is failing. Is there a more robust wat to check that the version in question is greater than 20.0.3 without a lot of if clauses?
Just use a 64bit int.
auto Version = [](WORD a, WORD b, WORD c)
{
return int64_t(a)<<32 | int64_t(b)<<16 | int64_t(c);
};
if (Version(HIWORD(pVerInfo->dwFileVersionMS),LOWORD(pVerInfo->dwFileVersionMS),HIWORD(pVerInfo->dwFileVersionLS))>=Version(20,0,3))
{
bOK = true;
}

How to send input keys to a window with node.js's ffi

How could I send input to a window using node.js ffi?
My intention is to input text and keypresses to a window whether it's in the foreground or background (if it's possible).
You could try one of these functions.
I've collected these three key-simulation approaches for personal use, so it's kind of messy. But since your question hasn't gotten any answers yet, I figure it's better to give a messy response than none at all.
import robot from "robotjs";
import keycode from "keycode";
import ffi from "ffi";
import ref from "ref";
import StructType from "ref-struct";
//var ArrayType = require("ref-array");
var arch = require("os").arch();
declare var Buffer;
var user32 = new ffi.Library("user32", {
"GetForegroundWindow": ["int32", []],
"GetWindowTextA": ["int32", ["int32", "string", "int32"]],
//"GetWindowTextW": ["int32", ["int32", ref.refType("string"), "int32"]],
});
export function GetForegroundWindowHandle() {
return user32.GetForegroundWindow();
}
export function GetForegroundWindowText() {
var buffer = new Buffer(256);
buffer.type = ref.types.CString;
var handle = GetForegroundWindowHandle();
let length = user32.GetWindowTextA(handle, buffer, 256);
return buffer.toString().substr(0, length);
}
const WM_KEYDOWN = 0x0100; // key-down
const WM_KEYUP = 0x0101; // key-up
const WM_SYSKEYDOWN = 0x0104; // key-down (for alt-key)
const WM_SYSKEYUP = 0x0105; // key-up (for alt-key)
const extraKeys = {
leftShift: 160,
rightShift: 161,
leftControl: 162,
rightControl: 163,
leftAlt: 164,
rightAlt: 165
};
var intPtr = ref.refType("int");
var Input = StructType({
"type": "int",
"???": "int", // for some reason, the wScan value is only recognized as the wScan value when we add this filler slot
"wVK": "short",
"wScan": "short",
"dwFlags": "int",
"time": "int",
"dwExtraInfo": "int64"
//"dwExtraInfo": "int"
});
var InputPtr = ref.refType(Input);
var user32 = ffi.Library("user32", {
keybd_event: ["void", ["int32", "int32", "int32", "int32"]],
SendMessageA: ["int32", ["long", "int32", "long", "int32"]],
PostMessageA: ["int32", ["long", "int32", "long", "int32"]],
SendInput: ["int", ["int", Input, "int"]],
//SendInput: ["int", ["uint", ArrayType(keyboardInputPtr, 10), "int"]],
//MapVirtualKeyEx: ["uint", ["uint", "uint", intPtr]],
// external use
GetKeyState: ["short", ["int"]], // not really needed, since we track each key ourselves
});
// external use
// ==========
export function GetKeyState(keyCode: number) {
return user32.GetKeyState(keyCode);
}
// general
// ==========
enum keybd_event_flags {
KEYEVENTF_EXTENDEDKEY = 0x0001, // key-down flag (kind of)
KEYEVENTF_KEYUP = 0x0002, // key-up flag
}
export enum SendMessage_Flags {
WM_KEYDOWN = 0x0100,
WM_KEYUP = 0x0101,
WM_CHAR = 0x0102,
}
export function KeyToggle(keyCode: number, type = "down" as "down" | "up") {
/*if (keyCode == extraKeys.leftControl) user32.PostMessageA(GetForegroundWindowHandle(), messageType, keyCode, 0);
else if (keyCode == extraKeys.leftShift) user32.PostMessageA(GetForegroundWindowHandle(), messageType, keyCode, 0);
else*/
/*if (keyCode == extraKeys.leftControl) return void robot.keyToggle("control", type);
if (keyCode == extraKeys.leftShift) return void robot.keyToggle("shift", type);
if (keyCode == extraKeys.leftAlt) return void robot.keyToggle("alt", type);*/
/*if (keyCode == keycode.codes.ctrl || keyCode == extraKeys.leftShift || keyCode == extraKeys.leftAlt) {
user32.keybd_event(keyCode, 0, type == "down" ? 0 : keybd_event_flags.KEYEVENTF_KEYUP, 0);
return;
}*/
/*if (keyCode == extraKeys.leftControl) keyCode = keycode.codes.ctrl;
else if (keyCode == extraKeys.leftControl) keyCode = keycode.codes.shift;
else if (keyCode == extraKeys.leftAlt) keyCode = keycode.codes.alt;*/
let messageType = type == "down" ? SendMessage_Flags.WM_KEYDOWN : SendMessage_Flags.WM_KEYUP;
//if (keyCode == extraKeys.leftControl || keyCode == extraKeys.leftShift || keyCode == extraKeys.leftAlt) {
if (keyCode == extraKeys.leftAlt) {
messageType = type == "down" ? WM_SYSKEYDOWN : WM_SYSKEYUP;
}
user32.PostMessageA(GetForegroundWindowHandle(), messageType, keyCode, 0);
}
export function KeyTap(keyCode: number, includeCharEvent = false) {
/*IgnoreNextKeyPress(keyCode);
IgnoreNextKeyRelease(keyCode);
robot.keyTap(keyName);*/
KeyToggle(keyCode, "down");
/*if (includeCharEvent) {
user32.PostMessageA(GetForegroundWindowHandle(), SendMessage_Flags.WM_CHAR, keyCode, 0x00390001);
}*/
KeyToggle(keyCode, "up");
}
const INPUT_KEYBOARD = 1;
const KEYEVENTF_EXTENDEDKEY = 0x0001;
const KEYEVENTF_KEYUP = 0x0002;
const KEYEVENTF_UNICODE = 0x0004;
const KEYEVENTF_SCANCODE = 0x0008;
const MAPVK_VK_TO_VSC = 0;
export function ConvertKeyCodeToScanCode(keyCode: number) {
let keys = "**1234567890-=**qwertyuiop[]**asdfghjkl;'`*\\zxcvbnm,./".split("");
return keys.indexOf(String.fromCharCode(keyCode).toLowerCase());
}
//var EntryArray = ArrayType(keyboardInput)
export function KeyToggle2(keyCode: number, type = "down" as "down" | "up", asScanCode = false) {
let entry = new Input();
entry.type = INPUT_KEYBOARD;
entry.time = 0;
entry.dwExtraInfo = 0;
// (virtual) key-code approach (default)
if (!asScanCode) {
entry.dwFlags = type == "down" ? 0 : KEYEVENTF_KEYUP;
entry.wVK = keyCode;
//info.wScan = 0x0200;
entry.wScan = 0;
}
// scan-code approach
else {
//keyCode = 16 + (keyCode - keycode.codes.a);
//let scanCode = user32.MapVirtualKeyEx(keyCode, MAPVK_VK_TO_VSC);
let scanCode = ConvertKeyCodeToScanCode(keyCode);
entry.dwFlags = type == "down" ? KEYEVENTF_SCANCODE : KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
entry.wVK = 0;
entry.wScan = scanCode;
}
/*var array = new EntryArray(1) // by length
array[0] = entry;*/
//var r = user32.SendInput(1, entry.ref(), 28);
let result = user32.SendInput(1, entry, arch === "x64" ? 40 : 28);
console.log(result);
}
export function KeyTap2(keyCode: number, asScanCode = false) {
KeyToggle2(keyCode, "down", asScanCode);
KeyToggle2(keyCode, "up", asScanCode);
}
export function KeyToggle3(keyCode: number, type = "down" as "down" | "up") {
let messageType = type == "down" ? SendMessage_Flags.WM_KEYDOWN : SendMessage_Flags.WM_KEYUP;
//if (keyCode == extraKeys.leftControl || keyCode == extraKeys.leftShift || keyCode == extraKeys.leftAlt) {
if (keyCode == extraKeys.leftAlt) {
messageType = type == "down" ? WM_SYSKEYDOWN : WM_SYSKEYUP;
}
if (type == "down") {
IgnoreNextKeyPress(keyCode);
user32.keybd_event(keyCode, 0, 0, 0);
//user32.keybd_event(keyCode, 0, keybd_event_flags.KEYEVENTF_EXTENDEDKEY, 0);
user32.PostMessageA(GetForegroundWindowHandle(), SendMessage_Flags.WM_KEYDOWN, keyCode, 0);
} else {
IgnoreNextKeyRelease(keyCode);
user32.keybd_event(keyCode, 0, keybd_event_flags.KEYEVENTF_KEYUP, 0);
//user32.keybd_event(keyCode, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
user32.PostMessageA(GetForegroundWindowHandle(), SendMessage_Flags.WM_KEYUP, keyCode, 0);
}
}
export function KeyTap3(keyCode: number) {
KeyToggle3(keyCode, "down");
KeyToggle3(keyCode, "up");
}
Again, it's really messy, and I don't remember if all of them work. I know that at least KeyTap2 works (with asScanCode = true), because that's the one I'm currently using.
However, note that KeyTap2 does not let you target a background window -- only whatever window currently has focus. The other ones appear to let you target background windows, although I haven't tested it on background windows yet.
Note: A cleaner version of this answer (though only including the KeyTap2 approach) can be found here: https://stackoverflow.com/a/50412529/2441655

Check if a String is alphanumeric in Swift

In Swift, how can I check if a String is alphanumeric, ie, if it contains only one or more alphanumeric characters [a-zA-Z0-9], excluding letters with diacritics, eg, é.
extension String {
var isAlphanumeric: Bool {
return !isEmpty && range(of: "[^a-zA-Z0-9]", options: .regularExpression) == nil
}
}
"".isAlphanumeric // false
"abc".isAlphanumeric // true
"123".isAlphanumeric // true
"ABC123".isAlphanumeric // true
"iOS 9".isAlphanumeric // false
A modern Swift 3 and 4 solution
extension String {
func isAlphanumeric() -> Bool {
return self.rangeOfCharacter(from: CharacterSet.alphanumerics.inverted) == nil && self != ""
}
func isAlphanumeric(ignoreDiacritics: Bool = false) -> Bool {
if ignoreDiacritics {
return self.range(of: "[^a-zA-Z0-9]", options: .regularExpression) == nil && self != ""
}
else {
return self.isAlphanumeric()
}
}
}
Usage:
"".isAlphanumeric() == false
"Hello".isAlphanumeric() == true
"Hello 2".isAlphanumeric() == false
"Hello3".isAlphanumeric() == true
"Français".isAlphanumeric() == true
"Français".isAlphanumeric(ignoreDiacritics: true) == false
This works with languages other than English, allowing diacritic characters like è and á, etc. If you'd like to ignore these, use the flag "ignoreDiacritics: true".
I felt the accepted answer using regex was concrete but a rather heavy solution. You could check it this way also in Swift 3.0:
if yourString.rangeOfCharacter(from: CharacterSet.alphanumerics.inverted) != nil {
return "Username can only contain numbers or digits"
}
extension String {
/// Allows only `a-zA-Z0-9`
public var isAlphanumeric: Bool {
guard !isEmpty else {
return false
}
let allowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
let characterSet = CharacterSet(charactersIn: allowed)
guard rangeOfCharacter(from: characterSet.inverted) == nil else {
return false
}
return true
}
}
XCTAssertFalse("".isAlphanumeric)
XCTAssertFalse("climate change".isAlphanumeric)
XCTAssertFalse("Poüet".isAlphanumeric)
XCTAssertTrue("Hawking2018".isAlphanumeric)
The problem with the CharacterSet.alphanumerics CharacterSet is that it is more permissive than [a-zA-Z0-9]. It contains letters with diacritics, Eastern Arabic numerals, etc.
assert(["e", "E", "3"].allSatisfy({ CharacterSet.alphanumerics.contains($0) }))
assert(["ê", "É", "٣"].allSatisfy({ CharacterSet.alphanumerics.contains($0) }))
You can build your own CharacterSet using only the specific 62 "alphanumeric" characters:
extension CharacterSet {
static var alphanumeric62: CharacterSet {
return lowercase26.union(uppercase26).union(digits10)
}
static var lowercase26: CharacterSet { CharacterSet(charactersIn: "a"..."z") }
static var uppercase26: CharacterSet { CharacterSet(charactersIn: "A"..."Z") }
static var digits10: CharacterSet { CharacterSet(charactersIn: "0"..."9") }
}
assert(["e", "E", "3"].allSatisfy({ CharacterSet.alphanumeric62.contains($0) }))
assert(["ê", "É", "٣"].allSatisfy({ CharacterSet.alphanumeric62.contains($0) == false }))
Then test your string against the inverse of that CharacterSet:
guard "string".rangeOfCharacter(from: CharacterSet.alphanumeric62.inverted) == nil else {
fatalError()
}
This regex used to check that string contains atleast 1 alphabet + atleast 1 digit alongwith 8 characters.
"^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$"
extension String {
var isAlphaNumeric: Bool {
let hasLetters = rangeOfCharacter(from: .letters, options: .numeric, range: nil) != nil
let hasNumbers = rangeOfCharacter(from: .decimalDigits, options: .literal, range: nil) != nil
let comps = components(separatedBy: .alphanumerics)
return comps.joined(separator: "").count == 0 && hasLetters && hasNumbers
}
}
Here's a succinct approach:
extension String {
var isAlphanumeric: Bool {
allSatisfy { $0.isLetter || $0.isNumber }
}
}

A question in ip_append_data

I am confused with ip_append_data in linux network protocol stack when I see those codes:
if (!(rt->u.dst.dev->features&NETIF_F_SG)) {
unsigned int off;
off = skb->len;
if (getfrag(from, skb_put(skb, copy),
offset, copy, off, skb) < 0) {
__skb_trim(skb, off);
err = -EFAULT;
goto error;
}
} else {
int i = skb_shinfo(skb)->nr_frags;
skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1];
struct page *page = sk->sk_sndmsg_page;
int off = sk->sk_sndmsg_off;
unsigned int left;
if (page && (left = PAGE_SIZE - off) > 0) {
if (copy >= left)
copy = left;
if (page != frag->page) {
if (i == MAX_SKB_FRAGS) {
err = -EMSGSIZE;
goto error;
}
get_page(page);
skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0);
frag = &skb_shinfo(skb)->frags[i];
}
} else if (i < MAX_SKB_FRAGS) {
if (copy > PAGE_SIZE)
copy = PAGE_SIZE;
page = alloc_pages(sk->sk_allocation, 0);
if (page == NULL) {
err = -ENOMEM;
goto error;
}
sk->sk_sndmsg_page = page;
sk->sk_sndmsg_off = 0;
skb_fill_page_desc(skb, i, page, 0, 0);
frag = &skb_shinfo(skb)->frags[i];
skb->truesize += PAGE_SIZE;
atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc);
} else {
err = -EMSGSIZE;
goto error;
}
if (getfrag(from, page_address(frag->page)+frag->page_offset+frag->size, offset, copy, skb->len, skb) < 0) {
err = -EFAULT;
goto error;
}
sk->sk_sndmsg_off += copy;
frag->size += copy;
skb->len += copy;
skb->data_len += copy;
}
My question is as bellow:
The condition is (page != frag->page), why? can it be replaced by (!frag->page)? I think (page == frag->page) is always true when (!frag->page) is true. Hope anybody tell me the reason.
if **(page != frag->page)** {
if (i == MAX_SKB_FRAGS) {
err = -EMSGSIZE;
goto error;
}
get_page(page);
skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0);
frag = &skb_shinfo(skb)->frags[i];
}
The condition is (page != frag->page), why? can it be replaced by
(!frag->page)? I think (page == frag->page) is always true when
(!frag->page) is true.
If (page == frag->page) is always true when (!frag->page) is true, (page != frag->page) is false when (!frag->page) is true, and replacing (page != frag->page) by (!frag->page) would be replacing the value false by true.
And if you meant to write that (page != frag->page) is always true when (!frag->page) is true and if that is even right, that is not sufficient for (page != frag->page) to be equivalent to (!frag->page), because (page != frag->page) is not necessarily always false when (!frag->page) is false.

Unexpected '}' On Line 135, but all } needed JavaScript GameEngine

I am making a JavaScript Game Engine called Rage Engine. After about 1.5 hours of working on Version 1.0 Build 1, I had enough features and decided to do a test. Immediately I ran into a problem. The Console was saying Unexpected token } on line 135. I went to line 135 and found where the Console said there was a unexpected } and removed it. The Console next told me that there was an unexpected else on line 135. I use Sublime Text 2 as my IDLE and I made sure of that there were no brackets that were unintended.
Update:
I have identified, thanks in part to +Jason, what I think to be the problem
The Method RageEngine.data.file.requestQuota is too large. I have run into this problem before and I think the javascript compiler cannot handle functions larger than a size without breaking down. I don't know how I could fix that.
Method Error Appeared In:
RageEngine.data.file.requestQuota = function(type,size,success) {
if (RageEngine.data.file.check().FileSystem) {
if(type == 'temp') {
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY,size,success,function(e) {
var msg = '', c = 0;
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
c = 1
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
c = 2
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
c = 3
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
c = 4
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
c = 5
break;
default:
msg = 'Unknown Error';
break;
};
throw new Error('TEMP QUOTA Error: ' +msg+'. Error #3211.'+c+' '+msg)
}
} else if (type == 'perm') {
window.webkitStorageInfo.requestQuota(PERSISTENT, size, function(grantedBytes) {
window.requestFileSystem(PERSISTENT, grantedBytes, success, function(e) {
var msg = '', c = 0;
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
c = 1
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
c = 2
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
c = 3
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
c = 4
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
c = 5
break;
default:
msg = 'Unknown Error';
break;
};
throw new Error('PERM QUOTA Error: ' +msg+'. Error #3212.'+c+' '+msg));
}, function(e) {
throw new Error('PERM QUOTA Error: '+e+'. Errror #3213 PERM QUOTA Error (in RageEngine.data.file.requestQuota)')
});
} else {
throw new TypeError("Invalid type "+type+". Error #3214 INVALID_TYPE (in RageEngine.data.file.requestQuota)")
}
} else {
throw new ReferenceError("Invalid User Support for FileSystem. Error #011 NO_SUPPORT (in RageEngine.data.file.requestQuota)")
}
Full Code
var RageEngine = {} // Initalize main object
// Initalize Sub Objects
RageEngine.hardware = {};
RageEngine.canvas = {};
RageEngine.data = {};
// Go Through each one and add methods
//** Sound **\\
RageEngine.hardware.sound.canPlayType = function(file) {
var audioElement = document.createElement( 'audio' );
return !!( audioElement.canPlayType &&
audioElement.canPlayType( 'audio/' + file.split( '.' ).pop().toLowerCase() + ';' ).replace( /no/, '' ) );
}
RageEngine.hardware.sound.preload = function(url) {
if(RageEngine.sound.canPlayType(url.split(".")[url.split(".").length - 1])) { // Test if the computer can play that type of audio
audio = new Audio(url)
return audio
} else {
throw new TypeError("Cannot load "+url+". Error: #111 USER_CANNOT_PLAY (in RageEngine.hardware.sound.preload)")
}
return audio
}
//** Video and Audio**\\
RageEngine.hardware.userMedia = {}
RageEngine.hardware.userMedia.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia
RageEngine.hardware.userMedia.check = function() {
return !!(navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia);
}
RageEngine.hardware.userMedia.get = function(video,audio,stream_options) {
if (!RageEngine.hardware.userMedia.check()) {
throw new Error("Invalid Support for getUserMedia. Error #011 NO_SUPPORT (in RageEngine.hardware.userMedia.get)")
} else {
if(video || audio != (true||false)) throw new TypeError('Invalid Video or Audio type. Expecting Boolean (RageEngine.hardware.userMedia.get)')
if (stream_options.type == "auto") {
RageEngine.hardware.userMedia.getUserMedia({video:video,audio:audio},function(mediastream) {
var video = document.createElement("VIDEO");
video.src = window.URL.createObjectURL(localMediaStream);
stream_options.stream(video)
});
} else if (stream_options.type == "man") {
RageEngine.hardware.userMedia.getUserMedia({video:video,audio:audio},stream_options.stream);
}
}
}
//** Canvas **\\
// Canvas API added to be added in v1.1
RageEngine.canvas.canvas = function() {
console.warn('Canvas API is not implemented yet (in RageEngine.canvas.canvas)')
}
//** Data **\\
RageEngine.data.string = {};
RageEngine.data.string.store = function(type,key,value) {
switch(type.toLowerCase()) {
case "temp":
sessionStorage[key] = value;
break;
case "perm":
localStorage[key] = value;
break;
default:
throw new TypeError("Invalid type "+type+". Error: #2111 INVAILD_STORE_TYPE (in RageEngine.data.string.store)")
}
}
RageEngine.data.string.recall = function(type,key) {
switch(type.toLowerCase()) {
case "temp":
return sessionStorage[key]
break;
case "perm":
return localStorage[key]
break;
default:
throw new TypeError("Invalid type "+type+". Error: #2112 INVAILD_RECALL_TYPE (in RageEngine.data.string.store)")
}
}
RageEngine.data.string.check = function() {
var support = {
'temp': sessionStorage==undefined ? false : true,
'perm': localStorage==undefined ? false : true
};
return support
}
RageEngine.data.file = {};
RageEngine.data.file.check = function() {
var support = {
'File':window.File==undefined ? false : true,
'FileReader':window.FileReader==undefined ? false : true,
'FileList':window.FileList==undefined ? false : true,
'Blob':window.Blob==undefined ? false : true,
'FileSystem':window.FileSystem==undefined ? false : true
}
return support
}
RageEngine.data.file.requestQuota = function(type,size,success) {
if (RageEngine.data.file.check().FileSystem) {
if(type == 'temp') {
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY,size,success,function(e) {
var msg = '', c = 0;
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
c = 1
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
c = 2
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
c = 3
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
c = 4
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
c = 5
break;
default:
msg = 'Unknown Error';
break;
};
throw new Error('TEMP QUOTA Error: ' +msg+'. Error #3211.'+c+' '+msg)
}
} else if (type == 'perm') {
window.webkitStorageInfo.requestQuota(PERSISTENT, size, function(grantedBytes) {
window.requestFileSystem(PERSISTENT, grantedBytes, success, function(e) {
var msg = '', c = 0;
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
c = 1
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
c = 2
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
c = 3
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
c = 4
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
c = 5
break;
default:
msg = 'Unknown Error';
break;
};
throw new Error('PERM QUOTA Error: ' +msg+'. Error #3212.'+c+' '+msg));
}, function(e) {
throw new Error('PERM QUOTA Error: '+e+'. Errror #3213 PERM QUOTA Error (in RageEngine.data.file.requestQuota)')
});
} else {
throw new TypeError("Invalid type "+type+". Error #3214 INVALID_TYPE (in RageEngine.data.file.requestQuota)")
}
} else {
throw new ReferenceError("Invalid User Support for FileSystem. Error #011 NO_SUPPORT (in RageEngine.data.file.requestQuota)")
}
Thank you,
--Vulpus
I know the code is sloppy, but this is Version 1 Build 1.
BTW: The code is live at http://www.vulpusinc.co.nf/RageEngine/J/RageEngine.js or http://www.vulpusinc.co.nf/RageEngine/J/RageEngine.min.js (4Kb of 68% smaller!). Feel Free to use it
Didn't analyze the whole file, but you have an extra end parenthesis which could cause errors on following lines;
throw new Error('PERM QUOTA Error: ' +msg+'. Error #3212.'+c+' '+msg));
// Extra ')' ^
It looks like you have a whole bunch of mismatched braces. For example:
window.requestFileSystem(window.TEMPORARY,size,success,function(e) {
//Stuff
}
} else if (type == 'perm')
You're missing some parentheses to properly complete that function call.
The easiest way to fix a problem like this is to have Sublime fix your indenting for you; if some blocks get misaligned, that's a good clue that you have some parenthesis issues. This article gives you a way to do that

Resources