Hi guys

For what it's worth I did also test it using TFileStream. I have now found and fixed the bug in the import code (not dealing with a NULL value in the XML file correctly) and it is working like a charm.

I also agree with Joylon with regards to TStringStream, it should work like 'String' i.e. always UTF-16 all the time and coverted (if reqd) when reading or writing.

Cheers
Rob

On 10/08/2016 10:21 AM, Jolyon Direnko-Smith wrote:
@Todd

The input stream is not what needs to be saved. It is the result of *encoding* the stream that needs to be saved, which in the code is available as a string (since that is the final result required by the function). Unless you are going to use file handling primitives (Assign / ResetFile etc) you need something to provide the file handling to get that string onto disc in UTF8 form.

You /could/ use a file stream for that but you would need to separately convert the string to a UTF8 buffer before Write()ing it to that stream, introducing multiple opportunities to aim the trigger at your own leg appendage. :)

You /could/ use a string stream. Interestingly though, as far as I can tell in this case you don't get a BOM in the output file and can't get one unless you explicitly write it there first yourself (adding much more complexity), so if you actually need/want a BOM this isn't easily adaptable to provide that. As I understand it, the BOM wasn't actually the problem in Robert's case, rather the assumption that there *wasn't* a BOM was the only problem.

An encoded string stream is also a bit of a mess to get your head around. The encoding specified in the constructor determines the encoding of the bytes backing the storage of the "string". i.e. it isn't really a "StringStream" at all since this (to me) means a stream(able) "string", i.e. (in 2009+) UTF16. Before Delphi 2009 this is what it would have been, except in that case an ANSI string.

Rather, as implemented, it's a "CharacterStream". A byte stream holding a sequence of characters in some arbitrary encoding.

imho it would be more intuitive for a T/String/Stream to be a *stream* containing a *String *and instead of an Encoding property (unnecessary since it would always be UTF16 internally) have an Encoding parameter on the I/O methods etc. Just as a T/String/List is a *list* of *String*(s) which you Encode/Decode as necessary for any I/O.

Even if you did use a string stream it wouldn't be any/much simpler than the string list version (and if that lack of BOM in any output file does actually cause a problem then it's a non-starter anyway).


Which leaves... a stringlist as the simplest and most flexible option. You might choose one of the more complex options for a more robust implementation, but imho that would be overkill for a quick diagnostic facility.

:)


On 10 August 2016 at 09:31, Todd Martin <[email protected] <mailto:[email protected]>> wrote:

    @Jolyon
    The memory steam could have been simply copied to a TFilestream
    for that.

    Todd


    On 10 Aug 2016 8:38 a.m., "Jolyon Direnko-Smith"
    <[email protected] <mailto:[email protected]>> wrote:

        @Todd - looking at the code I suspect that the stringlist is
        in there as a temporary facility to dump the encoded data to a
        file for inspection/diagnostics (the function returns the
        encoded string as it's result as well as writing it out to a
        file using a string list for convenience).

        I think in this case, the BOM behaviour of a string list has
        caused a bit of Heisenbergnostics - the thing observing the
        thing has changed the thing.  :)

        Using a file/string stream to output the resulting string
        might have avoided introducing the BOM complication, but if
        this is a temporary diagnostic facility, and if it is the BOM
        which is the problem, then just turning off the BOM facility
        on the string list does the job just as nicely.

        :)

        On 9 August 2016 at 18:35, Todd Martin
        <[email protected] <mailto:[email protected]>>
        wrote:

            Why are you using a TStringlist at all?

            If you're encoding to Base64, encoding to UTF8 is meaningless.

            Todd


            On 9 Aug 2016 5:54 p.m., "Peter Ingham"
            <[email protected]
            <mailto:[email protected]>> wrote:

                If you look at the output file in a hex editor, what
                do you see?

                If the first 3 bytes are |0xEF,0xBB,0xBF, then that is
                a "Byte Order Mark".|

                |UTF-8 is a method for encoding UNICODE characters
                using 8-Bit Bytes.|

                |A file containing 7-Bit ASCII (high-order bit of
                every character zero), when converted to UTF-8 is
                likely to look||| very similar.  For anything else,
                all bets are off. Treating them as universally
                equivalent is asking for trouble.

                Many text editors will look for Byte Order marks (of
                varying types) and use them without displaying them
                (e.g: see
                https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
                <https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8>).


                Regards

                On 9/08/2016 5:01 p.m., Robert Martin wrote:
                Hi guys


                I have been struggling to get some basic Mime encoding working, 
I have
                the following code which I use to Mime64 Encode a picture 
