Pārlūkot izejas kodu

OSX/IOS partial support

Unknown 6 gadi atpakaļ
vecāks
revīzija
c34235a8f3
7 mainītis faili ar 213 papildinājumiem un 78 dzēšanām
  1. 6 6
      Quick.Chrono.pas
  2. 111 20
      Quick.Commons.pas
  3. 27 21
      Quick.Files.pas
  4. 28 6
      Quick.Log.pas
  5. 21 7
      Quick.SysInfo.pas
  6. 1 1
      Quick.Threads.pas
  7. 19 17
      Quick.Value.pas

+ 6 - 6
Quick.Chrono.pas

@@ -1,13 +1,13 @@
 { ***************************************************************************
 
-  Copyright (c) 2015-2018 Kike Pérez
+  Copyright (c) 2015-2019 Kike Pérez
 
   Unit        : Quick.Chrono
   Description : Chronometers time elapsed and estimated time to do a task
   Author      : Kike Pérez
-  Version     : 1.4
+  Version     : 1.5
   Created     : 27/08/2015
-  Modified    : 31/08/2018
+  Modified    : 20/01/2019
 
   This file is part of QuickLib: https://github.com/exilon/QuickLib
 
@@ -70,7 +70,7 @@ resourcestring
 
 type
 
-  {$IF Defined(ANDROID) OR Defined(LINUX)}
+  {$IF Defined(NEXTGEN) OR Defined(LINUX) OR Defined(OSX)}
   TLargeInteger = Int64;
   {$ENDIF}
 
@@ -193,7 +193,7 @@ begin
 end;
 
 procedure TChronometer.SetTickStamp(var lInt: TLargeInteger);
-{$IF Defined(POSIX) OR Defined(LINUX) AND NOT Defined(MACOS)}
+{$IF (Defined(POSIX) OR Defined(LINUX)) AND NOT Defined(MACOS)}
 var
   res: timespec;
 {$ENDIF}
@@ -205,7 +205,7 @@ begin
     {$IFDEF MACOS}
     lInt := Int64(AbsoluteToNanoseconds(mach_absolute_time) div 100);
     {$ENDIF}
-    {$IF defined(POSIX) OR Defined(LINUX)}
+    {$IF (Defined(POSIX) OR Defined(LINUX)) AND NOT Defined(MACOS)}
     clock_gettime(CLOCK_MONOTONIC, @res);
     lInt := (Int64(1000000000) * res.tv_sec + res.tv_nsec) div 100;
     {$ENDIF}

+ 111 - 20
Quick.Commons.pas

@@ -56,6 +56,20 @@ interface
     Androidapi.JNI.JavaTypes,
     Androidapi.JNI.GraphicsContentViewText,
     {$ENDIF}
+    {$IFDEF IOS}
+    iOSapi.UIKit,
+    Posix.SysSysctl,
+    Posix.StdDef,
+    iOSapi.Foundation,
+    Macapi.ObjectiveC,
+    Macapi.Helpers,
+    {$ENDIF}
+    {$IFDEF OSX}
+    Macapi.Foundation,
+    Macapi.Helpers,
+    FMX.Helpers.Mac,
+    Macapi.ObjectiveC,
+    {$ENDIF}
     DateUtils;
 
 type
@@ -724,6 +738,23 @@ function GetLoggedUserName : string;
   {$ENDIF}
 {$ENDIF}
 
+{$IFDEF IOS}
+function GetDeviceModel : String;
+var
+  size : size_t;
+  buffer : array of Byte;
+begin
+  sysctlbyname('hw.machine',nil,@size,nil,0);
+  if size > 0 then
+  begin
+    SetLength(buffer, size);
+    sysctlbyname('hw.machine',@buffer[0],@size,nil,0);
+    Result := UTF8ToString(MarshaledAString(buffer));
+  end
+  else Result := EmptyStr;
+end;
+{$ENDIF}
+
 function GetComputerName : string;
 {$IFDEF MSWINDOWS}
   var
@@ -741,7 +772,15 @@ function GetComputerName : string;
   end;
   {$ELSE} //Android gets model name
   begin
-    Result := JStringToString(TJBuild.JavaClass.MODEL);
+    {$IFDEF NEXTGEN}
+      {$IFDEF ANDROID}
+      Result := JStringToString(TJBuild.JavaClass.MODEL);
+      {$ELSE} //IOS
+      Result := GetDeviceModel;
+      {$ENDIF}
+    {$ELSE} //OSX
+    Result := NSStrToStr(TNSHost.Wrap(TNSHost.OCClass.currentHost).localizedName);
+    {$ENDIF}
   end;
   {$ENDIF}
 {$ENDIF}
@@ -867,16 +906,48 @@ end;
   end;
   {$ELSE}
     {$IFDEF NEXTGEN}
-    var
-      PkgInfo : JPackageInfo;
-    begin
-      PkgInfo := SharedActivity.getPackageManager.getPackageInfo(SharedActivity.getPackageName,0);
-      Result := IntToStr(PkgInfo.VersionCode);
-    end;
-    {$ELSE}
-    begin
-      Result := 'N/A';
-    end;
+      {$IFDEF ANDROID}
+      var
+        PkgInfo : JPackageInfo;
+      begin
+        PkgInfo := SharedActivity.getPackageManager.getPackageInfo(SharedActivity.getPackageName,0);
+        Result := IntToStr(PkgInfo.VersionCode);
+      end;
+      {$ELSE} //IOS
+      var
+        AppKey: Pointer;
+        AppBundle: NSBundle;
+        BuildStr : NSString;
+      begin
+        try
+          AppKey := (StrToNSStr('CFBundleVersion') as ILocalObject).GetObjectID;
+          AppBundle := TNSBundle.Wrap(TNSBundle.OCClass.mainBundle);
+          BuildStr := TNSString.Wrap(AppBundle.infoDictionary.objectForKey(AppKey));
+          Result := UTF8ToString(BuildStr.UTF8String);
+        except
+          Result := 'N/A';
+        end;
+      end;
+      {$ENDIF}
+    {$ELSE} //OSX
+      {$IFDEF OSX}
+      var
+        AppKey: Pointer;
+        AppBundle: NSBundle;
+        BuildStr : NSString;
+      begin
+        try
+          AppKey := (StrToNSStr('CFBundleVersion') as ILocalObject).GetObjectID;
+
+          AppBundle := TNSBundle.Wrap(TNSBundle.OCClass.mainBundle);
+          BuildStr := TNSString.Wrap(AppBundle.infoDictionary.objectForKey(AppKey));
+          Result := UTF8ToString(BuildStr.UTF8String);
+
+        except
+          Result := 'N/A';
+        end;
+      end;
+      {$ENDIF}
     {$ENDIF}
   {$ENDIF}
 {$ENDIF}
@@ -935,16 +1006,36 @@ end;
   end;
   {$ELSE}
     {$IFDEF NEXTGEN}
+      {$IFDEF ANDROID}
+      var
+        PkgInfo : JPackageInfo;
+      begin
+        PkgInfo := SharedActivity.getPackageManager.getPackageInfo(SharedActivity.getPackageName,0);
+        Result := JStringToString(PkgInfo.versionName);
+      end;
+      {$ELSE} //IOS
+      var
+        AppKey: Pointer;
+        AppBundle: NSBundle;
+        BuildStr : NSString;
+      begin
+        AppKey := (StrToNSStr('CFBundleVersion') as ILocalObject).GetObjectID;
+        AppBundle := TNSBundle.Wrap(TNSBundle.OCClass.mainBundle);
+        BuildStr := TNSString.Wrap(AppBundle.infoDictionary.objectForKey(AppKey));
+        Result := UTF8ToString(BuildStr.UTF8String);
+      end;
+      {$ENDIF}
+    {$ELSE} //OSX
     var
-      PkgInfo : JPackageInfo;
-    begin
-      PkgInfo := SharedActivity.getPackageManager.getPackageInfo(SharedActivity.getPackageName,0);
-      Result := JStringToString(PkgInfo.versionName);
-    end;
-    {$ELSE}
-    begin
-      Result := 'N/A';
-    end;
+        AppKey: Pointer;
+        AppBundle: NSBundle;
+        BuildStr : NSString;
+      begin
+        AppKey := (StrToNSStr('CFBundleVersion') as ILocalObject).GetObjectID;
+        AppBundle := TNSBundle.Wrap(TNSBundle.OCClass.mainBundle);
+        BuildStr := TNSString.Wrap(AppBundle.infoDictionary.objectForKey(AppKey));
+        Result := UTF8ToString(BuildStr.UTF8String);
+      end;
     {$ENDIF}
   {$ENDIF}
 {$ENDIF}

+ 27 - 21
Quick.Files.pas

@@ -1,13 +1,13 @@
 { ***************************************************************************
 
-  Copyright (c) 2016-2018 Kike Pérez
+  Copyright (c) 2016-2019 Kike Pérez
 
   Unit        : Quick.Files
   Description : Files functions
   Author      : Kike Pérez
-  Version     : 1.2
+  Version     : 1.4
   Created     : 09/03/2018
-  Modified    : 29/05/2018
+  Modified    : 21/01/2019
 
   This file is part of QuickLib: https://github.com/exilon/QuickLib
 
@@ -71,22 +71,25 @@ type
 
 
   {$IFNDEF FPC}
-  TTextFileOperation = (tfOpenRead,tfOpenOverwrite,tfOpenAppend);
-
-  TTextStreamFile = class
-    private
-      fReadStream : TStreamReader;
-      fWriteStream : TStreamWriter;
-      function GetEOF : Boolean;
-    public
-      constructor Create(const aFileName : string; aOpenMode : TTextFileOperation);
-      destructor Destroy; override;
-      function ReadLn: string; overload;
-      function ReadLn(out Data: string): Boolean; overload;
-      procedure WriteLn (const Data : string);
-      procedure Close;
-      property EOF: Boolean read GetEOF;
-  end;
+    TTextFileOperation = (tfOpenRead,tfOpenOverwrite,tfOpenAppend);
+
+    TTextStreamFile = class
+      private
+        fReadStream : TStreamReader;
+        fWriteStream : TStreamWriter;
+        function GetEOF : Boolean;
+      public
+        constructor Create(const aFileName : string; aOpenMode : TTextFileOperation);
+        destructor Destroy; override;
+        function ReadLn: string; overload;
+        function ReadLn(out Data: string): Boolean; overload;
+        procedure WriteLn (const Data : string);
+        procedure Close;
+        property EOF: Boolean read GetEOF;
+    end;
+    {$IF Defined(MACOS) OR Defined(NEXTGEN)}
+    TFileTime = LongInt;
+    {$ENDIF}
   {$ELSE}
     {$IFDEF LINUX}
     TFILETIME = LongInt;
@@ -214,7 +217,9 @@ type
   procedure SplitFile(const aFileName : string; aSplitByteSize : Int64);
   procedure MergeFiles(const aFirstSplitFileName, aOutFileName : string); overload;
   procedure MergeFiles(aFilenames : array of string; const aOutFileName : string); overload;
+  {$IFNDEF NEXTGEN}
   function IsFileInUse(const aFileName : string) : Boolean;
+  {$ENDIF}
   procedure FileReplaceText(const aFileName, aSearchText, AReplaceText : string);
   function FileSearchText(const aFileName, SearchText: string; caseSensitive : Boolean): Longint;
   function GetCreationTime(const aFilename : string): TDateTime;
@@ -382,11 +387,12 @@ begin
   {$ENDIF}
 end;
 
+{$IFNDEF NEXTGEN}
 class function TFile.IsInUse(const Path : string) : Boolean;
 begin
   Result := IsFileInUse(Path);
 end;
-
+{$ENDIF}
 
 class function TFile.GetSize(const Path : string) : Int64;
 var
@@ -743,7 +749,7 @@ begin
 end;
 
 function IsFileInUse(const aFileName : string) : Boolean;
-{$IFNDEF LINUX}
+{$IF NOT Defined(LINUX) AND NOT Defined(MACOS)}
 var
   HFileRes: HFILE;
 begin

+ 28 - 6
Quick.Log.pas

@@ -1,13 +1,13 @@
 { ***************************************************************************
 
-  Copyright (c) 2016-2018 Kike Pérez
+  Copyright (c) 2016-2019 Kike Pérez
 
   Unit        : Quick.Log
   Description : Threadsafe Log
   Author      : Kike Pérez
-  Version     : 1.18
+  Version     : 1.19
   Created     : 10/04/2016
-  Modified    : 08/04/2018
+  Modified    : 21/01/2019
 
   This file is part of QuickLib: https://github.com/exilon/QuickLib
 
@@ -47,7 +47,7 @@ uses
   {$ELSE}
   Quick.Files,
   {$ENDIF}
-  {$IFDEF LINUX}
+  {$IF Defined(NEXTGEN) OR Defined(LINUX) or Defined(MACOS)}
   syncObjs,
   {$ENDIF}
   SysUtils;
@@ -98,7 +98,11 @@ type
   end;
 
 var
+  {$IF Defined(MACOS) OR Defined(ANDROID)}
+  CS : TCriticalSection;
+  {$ELSE}
   CS : TRTLCriticalSection;
+  {$ENDIF}
   Log : TQuickLog;
 
 implementation
@@ -185,7 +189,9 @@ begin
     end;
   end;
   //Checks if it's in use
+  {$IF NOT Defined(MACOS) AND NOT Defined(ANDROID)}
   if (fCheckFileInUse) and (TFile.IsInUse(logname)) Then fLogFileName := Format('%s_(1).%s',[ExtractFileNameWithoutExt(logname),ExtractFileExt(logname)]);
+  {$ENDIF}
 
   //writes header info
   if fShowHeaderInfo then
@@ -233,7 +239,11 @@ var
 begin
   //Checks if need to add date to filename
   logname := GetLogFileName;
+  {$IF Defined(MACOS) OR Defined(ANDROID)}
+  CS.Enter;
+  {$ELSE}
   EnterCriticalSection(CS);
+  {$ENDIF}
   try
     cMsg := cMsg + #13#10;
     LEncoding:= TEncoding.Unicode;
@@ -279,7 +289,11 @@ begin
       //
     end;
   finally
+    {$IF Defined(MACOS) OR Defined(ANDROID)}
+    CS.Leave;
+    {$ELSE}
     LeaveCriticalSection(CS);
+    {$ENDIF}
   end;
 end;
 
@@ -292,14 +306,22 @@ initialization
 {$IF DEFINED(FPC) AND DEFINED(LINUX)}
 InitCriticalSection(CS);
 {$ELSE}
-InitializeCriticalSection(CS);
+  {$IF Defined(MACOS) OR Defined(ANDROID)}
+  CS := TCriticalSection.Create;
+  {$ELSE}
+  InitializeCriticalSection(CS);
+  {$ENDIF}
 {$ENDIF}
 
 finalization
 {$IF DEFINED(FPC) AND DEFINED(LINUX)}
 DoneCriticalsection(CS);
 {$ELSE}
-DeleteCriticalSection(CS);
+  {$IF Defined(MACOS) OR Defined(ANDROID)}
+  CS.Free;
+  {$ELSE}
+  DeleteCriticalSection(CS);
+  {$ENDIF}
 {$ENDIF}
 
 end.

+ 21 - 7
Quick.SysInfo.pas

@@ -1,13 +1,13 @@
 { ***************************************************************************
 
-  Copyright (c) 2016-2018 Kike Pérez
+  Copyright (c) 2016-2019 Kike Pérez
 
   Unit        : Quick.SysInfo
   Description : System Info functions
   Author      : Kike Pérez
-  Version     : 1.1
+  Version     : 1.2
   Created     : 17/05/2018
-  Modified    : 08/09/2018
+  Modified    : 21/01/2019
 
   This file is part of QuickLib: https://github.com/exilon/QuickLib
 
@@ -38,9 +38,15 @@ interface
 uses
   SysUtils,
   {$IFNDEF FPC}
-    {$IFDEF ANDROID}
+    {$IFDEF NEXTGEN}
     System.IOUtils,
-    Androidapi.Helpers,
+      {$IFDEF ANDROID}
+      Androidapi.Helpers,
+      {$ENDIF}
+      {$IFDEF IOS}
+      Macapi.CoreFoundation,
+      iOSApi.Foundation,
+      {$ENDIF}
     {$ENDIF}
   {$ENDIF}
   Quick.Commons;
@@ -80,7 +86,11 @@ begin
   {$IFNDEF NEXTGEN}
   fAppName := ExtractFilenameWithoutExt(ParamStr(0));
   {$ELSE}
-  fAppName := JStringToString(SharedActivityContext.getPackageName);
+    {$IFDEF ANDROID}
+    fAppName := JStringToString(SharedActivityContext.getPackageName);
+    {$ELSE}
+    fAppName := TNSString.Wrap(CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle, kCFBundleIdentifierKey)).UTF8String;
+    {$ENDIF}
   {$ENDIF}
   fAppVersion := GetAppVersionFullStr;
   {$IFNDEF NEXTGEN}
@@ -96,7 +106,11 @@ end;
 
 function TSystemInfo.GetOSVersion: string;
 begin
-  Result := {$IFDEF FPC}{$I %FPCTARGETOS%}+'-'+{$I %FPCTARGETCPU%}{$ELSE}TOSVersion.ToString{$ENDIF};
+  Result := {$IFDEF FPC}
+              {$I %FPCTARGETOS%}+'-'+{$I %FPCTARGETCPU%}
+            {$ELSE}
+            TOSVersion.ToString
+            {$ENDIF};
 end;
 
 initialization

+ 1 - 1
Quick.Threads.pas

@@ -7,7 +7,7 @@
   Author      : Kike Pérez
   Version     : 1.4
   Created     : 09/03/2018
-  Modified    : 16/01/2019
+  Modified    : 21/01/2019
 
   This file is part of QuickLib: https://github.com/exilon/QuickLib
 

+ 19 - 17
Quick.Value.pas

@@ -7,7 +7,7 @@
   Author      : Kike Pérez
   Version     : 1.4
   Created     : 07/01/2019
-  Modified    : 16/01/2019
+  Modified    : 21/01/2019
 
   This file is part of QuickLib: https://github.com/exilon/QuickLib
 
@@ -62,7 +62,7 @@ type
     property Value : string read GetValue write SetValue;
   end;
 
-  {$IFNDEF NEXTGEN}
+  {$IFDEF MSWINDOWS}
    IValueAnsiString = interface
    ['{75775F25-6F7A-49F0-A1E0-BDE1F55EC378}']
     function GetValue : AnsiString;
@@ -183,7 +183,7 @@ type
     {$ENDIF}
     fDataType : TValueDataType;
     function CastToString : string;
-    {$IFNDEF NEXTGEN}
+    {$IFDEF MSWINDOWS}
     function CastToAnsiString : AnsiString;
     function CastToWideString : WideString;
     {$ENDIF}
@@ -199,7 +199,7 @@ type
     function CastToVariant: Variant;
     function CastToCardinal : Cardinal;
     procedure SetAsString(const Value : string);
-    {$IFNDEF NEXTGEN}
+    {$IFDEF MSWINDOWS}
     procedure SetAsAnsiString(const Value : AnsiString);
     procedure SetAsWideString(const Value : WideString);
     {$ENDIF}
@@ -217,7 +217,7 @@ type
     constructor Create(const Value: TVarRec);
     property DataType : TValueDataType read fDataType;
     property AsString : string read CastToString write SetAsString;
-    {$IFNDEF NEXTGEN}
+    {$IFDEF MSWINDOWS}
     property AsAnsiString : AnsiString read CastToAnsiString write SetAsAnsiString;
     property AsWideString : WideString read CastToWideString write SetAsWideString;
     {$ENDIF}
@@ -268,7 +268,7 @@ begin
     case fDataType of
       dtNull : Result := '';
       dtString : Result := (fDataIntf as IValueString).Value;
-      {$IFNDEF NEXTGEN}
+      {$IFDEF MSWINDOWS}
       dtAnsiString : Result := string((fDataIntf as IValueAnsiString).Value);
       dtWideString : Result := (fDataIntf as IValueWideString).Value;
       {$ENDIF}
@@ -287,7 +287,7 @@ begin
   end;
 end;
 
-{$IFNDEF NEXTGEN}
+{$IFDEF MSWINDOWS}
 function TFlexValue.CastToAnsiString: AnsiString;
 begin
   try
@@ -316,7 +316,7 @@ begin
     case fDataType of
       dtNull : Result := '';
       dtString : Result := Widestring((fDataIntf as IValueString).Value);
-      {$IFNDEF NEXTGEN}
+      {$IFDEF MSWINDOWS}
       dtAnsiString : Result := Widestring((fDataIntf as IValueAnsiString).Value);
       dtWideString : Result := (fDataIntf as IValueWideString).Value;
       {$ENDIF}
@@ -341,7 +341,7 @@ begin
     case fDataType of
       dtNull : Result := False;
       dtString : Result := StrToBool((fDataIntf as IValueString).Value);
-      {$IFNDEF NEXTGEN}
+      {$IFDEF MSWINDOWS}
       dtAnsiString : Result := StrToBool(string((fDataIntf as IValueAnsiString).Value));
       dtWideString : Result := StrToBool((fDataIntf as IValueWideString).Value);
       {$ENDIF}
@@ -385,7 +385,7 @@ begin
     case fDataType of
       dtNull : Result := 0.0;
       dtString : Result := StrToDateTime((fDataIntf as IValueString).Value);
-      {$IFNDEF NEXTGEN}
+      {$IFDEF MSWINDOWS}
       dtAnsiString : Result := StrToDateTime(string((fDataIntf as IValueAnsiString).Value));
       dtWideString : Result := StrToDateTime((fDataIntf as IValueWideString).Value);
       {$ENDIF}
@@ -408,7 +408,7 @@ begin
     case fDataType of
       dtNull : Result := 0.0;
       dtString : Result := StrToFloat((fDataIntf as IValueString).Value);
-      {$IFNDEF NEXTGEN}
+      {$IFDEF MSWINDOWS}
       dtAnsiString : Result := StrToFloat(string((fDataIntf as IValueAnsiString).Value));
       dtWideString : Result := StrToFloat((fDataIntf as IValueWideString).Value);
       {$ENDIF}
@@ -432,7 +432,7 @@ begin
     case fDataType of
       dtNull : Result := 0;
       dtString : Result := StrToInt((fDataIntf as IValueString).Value);
-      {$IFNDEF NEXTGEN}
+      {$IFDEF MSWINDOWS}
       dtAnsiString : Result := StrToInt(string((fDataIntf as IValueAnsiString).Value));
       dtWideString : Result := StrToInt((fDataIntf as IValueWideString).Value);
       {$ENDIF}
@@ -519,13 +519,15 @@ begin
   case Value.VType of
     {$IFNDEF NEXTGEN}
     vtString : AsString := string(Value.VString^);
-    {$ENDIF}
     vtChar : AsString := string(Value.VChar);
-    {$IFNDEF NEXTGEN}
+    {$ENDIF}
+    {$IFDEF MSWINDOWS}
     vtAnsiString : AsAnsiString := AnsiString(Value.VAnsiString);
     vtWideString : AsWideString := WideString(Value.VWideString);
     {$ENDIF}
+    {$IFDEF UNICODE}
     vtUnicodeString: AsString := string(Value.VUnicodeString);
+    {$ENDIF UNICODE}
     vtInteger : AsInteger := Value.VInteger;
     vtInt64 : AsInt64 := Value.VInt64^;
     vtExtended : AsExtended := Value.VExtended^;
@@ -640,7 +642,7 @@ begin
   Result := fDataType = dtVariant;
 end;
 
-{$IFNDEF NEXTGEN}
+{$IFDEF MSWINDOWS}
 procedure TFlexValue.SetAsAnsiString(const Value: AnsiString);
 begin
   Clear;
@@ -726,7 +728,7 @@ begin
   fDataType := TValueDataType.dtVariant;
 end;
 
-{$IFNDEF NEXTGEN}
+{$IFDEF MSWINDOWS}
 procedure TFlexValue.SetAsWideString(const Value: WideString);
 begin
   Clear;
@@ -781,7 +783,7 @@ end;
 
 { TValueAnsiStringData }
 
-{$IFNDEF NEXTGEN}
+{$IFDEF MSWINDOWS}
 constructor TValueAnsiString.Create(const Value: AnsiString);
 begin
   fData := Value;