| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- #include "squirrel.h"
- #include "sqstdblobimpl.h"
- #define MixInteger SQInteger
- #include "sqlite3.h"
- #define USE_MG_MD5
- #include "mongoose.h"
- #include "fossil-delta.h"
- static SQRESULT sq_fossil_delta_create(HSQUIRRELVM v) {
- SQ_FUNC_VARS_NO_TOP(v);
- SQ_GET_STRING(v, 2, str_from);
- SQ_GET_STRING(v, 3, str_to);
- SQChar *delta = sq_getscratchpad(v, str_to_size + DELTA_OVERFLOW);
- int delta_size = delta_create(str_from, str_from_size, str_to, str_to_size, delta);
- sq_pushstring(v, delta, delta_size);
- return 1;
- }
- static SQRESULT sq_fossil_delta_apply(HSQUIRRELVM v) {
- SQ_FUNC_VARS_NO_TOP(v);
- SQ_GET_STRING(v, 2, str_from);
- SQ_GET_STRING(v, 3, str_delta);
- int str_to_size = delta_output_size(str_delta, str_delta_size);
- if(str_to_size < 0) return sq_throwerror(v, _SC("invalid delta string"));
- SQChar *str_to = sq_getscratchpad(v, str_to_size);
- str_to_size = delta_apply(str_from, str_from_size, str_delta, str_delta_size, str_to);
- if(str_to_size < 0) return sq_throwerror(v, _SC("error applying delta"));
- sq_pushstring(v, str_to, str_to_size);
- return 1;
- }
- static SQRESULT sq_fossil_delta_output_size(HSQUIRRELVM v) {
- SQ_FUNC_VARS_NO_TOP(v);
- SQ_GET_STRING(v, 2, str_delta);
- int str_to_size = delta_output_size(str_delta, str_delta_size);
- sq_pushinteger(v, str_to_size);
- return 1;
- }
- static SQRESULT sq_fossil_delta_analyze(HSQUIRRELVM v) {
- SQ_FUNC_VARS_NO_TOP(v);
- SQ_GET_STRING(v, 2, str_delta);
- int pnCopy, pnInsert;
- int rc = delta_analyze(str_delta, str_delta_size, &pnCopy, &pnInsert);
- if(rc < 0) return sq_throwerror(v, _SC("invalid delta string"));
- sq_newarray(v, 2);
- sq_pushinteger(v, pnCopy);
- sq_arrayset(v, -2, 0);
- sq_pushinteger(v, pnInsert);
- sq_arrayset(v, -2, 1);
- return 1;
- }
- extern "C" {
- typedef sqlite3_uint64 u64;
- /*
- ** State structure for a SHA3 hash in progress
- */
- typedef struct SHA3Context SHA3Context;
- struct SHA3Context {
- union {
- u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */
- unsigned char x[1600]; /* ... or 1600 bytes */
- } u;
- unsigned nRate; /* Bytes of input accepted per Keccak iteration */
- unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */
- unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */
- };
- void xsqlite3_SHA3Init(SHA3Context*, int);
- void xsqlite3_SHA3Update(SHA3Context*, const unsigned char*, unsigned);
- const unsigned char* xsqlite3_SHA3Final(SHA3Context*);
- #define SHA3Init xsqlite3_SHA3Init
- #define SHA3Update xsqlite3_SHA3Update
- #define SHA3Final xsqlite3_SHA3Final
- /* Context for the SHA1 hash */
- typedef struct SHA1Context SHA1Context;
- struct SHA1Context {
- unsigned int state[5];
- unsigned int count[2];
- unsigned char buffer[64];
- };
- void xsqlite3_SHA1Init(SHA1Context*);
- void xsqlite3_SHA1Update(SHA1Context*, const unsigned char*, unsigned);
- void xsqlite3_SHA1Final(SHA1Context*, char*);
- #define SHA1Init xsqlite3_SHA1Init
- #define SHA1Update xsqlite3_SHA1Update
- #define SHA1Final xsqlite3_SHA1Final
- }
- /*
- ** Convert a digest into base-16. digest should be declared as
- ** "unsigned char digest[20]" in the calling function. The SHA3
- ** digest is stored in the first 20 bytes. zBuf should
- ** be "char zBuf[41]".
- */
- static void DigestToBase16(const unsigned char *digest, char *zBuf, int nByte){
- static const char zEncode[] = "0123456789abcdef";
- int ix;
- for(ix=0; ix<nByte; ix++){
- *zBuf++ = zEncode[(*digest>>4)&0xf];
- *zBuf++ = zEncode[*digest++ & 0xf];
- }
- *zBuf = '\0';
- }
- static SQRESULT sq_fossil_sha3sum(HSQUIRRELVM v) {
- SQ_FUNC_VARS(v);
- SQ_GET_INTEGER(v, 2, iSize);
- switch(iSize)
- {
- case 0:
- iSize = 256;
- case 224:
- case 256:
- case 384:
- case 512:
- break;
- default:
- return sq_throwerror(v, _SC("invalid hash size expected one of [0, 224, 256, 384, 512]"));
- }
- SHA3Context ctx;
- SHA3Init(&ctx, iSize);
- for (int i = 3; i <= _top_; ++i) {
- SQ_GET_STRING(v, i, p);
- SHA3Update(&ctx, (const unsigned char *) p, p_size);
- }
- SQInteger buf_size = iSize/4;
- SQChar *buf = sq_getscratchpad(v, buf_size);
- DigestToBase16(SHA3Final(&ctx), buf, buf_size/2);
- sq_pushstring(v, buf, buf_size);
- return 1;
- }
- static SQRESULT sq_fossil_sha1sum(HSQUIRRELVM v) {
- SQ_FUNC_VARS(v);
- const int hash_size = 20;
- const int buf_size = hash_size*2;
- char buf[buf_size+1];
- SHA1Context ctx;
- SHA1Init(&ctx);
- for (int i = 2; i <= _top_; ++i) {
- SQ_GET_STRING(v, i, p);
- SHA1Update(&ctx, (const unsigned char *) p, p_size);
- }
- SHA1Final(&ctx, buf);
- sq_pushstring(v, buf, buf_size);
- return 1;
- }
- static SQRESULT sq_fossil_md5sum(HSQUIRRELVM v) {
- SQ_FUNC_VARS(v);
- const int hash_size = 16;
- const int buf_size = hash_size*2;
- char buf[buf_size+1];
- unsigned char hash[hash_size];
- MD5_CTX ctx;
- MD5Init(&ctx);
- for (int i = 2; i <= _top_; ++i) {
- SQ_GET_STRING(v, i, p);
- MD5Update(&ctx, (const unsigned char *) p, p_size);
- }
- MD5Final(hash, &ctx);
- DigestToBase16(hash, buf, hash_size);
- sq_pushstring(v, buf, buf_size);
- return 1;
- }
- #define _DECL_FUNC(name,nparams,pmask) {_SC(#name), sq_fossil_##name,nparams,pmask}
- static SQRegFunction fossil_obj_funcs[]={
- _DECL_FUNC(delta_create,3, _SC(".ss")),
- _DECL_FUNC(delta_apply,3, _SC(".ss")),
- _DECL_FUNC(delta_output_size,2, _SC(".s")),
- _DECL_FUNC(delta_analyze,2, _SC(".s")),
- _DECL_FUNC(sha3sum,-3, _SC(".is")),
- _DECL_FUNC(sha1sum,-2, _SC(".s")),
- _DECL_FUNC(md5sum,-2, _SC(".s")),
- {0,0}
- };
- #undef _DECL_FUNC
- #ifdef __cplusplus
- extern "C" {
- #endif
- /* This defines a function that opens up your library. */
- SQRESULT sqext_register_fossil (HSQUIRRELVM sqvm) {
- //add a namespace sqmix
- sq_pushstring(sqvm,_SC("sqfossil"),-1);
- sq_newclass(sqvm,SQFalse);
- sq_insert_reg_funcs(sqvm, fossil_obj_funcs);
- sq_newslot(sqvm,-3,SQTrue); //add sq_fossil table to the root table
- return SQ_OK;
- }
- #ifdef __cplusplus
- }
- #endif
|