contained in a
                TImage component....

                              Base64 := TMime64.create;
                              try
                                      MemoryStream := TMemoryStream.Create;
                                      MemoryStream.Position := 0;
                Image.Picture.Graphic.SaveToStream(MemoryStream);

                                      ReportImage.ImageMime   :=
                Base64.Encode_New(MemoryStream);
                              .....

                Function shown below...



                function TMime64.Encode_New(aSourceStream: TMemoryStream): 
String;
                var
                      IdEncoderMIME       : TIdEncoderMIME;
                      Sl                  : TStringList;
                begin
                      Result := '';
                      try

                          IdEncoderMIME := TIdEncoderMIME.Create(nil);
                          sl := TStringList.Create;
                          try
                              aSourceStream.Position := 0;
                              Result := 
IdEncoderMIME.EncodeStream(aSourceStream);

                              sl.Text := Result;
                              sl.SaveToFile('d:\d\a.txt', TEncoding.UTF8);
                          finally
                              IdEncoderMIME.Free;
                              sl.Free;
                          end;
                      except
                          on E : Exception do begin
                              raise EMimeError.Create(E.Message);
                          end;
                      end;
                end;

                The issue is that when I try to save the results in a UTF8 
formatted
                file (the destination is to be a UTF-8 formatted XML file), 
there are
                'bad' characters in the file which are invisible in Notepad++ 
but are
                present.

                If I save without specifying the file encoding (
                sl.SaveToFile('d:\d\a.txt') instead of 
sl.SaveToFile('d:\d\a.txt',
                TEncoding.UTF8)   ) I have what appears to be a clean ASCII 
file. My
                understanding is that ASCII characters have the same byte value 
(0-127)
                in an ASCII formatted file or a UTF-8 formatted file so I don't
                understand why the values would change.

                Any suggestions.


                p.s. I have to be able to save the file as UTF-8 because that 
is what
                the destination XML is encoded in.  Currently it is 'corrupt' 
because of
                the 'bad' characters.

                p.p.s TIdEncoderMIME.EncodeStream returns a String.  I am using 
Delphi Xe2.

                p.p.p.s I know it is something stupid I am doing !




                Thanks
                Rob


                _______________________________________________
                NZ Borland Developers Group - Delphi mailing list
                Post:[email protected]
                <mailto:[email protected]>
                Admin:http://delphi.org.nz/mailman/listinfo/delphi
                <http://delphi.org.nz/mailman/listinfo/delphi>
                Unsubscribe: send an email 
[email protected]
                <mailto:[email protected]>  with Subject: 
unsubscribe

                _______________________________________________ NZ
                Borland Developers Group - Delphi mailing list Post:
                [email protected]
                <mailto:[email protected]> Admin:
                http://delphi.org.nz/mailman/listinfo/delphi
                <http://delphi.org.nz/mailman/listinfo/delphi>
                Unsubscribe: send an email to
                [email protected]
                <mailto:[email protected]> with
Subject: unsubscribe
            _______________________________________________ NZ Borland
            Developers Group - Delphi mailing list Post:
            [email protected]
            <mailto:[email protected]> Admin:
            http://delphi.org.nz/mailman/listinfo/delphi
            <http://delphi.org.nz/mailman/listinfo/delphi>
            Unsubscribe: send an email to
            [email protected]
            <mailto:[email protected]> with
Subject: unsubscribe
        _______________________________________________ NZ Borland
        Developers Group - Delphi mailing list Post:
        [email protected]
        <mailto:[email protected]> Admin:
        http://delphi.org.nz/mailman/listinfo/delphi
        <http://delphi.org.nz/mailman/listinfo/delphi> Unsubscribe:
        send an email to [email protected]
        <mailto:[email protected]> with Subject:
unsubscribe
    _______________________________________________ NZ Borland
    Developers Group - Delphi mailing list Post:
    [email protected] <mailto:[email protected]>
    Admin: http://delphi.org.nz/mailman/listinfo/delphi
    <http://delphi.org.nz/mailman/listinfo/delphi> Unsubscribe: send
    an email to [email protected]
    <mailto:[email protected]> with Subject:
unsubscribe
_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: [email protected]
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to [email protected] with 
Subject: unsubscribe

No virus found in this message. Checked by AVG - www.avg.com <http://www.avg.com> Version: 2016.0.7690 / Virus Database: 4633/12782 - Release Date: 08/09/16

_______________________________________________
NZ Borland Developers Group - Delphi mailing list
Post: [email protected]
Admin: http://delphi.org.nz/mailman/listinfo/delphi
Unsubscribe: send an email to [email protected] with 
Subject: unsubscribe

Reply via email to