merge -r 112783:112799 linden/branches/kelly/lsl-http-in-merge to linden/trunk

master
Kelly Washington 2009-02-24 19:29:36 +00:00
parent f5242719b6
commit aa2b978bf5
30 changed files with 1048 additions and 32 deletions

View File

@ -188,4 +188,18 @@ const S32 OBJECT_CREATOR = 8;
// llTextBox() magic token string - yes this is a hack. sue me.
const std::string TEXTBOX_MAGIC_TOKEN = "!!llTextBox!!";
// changed() event flags
const U32 CHANGED_NONE = 0x0;
const U32 CHANGED_INVENTORY = 0x1;
const U32 CHANGED_COLOR = 0x2;
const U32 CHANGED_SHAPE = 0x4;
const U32 CHANGED_SCALE = 0x8;
const U32 CHANGED_TEXTURE = 0x10;
const U32 CHANGED_LINK = 0x20;
const U32 CHANGED_ALLOWED_DROP = 0x40;
const U32 CHANGED_OWNER = 0x80;
const U32 CHANGED_REGION = 0x100;
const U32 CHANGED_TELEPORT = 0x200;
const U32 CHANGED_REGION_START = 0x400;
#endif

View File

@ -243,7 +243,7 @@ public:
void setAllParcelFlags(U32 flags);
void setParcelFlag(U32 flag, BOOL b);
void setArea(S32 area, S32 sim_object_limit);
virtual void setArea(S32 area, S32 sim_object_limit);
void setDiscountRate(F32 rate);
void setAllowModify(BOOL b) { setParcelFlag(PF_CREATE_OBJECTS, b); }

View File

