Results 1 to 12 of 12

Thread: WriteINI/ReadINI TStringArray?

  1. #1
    Join Date
    Aug 2007
    Location
    Colorado
    Posts
    7,421
    Mentioned
    268 Post(s)
    Quoted
    1442 Post(s)

    Default WriteINI/ReadINI TStringArray?

    I've a quick question: Is it currently possible to read & write a TStringArray? If nothing else I can just write & read multiple lines in a text document then merge them into an array but that's kinda sloppy, so if anyone has any better suggestions do tell. Please and thank you.

    Current projects:
    [ AeroGuardians (GotR minigame), Motherlode Miner, Blast furnace ]

    "I won't fall in your gravity. Open your eyes,
    you're the Earth and I'm the sky..."


  2. #2
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Either NULL terminate each string or double NULL terminate each string.. This technique is used in basic C serialization if binary isn't allowed.. You could use the NULL terminator as a delimiter. It isn't visible to the naked eye but can be viewed using a hex editor. This also makes it easy to read and allows the string to contain any characters.. Further optimisation can be done by storing the size of the array in the first chunk. This way, you only resize/setlength the read array once..


    Demo:
    Simba Code:
    Procedure WriteINIArray(const Section, KeyName, FileName: String; const StrArr: TStringArray);
    var
      I: Integer;
      Str: String;
    begin
      For I := 0 To High(StrArr) Do
        Str := Str + StrArr[I] + #0;

      WriteINI(Section, KeyName, ToStr(Length(StrArr)) + #0 + Str, FileName);
    end;

    Function ReadINIArray(const Section, KeyName, FileName: String): TStringArray;
    var
      Str: String;
      I, J, K, Size: Integer;
    Begin
      J := 0;
      I := 1;
      Str := ReadINI(Section, KeyName, FileName);
      While (Str[Inc(I)] <> #0) Do;

      Size := StrToIntDef(Copy(Str, 0, I), -1);
      If (Size > 0) Then
      Begin
        SetLength(Result, Size); //Optimisation..

        For Inc(I) To Length(Str)
          If (Str[I] <> #0) Then
            Result[J] := Result[J] + Str[I]
          Else
            Inc(J);
      End;
    End;

    var
      Arr: TStringArray;
    begin
      Arr := ['one', 'two', 'three', 'four', 'five'];
      WriteINIArray('Sector', 'Key', 'C:/Users/Brandon/Desktop/Test.INI', Arr);

      writeln(ReadINIArray('Sector', 'Key', 'C:/Users/Brandon/Desktop/Test.INI'));
    end.


    Results:

    Progress Report:
    [one, two, three, four, five]
    Successfully executed.
    Last edited by Brandon; 04-16-2014 at 04:49 AM.
    I am Ggzz..
    Hackintosher

  3. #3
    Join Date
    May 2012
    Location
    Moscow, Russia
    Posts
    661
    Mentioned
    35 Post(s)
    Quoted
    102 Post(s)

    Default

    Quote Originally Posted by Flight View Post
    I've a quick question: Is it currently possible to read & write a TStringArray? If nothing else I can just write & read multiple lines in a text document then merge them into an array but that's kinda sloppy, so if anyone has any better suggestions do tell. Please and thank you.
    Also you can use this method:

    Save:
    Simba Code:
    procedure WriteToFile3;
    var
    FileStream1: TFileStream;
    arrayString: Array of String;
    Len1, c: Cardinal;
    begin
    SetLength(arrayString, 4);
    arrayString[0] := 'First string in this Array';
    arrayString[1] := 'the Second Array string';
    arrayString[2] := 'String number three of this Array';
    arrayString[3] := 'this is the fourth String';

    FileStream1.init('D:\arraystr.msf',
                     $FF00 or $0001 or $0020);

    try
      c := Length(arrayString);
      FileStream1.WriteBuffer(c, SizeOf(c));
      FOR c := 0 to High(arrayString) do
        begin
        Len1 := Length(arrayString[c]);
        FileStream1.WriteBuffer(Len1, SizeOf(Len1));
        if Len1 > 0 then
        FileStream1.WriteBuffer(arrayString[c][1], Len1);
        end;
      finally
      FileStream1.Free;
      end;
    end;

    Load:
    Simba Code:
    procedure ReadFromFile3;
      var
      FileStream1: TFileStream;
      arrayString: Array of String;
      Len1, c: Cardinal;

    begin
    FileStream1.Init('D:\arraystr.msf',
                     $0000 or $0020);
    try
      FileStream1.ReadBuffer(Len1, SizeOf(Len1));
      if (Len1 = 0) or (Len1 > 1000) then Exit;
      SetLength(arrayString, Len1);
      FOR c := 0 to Len1-1 do
        begin
        FileStream1.ReadBuffer(Len1, SizeOf(Len1));
        if Len1 > 2048 then Exit;
        SetLength(arrayString[c], Len1);
        FileStream1.ReadBuffer(arrayString[c][1], Len1);
        end;
      finally
      FileStream1.Free;;
      end;
    WriteLn(arrayString[0]);
    WriteLn(arrayString[High(arrayString)]);
    end;

    And you can read more about the file reading/writing here
    Per aspera ad Astra!
    ----------------------------------------
    Slow and steady wins the race.

  4. #4
    Join Date
    Aug 2007
    Location
    Colorado
    Posts
    7,421
    Mentioned
    268 Post(s)
    Quoted
    1442 Post(s)

    Default

    Thanks a million Brandon. I'll give that a shot, even though most of what you said makes no sense to me, haha.

    Thank you for that as well CynicRus, I'll definitely take a look at it.
    Last edited by Flight; 04-16-2014 at 07:25 AM.

    Current projects:
    [ AeroGuardians (GotR minigame), Motherlode Miner, Blast furnace ]

    "I won't fall in your gravity. Open your eyes,
    you're the Earth and I'm the sky..."


  5. #5
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    @CynicRus; +1 for binary serialisation. Had no clue you could do that in Simba without doing it manually. @Op, you should use that.
    I am Ggzz..
    Hackintosher

  6. #6
    Join Date
    Aug 2007
    Location
    Colorado
    Posts
    7,421
    Mentioned
    268 Post(s)
    Quoted
    1442 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    @CynicRus; +1 for binary serialisation. Had no clue you could do that in Simba without doing it manually. @Op, you should use that.
    I would be happy to but what I like about the default Read/WriteINI is the Section & KeyName. I'd like the same simplicity but instead of a single string assigned to KeyName I'd like to write & read an array; exactly what you posted before.

    CynicRus, would would be the advantages of using your method over Brandon's example posted above?

    Current projects:
    [ AeroGuardians (GotR minigame), Motherlode Miner, Blast furnace ]

    "I won't fall in your gravity. Open your eyes,
    you're the Earth and I'm the sky..."


  7. #7
    Join Date
    May 2012
    Location
    Moscow, Russia
    Posts
    661
    Mentioned
    35 Post(s)
    Quoted
    102 Post(s)

    Default

    Well, you just take your array and save it in binary stream. Instead TFileStream, you can use TSringStream or TMemoryStream. Or you can create your own file format. Using binary delimiters.
    Per aspera ad Astra!
    ----------------------------------------
    Slow and steady wins the race.

  8. #8
    Join Date
    May 2012
    Location
    Moscow, Russia
    Posts
    661
    Mentioned
    35 Post(s)
    Quoted
    102 Post(s)

    Default

    Per aspera ad Astra!
    ----------------------------------------
    Slow and steady wins the race.

  9. #9
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    @Flight; I'm not sure there is a "advantage" in Simba itself but if you are interfacing with another language or plan on communicating with another API, then binary serialization IS beneficial.


    For example, in that link Cynic linked above, you could easily just write the Bitmap string to the file and when reading it back, you do BitmapFromString.. However, instead of doing that, he chose to write every pixel to the file in binary format. Advantage there is that someone else can just read the pixels from any language/api and be able to use the image too without having to write Simba's internal algorithm for interpreting bitmap strings.. If you can guarantee that this information isn't used by anything other than your script and no other programs, then there is little advantage to binary serialisation.

    That is the advantage. Simba-wise, there isn't "much" but there is a little bit. One such advantage is that reading is simply the opposite of writing.

    If you noticed in my example, writing is way easier than reading. Writing is a couple lines long but reading requires a bit extra work. With binary serialisation, the way you write is the exact same way you read. It's also good for POD structures (Plain Old Datatypes)..


    Write one byte, read one byte. Write one int, read one int, etc.. - Binary Serialisation.

    Write a one byte, delimit, write another, delimit. Write one int, delimit, write another.
    Read until each delimiter is reached, reinterpret that data as the correct type, rinse and repeat. - Plain Serialisation.

    Binary can be smaller in terms of bytes and is native. Example: 0xFF is 255 in binary. It takes up 1 byte. 255 in plain-text is 3 bytes aka 3 digits. Binary require more knowledge of language and bytes and structure.

    That is the differences. Whether it is an advantage in Simba is highly debatable because there isn't any interfacing or outside communication going on.

    Just choose whichever suits your needs.. There isn't really a right or wrong.

    http://stackoverflow.com/questions/2...text-protocols
    Last edited by Brandon; 04-16-2014 at 08:25 PM.
    I am Ggzz..
    Hackintosher

  10. #10
    Join Date
    Aug 2007
    Location
    Colorado
    Posts
    7,421
    Mentioned
    268 Post(s)
    Quoted
    1442 Post(s)

    Default

    Thanks very much for your input and explanation Brandon. Actually the task I'm doing is quite simple, just reading & writing strings (and string arrays) to & from a text file . So I imagine the examples you first posted would work just fine.

    Current projects:
    [ AeroGuardians (GotR minigame), Motherlode Miner, Blast furnace ]

    "I won't fall in your gravity. Open your eyes,
    you're the Earth and I'm the sky..."


  11. #11
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    I guess im a little late to the party but what I did with my SS fighter was save a tstringarray of uptext like so

    Simba Code:
    ['ave^rawl^raw']

    I replace that '' with ^

    And convert it back to a string array like

    Simba Code:
    function string.toStringArray():TStringArray;
    var
      strArr:TStringArray;
      strArrPtr: ^String;
      i, len:integer;
    begin
      self := Replace(self, ']', '', [rfReplaceAll]);
      self := Replace(self, '[', '', [rfReplaceAll]);
      strArr := explode('^', self);
      len := length(strArr);
      setLength(result, len);
      strArrPtr := @strArr[0];
      for i := 0 to (len - 1) do
        result[i] := strArrPtr[i]^;
    end;


    Above is probably better what w/e thought id throw my 2 cents in

  12. #12
    Join Date
    Aug 2007
    Location
    Colorado
    Posts
    7,421
    Mentioned
    268 Post(s)
    Quoted
    1442 Post(s)

    Default

    Quote Originally Posted by Robert View Post
    I guess im a little late to the party but what I did with my SS fighter was save a tstringarray of uptext like so

    Simba Code:
    ['ave^rawl^raw']

    I replace that '' with ^
    Yep I thought about doing something similar, saving a single string to a file, separating strings by certain character and parsing it Simba-side; nothing wrong with that. Thanks for the suggestion, Robert.

    Current projects:
    [ AeroGuardians (GotR minigame), Motherlode Miner, Blast furnace ]

    "I won't fall in your gravity. Open your eyes,
    you're the Earth and I'm the sky..."


Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •