The Squirrel interpreter. See http://www.squirrel-lang.org/

Dependents:   Squirrel

Committer:
jhnwkmn
Date:
Tue Dec 16 10:20:34 2014 +0000
Revision:
0:97a4f8cc534c
Initial import of Squirrel.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jhnwkmn 0:97a4f8cc534c 1 /* see copyright notice in squirrel.h */
jhnwkmn 0:97a4f8cc534c 2 #include <new>
jhnwkmn 0:97a4f8cc534c 3 #include <squirrel.h>
jhnwkmn 0:97a4f8cc534c 4 #include <sqstdio.h>
jhnwkmn 0:97a4f8cc534c 5 #include <string.h>
jhnwkmn 0:97a4f8cc534c 6 #include <sqstdblob.h>
jhnwkmn 0:97a4f8cc534c 7 #include "sqstdstream.h"
jhnwkmn 0:97a4f8cc534c 8 #include "sqstdblobimpl.h"
jhnwkmn 0:97a4f8cc534c 9
jhnwkmn 0:97a4f8cc534c 10 #define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002)
jhnwkmn 0:97a4f8cc534c 11
jhnwkmn 0:97a4f8cc534c 12 //Blob
jhnwkmn 0:97a4f8cc534c 13
jhnwkmn 0:97a4f8cc534c 14
jhnwkmn 0:97a4f8cc534c 15 #define SETUP_BLOB(v) \
jhnwkmn 0:97a4f8cc534c 16 SQBlob *self = NULL; \
jhnwkmn 0:97a4f8cc534c 17 { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \
jhnwkmn 0:97a4f8cc534c 18 return sq_throwerror(v,_SC("invalid type tag")); } \
jhnwkmn 0:97a4f8cc534c 19 if(!self || !self->IsValid()) \
jhnwkmn 0:97a4f8cc534c 20 return sq_throwerror(v,_SC("the blob is invalid"));
jhnwkmn 0:97a4f8cc534c 21
jhnwkmn 0:97a4f8cc534c 22
jhnwkmn 0:97a4f8cc534c 23 static SQInteger _blob_resize(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 24 {
jhnwkmn 0:97a4f8cc534c 25 SETUP_BLOB(v);
jhnwkmn 0:97a4f8cc534c 26 SQInteger size;
jhnwkmn 0:97a4f8cc534c 27 sq_getinteger(v,2,&size);
jhnwkmn 0:97a4f8cc534c 28 if(!self->Resize(size))
jhnwkmn 0:97a4f8cc534c 29 return sq_throwerror(v,_SC("resize failed"));
jhnwkmn 0:97a4f8cc534c 30 return 0;
jhnwkmn 0:97a4f8cc534c 31 }
jhnwkmn 0:97a4f8cc534c 32
jhnwkmn 0:97a4f8cc534c 33 static void __swap_dword(unsigned int *n)
jhnwkmn 0:97a4f8cc534c 34 {
jhnwkmn 0:97a4f8cc534c 35 *n=(unsigned int)(((*n&0xFF000000)>>24) |
jhnwkmn 0:97a4f8cc534c 36 ((*n&0x00FF0000)>>8) |
jhnwkmn 0:97a4f8cc534c 37 ((*n&0x0000FF00)<<8) |
jhnwkmn 0:97a4f8cc534c 38 ((*n&0x000000FF)<<24));
jhnwkmn 0:97a4f8cc534c 39 }
jhnwkmn 0:97a4f8cc534c 40
jhnwkmn 0:97a4f8cc534c 41 static void __swap_word(unsigned short *n)
jhnwkmn 0:97a4f8cc534c 42 {
jhnwkmn 0:97a4f8cc534c 43 *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00);
jhnwkmn 0:97a4f8cc534c 44 }
jhnwkmn 0:97a4f8cc534c 45
jhnwkmn 0:97a4f8cc534c 46 static SQInteger _blob_swap4(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 47 {
jhnwkmn 0:97a4f8cc534c 48 SETUP_BLOB(v);
jhnwkmn 0:97a4f8cc534c 49 SQInteger num=(self->Len()-(self->Len()%4))>>2;
jhnwkmn 0:97a4f8cc534c 50 unsigned int *t=(unsigned int *)self->GetBuf();
jhnwkmn 0:97a4f8cc534c 51 for(SQInteger i = 0; i < num; i++) {
jhnwkmn 0:97a4f8cc534c 52 __swap_dword(&t[i]);
jhnwkmn 0:97a4f8cc534c 53 }
jhnwkmn 0:97a4f8cc534c 54 return 0;
jhnwkmn 0:97a4f8cc534c 55 }
jhnwkmn 0:97a4f8cc534c 56
jhnwkmn 0:97a4f8cc534c 57 static SQInteger _blob_swap2(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 58 {
jhnwkmn 0:97a4f8cc534c 59 SETUP_BLOB(v);
jhnwkmn 0:97a4f8cc534c 60 SQInteger num=(self->Len()-(self->Len()%2))>>1;
jhnwkmn 0:97a4f8cc534c 61 unsigned short *t = (unsigned short *)self->GetBuf();
jhnwkmn 0:97a4f8cc534c 62 for(SQInteger i = 0; i < num; i++) {
jhnwkmn 0:97a4f8cc534c 63 __swap_word(&t[i]);
jhnwkmn 0:97a4f8cc534c 64 }
jhnwkmn 0:97a4f8cc534c 65 return 0;
jhnwkmn 0:97a4f8cc534c 66 }
jhnwkmn 0:97a4f8cc534c 67
jhnwkmn 0:97a4f8cc534c 68 static SQInteger _blob__set(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 69 {
jhnwkmn 0:97a4f8cc534c 70 SETUP_BLOB(v);
jhnwkmn 0:97a4f8cc534c 71 SQInteger idx,val;
jhnwkmn 0:97a4f8cc534c 72 sq_getinteger(v,2,&idx);
jhnwkmn 0:97a4f8cc534c 73 sq_getinteger(v,3,&val);
jhnwkmn 0:97a4f8cc534c 74 if(idx < 0 || idx >= self->Len())
jhnwkmn 0:97a4f8cc534c 75 return sq_throwerror(v,_SC("index out of range"));
jhnwkmn 0:97a4f8cc534c 76 ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val;
jhnwkmn 0:97a4f8cc534c 77 sq_push(v,3);
jhnwkmn 0:97a4f8cc534c 78 return 1;
jhnwkmn 0:97a4f8cc534c 79 }
jhnwkmn 0:97a4f8cc534c 80
jhnwkmn 0:97a4f8cc534c 81 static SQInteger _blob__get(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 82 {
jhnwkmn 0:97a4f8cc534c 83 SETUP_BLOB(v);
jhnwkmn 0:97a4f8cc534c 84 SQInteger idx;
jhnwkmn 0:97a4f8cc534c 85 sq_getinteger(v,2,&idx);
jhnwkmn 0:97a4f8cc534c 86 if(idx < 0 || idx >= self->Len())
jhnwkmn 0:97a4f8cc534c 87 return sq_throwerror(v,_SC("index out of range"));
jhnwkmn 0:97a4f8cc534c 88 sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]);
jhnwkmn 0:97a4f8cc534c 89 return 1;
jhnwkmn 0:97a4f8cc534c 90 }
jhnwkmn 0:97a4f8cc534c 91
jhnwkmn 0:97a4f8cc534c 92 static SQInteger _blob__nexti(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 93 {
jhnwkmn 0:97a4f8cc534c 94 SETUP_BLOB(v);
jhnwkmn 0:97a4f8cc534c 95 if(sq_gettype(v,2) == OT_NULL) {
jhnwkmn 0:97a4f8cc534c 96 sq_pushinteger(v, 0);
jhnwkmn 0:97a4f8cc534c 97 return 1;
jhnwkmn 0:97a4f8cc534c 98 }
jhnwkmn 0:97a4f8cc534c 99 SQInteger idx;
jhnwkmn 0:97a4f8cc534c 100 if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) {
jhnwkmn 0:97a4f8cc534c 101 if(idx+1 < self->Len()) {
jhnwkmn 0:97a4f8cc534c 102 sq_pushinteger(v, idx+1);
jhnwkmn 0:97a4f8cc534c 103 return 1;
jhnwkmn 0:97a4f8cc534c 104 }
jhnwkmn 0:97a4f8cc534c 105 sq_pushnull(v);
jhnwkmn 0:97a4f8cc534c 106 return 1;
jhnwkmn 0:97a4f8cc534c 107 }
jhnwkmn 0:97a4f8cc534c 108 return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type"));
jhnwkmn 0:97a4f8cc534c 109 }
jhnwkmn 0:97a4f8cc534c 110
jhnwkmn 0:97a4f8cc534c 111 static SQInteger _blob__typeof(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 112 {
jhnwkmn 0:97a4f8cc534c 113 sq_pushstring(v,_SC("blob"),-1);
jhnwkmn 0:97a4f8cc534c 114 return 1;
jhnwkmn 0:97a4f8cc534c 115 }
jhnwkmn 0:97a4f8cc534c 116
jhnwkmn 0:97a4f8cc534c 117 static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size)
jhnwkmn 0:97a4f8cc534c 118 {
jhnwkmn 0:97a4f8cc534c 119 SQBlob *self = (SQBlob*)p;
jhnwkmn 0:97a4f8cc534c 120 self->~SQBlob();
jhnwkmn 0:97a4f8cc534c 121 sq_free(self,sizeof(SQBlob));
jhnwkmn 0:97a4f8cc534c 122 return 1;
jhnwkmn 0:97a4f8cc534c 123 }
jhnwkmn 0:97a4f8cc534c 124
jhnwkmn 0:97a4f8cc534c 125 static SQInteger _blob_constructor(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 126 {
jhnwkmn 0:97a4f8cc534c 127 SQInteger nparam = sq_gettop(v);
jhnwkmn 0:97a4f8cc534c 128 SQInteger size = 0;
jhnwkmn 0:97a4f8cc534c 129 if(nparam == 2) {
jhnwkmn 0:97a4f8cc534c 130 sq_getinteger(v, 2, &size);
jhnwkmn 0:97a4f8cc534c 131 }
jhnwkmn 0:97a4f8cc534c 132 if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size"));
jhnwkmn 0:97a4f8cc534c 133 //SQBlob *b = new SQBlob(size);
jhnwkmn 0:97a4f8cc534c 134
jhnwkmn 0:97a4f8cc534c 135 SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size);
jhnwkmn 0:97a4f8cc534c 136 if(SQ_FAILED(sq_setinstanceup(v,1,b))) {
jhnwkmn 0:97a4f8cc534c 137 b->~SQBlob();
jhnwkmn 0:97a4f8cc534c 138 sq_free(b,sizeof(SQBlob));
jhnwkmn 0:97a4f8cc534c 139 return sq_throwerror(v, _SC("cannot create blob"));
jhnwkmn 0:97a4f8cc534c 140 }
jhnwkmn 0:97a4f8cc534c 141 sq_setreleasehook(v,1,_blob_releasehook);
jhnwkmn 0:97a4f8cc534c 142 return 0;
jhnwkmn 0:97a4f8cc534c 143 }
jhnwkmn 0:97a4f8cc534c 144
jhnwkmn 0:97a4f8cc534c 145 static SQInteger _blob__cloned(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 146 {
jhnwkmn 0:97a4f8cc534c 147 SQBlob *other = NULL;
jhnwkmn 0:97a4f8cc534c 148 {
jhnwkmn 0:97a4f8cc534c 149 if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
jhnwkmn 0:97a4f8cc534c 150 return SQ_ERROR;
jhnwkmn 0:97a4f8cc534c 151 }
jhnwkmn 0:97a4f8cc534c 152 //SQBlob *thisone = new SQBlob(other->Len());
jhnwkmn 0:97a4f8cc534c 153 SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len());
jhnwkmn 0:97a4f8cc534c 154 memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len());
jhnwkmn 0:97a4f8cc534c 155 if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) {
jhnwkmn 0:97a4f8cc534c 156 thisone->~SQBlob();
jhnwkmn 0:97a4f8cc534c 157 sq_free(thisone,sizeof(SQBlob));
jhnwkmn 0:97a4f8cc534c 158 return sq_throwerror(v, _SC("cannot clone blob"));
jhnwkmn 0:97a4f8cc534c 159 }
jhnwkmn 0:97a4f8cc534c 160 sq_setreleasehook(v,1,_blob_releasehook);
jhnwkmn 0:97a4f8cc534c 161 return 0;
jhnwkmn 0:97a4f8cc534c 162 }
jhnwkmn 0:97a4f8cc534c 163
jhnwkmn 0:97a4f8cc534c 164 #define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck}
jhnwkmn 0:97a4f8cc534c 165 static SQRegFunction _blob_methods[] = {
jhnwkmn 0:97a4f8cc534c 166 _DECL_BLOB_FUNC(constructor,-1,_SC("xn")),
jhnwkmn 0:97a4f8cc534c 167 _DECL_BLOB_FUNC(resize,2,_SC("xn")),
jhnwkmn 0:97a4f8cc534c 168 _DECL_BLOB_FUNC(swap2,1,_SC("x")),
jhnwkmn 0:97a4f8cc534c 169 _DECL_BLOB_FUNC(swap4,1,_SC("x")),
jhnwkmn 0:97a4f8cc534c 170 _DECL_BLOB_FUNC(_set,3,_SC("xnn")),
jhnwkmn 0:97a4f8cc534c 171 _DECL_BLOB_FUNC(_get,2,_SC("xn")),
jhnwkmn 0:97a4f8cc534c 172 _DECL_BLOB_FUNC(_typeof,1,_SC("x")),
jhnwkmn 0:97a4f8cc534c 173 _DECL_BLOB_FUNC(_nexti,2,_SC("x")),
jhnwkmn 0:97a4f8cc534c 174 _DECL_BLOB_FUNC(_cloned,2,_SC("xx")),
jhnwkmn 0:97a4f8cc534c 175 {0,0,0,0}
jhnwkmn 0:97a4f8cc534c 176 };
jhnwkmn 0:97a4f8cc534c 177
jhnwkmn 0:97a4f8cc534c 178
jhnwkmn 0:97a4f8cc534c 179
jhnwkmn 0:97a4f8cc534c 180 //GLOBAL FUNCTIONS
jhnwkmn 0:97a4f8cc534c 181
jhnwkmn 0:97a4f8cc534c 182 static SQInteger _g_blob_casti2f(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 183 {
jhnwkmn 0:97a4f8cc534c 184 SQInteger i;
jhnwkmn 0:97a4f8cc534c 185 sq_getinteger(v,2,&i);
jhnwkmn 0:97a4f8cc534c 186 sq_pushfloat(v,*((SQFloat *)&i));
jhnwkmn 0:97a4f8cc534c 187 return 1;
jhnwkmn 0:97a4f8cc534c 188 }
jhnwkmn 0:97a4f8cc534c 189
jhnwkmn 0:97a4f8cc534c 190 static SQInteger _g_blob_castf2i(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 191 {
jhnwkmn 0:97a4f8cc534c 192 SQFloat f;
jhnwkmn 0:97a4f8cc534c 193 sq_getfloat(v,2,&f);
jhnwkmn 0:97a4f8cc534c 194 sq_pushinteger(v,*((SQInteger *)&f));
jhnwkmn 0:97a4f8cc534c 195 return 1;
jhnwkmn 0:97a4f8cc534c 196 }
jhnwkmn 0:97a4f8cc534c 197
jhnwkmn 0:97a4f8cc534c 198 static SQInteger _g_blob_swap2(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 199 {
jhnwkmn 0:97a4f8cc534c 200 SQInteger i;
jhnwkmn 0:97a4f8cc534c 201 sq_getinteger(v,2,&i);
jhnwkmn 0:97a4f8cc534c 202 short s=(short)i;
jhnwkmn 0:97a4f8cc534c 203 sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF));
jhnwkmn 0:97a4f8cc534c 204 return 1;
jhnwkmn 0:97a4f8cc534c 205 }
jhnwkmn 0:97a4f8cc534c 206
jhnwkmn 0:97a4f8cc534c 207 static SQInteger _g_blob_swap4(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 208 {
jhnwkmn 0:97a4f8cc534c 209 SQInteger i;
jhnwkmn 0:97a4f8cc534c 210 sq_getinteger(v,2,&i);
jhnwkmn 0:97a4f8cc534c 211 unsigned int t4 = (unsigned int)i;
jhnwkmn 0:97a4f8cc534c 212 __swap_dword(&t4);
jhnwkmn 0:97a4f8cc534c 213 sq_pushinteger(v,(SQInteger)t4);
jhnwkmn 0:97a4f8cc534c 214 return 1;
jhnwkmn 0:97a4f8cc534c 215 }
jhnwkmn 0:97a4f8cc534c 216
jhnwkmn 0:97a4f8cc534c 217 static SQInteger _g_blob_swapfloat(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 218 {
jhnwkmn 0:97a4f8cc534c 219 SQFloat f;
jhnwkmn 0:97a4f8cc534c 220 sq_getfloat(v,2,&f);
jhnwkmn 0:97a4f8cc534c 221 __swap_dword((unsigned int *)&f);
jhnwkmn 0:97a4f8cc534c 222 sq_pushfloat(v,f);
jhnwkmn 0:97a4f8cc534c 223 return 1;
jhnwkmn 0:97a4f8cc534c 224 }
jhnwkmn 0:97a4f8cc534c 225
jhnwkmn 0:97a4f8cc534c 226 #define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck}
jhnwkmn 0:97a4f8cc534c 227 static SQRegFunction bloblib_funcs[]={
jhnwkmn 0:97a4f8cc534c 228 _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")),
jhnwkmn 0:97a4f8cc534c 229 _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")),
jhnwkmn 0:97a4f8cc534c 230 _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")),
jhnwkmn 0:97a4f8cc534c 231 _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")),
jhnwkmn 0:97a4f8cc534c 232 _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")),
jhnwkmn 0:97a4f8cc534c 233 {0,0}
jhnwkmn 0:97a4f8cc534c 234 };
jhnwkmn 0:97a4f8cc534c 235
jhnwkmn 0:97a4f8cc534c 236 SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr)
jhnwkmn 0:97a4f8cc534c 237 {
jhnwkmn 0:97a4f8cc534c 238 SQBlob *blob;
jhnwkmn 0:97a4f8cc534c 239 if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
jhnwkmn 0:97a4f8cc534c 240 return -1;
jhnwkmn 0:97a4f8cc534c 241 *ptr = blob->GetBuf();
jhnwkmn 0:97a4f8cc534c 242 return SQ_OK;
jhnwkmn 0:97a4f8cc534c 243 }
jhnwkmn 0:97a4f8cc534c 244
jhnwkmn 0:97a4f8cc534c 245 SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx)
jhnwkmn 0:97a4f8cc534c 246 {
jhnwkmn 0:97a4f8cc534c 247 SQBlob *blob;
jhnwkmn 0:97a4f8cc534c 248 if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG)))
jhnwkmn 0:97a4f8cc534c 249 return -1;
jhnwkmn 0:97a4f8cc534c 250 return blob->Len();
jhnwkmn 0:97a4f8cc534c 251 }
jhnwkmn 0:97a4f8cc534c 252
jhnwkmn 0:97a4f8cc534c 253 SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size)
jhnwkmn 0:97a4f8cc534c 254 {
jhnwkmn 0:97a4f8cc534c 255 SQInteger top = sq_gettop(v);
jhnwkmn 0:97a4f8cc534c 256 sq_pushregistrytable(v);
jhnwkmn 0:97a4f8cc534c 257 sq_pushstring(v,_SC("std_blob"),-1);
jhnwkmn 0:97a4f8cc534c 258 if(SQ_SUCCEEDED(sq_get(v,-2))) {
jhnwkmn 0:97a4f8cc534c 259 sq_remove(v,-2); //removes the registry
jhnwkmn 0:97a4f8cc534c 260 sq_push(v,1); // push the this
jhnwkmn 0:97a4f8cc534c 261 sq_pushinteger(v,size); //size
jhnwkmn 0:97a4f8cc534c 262 SQBlob *blob = NULL;
jhnwkmn 0:97a4f8cc534c 263 if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse))
jhnwkmn 0:97a4f8cc534c 264 && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) {
jhnwkmn 0:97a4f8cc534c 265 sq_remove(v,-2);
jhnwkmn 0:97a4f8cc534c 266 return blob->GetBuf();
jhnwkmn 0:97a4f8cc534c 267 }
jhnwkmn 0:97a4f8cc534c 268 }
jhnwkmn 0:97a4f8cc534c 269 sq_settop(v,top);
jhnwkmn 0:97a4f8cc534c 270 return NULL;
jhnwkmn 0:97a4f8cc534c 271 }
jhnwkmn 0:97a4f8cc534c 272
jhnwkmn 0:97a4f8cc534c 273 SQRESULT sqstd_register_bloblib(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 274 {
jhnwkmn 0:97a4f8cc534c 275 return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs);
jhnwkmn 0:97a4f8cc534c 276 }
jhnwkmn 0:97a4f8cc534c 277