@ -36,8 +36,8 @@
#include <boost/tokenizer.hpp>
#include "llstl.h"
#include "lliohttpserver.h" // for string constants
static const std::string CONTEXT_REQUEST("request");
static const std::string CONTEXT_WILDCARD("wildcard");
/**
@ -181,7 +181,8 @@ void LLHTTPNode::options(ResponsePtr response, const LLSD& context) const
//llinfos << "options context: " << context << llendl;
// default implementation constructs an url to the documentation.
std::string host = context[CONTEXT_REQUEST]["headers"]["host"].asString();
std::string host(
context[CONTEXT_REQUEST][CONTEXT_HEADERS]["host"].asString());
if(host.empty())
{
response->status(400, "Bad Request -- need Host header");
@ -475,6 +476,11 @@ void LLSimpleResponse::result(const LLSD& result)
status(200, "OK");
}
void LLSimpleResponse::extendedResult(S32 code, const std::string& body, const LLSD& headers)
{
status(code,body);
}
void LLSimpleResponse::status(S32 code, const std::string& message)
{
mCode = code;

View File

@ -38,7 +38,6 @@
class LLChainIOFactory;
/**
* These classes represent the HTTP framework: The URL tree, and the LLSD
* REST interface that such nodes implement.
@ -100,6 +99,11 @@ public:
*/
virtual void result(const LLSD&) = 0;
/**
* @brief return status code and message with headers.
*/
virtual void extendedResult(S32 code, const std::string& message, const LLSD& headers) = 0;
/**
* @brief return status code and reason string on http header,
* but do not return a payload.
@ -218,6 +222,14 @@ public:
const LLHTTPNode* rootNode() const;
const LLHTTPNode* findNode(const std::string& name) const;
enum EHTTPNodeContentType
{
CONTENT_TYPE_LLSD,
CONTENT_TYPE_TEXT
};
virtual EHTTPNodeContentType getContentType() const { return CONTENT_TYPE_LLSD; }
//@}
/* @name Description system
@ -277,6 +289,7 @@ public:
static LLPointer<LLSimpleResponse> create();
void result(const LLSD& result);
void extendedResult(S32 code, const std::string& body, const LLSD& headers);
void status(S32 code, const std::string& message);
void print(std::ostream& out) const;

View File

@ -57,15 +57,15 @@
#include <boost/tokenizer.hpp>
static const char HTTP_VERSION_STR[] = "HTTP/1.0";
static const std::string CONTEXT_REQUEST("request");
static const std::string CONTEXT_RESPONSE("response");
static const std::string CONTEXT_VERB("verb");
static const std::string CONTEXT_HEADERS("headers");
static const std::string HTTP_VERB_GET("GET");
static const std::string HTTP_VERB_PUT("PUT");
static const std::string HTTP_VERB_POST("POST");
static const std::string HTTP_VERB_DELETE("DELETE");
static const std::string HTTP_VERB_OPTIONS("OPTIONS");
const std::string CONTEXT_REQUEST("request");
const std::string CONTEXT_RESPONSE("response");
const std::string CONTEXT_VERB("verb");
const std::string CONTEXT_HEADERS("headers");
const std::string HTTP_VERB_GET("GET");
const std::string HTTP_VERB_PUT("PUT");
const std::string HTTP_VERB_POST("POST");
const std::string HTTP_VERB_DELETE("DELETE");
const std::string HTTP_VERB_OPTIONS("OPTIONS");
static LLIOHTTPServer::timing_callback_t sTimingCallback = NULL;
static void* sTimingCallbackData = NULL;
@ -104,6 +104,7 @@ private:
// from LLHTTPNode::Response
virtual void result(const LLSD&);
virtual void extendedResult(S32 code, const std::string& body, const LLSD& headers);
virtual void status(S32 code, const std::string& message);
void nullPipe();
@ -122,7 +123,8 @@ private:
STATE_DELAYED,
STATE_LOCKED,
STATE_GOOD_RESULT,
STATE_STATUS_RESULT
STATE_STATUS_RESULT,
STATE_EXTENDED_RESULT
};
State mState;
@ -180,14 +182,32 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
{
LLPerfBlock putblock("http_put");
LLSD input;
LLSDSerialize::fromXML(input, istr);
if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD)
{
LLSDSerialize::fromXML(input, istr);
}
else if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_TEXT)
{
std::stringstream strstrm;
strstrm << istr.rdbuf();
input = strstrm.str();
}
mNode.put(LLHTTPNode::ResponsePtr(mResponse), context, input);
}
else if(verb == HTTP_VERB_POST)
{
LLPerfBlock postblock("http_post");
LLSD input;
LLSDSerialize::fromXML(input, istr);
if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD)
{
LLSDSerialize::fromXML(input, istr);
}
else if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_TEXT)
{
std::stringstream strstrm;
strstrm << istr.rdbuf();
input = strstrm.str();
}
mNode.post(LLHTTPNode::ResponsePtr(mResponse), context, input);
}
else if(verb == HTTP_VERB_DELETE)
@ -262,7 +282,16 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl(
context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode;
context[CONTEXT_RESPONSE]["statusMessage"] = mStatusMessage;
LLBufferStream ostr(channels, buffer.get());
ostr << mStatusMessage << std::ends;
ostr << mStatusMessage;
return STATUS_DONE;
}
case STATE_EXTENDED_RESULT:
{
context[CONTEXT_RESPONSE][CONTEXT_HEADERS] = mHeaders;
context[CONTEXT_RESPONSE]["statusCode"] = mStatusCode;
LLBufferStream ostr(channels, buffer.get());
ostr << mStatusMessage;
return STATUS_DONE;
}
@ -309,6 +338,21 @@ void LLHTTPPipe::Response::result(const LLSD& r)
mPipe->unlockChain();
}
void LLHTTPPipe::Response::extendedResult(S32 code, const std::string& body, const LLSD& headers)
{
if(! mPipe)
{
llwarns << "LLHTTPPipe::Response::status: NULL pipe" << llendl;
return;
}
mPipe->mStatusCode = code;
mPipe->mStatusMessage = body;
mPipe->mHeaders = headers;
mPipe->mState = STATE_EXTENDED_RESULT;
mPipe->unlockChain();
}
// virtual
void LLHTTPPipe::Response::status(S32 code, const std::string& message)
{
@ -409,6 +453,7 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(
}
ostr << HTTP_VERSION_STR << " " << code << " " << message << "\r\n";
S32 content_length = buffer->countAfter(channels.in(), NULL);
if(0 < content_length)
{

View File

@ -40,6 +40,18 @@
class LLPumpIO;
// common strings use for populating the context. bascally 'request',
// 'wildcard', and 'headers'.
extern const std::string CONTEXT_REQUEST;
extern const std::string CONTEXT_RESPONSE;
extern const std::string CONTEXT_VERB;
extern const std::string CONTEXT_HEADERS;
extern const std::string HTTP_VERB_GET;
extern const std::string HTTP_VERB_PUT;
extern const std::string HTTP_VERB_POST;
extern const std::string HTTP_VERB_DELETE;
extern const std::string HTTP_VERB_OPTIONS;
class LLIOHTTPServer
{
public:

View File

@ -86,6 +86,14 @@ void LLServiceBuilder::createServiceDefinition(
}
}
static
bool starts_with(const std::string& text, const char* prefix)
{
return text.substr(0, strlen(prefix)) == prefix;
}
// TODO: Build a real services.xml for windows development.
// and remove the base_url logic below.
std::string LLServiceBuilder::buildServiceURI(const std::string& service_name)
{
std::ostringstream service_url;
@ -96,7 +104,19 @@ std::string LLServiceBuilder::buildServiceURI(const std::string& service_name)
LLApp* app = LLApp::instance();
if(app)
{
LLSD base_url = app->getOption("services-base-url");
// We define a base-url for some development configurations
// In production neither of these are defined and all services have full urls
LLSD base_url;
if (starts_with(service_name,"cap"))
{
base_url = app->getOption("cap-base-url");
}
if (base_url.asString().empty())
{
base_url = app->getOption("services-base-url");
}
service_url << base_url.asString();
}
service_url << mServiceMap[service_name];

View File

@ -1,6 +1,9 @@
# -*- cmake -*-
set(lscript_HEADER_FILES
llscriptresource.h
llscriptresourceconsumer.h
llscriptresourcepool.h
lscript_alloc.h
lscript_byteconvert.h
lscript_byteformat.h

View File

@ -0,0 +1,64 @@
/**
* @file llscriptresource.h
* @brief LLScriptResource class definition
*
* $LicenseInfo:firstyear=2008&license=internal$
*
* Copyright (c) 2008, Linden Research, Inc.
*
* The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
* this source code is governed by the Linden Lab Source Code Disclosure
* Agreement ("Agreement") previously entered between you and Linden
* Lab. By accessing, using, copying, modifying or distributing this
* software, you acknowledge that you have been informed of your
* obligations under the Agreement and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLSCRIPTRESOURCE_H
#define LL_LLSCRIPTRESOURCE_H
#include "stdtypes.h"
// An LLScriptResource is a limited resource per ID.
class LLScriptResource
{
public:
LLScriptResource();
// If amount resources are available will mark amount resouces
// used and returns true
// Otherwise returns false and doesn't mark any resources used.
bool request(S32 amount = 1);
// Release amount resources from use if at least amount resources are used and return true
// If amount is more than currently used no resources are released and return false
bool release(S32 amount = 1);
// Returns how many resources are available
S32 getAvailable() const;
// Sets the total amount of available resources
// It is possible to set the amount to less than currently used
// Most likely to happen on parcel ownership change
void setTotal(S32 amount);
// Get the total amount of available resources
S32 getTotal() const;
// Get the number of resources used
S32 getUsed() const;
// true if more resources used than total available
bool isOverLimit() const;
private:
S32 mTotal; // How many resources have been set aside
S32 mUsed; // How many resources are currently in use
};
#endif // LL_LLSCRIPTRESOURCE_H

View File

@ -0,0 +1,56 @@
/**
* @file llscriptresourceconsumer.h
* @brief An interface for a script resource consumer.
*
* $LicenseInfo:firstyear=2008&license=internal$
*
* Copyright (c) 2008, Linden Research, Inc.
*
* The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
* this source code is governed by the Linden Lab Source Code Disclosure
* Agreement ("Agreement") previously entered between you and Linden
* Lab. By accessing, using, copying, modifying or distributing this
* software, you acknowledge that you have been informed of your
* obligations under the Agreement and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLSCRIPTRESOURCECONSUMER_H
#define LL_LLSCRIPTRESOURCECONSUMER_H
#include "linden_common.h"
class LLScriptResourcePool;
// Entities that use limited script resources
// should implement this interface
class LLScriptResourceConsumer
{
public:
LLScriptResourceConsumer();
virtual ~LLScriptResourceConsumer() { }
// Get the number of public urls used by this consumer.
virtual S32 getUsedPublicURLs() const = 0;
// Get the resource pool this consumer is currently using.
LLScriptResourcePool& getScriptResourcePool();
const LLScriptResourcePool& getScriptResourcePool() const;
bool switchScriptResourcePools(LLScriptResourcePool& new_pool);
bool canUseScriptResourcePool(const LLScriptResourcePool& resource_pool);
bool isInPool(const LLScriptResourcePool& resource_pool);
protected:
virtual void setScriptResourcePool(LLScriptResourcePool& pool);
LLScriptResourcePool* mScriptResourcePool;
};
#endif // LL_LLSCRIPTRESOURCECONSUMER_H

View File

@ -0,0 +1,46 @@
/**
* @file llscriptresourcepool.h
* @brief A collection of LLScriptResources
*
* $LicenseInfo:firstyear=2008&license=internal$
*
* Copyright (c) 2008, Linden Research, Inc.
*
* The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
* this source code is governed by the Linden Lab Source Code Disclosure
* Agreement ("Agreement") previously entered between you and Linden
* Lab. By accessing, using, copying, modifying or distributing this
* software, you acknowledge that you have been informed of your
* obligations under the Agreement and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLSCRIPTRESOURCEPOOL_H
#define LL_LLSCRIPTRESOURCEPOOL_H
#include "llscriptresource.h"
// This is just a holder for LLSimResources
class LLScriptResourcePool
{
public:
LLScriptResourcePool();
// ~LLSimResourceMgr();
LLScriptResource& getPublicURLResource();
const LLScriptResource& getPublicURLResource() const;
// An empty resource pool.
static LLScriptResourcePool null;
private:
LLScriptResource mLSLPublicURLs;
};
#endif

View File

@ -360,6 +360,7 @@ typedef enum e_lscript_state_event_type
LSTT_OBJECT_REZ,
LSTT_REMOTE_DATA,
LSTT_HTTP_RESPONSE,
LSTT_HTTP_REQUEST,
LSTT_EOF,
LSTT_STATE_BEGIN = LSTT_STATE_ENTRY,
@ -401,7 +402,8 @@ const U64 LSCRIPTStateBitField[LSTT_EOF] =
0x0000000020000000, // LSTT_MOVING_END
0x0000000040000000, // LSTT_OBJECT_REZ
0x0000000080000000, // LSTT_REMOTE_DATA
0x0000000100000000LL // LSTT_HTTP_RESPOSE
0x0000000100000000LL, // LSTT_HTTP_RESPOSE
0x0000000200000000LL // LSTT_HTTP_REQUEST
};
inline S32 get_event_handler_jump_position(U64 bit_field, LSCRIPTStateEventType type)
@ -551,5 +553,10 @@ const U32 LSCRIPTRunTimePermissionBits[SCRIPT_PERMISSION_EOF] =
(0x1 << 11),// SCRIPT_PERMISSION_CONTROL_CAMERA
};
// http_request string constants
extern const char* URL_REQUEST_GRANTED;
extern const char* URL_REQUEST_DENIED;
extern const U64 LSL_HTTP_REQUEST_TIMEOUT;
#endif

View File

@ -118,6 +118,7 @@ extern "C" { int yyerror(const char *fmt, ...); }
"object_rez" { count(); return(OBJECT_REZ); }
"remote_data" { count(); return(REMOTE_DATA); }
"http_response" { count(); return(HTTP_RESPONSE); }
"http_request" { count(); return(HTTP_REQUEST); }
"." { count(); return(PERIOD); }
@ -221,16 +222,17 @@ extern "C" { int yyerror(const char *fmt, ...); }
"INVENTORY_ALL" { count(); yylval.ival = LLAssetType::AT_NONE; return(INTEGER_CONSTANT); }
"INVENTORY_NONE" { count(); yylval.ival = LLAssetType::AT_NONE; return(INTEGER_CONSTANT); }
"CHANGED_INVENTORY" { count(); yylval.ival = 0x1; return(INTEGER_CONSTANT); }
"CHANGED_COLOR" { count(); yylval.ival = 0x2; return(INTEGER_CONSTANT); }
"CHANGED_SHAPE" { count(); yylval.ival = 0x4; return(INTEGER_CONSTANT); }
"CHANGED_SCALE" { count(); yylval.ival = 0x8; return(INTEGER_CONSTANT); }
"CHANGED_TEXTURE" { count(); yylval.ival = 0x10; return(INTEGER_CONSTANT); }
"CHANGED_LINK" { count(); yylval.ival = 0x20; return(INTEGER_CONSTANT); }
"CHANGED_ALLOWED_DROP" { count(); yylval.ival = 0x40; return(INTEGER_CONSTANT); }
"CHANGED_OWNER" { count(); yylval.ival = 0x80; return(INTEGER_CONSTANT); }
"CHANGED_REGION" { count(); yylval.ival = 0x100; return(INTEGER_CONSTANT); }
"CHANGED_TELEPORT" { count(); yylval.ival = 0x200; return(INTEGER_CONSTANT); }
"CHANGED_INVENTORY" { count(); yylval.ival = CHANGED_INVENTORY; return(INTEGER_CONSTANT); }
"CHANGED_COLOR" { count(); yylval.ival = CHANGED_COLOR; return(INTEGER_CONSTANT); }
"CHANGED_SHAPE" { count(); yylval.ival = CHANGED_SHAPE; return(INTEGER_CONSTANT); }
"CHANGED_SCALE" { count(); yylval.ival = CHANGED_SCALE; return(INTEGER_CONSTANT); }
"CHANGED_TEXTURE" { count(); yylval.ival = CHANGED_TEXTURE; return(INTEGER_CONSTANT); }
"CHANGED_LINK" { count(); yylval.ival = CHANGED_LINK; return(INTEGER_CONSTANT); }
"CHANGED_ALLOWED_DROP" { count(); yylval.ival = CHANGED_ALLOWED_DROP; return(INTEGER_CONSTANT); }
"CHANGED_OWNER" { count(); yylval.ival = CHANGED_OWNER; return(INTEGER_CONSTANT); }
"CHANGED_REGION" { count(); yylval.ival = CHANGED_REGION; return(INTEGER_CONSTANT); }
"CHANGED_TELEPORT" { count(); yylval.ival = CHANGED_TELEPORT; return(INTEGER_CONSTANT); }
"CHANGED_REGION_START" { count(); yylval.ival = CHANGED_REGION_START; return(INTEGER_CONSTANT); }
"OBJECT_UNKNOWN_DETAIL" { count(); yylval.ival = OBJECT_UNKNOWN_DETAIL; return(INTEGER_CONSTANT); }
"OBJECT_NAME" { count(); yylval.ival = OBJECT_NAME; return(INTEGER_CONSTANT); }
@ -252,6 +254,8 @@ extern "C" { int yyerror(const char *fmt, ...); }
"NULL_KEY" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, "00000000-0000-0000-0000-000000000000"); return(STRING_CONSTANT); }
"EOF" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, "\n\n\n"); return(STRING_CONSTANT); }
"URL_REQUEST_GRANTED" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, URL_REQUEST_GRANTED); return(STRING_CONSTANT); }
"URL_REQUEST_DENIED" { yylval.sval = new char[UUID_STR_LENGTH]; strcpy(yylval.sval, URL_REQUEST_DENIED); return(STRING_CONSTANT); }
"PI" { count(); yylval.fval = F_PI; return(FP_CONSTANT); }
"TWO_PI" { count(); yylval.fval = F_TWO_PI; return(FP_CONSTANT); }

View File

@ -92,6 +92,7 @@
%token LINK_MESSAGE
%token REMOTE_DATA
%token HTTP_RESPONSE
%token HTTP_REQUEST
%token <sval> IDENTIFIER
%token <sval> STATE_DEFAULT
@ -195,6 +196,7 @@
%type <event> object_rez
%type <event> remote_data
%type <event> http_response
%type <event> http_request
%type <event> link_message
%type <event> timer
%type <event> chat
@ -848,6 +850,11 @@ event
$$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
gAllocationManager->addAllocation($$);
}
| http_request compound_statement
{
$$ = new LLScriptEventHandler(gLine, gColumn, $1, $2);
gAllocationManager->addAllocation($$);
}
;
state_entry
@ -1216,6 +1223,20 @@ http_response
}
;
http_request
: HTTP_REQUEST '(' LLKEY IDENTIFIER ',' STRING IDENTIFIER ',' STRING IDENTIFIER ')'
{
LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4);
gAllocationManager->addAllocation(id1);
LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7);
gAllocationManager->addAllocation(id2);
LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10);
gAllocationManager->addAllocation(id3);
$$ = new LLScriptHTTPRequestEvent(gLine, gColumn, id1, id2, id3);
gAllocationManager->addAllocation($$);
}
;
compound_statement
: '{' '}'
{

View File

@ -3291,6 +3291,110 @@ S32 LLScriptHTTPResponseEvent::getSize()
return 16;
}
void LLScriptHTTPRequestEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
if (gErrorToText.getErrors())
{
return;
}
switch(pass)
{
case LSCP_PRETTY_PRINT:
case LSCP_EMIT_ASSEMBLY:
fdotabs(fp, tabs, tabsize);
fprintf(fp, "http_request( key ");
mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, ", string ");
mMethod->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, ", string ");
mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, " )\n");
break;
case LSCP_SCOPE_PASS1:
checkForDuplicateHandler(fp, this, scope, "http_request");
if (scope->checkEntry(mRequestId->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
}
else
{
mRequestId->mScopeEntry = scope->addEntry(mRequestId->mName, LIT_VARIABLE, LST_KEY);
}
if (scope->checkEntry(mMethod->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
}
else
{
mMethod->mScopeEntry = scope->addEntry(mMethod->mName, LIT_VARIABLE, LST_STRING);
}
if (scope->checkEntry(mBody->mName))
{
gErrorToText.writeError(fp, this, LSERROR_DUPLICATE_NAME);
}
else
{
mBody->mScopeEntry = scope->addEntry(mBody->mName, LIT_VARIABLE, LST_STRING);
}
break;
case LSCP_RESOURCE:
{
// we're just tryng to determine how much space the variable needs
if (mRequestId->mScopeEntry)
{
mRequestId->mScopeEntry->mOffset = (S32)count;
mRequestId->mScopeEntry->mSize = 4;
count += mRequestId->mScopeEntry->mSize;
mMethod->mScopeEntry->mOffset = (S32)count;
mMethod->mScopeEntry->mSize = 4;
count += mMethod->mScopeEntry->mSize;
mBody->mScopeEntry->mOffset = (S32)count;
mBody->mScopeEntry->mSize = 4;
count += mBody->mScopeEntry->mSize;
}
}
break;
case LSCP_EMIT_BYTE_CODE:
{
#ifdef LSL_INCLUDE_DEBUG_INFO
char name[] = "http_request";
chunk->addBytes(name, strlen(name) + 1); /*Flawfinder: ignore*/
chunk->addBytes(mRequestId->mName, strlen(mRequestId->mName) + 1); /*Flawfinder: ignore*/
chunk->addBytes(mMethod->mName, strlen(mMethod->mName) + 1); /*Flawfinder: ignore*/
chunk->addBytes(mBody->mName, strlen(mBody->mName) + 1); /*Flawfinder: ignore*/
#endif
}
break;
case LSCP_EMIT_CIL_ASSEMBLY:
fdotabs(fp, tabs, tabsize);
fprintf(fp, "http_request( valuetype [ScriptTypes]LindenLab.SecondLife.Key ");
mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, ", string ");
mMethod->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, ", string ");
mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
fprintf(fp, " )\n");
break;
default:
mRequestId->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mMethod->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
mBody->recurse(fp, tabs, tabsize, pass, ptype, prunearg, scope, type, basetype, count, chunk, heap, stacksize, entry, entrycount, NULL);
break;
}
}
S32 LLScriptHTTPRequestEvent::getSize()
{
// key + string + string = 12
return 12;
}
void LLScriptMoneyEvent::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass, LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope, LSCRIPTType &type, LSCRIPTType basetype, U64 &count, LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap, S32 stacksize, LLScriptScopeEntry *entry, S32 entrycount, LLScriptLibData **ldata)
{
@ -9658,6 +9762,11 @@ void LLScriptEventHandler::recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCom
mScopeEntry->mFunctionArgs.addType(LST_LIST);
mScopeEntry->mFunctionArgs.addType(LST_STRING);
break;
case LSTT_HTTP_REQUEST:
mScopeEntry->mFunctionArgs.addType(LST_KEY);
mScopeEntry->mFunctionArgs.addType(LST_STRING);
mScopeEntry->mFunctionArgs.addType(LST_STRING);
break;
default:
break;

View File

@ -759,12 +759,12 @@ class LLScriptHTTPResponseEvent : public LLScriptEvent
{
public:
LLScriptHTTPResponseEvent(S32 line, S32 col,
LLScriptIdentifier *reqeust_id,
LLScriptIdentifier *request_id,
LLScriptIdentifier *status,
LLScriptIdentifier *metadata,
LLScriptIdentifier *body)
: LLScriptEvent(line, col, LSTT_HTTP_RESPONSE),
mRequestId(reqeust_id), mStatus(status), mMetadata(metadata), mBody(body)
mRequestId(request_id), mStatus(status), mMetadata(metadata), mBody(body)
{
}
@ -783,6 +783,32 @@ public:
LLScriptIdentifier *mBody;
};
class LLScriptHTTPRequestEvent : public LLScriptEvent
{
public:
LLScriptHTTPRequestEvent(S32 line, S32 col,
LLScriptIdentifier *request_id,
LLScriptIdentifier *method,
LLScriptIdentifier *body)
: LLScriptEvent(line, col, LSTT_HTTP_REQUEST),
mRequestId(request_id), mMethod(method), mBody(body)
{
}
void recurse(LLFILE *fp, S32 tabs, S32 tabsize, LSCRIPTCompilePass pass,
LSCRIPTPruneType ptype, BOOL &prunearg, LLScriptScope *scope,
LSCRIPTType &type, LSCRIPTType basetype, U64 &count,
LLScriptByteCodeChunk *chunk, LLScriptByteCodeChunk *heap,
S32 stacksize, LLScriptScopeEntry *entry,
S32 entrycount, LLScriptLibData **ldata);
S32 getSize();
LLScriptIdentifier *mRequestId;
LLScriptIdentifier *mMethod;
LLScriptIdentifier *mBody;
};
class LLScriptRezEvent : public LLScriptEvent
{
public:

View File

@ -12,6 +12,9 @@ include_directories(
)
set(lscript_execute_SOURCE_FILES
llscriptresource.cpp
llscriptresourceconsumer.cpp
llscriptresourcepool.cpp
lscript_execute.cpp
lscript_heapruntime.cpp
lscript_readlso.cpp
@ -20,6 +23,9 @@ set(lscript_execute_SOURCE_FILES
set(lscript_execute_HEADER_FILES
CMakeLists.txt
../llscriptresource.h
../llscriptresourceconsumer.h
../llscriptresourcepool.h
../lscript_execute.h
../lscript_rt_interface.h
lscript_heapruntime.h

View File

@ -0,0 +1,86 @@
/**
* @file llscriptresource.cpp
* @brief LLScriptResource class implementation for managing limited resources
*
* $LicenseInfo:firstyear=2008&license=internal$
*
* Copyright (c) 2008, Linden Research, Inc.
*
* The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
* this source code is governed by the Linden Lab Source Code Disclosure
* Agreement ("Agreement") previously entered between you and Linden
* Lab. By accessing, using, copying, modifying or distributing this
* software, you acknowledge that you have been informed of your
* obligations under the Agreement and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llscriptresource.h"
#include "llerror.h"
LLScriptResource::LLScriptResource()
: mTotal(0),
mUsed(0)
{
}
bool LLScriptResource::request(S32 amount /* = 1 */)
{
if (mUsed + amount <= mTotal)
{
mUsed += amount;
return true;
}
return false;
}
bool LLScriptResource::release(S32 amount /* = 1 */)
{
if (mUsed >= amount)
{
mUsed -= amount;
return true;
}
return false;
}
S32 LLScriptResource::getAvailable() const
{
if (mUsed > mTotal)
{
// It is possible after a parcel ownership change for more than total to be used
// In this case the user of this class just wants to know
// whether or not they can use a resource
return 0;
}
return (mTotal - mUsed);
}
void LLScriptResource::setTotal(S32 amount)
{
// This may cause this resource to be over spent
// such that more are in use than total allowed
// Until those resources are released getAvailable will return 0.
mTotal = amount;
}
S32 LLScriptResource::getTotal() const
{
return mTotal;
}
S32 LLScriptResource::getUsed() const
{
return mUsed;
}
bool LLScriptResource::isOverLimit() const
{
return (mUsed > mTotal);
}

View File

@ -0,0 +1,101 @@
/**
* @file llscriptresourceconsumer.cpp
* @brief An interface for a script resource consumer.
*
* $LicenseInfo:firstyear=2008&license=internal$
*
* Copyright (c) 2008, Linden Research, Inc.
*
* The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
* this source code is governed by the Linden Lab Source Code Disclosure
* Agreement ("Agreement") previously entered between you and Linden
* Lab. By accessing, using, copying, modifying or distributing this
* software, you acknowledge that you have been informed of your
* obligations under the Agreement and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llscriptresourceconsumer.h"
#include "llscriptresourcepool.h"
LLScriptResourceConsumer::LLScriptResourceConsumer()
: mScriptResourcePool(&LLScriptResourcePool::null)
{ }
// Get the resource pool this consumer is currently using.
// virtual
LLScriptResourcePool& LLScriptResourceConsumer::getScriptResourcePool()
{
return *mScriptResourcePool;
}
// Get the resource pool this consumer is currently using.
// virtual
const LLScriptResourcePool& LLScriptResourceConsumer::getScriptResourcePool() const
{
return *mScriptResourcePool;
}
// virtual
void LLScriptResourceConsumer::setScriptResourcePool(LLScriptResourcePool& new_pool)
{
mScriptResourcePool = &new_pool;
}
bool LLScriptResourceConsumer::switchScriptResourcePools(LLScriptResourcePool& new_pool)
{
if (&new_pool == &LLScriptResourcePool::null)
{
llwarns << "New pool is null" << llendl;
}
if (isInPool(new_pool))
{
return true;
}
if (!canUseScriptResourcePool(new_pool))
{
return false;
}
S32 used_urls = getUsedPublicURLs();
getScriptResourcePool().getPublicURLResource().release( used_urls );
setScriptResourcePool(new_pool);
getScriptResourcePool().getPublicURLResource().request( used_urls );
return true;
}
bool LLScriptResourceConsumer::canUseScriptResourcePool(const LLScriptResourcePool& resource_pool)
{
if (isInPool(resource_pool))
{
return true;
}
if (resource_pool.getPublicURLResource().getAvailable() < getUsedPublicURLs())
{
return false;
}
return true;
}
bool LLScriptResourceConsumer::isInPool(const LLScriptResourcePool& resource_pool)
{
const LLScriptResourcePool& current_pool = getScriptResourcePool();
if ( &resource_pool == &current_pool )
{
// This consumer is already in this pool
return true;
}
return false;
}

View File

@ -0,0 +1,39 @@
/**
* @file llscriptresourcepool.cpp
* @brief Collection of limited script resources
*
* $LicenseInfo:firstyear=2002&license=internal$
*
* Copyright (c) 2002-2007, Linden Research, Inc.
*
* The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
* this source code is governed by the Linden Lab Source Code Disclosure
* Agreement ("Agreement") previously entered between you and Linden
* Lab. By accessing, using, copying, modifying or distributing this
* software, you acknowledge that you have been informed of your
* obligations under the Agreement and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llscriptresourcepool.h"
LLScriptResourcePool LLScriptResourcePool::null;
LLScriptResourcePool::LLScriptResourcePool()
{
}
LLScriptResource& LLScriptResourcePool::getPublicURLResource()
{
return mLSLPublicURLs;
}
const LLScriptResource& LLScriptResourcePool::getPublicURLResource() const
{
return mLSLPublicURLs;
}

View File

@ -68,6 +68,12 @@ const char* LSCRIPTRunTimeFaultStrings[LSRF_EOF] = /*Flawfinder: ignore*/
void LLScriptExecuteLSL2::startRunning() {}
void LLScriptExecuteLSL2::stopRunning() {}
const char* URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED";
const char* URL_REQUEST_DENIED = "URL_REQUEST_DENIED";
// HTTP Requests to LSL scripts will time out after 25 seconds.
const U64 LSL_HTTP_REQUEST_TIMEOUT = 25 * USEC_PER_SEC;
LLScriptExecuteLSL2::LLScriptExecuteLSL2(LLFILE *fp)
{
U8 sizearray[4];

View File

@ -625,6 +625,16 @@ void LLScriptLSOParse::printStates(LLFILE *fp)
bytestream2char(name, mRawData, event_offset, sizeof(name));
fprintf(fp, "\t\tstring %s\n", name);
break;
case LSTT_HTTP_REQUEST: // LSTT_HTTP_REQUEST
bytestream2char(name, mRawData, event_offset, sizeof(name));
fprintf(fp, "%s\n", name);
bytestream2char(name, mRawData, event_offset, sizeof(name));
fprintf(fp, "\t\tkey %s\n", name);
bytestream2char(name, mRawData, event_offset, sizeof(name));
fprintf(fp, "\t\tstring %s\n", name);
bytestream2char(name, mRawData, event_offset, sizeof(name));
fprintf(fp, "\t\tstring %s\n", name);
break;
default:
break;
}

View File

@ -451,6 +451,12 @@ void LLScriptLibrary::init()
addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSHA1String", "s", "s", "string llSHA1String(string sr)\nPerforms a SHA1 security Hash. Returns a 40 character hex string."));
addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetFreeURLs", "i", NULL, "integer llGetFreeURLs()\nreturns the available urls for the current script"));
addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRequestURL", "k", NULL, "key llRequestURL()\nRequests one HTTP:// url for use by this object\nTriggers an http_server event with results."));
addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRequestSecureURL", "k", NULL, "key llRequestSecureURL()\nRequests one HTTPS:// (SSL) url for use by this object\nTriggers an http_server event with results."));
addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llReleaseURL", NULL, "s", "llReleaseURL(string url)\nReleases the specified URL, it will no longer be usable."));
addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llHTTPResponse", NULL, "kis", "llHTTPResponse(key id, integer status, string body)\nResponds to request id with status and body."));
addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetHTTPHeader", "s", "ks", "string llGetHTTPHeader(key id, string header)\nGet the value for header for request id."));
// energy, sleep, dummy_func, name, return type, parameters, help text, gods-only

View File

@ -50,6 +50,7 @@ link_message link_message(integer sender_num, integer num, string str, key id):T
changed changed( integer change ):Triggered various event change the task:(test change with CHANGED_INVENTORY, CHANGED_COLOR, CHANGED_SHAPE, CHANGED_SCALE, CHANGED_TEXTURE, CHANGED_LINK, CHANGED_ALLOWED_DROP, CHANGED_OWNER, CHANGED_REGION, CHANGED_TELEPORT)
remote_data remote_data(integer event_type, key channel, key message_id, string sender,integer idata, string sdata):Triggered by various XML-RPC calls (event_type will be one of REMOTE_DATA_CHANNEL, REMOTE_DATA_REQUEST, REMOTE_DATA_REPLY)
http_response http_response(key request_id, integer status, list metadata, string body):Triggered when task receives a response to one of its llHTTPRequests
http_request http_request(key id, string method, string body):Triggered when task receives an http request against a public URL
# integer constants
[word .1, .1, .5]
@ -317,6 +318,7 @@ CHANGED_ALLOWED_DROP Parameter of changed event handler used to indicate a user
CHANGED_OWNER Parameter of changed event handler used to indicate change to task's owner ONLY when an object is sold as original or deeded to group
CHANGED_REGION Parameter of changed event handler used to indicate the region has changed
CHANGED_TELEPORT Parameter of changed event handler used to indicate teleport has completed
CHANGED_REGION_START Parameter of changed event handler used to indicate the region has been restarted
TYPE_INTEGER Indicates that the list entry is holding an integer
TYPE_FLOAT Indicates that the list entry is holding an float
@ -519,6 +521,9 @@ TEXTURE_DEFAULT UUID for the "Default Media" texture
TEXTURE_PLYWOOD UUID for the default "Plywood" texture
TEXTURE_TRANSPARENT UUID for the "White - Transparent" texture
URL_REQUEST_GRANTED Used with http_request when a public URL is successfully granted
URL_REQUEST_DENIED Used with http_request when a public URL is not available
# float constants
[word .3, .1, .5]
PI 3.1415926535897932384626433832795

View File

@ -172,6 +172,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
std::string owner_buf;
F32 mono_score = 0.f;
bool have_extended_data = false;
S32 public_urls = 0;
msg->getU32Fast(_PREHASH_ReportData, _PREHASH_TaskLocalID, task_local_id, block);
msg->getUUIDFast(_PREHASH_ReportData, _PREHASH_TaskID, task_id, block);
@ -186,6 +187,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
have_extended_data = true;
msg->getU32("DataExtended", "TimeStamp", time_stamp, block);
msg->getF32("DataExtended", "MonoScore", mono_score, block);
msg->getS32(_PREHASH_ReportData,"PublicURLs",public_urls,block);
}
LLSD element;
@ -216,6 +218,10 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
element["columns"][5]["column"] = "mono_time";
element["columns"][5]["value"] = llformat("%0.3f", mono_score);
element["columns"][5]["font"] = "SANSSERIF";
element["columns"][6]["column"] = "URLs";
element["columns"][6]["value"] = llformat("%d", public_urls);
element["columns"][6]["font"] = "SANSSERIF";
}
list->addElement(element);

View File

@ -10,6 +10,7 @@ include(LLMath)
include(LLMessage)
include(LLVFS)
include(LLXML)
include(LScript)
include(Linking)
include_directories(
@ -20,6 +21,7 @@ include_directories(
${LLINVENTORY_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}
)
set(test_SOURCE_FILES
@ -48,6 +50,7 @@ set(test_SOURCE_FILES
llquaternion_tut.cpp
llrandom_tut.cpp
llsaleinfo_tut.cpp
llscriptresource_tut.cpp
llsdmessagebuilder_tut.cpp
llsdmessagereader_tut.cpp
llsd_new_tut.cpp
@ -58,6 +61,7 @@ set(test_SOURCE_FILES
llstring_tut.cpp
lltemplatemessagebuilder_tut.cpp
lltiming_tut.cpp
lltranscode_tut.cpp
lltut.cpp
lluri_tut.cpp
lluuidhashmap_tut.cpp
@ -109,7 +113,9 @@ target_link_libraries(test
${LLMATH_LIBRARIES}
${LLVFS_LIBRARIES}
${LLXML_LIBRARIES}
${LSCRIPT_LIBRARIES}
${LLCOMMON_LIBRARIES}
${APRICONV_LIBRARIES}
${PTHREAD_LIBRARY}
${WINDOWS_LIBRARIES}
${DL_LIBRARY}

View File

@ -86,7 +86,8 @@ namespace tut
void result(const LLSD& result) { mResult = result; }
void status(S32 code, const std::string& message) { }
void extendedResult(S32 code, const std::string& message, const LLSD& headers) { }
private:
Response() {;} // Must be accessed through LLPointer.
};

View File

@ -0,0 +1,203 @@
/**
* @file llscriptresource_tut.cpp
* @brief Test LLScriptResource
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
* Copyright (c) 2006-2007, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlife.com/developers/opensource/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at http://secondlife.com/developers/opensource/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
//#include <tut/tut.h>
#include "linden_common.h"
#include "lltut.h"
#include "llscriptresource.h"
#include "llscriptresourceconsumer.h"
#include "llscriptresourcepool.h"
class TestConsumer : public LLScriptResourceConsumer
{
public:
TestConsumer()
: mUsedURLs(0)
{ }
// LLScriptResourceConsumer interface:
S32 getUsedPublicURLs() const
{
return mUsedURLs;
}
// Test details:
S32 mUsedURLs;
};
namespace tut
{
class LLScriptResourceTestData
{
};
typedef test_group<LLScriptResourceTestData> LLScriptResourceTestGroup;
typedef LLScriptResourceTestGroup::object LLScriptResourceTestObject;
LLScriptResourceTestGroup scriptResourceTestGroup("scriptResource");
template<> template<>
void LLScriptResourceTestObject::test<1>()
{
LLScriptResource resource;
U32 total = 42;
resource.setTotal(total);
ensure_equals("Verify set/get total", resource.getTotal(), total);
ensure_equals("Verify all resources are initially available",resource.getAvailable(),total);
// Requesting too many, releasing non-allocated
ensure("Request total + 1 resources should fail",!resource.request(total + 1));
ensure_equals("Verify all resources available after failed request",resource.getAvailable(),total);
ensure("Releasing resources when none allocated should fail",!resource.release());
ensure_equals("All resources should be available after failed release",resource.getAvailable(),total);
ensure("Request one resource", resource.request());
ensure_equals("Verify available resources after successful request",resource.getAvailable(),total - 1);
// Is this right? Or should we release all used resources if we try to release more than are currently used?
ensure("Release more resources than allocated",!resource.release(2));
ensure_equals("Verify resource availability after failed release",resource.getAvailable(),total - 1);
ensure("Release a resource",resource.release());
ensure_equals("Verify all resources available after successful release",resource.getAvailable(),total);
}
template<> template<>
void LLScriptResourceTestObject::test<2>()
{
LLScriptResource resource;
U32 total = 42;
resource.setTotal(total);
S32 resources_to_request = 30;
ensure("Get multiple resources resources",resource.request(resources_to_request));
ensure_equals("Verify available resources is correct after request of multiple resources",resource.getAvailable(), total - resources_to_request);
S32 resources_to_release = (resources_to_request / 2);
ensure("Release some resources",resource.release(resources_to_release));
S32 expected_available = (total - resources_to_request + resources_to_release);
ensure_equals("Verify available resources after release of some resources",resource.getAvailable(), expected_available);
resources_to_release = (resources_to_request - resources_to_release);
ensure("Release remaining resources",resource.release(resources_to_release));
ensure_equals("Verify available resources after release of remaining resources",resource.getAvailable(), total);
}
template<> template<>
void LLScriptResourceTestObject::test<3>()
{
LLScriptResource resource;
U32 total = 42;
resource.setTotal(total);
ensure("Request all resources",resource.request(total));
U32 low_total = 10;
ensure("Release all resources",resource.release(total));
ensure_equals("Verify all resources available after releasing",resource.getAvailable(),total);
resource.setTotal(low_total);
ensure_equals("Verify low total resources are available after set",resource.getAvailable(),low_total);
}
template<> template<>
void LLScriptResourceTestObject::test<4>()
{
S32 big_resource_total = 100;
S32 small_resource_total = 10;
LLScriptResourcePool big_pool;
big_pool.getPublicURLResource().setTotal(big_resource_total);
LLScriptResourcePool small_pool;
small_pool.getPublicURLResource().setTotal(small_resource_total);
TestConsumer consumer;
LLScriptResourcePool& initial_pool = consumer.getScriptResourcePool();
ensure("Initial resource pool is 'null'.", (&initial_pool == &LLScriptResourcePool::null));
consumer.switchScriptResourcePools(big_pool);
LLScriptResourcePool& get_pool = consumer.getScriptResourcePool();
ensure("Get resource that was set.", (&big_pool == &get_pool));
ensure_equals("No public urls in use yet.", consumer.getUsedPublicURLs(),0);
S32 request_urls = 5;
consumer.mUsedURLs = request_urls;
consumer.getScriptResourcePool().getPublicURLResource().request(request_urls);
ensure_equals("Available urls on big_pool is 5 less than total.",
big_pool.getPublicURLResource().getAvailable(), big_resource_total - request_urls);
ensure("Switching from big pool to small pool",
consumer.switchScriptResourcePools(small_pool));
ensure_equals("All resources available to big pool again",
big_pool.getPublicURLResource().getAvailable(), big_resource_total);
ensure_equals("Available urls on small pool is 5 less than total.",
small_pool.getPublicURLResource().getAvailable(), small_resource_total - request_urls);
ensure("Switching from small pool to big pool",
consumer.switchScriptResourcePools(big_pool));
consumer.getScriptResourcePool().getPublicURLResource().release(request_urls);
request_urls = 50; // Too many for the small_pool
consumer.mUsedURLs = request_urls;
consumer.getScriptResourcePool().getPublicURLResource().request(request_urls);
// Verify big pool has them
ensure_equals("Available urls on big pool is 50 less than total.",
big_pool.getPublicURLResource().getAvailable(), big_resource_total - request_urls);
// Verify can't switch to small_pool
ensure("Switching to small pool with too many resources",
!consumer.switchScriptResourcePools(small_pool));
// Verify big pool still accounting for used resources
ensure_equals("Available urls on big_pool is still 50 less than total.",
big_pool.getPublicURLResource().getAvailable(), big_resource_total - request_urls);
// Verify small pool still has all resources available.
ensure_equals("All resources in small pool are still available.",
small_pool.getPublicURLResource().getAvailable(), small_resource_total);
}
}

View File

@ -0,0 +1,94 @@
/**
* @file llscriptresource_tut.cpp
* @brief Test LLScriptResource
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
* Copyright (c) 2006-2007, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlife.com/developers/opensource/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at http://secondlife.com/developers/opensource/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
//#include <tut/tut.h>
#include "linden_common.h"
#include "lltut.h"
#include "../newsim/lltranscode.cpp" // include TU to pull in newsim implementation.
static const char test_utf8[] = "Edelwei\xc3\x9f";
static const char test_utf7[] = "Edelwei+AN8-";
static const char test_latin1[] = "Edelwei\xdf";
static const char test_latin2[] = "Edelwei\xdf";
namespace tut
{
class LLTranscodeTestData
{
};
typedef test_group<LLTranscodeTestData> LLTranscodeTestGroup;
typedef LLTranscodeTestGroup::object LLTranscodeTestObject;
LLTranscodeTestGroup transcodeTestGroup("transcode");
template<> template<>
void LLTranscodeTestObject::test<1>()
{
#if LL_WINDOWS
skip("Windows APR libs can't transcode.");
#endif
// Test utf8
std::stringstream input;
std::stringstream output;
input.str(test_utf7);
output.clear();
LLTranscode::transcode("charset=UTF-7", input, output);
ensure_equals("UTF-7 to UTF-8 transcoding", output.str(),
std::string(test_utf8));
input.str(test_latin1);
output.clear();
LLTranscode::transcode("", input, output);
ensure_equals("Default (latin_1) to UTF8 transcoding", output.str(),
std::string(test_utf8));
input.str(test_latin1);
output.clear();
LLTranscode::transcode("charset=iso-8859-1", input, output);
ensure_equals("latin_1 (ISO-8859-1) to UTF8 transcoding", output.str(),
std::string(test_utf8));
input.str(test_latin2);
output.clear();
LLTranscode::transcode("charset=iso-8859-2", input, output);
ensure_equals("latin_2 (ISO-8859-2) to UTF8 transcoding", output.str(),
std::string(test_utf8));
input.str(test_utf8);
output.clear();
LLTranscode::transcode("charset=utf-8", input, output);
ensure_equals("UTF8 to UTF8 transcoding", output.str(),
std::string(test_utf8));
}
}

View File

@ -51,6 +51,7 @@ namespace
{
mStatus = code;
}
virtual void extendedResult(S32 code, const std::string& message, const LLSD& headers) { }
S32 mStatus;
};
}