コード例 #1
0
ファイル: gfxPlatform.cpp プロジェクト: lofter2011/Icefox
already_AddRefed<gfxASurface>
gfxPlatform::OptimizeImage(gfxImageSurface *aSurface,
                           gfxASurface::gfxImageFormat format)
{
    const gfxIntSize& surfaceSize = aSurface->GetSize();

#ifdef XP_WIN
    if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() == 
        gfxWindowsPlatform::RENDER_DIRECT2D) {
        return nsnull;
    }
#endif
    nsRefPtr<gfxASurface> optSurface = CreateOffscreenSurface(surfaceSize, format);
    if (!optSurface || optSurface->CairoStatus() != 0)
        return nsnull;

    gfxContext tmpCtx(optSurface);
    tmpCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
    tmpCtx.SetSource(aSurface);
    tmpCtx.Paint();

    gfxASurface *ret = optSurface;
    NS_ADDREF(ret);
    return ret;
}
コード例 #2
0
imgFrame::SurfaceWithFormat
imgFrame::SurfaceForDrawing(bool               aDoPadding,
                            bool               aDoPartialDecode,
                            bool               aDoTile,
                            const nsIntMargin& aPadding,
                            gfxMatrix&         aUserSpaceToImageSpace,
                            gfxRect&           aFill,
                            gfxRect&           aSubimage,
                            gfxRect&           aSourceRect,
                            gfxRect&           aImageRect)
{
  gfxIntSize size(PRInt32(aImageRect.Width()), PRInt32(aImageRect.Height()));
  if (!aDoPadding && !aDoPartialDecode) {
    NS_ASSERTION(!mSinglePixel, "This should already have been handled");
    return SurfaceWithFormat(new gfxSurfaceDrawable(ThebesSurface(), size), mFormat);
  }

  gfxRect available = gfxRect(mDecoded.x, mDecoded.y, mDecoded.width, mDecoded.height);

  if (aDoTile || mSinglePixel) {
    // Create a temporary surface.
    // Give this surface an alpha channel because there are
    // transparent pixels in the padding or undecoded area
    gfxImageSurface::gfxImageFormat format = gfxASurface::ImageFormatARGB32;
    nsRefPtr<gfxASurface> surface =
      gfxPlatform::GetPlatform()->CreateOffscreenSurface(size, gfxImageSurface::ContentFromFormat(format));
    if (!surface || surface->CairoStatus())
      return SurfaceWithFormat();

    // Fill 'available' with whatever we've got
    gfxContext tmpCtx(surface);
    tmpCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
    if (mSinglePixel) {
      tmpCtx.SetDeviceColor(mSinglePixelColor);
    } else {
      tmpCtx.SetSource(ThebesSurface(), gfxPoint(aPadding.left, aPadding.top));
    }
    tmpCtx.Rectangle(available);
    tmpCtx.Fill();
    return SurfaceWithFormat(new gfxSurfaceDrawable(surface, size), format);
  }

  // Not tiling, and we have a surface, so we can account for
  // padding and/or a partial decode just by twiddling parameters.
  // First, update our user-space fill rect.
  aSourceRect = aSourceRect.Intersect(available);
  gfxMatrix imageSpaceToUserSpace = aUserSpaceToImageSpace;
  imageSpaceToUserSpace.Invert();
  aFill = imageSpaceToUserSpace.Transform(aSourceRect);

  aSubimage = aSubimage.Intersect(available) - gfxPoint(aPadding.left, aPadding.top);
  aUserSpaceToImageSpace.Multiply(gfxMatrix().Translate(-gfxPoint(aPadding.left, aPadding.top)));
  aSourceRect = aSourceRect - gfxPoint(aPadding.left, aPadding.top);
  aImageRect = gfxRect(0, 0, mSize.width, mSize.height);

  gfxIntSize availableSize(mDecoded.width, mDecoded.height);
  return SurfaceWithFormat(new gfxSurfaceDrawable(ThebesSurface(),
                                                  availableSize),
                           mFormat);
}
コード例 #3
0
already_AddRefed<gfxWindowsSurface>
gfxWindowsSurface::OptimizeToDDB(HDC dc, const gfxIntSize& size, gfxImageFormat format)
{
    if (mForPrinting)
        return nsnull;

    if (format != ImageFormatRGB24)
        return nsnull;

    nsRefPtr<gfxWindowsSurface> wsurf = new gfxWindowsSurface(dc, size, format);
    if (wsurf->CairoStatus() != 0)
        return nsnull;

    gfxContext tmpCtx(wsurf);
    tmpCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
    tmpCtx.SetSource(this);
    tmpCtx.Paint();

    gfxWindowsSurface *raw = (gfxWindowsSurface*) (wsurf.get());
    NS_ADDREF(raw);

    // we let the new DDB surfaces be converted back to dibsections if
    // acquire_source_image is called on them
    cairo_win32_surface_set_can_convert_to_dib(raw->CairoSurface(), TRUE);

    return raw;
}
コード例 #4
0
void messageIdSequence::generateImpl
	(const generationContext& ctx, utility::outputStream& os,
	 const size_t curLinePos, size_t* newLinePos) const
{
	size_t pos = curLinePos;

	if (!m_list.empty())
	{
		generationContext tmpCtx(ctx);
		tmpCtx.setMaxLineLength(ctx.getMaxLineLength() - 2);

		for (std::vector <shared_ptr <messageId> >::const_iterator it = m_list.begin() ; ; )
		{
			(*it)->generate(ctx, os, pos, &pos);

			if (++it == m_list.end())
				break;

			os << " ";
			pos++;
		}
	}

	if (newLinePos)
		*newLinePos = pos;
}
コード例 #5
0
ファイル: addressList.cpp プロジェクト: 0xd34df00d/vmime
void addressList::generateImpl
	(const generationContext& ctx, utility::outputStream& os,
	 const size_t curLinePos, size_t* newLinePos) const
{
	size_t pos = curLinePos;

	generationContext tmpCtx(ctx);
	tmpCtx.setMaxLineLength(tmpCtx.getMaxLineLength() - 2);

	if (!m_list.empty())
	{
		for (std::vector <shared_ptr <address> >::const_iterator i = m_list.begin() ; ; )
		{
			(*i)->generate(ctx, os, pos, &pos);

			if (++i == m_list.end())
				break;

			os << ", ";
			pos += 2;
		}
	}

	if (newLinePos)
		*newLinePos = pos;
}
コード例 #6
0
ファイル: proto.cpp プロジェクト: BackupTheBerlios/smx-svn
void qObjProto::EvalXTCP(qCtx *ctx, qStr *out, qArgAry *args)
{
    if (args->Count() < 1) {
        ctx->Throw(out, 655, "USAGE: %connect-tcp(host,body[,timeout]])");
        return;
    }

    CStrAry hosts;

    CStr serv = (*args)[0];

    CStr bodyStr = args->GetAt(1);

    double timeout = ParseDbl((*args)[2]);

    if (serv.IsEmpty())
        return;

    int port = 0;

    char * p = strchr((const char *)serv, ':');

    if (p) {
        port = atoi(p+1);
        *p = '\0';
        ++p;
    }

    if (!port)
        port = IPPORT_TELNET;


    int sock_rval;
    Sock sock;

    CStr body, dom, ref;

    qCtxTmp tmpCtx(ctx);

    if (!bodyStr.IsEmpty()) {
        tmpCtx.MapObj(&sock, EvalXTCPSend,"send");
        tmpCtx.MapObj(&sock, EvalXTCPRecv,"recv");
    }

    PROTO_OPEN_SOCK();

    if (timeout > 1)
        sock.SetTimeout((float) timeout);

    tmpCtx.Parse(bodyStr, out);

    sock.Close();

    return;
}
コード例 #7
0
ファイル: io.cpp プロジェクト: BackupTheBerlios/smx-svn
void EvalCommOpen(const void *data, qCtx *ctx, qStr *out, qArgAry *args)
{
	CStr port = (*args)[0];
	CStr dcb_def = (*args)[1];

	qCtxTmp tmpCtx(ctx);
	qCommIO io;
	if (io.Open(ctx, out, port, dcb_def)) {
		tmpCtx.MapObj(&io, (QOBJMETH) &qCommIO::EvalCommWrite,  "comm-write");
		tmpCtx.MapObj(&io, (QOBJMETH) &qCommIO::EvalCommRead,   "comm-read");
		tmpCtx.Parse(args->GetAt(2), out);
	}
}
コード例 #8
0
ファイル: sql.cpp プロジェクト: BackupTheBerlios/smx-svn
void EvalSqlTrans(const void *data, qCtx *ctx, qStr *out, qArgAry *args)
{
    int errCode = 0;
    CStr errMsg;

    VALID_ARGC("sql-trans", 1,1);


    qObjTSRef ts = myDBL->GetRef();

    try {
        CDbPool *dbPool = new CDbPool(myDBL);
        CDbLib  *dbLib = GetDbLib(ctx);

        qObjTSRef ts2 = dbLib->GetRef();

        qCtxTmp tmpCtx(ctx);
        bool ok = true;

        tmpCtx.AddTry();
        tmpCtx.MapObj(dbPool, EvalSql, "sql");
        tmpCtx.MapObj(&ok , (QOBJFUNC) EvalBreak, "rollback");

        try {
            tmpCtx.Parse(args->GetAt(0), out);
        } catch(qCtxEx ex) {
            ok = false;
            errCode = ex.GetID();
            errMsg = ex.GetMsg();
        } catch (qCtxExAbort ex) {
            throw ex;
        } catch(...) {
            ok = false;
            errCode = 999;
            errMsg = "SqlTrans Unhandled exception.";
        }

        dbPool->EndTrans(ok ? SQL_COMMIT : SQL_ROLLBACK);
        dbPool->Free();

        tmpCtx.RemTry();
    } catch (qCtxExAbort ex) {
        throw ex;
    } catch(...) {
        ctx->Throw(out, 303, "Unknown SQL Library error during transaction.\nTransaction was rolled back");
    }
    if (errCode > 0)
        ctx->Throw(out, errCode, errMsg << "\nTransaction was rolled back.");
}
コード例 #9
0
ファイル: hset.cpp プロジェクト: BackupTheBerlios/smx-svn
void qObjHCtx::HEnum(qCtx *ctx, qStr *out, qArgAry *args)
{
// require body argument
	if (args->Count() < 1)
		return;

// get context
	CStr var   = (*args)[0];

// read filter
	int filter = 0;

	if (args->Count() > 2) {
		CStr tmp = (*args)[2];
		strlwr(tmp.GetBuffer());
		if (strchr((const char*)tmp, 'v'))
			filter |= HENUM_VALUES;
		if (strchr((const char*)tmp, 'k'))
			filter |= HENUM_KEYS; 
		if (strchr((const char*)tmp, 't'))
			filter |= HENUM_TREE; 
	} else 
		filter = HENUM_KEYS | HENUM_VALUES;

// loop through objects in my map

	qCtxTmp tmpCtx(ctx);

	LOOPCTX loop;

	loop.body = args->GetAt(1);
	loop.n = 0;
	loop.ctx = &tmpCtx;
	loop.out = out;
	
	loop.ctx->MapObj(&loop.key, "key");
	loop.ctx->MapObj(&loop.val, "value");
	
	ctx->MapObj(&loop.n,  "num");

	myHash.Enum(&loop, var, filter, HEnumLoop);

	return;
}
コード例 #10
0
ファイル: string.cpp プロジェクト: BackupTheBerlios/smx-svn
void EvalRxMatch(const void *data, qCtx *ctx, qStr *out, qArgAry *args)
{
	VALID_ARGC("rxmatch", 2, 4);

	CRegX rx;
	CStr str  = (*args)[0];
	CStr regx = (*args)[1];
	CStr flags = args->GetAt(3);

	if (!rx.Compile(regx)) {
		ctx->ThrowF(out, 701, "Invalid regular expression (%s)", rx.GetError() ? rx.GetError() : (const char *) regx);
		return;
	}

	rx.SetCase(false);

	const char * p;
	
	p = flags;
	while (p && *p) {
		if ((*p) == 's') rx.SetCase(true);
		++p;
	}

	p = str;
	int loc = rx.Match(p);
	if (loc) {
		if (args->Count() >= 3) {
			CStr body = args->GetAt(2);

			qCtxTmp tmpCtx(ctx);
			tmpCtx.MapObj(&rx, EvalSubExpr, "subx");
			tmpCtx.Parse(body, out);
		} else {
			const char *sp; const char *ep;
			if (rx.GetMatchInfo(sp, ep, 0))
				out->PutS(sp, ep-sp);
		}
	}
}
コード例 #11
0
already_AddRefed<gfxWindowsSurface>
gfxWindowsSurface::OptimizeToDDB(HDC dc, const gfxIntSize& size, gfxImageFormat format)
{
    if (mForPrinting)
        return nsnull;

    if (format != ImageFormatRGB24)
        return nsnull;

    nsRefPtr<gfxWindowsSurface> wsurf = new gfxWindowsSurface(dc, size, format);
    if (wsurf->CairoStatus() != 0)
        return nsnull;

    gfxContext tmpCtx(wsurf);
    tmpCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
    tmpCtx.SetSource(this);
    tmpCtx.Paint();

    gfxWindowsSurface *raw = (gfxWindowsSurface*) (wsurf.get());
    NS_ADDREF(raw);
    return raw;
}
コード例 #12
0
ファイル: file.cpp プロジェクト: BackupTheBerlios/smx-svn
bool ScanDir(CStr path, int mask, CStr body, qCtx *ctx, qStr *out)
{
	DIRSTATE st;

	qCtxTmp tmpCtx(ctx);

	tmpCtx.MapObj(&st, EvalFName, "fname");
	tmpCtx.MapObj(&st, EvalFPath, "fpath");
	tmpCtx.MapObj(&st, EvalFAttr, "fattr");
	tmpCtx.MapObj(&st, EvalFExt,  "fext");
	tmpCtx.MapObj(&st, EvalFSize, "fsize");
	tmpCtx.MapObj(&st, EvalFMtime,"fmtime");
	tmpCtx.MapObj(&st, EvalFCtime,"fctime");

#ifdef unix
	tmpCtx.MapObj(&st, EvalFMode,"fmode");
#endif

	tmpCtx.MapObj(&st, EvalFIsDir,"isdir");
	tmpCtx.MapObj(&st, EvalFBreak,"break");
  
	st.bquit = false;
  	return _ScanDir(path, mask, body, &tmpCtx, out, st);
}
コード例 #13
0
ファイル: string.cpp プロジェクト: BackupTheBerlios/smx-svn
void EvalRxSplit(const void *data, qCtx *ctx, qStr *out, qArgAry *args)
{
	VALID_ARGC("rxsplit", 2, 4);

	CRegX rx;
	CStr str  = (*args)[0];
	CStr regx = (*args)[1];
	CStr body = args->GetAt(2);
	CStr flags = args->GetAt(3);

	rx.SetCase(false);

	const char * p;
	
	p = flags;
	while (p && *p) {
		if ((*p) == 's') rx.SetCase(true);
		++p;
	}

	if (!rx.Compile(regx)) {
		ctx->ThrowF(out, 701, "Invalid regular expression (%s)", rx.GetError() ? rx.GetError() : (const char *) regx);
		return;
	}

	p = str;
	int loc = rx.Match(p);
	int cnt = 0;

	const char *sp; const char *ep = p;

	qCtxTmp tmpCtx(ctx);
	tmpCtx.MapObj(&rx, EvalSubExpr, "subx");
	tmpCtx.MapObj("", "last");
	tmpCtx.MapObj(&cnt, "rxnum");

	while (loc && *p) {
		++cnt;

		rx.GetMatchInfo(sp, ep, 0);
		tmpCtx.MapObj(CStr(p, sp-p), "elem");
		tmpCtx.MapObj(CStr(p, sp-p), "token");

		if (ep && !*ep)
			tmpCtx.MapObj("T", "last");

		tmpCtx.Parse(body, out);

		if (ep <= p)
			break;
		else
			loc = rx.Match(p=ep);
	}
	
	if ((loc && !(ep && !*ep)) || (ep && *ep)) {
		++cnt;
		tmpCtx.MapObj("T", "last");

		if (ep && *ep)
			str = ep;
		tmpCtx.MapObj(str, "elem");
		tmpCtx.MapObj(str, "token");
		tmpCtx.Parse(body, out);
	}

	if (cnt)
		ctx->MapObj(cnt, "rxcount");
	else
		ctx->MapObj("", "rxcount");
}
コード例 #14
0
ファイル: string.cpp プロジェクト: BackupTheBerlios/smx-svn
void EvalEnumSort(const void *data, qCtx *ctx, qStr *out, qArgAry *args)
{
	if (args->Count() > 2) {
		CStr datax = (*args)[0];;
		CStr body = args->GetAt(2).GetBuffer();
		if (!body)
			return;
		char * data = datax.GetBuffer();

		CStr delim = "\n\r|,;";
		CStr alg;

		if (args->Count() > 1 && args->GetAt(1))
			delim = (*args)[1];;

		if (args->Count() > 3)
			alg = args->GetAt(3);

		int num = 0;
		WNAryX *ary = NULL;
		char *p;


		WNCompX compx;

		if ((p = strtok(data, delim))) {
			int len;
			do {
				len = strlen(p);
				ary = (WNAryX*) realloc(ary, ++num * sizeof(WNAryX));
				memset(&(ary[num-1]), 0, sizeof(WNAryX));
				new(&ary[num-1]) WNAryX;
				ary[num-1].v = p;
				ary[num-1].c=&compx;
			} while ((p = strtok(NULL, delim)));
		}

		if (!alg.IsEmpty()) {
			qCtxTmp tmpCtx(ctx);
			qStrBuf tmpOut;
			compx.alg=alg;
			compx.out=&tmpOut;
			compx.ctx=&tmpCtx;
			tmpCtx.MapObj(&compx.a, "a");
			tmpCtx.MapObj(&compx.b, "b");
			qsort(ary, num, sizeof(WNAryX), EvalWNCom);
		} else 
			qsort(ary, num, sizeof(WNAryX), EvalWNComSimple);


		const char *curw;
		qCtxTmp tmpCtx(ctx);
		tmpCtx.MapObj(&curw, "token");

		bool ok = true;
		tmpCtx.MapObj(&ok, (QOBJFUNC) EvalBreak, "break");

		int i; for (i = 0; ok && i < num; ++i) {
			curw = ary[i].v;
			tmpCtx.Parse(body, out);
			ary[i].~WNAryX();
		}
		free(ary);
	}
}
コード例 #15
0
ファイル: core.cpp プロジェクト: BackupTheBerlios/smx-svn
void qObjDef::Eval(qCtx *ctx, qStr *out, qArgAry *args)
{
	AddRef();

	try {
		qCtxTmp tmpCtx(ctx);
		int i, an = myArgNames.Count();
		int mapcnt = min(an,args->Count());
		
		for (i = 0; i < mapcnt; ++i) {
			if (myArgNames[i].Length() > 0) {
				CStr s = args->GetAt(i);
				CStr n = myArgNames[i]; //n.Change();
				if (!n.IsEmpty()) {
				if (myQuoted[i] == dParsed ) {
					qObjParsed *p = new qObjParsed(s);
					tmpCtx.MapObj(p, n);
				} else if (myQuoted[i] == dQuoted) {
					tmpCtx.MapObj(s, n);
					args->SetAt(i, s);
				} else if (myQuoted[i] == dObjRef) {
					qObj *obj;
					args->SetAt(i,s);
					if (ctx->Find(&obj, s)) {
						tmpCtx.MapObj(new qObjByRef(obj, false), n);
					}
				} else {
					args->SetAt(i, s);
					tmpCtx.MapObj(s, n);
				}} else {
					args->SetAt(i, s);
				}
			}
		}

		for (; i < an; ++i) {
			if (myArgNames[i].Length() > 0) {
				CStr n = myArgNames[i]; n.Change();
				if (!n.IsEmpty()) 
					tmpCtx.MapObj(CStr::Null, n);
			}
		}

		for (; i < args->Count(); ++i) {
			args->SetAt(i,(*args)[i]);
		}


		qObjDefArgs *inst = new qObjDefArgs(this, args);

		tmpCtx.MapObj(inst, "arg");
		tmpCtx.MapObj(args->Count(), "num-args");
		tmpCtx.MapObj(args->Count(), "argc");

		// *** comp
		//tmpCtx.Parse(&qStrReadBuf(myBody), out);
		qStrReadBuf rTmp(myBody);
		RunCompiled(&tmpCtx, &rTmp, out);
	} catch (qCtxExAbort ex) {
		throw ex;
	} catch (qCtxEx ex) {
		throw ex;
	} catch (...) {
		ctx->Throw(out, 999, "Core Unhandled exception");
	}

	Free();
}
コード例 #16
0
ファイル: proto.cpp プロジェクト: BackupTheBerlios/smx-svn
void qObjProto::EvalWhois(qCtx *ctx, qStr *out, qArgAry *args)
{
    if (args->Count() < 1) {
        ctx->Throw(out, 655, "USAGE: %whois(host[;host;host...][,body[,server[,bindip]]])");
        return;
    }

    CStrAry hosts;
    CStr hostStr = (*args)[0];
    CStr bodyStr = (*args)[1];
    CStr serv = (*args)[2];
    CStr bindip = (*args)[3];

    ProtoParseHosts(hosts, hostStr);

    if (hosts.Count() == 0)
        return;

    int port;

    if(serv.IsEmpty())

        serv = DEFAULT_WHOIS_HOST;

    port = IPPORT_WHOIS;

    int sock_rval, i;
    Sock sock;

    if(!bindip.IsEmpty())
        sock.Bind(bindip);

    CStr body, dom, ref, reg, url;

    qCtxTmp tmpCtx(ctx);

    if (!bodyStr.IsEmpty()) {
        tmpCtx.MapObj(&body, "results");
        tmpCtx.MapObj(&body, "body");

        tmpCtx.MapObj(&dom,  "domain");
        tmpCtx.MapObj(&ref,  "refer");

        tmpCtx.MapObj(&dom,  "domain-name");
        tmpCtx.MapObj(&reg,  "registrar");
        tmpCtx.MapObj(&ref,  "whois-server");
        tmpCtx.MapObj(&url,  "referral-url");
    }

    for (i = 0; i < hosts.Count(); ++i) {
        PROTO_OPEN_SOCK();

        body = CStr();
        ref = CStr();
        dom = hosts[i];
        sock.Write(hosts[i]<<"\r\n", hosts[i].Length()+2);

        do {
            if ((sock_rval = sock.Read(SOCK_DEFAULT_BUF_SIZE)) < 0) {
                if (sock_rval == Sock::ERR_TIMEOUT)
                    ctx->ThrowF(out, 705, "Time out while reading from host %s:%d, %y", (const char *) serv, port, GetLastError());
                else if (sock_rval)
                    ctx->ThrowF(out, 706, "Error reading from host %s:%d, %y", (const char *) serv, port, GetLastError());
                return;
            }
            if (!bodyStr.IsEmpty())
                body << CStr(sock.GetBuf(), sock_rval);
            else
                out->PutS(sock.GetBuf(), sock_rval);
        }
        while( sock_rval > 0);	//  If something was received

        if (!bodyStr.IsEmpty()) {
            const char *p;
            if ((p = stristr(body.GetBuffer(),"Whois Server:"))) {
                p += 14;
                while (isspace(*p)) ++p;
                char *e = strchr(p, '\n');
                ref = CStr(p, e-p);
            }
            if ((p = stristr(body.GetBuffer(),"Registrar:"))) {
                p += 14;
                while (isspace(*p)) ++p;
                char *e = strchr(p, '\n');
                reg = CStr(p, e-p);
            }
            if ((p = stristr(body.GetBuffer(),"Referral URL:"))) {
                p += 14;
                while (isspace(*p)) ++p;
                char *e = strchr(p, '\n');
                url = CStr(p, e-p);

            }
            tmpCtx.Parse(bodyStr, out);
        }
        sock.Close();
    }

    return;
}
コード例 #17
0
ファイル: modsmx.cpp プロジェクト: BackupTheBerlios/smx-svn
static int psx_user(request_rec *r)
{
	qEnvApache *renv = NULL;
	try {
		qEnvApacheServer *senv = get_psx_srv_env(r);
		if (!senv)
			return DECLINED;

		const char *macro = senv->GetUserMacro();
		if (!macro || !*macro)
			return DECLINED;

		renv = get_psx_req_env(r);
		if (!renv)
			return DECLINED;


		if (renv->IsAuth == 1) {
			if (r->main)
				renv->Free();
			return OK;
		} else if (renv->IsAuth == -1) {
			return psx_auth_fail(r, renv);
		}

		qCtxTmp tmpCtx(renv->GetCtx());

		char *user = NULL;
		const char *pw = NULL;

		int res=ap_get_basic_auth_pw(r,&pw);

		if (!res) {
#ifdef APACHE2
			user = r->user;
#else
			user = r->connection->user;
#endif
			
		}

		if (!user) user = "";
		tmpCtx.MapObj(user, "username");

		if (!pw) pw = "";
		tmpCtx.MapObj(pw, "password");

		CStr out = tmpCtx.ParseStr(macro);
		out.Trim();

		// ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, AP2STATUS r, "macro: %s, username: %s, password: %s, macro output: %s, macro length: %d, macro char: %x", (const char *) macro, (const char *)user, (const char *)pw, (const char *)out, out.Length(), (unsigned int)*(const char *)out);

		if (out.IsEmpty()) {
			renv->IsAuth = -1;
			return psx_auth_fail(r, renv);
		} else {
			if (r->main)
				renv->Free();
			renv->IsAuth = 1;
			return OK;
		}
	} catch (...) {
		// login code redirected things
		if (r->status == HTTP_MOVED_TEMPORARILY) {
			return OK;
		}

		if (renv)
			renv->Free();

		smx_log_str(SMXLOGLEVEL_ERROR, "unhandled exception during authentication");

		return DECLINED;
	}
}