Example #1
0
  // Uses GDI+ to fill the LOGFONT structure. This is computationally expensive
  //   but easy to get right. However it doesn't handle some fonts like Terminal.
  //   font_size is in units of tenths of point size. i.e. 100 is a 10 point font
  bool get_logfont(const tstring & font_name, int font_size, LOGFONT * lf) {
    Bitmap b(1, 1);
    Graphics g(&b);

    FontFamily font_family(WideBuffer(font_name.c_str()));
    const FontFamily * ff = &font_family;
    if (!font_family.IsAvailable()) 
      return false;
    Gdiplus::Font font(ff, static_cast<REAL>(font_size) / POINT_SIZE_SCALE);
    if (!font.IsAvailable()) 
      return false;
      
    #ifdef UNICODE
      font.GetLogFontW(&g, lf);
    #else
      font.GetLogFontA(&g, lf);
    #endif
    return true;
  }
Example #2
0
bool FPerfCounters::Tick(float DeltaTime)
{
	// if we didn't get a socket, don't tick
	if (Socket == nullptr)
	{
		return false;
	}

	// accept any connections
	static const FString PerfCounterRequest = TEXT("FPerfCounters Request");
	FSocket* IncomingConnection = Socket->Accept(PerfCounterRequest);
	if (IncomingConnection)
	{
		// make sure this is non-blocking
		bool bSuccess = false;
		IncomingConnection->SetNonBlocking(true);

		// read any data that's ready
		// NOTE: this is not a full HTTP implementation, just enough to be usable by curl
		uint8 Buffer[2*1024] = { 0 };
		int32 DataLen = 0;
		if (IncomingConnection->Recv(Buffer, sizeof(Buffer)-1, DataLen, ESocketReceiveFlags::None))
		{
			// scan the buffer for a line
			FUTF8ToTCHAR WideBuffer(reinterpret_cast<const ANSICHAR*>(Buffer));
			const TCHAR* BufferEnd = FCString::Strstr(WideBuffer.Get(), TEXT("\r\n"));
			if (BufferEnd != nullptr)
			{
				// crack into pieces
				FString MainLine(BufferEnd - WideBuffer.Get(), WideBuffer.Get());
				TArray<FString> Tokens;
				MainLine.ParseIntoArrayWS(Tokens);
				if (Tokens.Num() >= 2)
				{
					FString Body;
					int ResponseCode = 200;

					// handle the request
					if (Tokens[0] != TEXT("GET"))
					{
						Body = FString::Printf(TEXT("{ \"error\": \"Method %s not allowed\" }"), *Tokens[0]);
						ResponseCode = 405;
					}
					else if (Tokens[1] == TEXT("/stats"))
					{
						Body = ToJson();
					}
					else
					{
						Body = FString::Printf(TEXT("{ \"error\": \"%s not found\" }"), *Tokens[1]);
						ResponseCode = 404;
					}

					// send the response headers
					FString Header = FString::Printf(TEXT("HTTP/1.0 %d\r\nContent-Length: %d\r\nContent-Type: application/json\r\n\r\n"), ResponseCode, Body.Len());
					if (SendAsUtf8(IncomingConnection, Header) && SendAsUtf8(IncomingConnection, Body))
					{
						bSuccess = true;
					}
				}
			}
		}

		// log if we didn't succeed
		if (!bSuccess)
		{
			UE_LOG(LogPerfCounters, Warning, TEXT("FPerfCounters was unable to send a JSON response (or sent partial response)"));
		}

		// close the socket (whether we processed or not
		IncomingConnection->Close();
		ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(IncomingConnection);
	}

	// keep ticking
	return true;
}
bool FPerfCounters::ProcessRequest(uint8* Buffer, int32 BufferLen, FResponse& Response)
{
	bool bSuccess = false;

	// scan the buffer for a line
	FUTF8ToTCHAR WideBuffer(reinterpret_cast<const ANSICHAR*>(Buffer));
	const TCHAR* BufferEnd = FCString::Strstr(WideBuffer.Get(), TEXT("\r\n"));
	if (BufferEnd != nullptr)
	{
		// crack into pieces
		FString MainLine(BufferEnd - WideBuffer.Get(), WideBuffer.Get());
		TArray<FString> Tokens;
		MainLine.ParseIntoArrayWS(Tokens);
		if (Tokens.Num() >= 2)
		{
			FString ContentType(TEXT("application/json"));
			Response.Code = 200;

			// handle the request
			if (Tokens[0] != TEXT("GET"))
			{
				Response.Body = FString::Printf(TEXT("{ \"error\": \"Method %s not allowed\" }"), *Tokens[0]);
				Response.Code = 405;
			}
			else if (Tokens[1].StartsWith(TEXT("/stats")))
			{
				Response.Body = GetAllCountersAsJson();
			}
			else if (Tokens[1].StartsWith(TEXT("/exec?c=")))
			{
				FString ExecCmd = Tokens[1].Mid(8);
				FString ExecCmdDecoded = FPlatformHttp::UrlDecode(ExecCmd);

				FStringOutputDevice StringOutDevice;
				StringOutDevice.SetAutoEmitLineTerminator(true);

				bool bResult = false;
				if (ExecCmdCallback.IsBound())
				{
					bResult = ExecCmdCallback.Execute(ExecCmdDecoded, StringOutDevice);
					Response.Body = StringOutDevice;
					ContentType = TEXT("text/text");
				}
				else
				{
					Response.Body = FString::Printf(TEXT("{ \"error\": \"exec handler not found\" }"));
				}

				Response.Code = bResult ? 200 : 404;
			}
			else
			{
				Response.Body = FString::Printf(TEXT("{ \"error\": \"%s not found\" }"), *Tokens[1]);
				Response.Code = 404;
			}

			// send the response headers
			Response.Header = FString::Printf(TEXT("HTTP/1.0 %d\r\nContent-Length: %d\r\nContent-Type: %s\r\n\r\n"), Response.Code, Response.Body.Len(), *ContentType);
			bSuccess = true;
		}
		else
		{
			UE_LOG(LogPerfCounters, Warning, TEXT("Unable to parse HTTP request header: %s"), *MainLine);
		}
	}
	else
	{
		UE_LOG(LogPerfCounters, Warning, TEXT("Unable to immediately receive full request header"));
	}

	return bSuccess;
}