// Basic types implementation for JavaX // Require: prototype.js // Bugs: Grep TODO's and NOTE's in the code // Exception var Exception = Class.create({ initialize: function(sMsg, iCode) { this.message=sMsg; this.code=iCode; }, Serialize: function(oSerializer) { oSerializer.BeginType("Exception"); oSerializer.SerializeString(this.message); if(this.code) oSerializer.SerializeInt(this.code); oSerializer.EndType("Exception"); }, Restore: function(oRestorer) { oRestorer.BeginType("Exception"); this.message=oRestorer.RestoreString(); if(oRestorer.GetType()=="u") { this.code=oRestorer.Restore().Value(); } else this.code=undefined; oRestorer.EndType("Exception"); }, ErrorCode: function() { return this.code; }, Message: function() { return this.message; }, toString: function() { return this.message; }}); // ------------------------------------------------------------ // 'Optional' container for optional data types // for proper serialization of optional types // ------------------------------------------------------------ function optional(oValue) { return new Optional(oValue); } var Optional = Class.create({ initialize: function(oValue) { if (typeof(oValue) == "undefined") { this.bNone_ = true; } else { this.bNone_ = false; this.oValue_ = oValue; } }, Value: function() { return this.oValue_; }, IsNull: function() { return this.bNone_; }, SetNull: function() { this.bNone_ = true; }, Serialize: function(oSerializer) { if (this.bNone_) { oSerializer.BeginType("none"); oSerializer.EndType("none"); } else { oSerializer.BeginType("optional"); oSerializer.Serialize(this.oValue_); oSerializer.EndType("optional"); } }, Restore: function(oRestorer) { var sTypeName = oRestorer.GetType(); if (sTypeName == "none") { oRestorer.BeginType("none"); oRestorer.EndType("none"); this.bNone_ = true; } else { oRestorer.BeginType("optional"); this.bNone_ = false; this.oValue_ = oRestorer.Restore(); oRestorer.EndType("optional"); } }, toString: function() { if (this.IsNull()) return ""; else if (typeof(this.oValue_.toString) == "function") return this.oValue_.toString(); else return ""; } }); // ------------------------------------------------------------ // int32_t type // ------------------------------------------------------------ // Wrapper function int(value) { return new Int(value); } var Int = Class.create({ initialize: function(value) { this.value_ = parseInt(value); }, Value: function() { return this.value_; }, Serialize: function(oSerializer) { oSerializer.SerializeInt(this.value_); }, Restore: function(oRestorer) { this.value_ = oRestorer.RestoreInt(); }, toString: function() { return this.value_.toString(); } }); // ------------------------------------------------------------ // uint32_t type // ------------------------------------------------------------ function unsigned(oValue) { return new Unsigned(oValue); } var Unsigned = Class.create({ initialize: function(value) { this.value_ = parseInt(value); }, Value: function() { return this.value_; }, Serialize: function(oSerializer) { oSerializer.BeginType("u"); // TODO: Bad impl! not pure unsigned (31-bit) oSerializer.Serialize(new Int(this.value_)); oSerializer.EndType("u"); }, Restore: function(oRestorer) { oRestorer.BeginType("u"); this.value_ = oRestorer.Restore().Value(); if(this.value_<0) { this.value_= this.value_+4294967296; } oRestorer.EndType("u"); }, toString: function() { return this.value_.toString(); } }); // ------------------------------------------------------------ // int64_t type // ------------------------------------------------------------ // Wrapper function int64(value) { return new Int64(value); } var Int64 = Class.create({ initialize: function(value) { // TODO: BAD (cannot constuct true Int64 from long number) this.value_ = parseInt(value); }, Value: function() { return this.value_; }, Serialize: function(oSerializer) { oSerializer.SerializeInt64(this.value_); }, Restore: function(oRestorer) { this.value_ = oRestorer.RestoreInt64().Value(); }, toString: function() { return this.value_.toString(); } }); // ------------------------------------------------------------ // uint64_t type // ------------------------------------------------------------ var UInt64 = Class.create({ initialize: function(value) { // TODO: BAD (cannot constuct true Int64 from long number) // TODO: BAD: not pure-32bit this.value_ = parseInt(value); }, Value: function() { return this.value_; }, Serialize: function(oSerializer) { oSerializer.BeginType("ul"); oSerializer.SerializeInt64(this.value_); oSerializer.EndType("ul"); }, Restore: function(oRestorer) { oRestorer.BeginType("ul"); this.value_ = oRestorer.RestoreInt64().Value(); oRestorer.EndType("ul"); }, toString: function() { return this.value_.toString(); } }); // ------------------------------------------------------------ // double type // ------------------------------------------------------------ // Wrapper function double(value) { return new Double(value); } var Double = Class.create({ initialize: function(value) { // null, undefined, any string, any object (including 'NaN', etc) is parsed as NaN this.value_=(value instanceof Double) ? value.value_ : parseFloat(value); }, Value: function() { return this.value_; }, IsNull: function() { return isNaN(this.value_); }, Serialize: function(oSerializer) { oSerializer.SerializeDouble(this.value_); }, Restore: function(oRestorer) { this.value_ = oRestorer.RestoreDouble(); }, toString: function() { return this.value_.toString(); } }); // ------------------------------------------------------------ // Decimal type // ------------------------------------------------------------ // Wrapper function decimal(value) { return new Decimal(value); } var Decimal = Class.create({ initialize: function(value) { if (!value) value=''; this.value_=value; }, Value: function() { return this.value_; }, IsNull: function() { return !this.value_ || (this.value_ == "NULL") || isNaN(this.value_); }, Serialize: function(oSerializer) { oSerializer.BeginType("decimal"); oSerializer.SerializeString(this.value_); oSerializer.EndType("decimal"); }, Restore: function(oRestorer) { oRestorer.BeginType("decimal"); this.value_=oRestorer.RestoreString(); oRestorer.EndType("decimal"); }, toString: function() { return this.value_; } }); var DecFlags = { SIGN: 0x8000, DATA_TRUNCATED: 0x4000, NOT_INITIALIZED: 0x2000 } var CDecimal = Class.create({ initialize: function(obj) { this.words_=[]; if (!obj) { alert("Empty object passed to CDecimal constructor. "); return; } if (obj instanceof CDecimal) { // copy constuctor for (var i=0; i<6; ++i) this.words_[i]=obj.words_[i]; this.flags_=obj.flags_; this.exp_=obj.exp_; } else if (obj.binary) { var str=obj.binary; // convert from string for (var i=0; i<3; ++i) { this.words_[i*2]=(str.charCodeAt(i*4+3)<<8)+str.charCodeAt(i*4+2); this.words_[i*2+1]=(str.charCodeAt(i*4+1)<<8)+str.charCodeAt(i*4+0); } this.flags_=str.charCodeAt(12)+(str.charCodeAt(13)<<8); this.exp_=str.charCodeAt(14)+(str.charCodeAt(15)<<8); } else { alert("Invalid object passed to CDecimal constructor. "); } }, Negative: function() { return !!(this.flags_ & DecFlags.SIGN); }, IsNull: function() { return !!(this.flags_ & DecFlags.NOT_INITIALIZED); }, right10: function() { var res=0; var t; if (this.Negative()) this.invert(); for (var i=0; i<6; ++i) { if (this.words_[i] || res) { t=this.words_[i] | (res<<16); res=t%10; this.words_[i]=Math.floor(t/10); } else { this.words_[i]=0; res=0; } } if(this.Negative()) { this.invert(); res=-res; } return res; }, invert: function() { for (var i=0; i<6; ++i) { // bit inversion equivalent, ~ works bad in JS this.words_[i]=0xFFFF-this.words_[i]; } // increment by 1 for (var i=5; i>=0; --i) { ++this.words_[i]; if (this.words_[i]==0x10000) { this.words_[i]=0; continue; } break; } }, toString: function() { if (this.IsNull()) return null; var t=new CDecimal(this); var residue; var res=""; var texp=t.exp_; if (this.Negative()) { if (this.isZero()) return "-79228162514264337593543950336."; t.invert(); } t.flags_=0; do { if(0==texp--) res='.'+res; residue=t.right10(); res=String(residue)+res; } while (!t.isZero() || texp >= 0); if (this.Negative()) res='-'+res; return res; }, isZero: function() { for (var i=0; i<6; ++i) if (this.words_[i]) return false; return true; } }); var Blob = Class.create({ initialize: function(value) { this.value=value; }, Value: function() { return this.value; }, Serialize: function(oSerializer) { oSerializer.SerializeBinary(this.value); }, Restore: function(oRestorer) { this.value = oRestorer.RestoreBinary(); }, toString: function() { return this.value; } }); var BlobFile = Class.create({ initialize: function(fileName, mimeType, fileBody){ this.fileName = fileName; this.mimeType = mimeType; this.fileBody = new Blob(fileBody); }, Serialize: function(oSerializer){ oSerializer.BeginType("BlobFile"); oSerializer.Serialize(this.fileName); oSerializer.Serialize(this.mimeType); oSerializer.Serialize(this.fileBody); oSerializer.Serialize(this.status); oSerializer.Serialize(this.expireTime); oSerializer.EndType("BlobFile"); }, Restore: function(oRestorer){ oRestorer.BeginType("BlobFile"); this.fileName = oRestorer.Restore(); this.mimeType = oRestorer.Restore(); this.fileBody = oRestorer.Restore(); this.status = oRestorer.Restore(); this.expireTime = oRestorer.Restore(); oRestorer.EndType("BlobFile"); }, IsNull: function() { return (this.fileName=="" || this.fileName==undefined); } }); // ------------------------------------------------------------ // BlobRef type // ------------------------------------------------------------ var BlobRef = Class.create({ initialize: function(sBlobID, isFileRef) { this.sBlobID = sBlobID; this.isFileRef=isFileRef; }, Value: function() { return this.sBlobID; }, Serialize: function(oSerializer) { oSerializer.BeginType("BlobRef"); if(this.isFileRef) { oSerializer.BeginType("FileRef"); oSerializer.SerializeString("true"); oSerializer.EndType("FileRef"); } oSerializer.SerializeString(this.sBlobID); oSerializer.EndType("BlobRef"); }, Restore: function(oRestorer) { oRestorer.BeginType("BlobRef"); if(oRestorer.GetType()=="FileRef") { oRestorer.BeginType("FileRef"); if(oRestorer.RestoreString()=="true") this.isFileRef=true; oRestorer.EndType("FileRef"); } this.sBlobID=oRestorer.RestoreString(); oRestorer.EndType("BlobRef"); }, toString: function() { if(this.sBlobID==undefined) return ""; return this.sBlobID.toString(); }, IsNull: function() { return (this.sBlobID=="null" || !this.sBlobID); } });