Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus-es / 2009-10

comportamiento erratico de TBase64EncodingStream

10 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Rafael Bidegain

Hola!

una vez mas, les pido una opinion para que me ayuden a comprender que estoy haciendo mal.

tengo un formulario con (use base64 adem�s de lo usual) en el formulario tengo dos componentes TMemo y un boton en el primer tmemo el texto cargado es Memo1 (el valor por defecto) en el segundo tmemo tambi�n tiene el valor por defecto.

en el bot�n tengo el siguiente c�digo

procedure TForm1.Button1Click(Sender: TObject);
var
buffer       : TMemoryStream;
EncodeStream : TBase64EncodingStream;
begin
     buffer := TMemoryStream.create();
     EncodeStream := TBase64EncodingStream.Create(buffer);
     Memo1.Lines.SaveToStream(buffer);
     buffer.position := 0;
     EncodeStream.Write(buffer, buffer.size);
     buffer.position := 0;
     Memo2.Lines.LoadFromStream(buffer);
     EncodeStream.free;
     buffer.free;
end;

el problema est� en que cada vez que presiono el bot�n obtengo un valor distinto.
por ejemplo estos:

wHGkt4CZ
gHSkt4CZ
gHWkt4CZ
AHakt4CZ
wHSkt4CZ

he notado que algunas veces los valores que se repiten son solo tres...

Rafael Bidegain Ya que los cuerdos no hablan, hablar� el loco. (The Fool, Padraic Pearse)

Reply by email

Carlos German Tejero
to Rafael Bidegain

He probado montones de formas, pero de todas me da dos resultados, debe ser un error o hay algo que no entiendo. Esta es la ultima forma que probe:

procedure TForm1.Button1Click(Sender: TObject);
var
buffer1       : TStringStream;
buffer2       : TStringStream;
EncodeStream : TBase64EncodingStream;
begin
    buffer1 := TStringStream.create('');
    buffer2 := TStringStream.create('');
    EncodeStream := TBase64EncodingStream.Create(buffer1);
    buffer2.WriteString(Utf8ToAnsi(Memo1.Lines.Text));
    buffer2.Position := 0;
    EncodeStream.Write(buffer2, buffer2.size);
    buffer1.Position := 0;
    Memo2.Lines.Text := AnsiToUtf8(buffer1.DataString);
    EncodeStream.free;
    buffer1.free;
    buffer2.free;
end;

para la cadena 'carlos germ�n tejero' me produce:

kO8TAHDvEwBoPh0A6EkdACj08AH0
cO8TAJDvEwBoPh0A6EkdACj08AH0

de forma intermitente. Siempre cambia el primer y el sexto caracter. Suena raro. Puedes reportarlo en la lista en ingles a ver si alguien aporta algo mas.

Saludos.

El 3 de octubre de 2009 00:09, Rafael Bidegain <r.bidegain en gmail.com>escribi�:

Show quoted text 56 lines
Hola! una vez mas, les pido una opinion para que me ayuden a comprender que estoy haciendo mal. tengo un formulario con (use base64 adem�s de lo usual) en el formulario tengo dos componentes TMemo y un boton en el primer tmemo el texto cargado es Memo1 (el valor por defecto) en el segundo tmemo tambi�n tiene el valor por defecto. en el bot�n tengo el siguiente c�digo procedure TForm1.Button1Click(Sender: TObject); var buffer : TMemoryStream; EncodeStream : TBase64EncodingStream; begin buffer := TMemoryStream.create(); EncodeStream := TBase64EncodingStream.Create(buffer); Memo1.Lines.SaveToStream(buffer); buffer.position := 0; EncodeStream.Write(buffer, buffer.size); buffer.position := 0; Memo2.Lines.LoadFromStream(buffer); EncodeStream.free; buffer.free; end; el problema est� en que cada vez que presiono el bot�n obtengo un valor distinto. por ejemplo estos: wHGkt4CZ gHSkt4CZ gHWkt4CZ AHakt4CZ wHSkt4CZ he notado que algunas veces los valores que se repiten son solo tres... -- Rafael Bidegain Ya que los cuerdos no hablan, hablar� el loco. (The Fool, Padraic Pearse) _______________________________________________ Lazarus-es mailing list Lazarus-es en lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es
Carlos Germ�n Tejero ------------ pr�xima parte ------------ Se ha borrado un adjunto en formato HTML... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus-es/attachments/20091003/6f9aff69/attachment.html>

Reply by email

Carlos German Tejero
to Rafael Bidegain: Hola! una vez mas, les pido una opinion para que me ayuden a comprender que estoy…

Ahora si, leyendo los ejemplos del paquete fcl-base, entendi el funcionamiento:

procedure TForm1.Button1Click(Sender: TObject);
var
IsEnd:boolean;
buffer1       : TStringStream;
buffer2       : TStringStream;
EncodeStream : TBase64EncodingStream;
begin
    buffer1 := TStringStream.create('');
    buffer2 := TStringStream.create('');
    EncodeStream := TBase64EncodingStream.Create(buffer1);
    buffer2.WriteString(Utf8ToAnsi(Memo1.Lines.Text));
    IsEnd := False;
    buffer2.Position := 0;
    //EncodeStream.Write(buffer2, buffer2.size);
    while not IsEnd do
    try
      EncodeStream.WriteByte(Buffer2.ReadByte);
    except
      on e: EStreamError do
        IsEnd := True;
    end;
    buffer1.Position := 0;
    Memo2.Lines.Text := AnsiToUtf8(buffer1.DataString);
    EncodeStream.free;
    buffer1.free;
    buffer2.free;
end;

Aparecera una excepcion EStreamError cuando alcance el fin del stream, no te hagas problema y dale continuar y veras por fin el resultado. Se puede hacer de otras formas, este es un buen comienzo.

Saludos.

El 3 de octubre de 2009 00:09, Rafael Bidegain <r.bidegain en gmail.com>escribi�:

Show quoted text 56 lines
Hola! una vez mas, les pido una opinion para que me ayuden a comprender que estoy haciendo mal. tengo un formulario con (use base64 adem�s de lo usual) en el formulario tengo dos componentes TMemo y un boton en el primer tmemo el texto cargado es Memo1 (el valor por defecto) en el segundo tmemo tambi�n tiene el valor por defecto. en el bot�n tengo el siguiente c�digo procedure TForm1.Button1Click(Sender: TObject); var buffer : TMemoryStream; EncodeStream : TBase64EncodingStream; begin buffer := TMemoryStream.create(); EncodeStream := TBase64EncodingStream.Create(buffer); Memo1.Lines.SaveToStream(buffer); buffer.position := 0; EncodeStream.Write(buffer, buffer.size); buffer.position := 0; Memo2.Lines.LoadFromStream(buffer); EncodeStream.free; buffer.free; end; el problema est� en que cada vez que presiono el bot�n obtengo un valor distinto. por ejemplo estos: wHGkt4CZ gHSkt4CZ gHWkt4CZ AHakt4CZ wHSkt4CZ he notado que algunas veces los valores que se repiten son solo tres... -- Rafael Bidegain Ya que los cuerdos no hablan, hablar� el loco. (The Fool, Padraic Pearse) _______________________________________________ Lazarus-es mailing list Lazarus-es en lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es
Carlos Germ�n Tejero ------------ pr�xima parte ------------ Se ha borrado un adjunto en formato HTML... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus-es/attachments/20091003/8509f524/attachment.html>

Reply by email

JoshyFun
to Carlos German Tejero: He probado montones de formas, pero de todas me da dos resultados, debe ser un error o…

Hello Carlos,

Sunday, October 4, 2009, 12:05:11 AM, you wrote:

CGT>     buffer2.Position := 0;
CGT>     EncodeStream.Write(buffer2, buffer2.size);
EncodeStream.Write(buffer2.Memory^, buffer2.size);

Le estabas mandando grabar no el stream, si no los datos, si no la direcci�n donde est� almacenado el objeto "buffer2".

Otro modo m�s simple aqu� ser�a:

EncodeStream.CopyFrom(Buffer2,0); // 0 significa todo el stream.
Best regards, JoshyFun

Reply by email

Carlos German Tejero
to JoshyFun

Exactamente. Ahora recuerdo buffer.Memory, lo he usado en delphi, pero ya hace mucho. Gracias por hacerme recordar, tanto programar en OpenEdge 4gl y Java me estan haciendo olvidar de lo poco que se de ObjectPascal.

Saludos.

El 3 de octubre de 2009 19:17, JoshyFun <joshyfun en gmail.com> escribi�:

Show quoted text 26 lines
Hello Carlos, Sunday, October 4, 2009, 12:05:11 AM, you wrote: CGT> buffer2.Position := 0; CGT> EncodeStream.Write(buffer2, buffer2.size); EncodeStream.Write(buffer2.Memory^, buffer2.size); Le estabas mandando grabar no el stream, si no los datos, si no la direcci�n donde est� almacenado el objeto "buffer2". Otro modo m�s simple aqu� ser�a: EncodeStream.CopyFrom(Buffer2,0); // 0 significa todo el stream. -- Best regards, JoshyFun _______________________________________________ Lazarus-es mailing list Lazarus-es en lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es
Carlos Germ�n Tejero ------------ pr�xima parte ------------ Se ha borrado un adjunto en formato HTML... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus-es/attachments/20091003/e3dac8b6/attachment.html>

Reply by email

Rafael Bidegain
to JoshyFun: CGT> buffer2.Position := 0; CGT> EncodeStream.Write(buffer2, buffer2.size);…

hola!

El d�a 3 de octubre de 2009 19:17, JoshyFun <joshyfun en gmail.com> escribi�:

Show quoted text 8 lines
Hello Carlos, Sunday, October 4, 2009, 12:05:11 AM, you wrote: CGT> � � buffer2.Position := 0; CGT> � � EncodeStream.Write(buffer2, buffer2.size); EncodeStream.Write(buffer2.Memory^, buffer2.size);

Esto no funciona en el ejemplo de Carlos, pero si funciona en el mio.

Le estabas mandando grabar no el stream, si no los datos, si no la direcci�n donde est� almacenado el objeto "buffer2".

mmmm �que interesante!, toda esta informaci�n la obtuviste del c�digo fuente de la Unit o �hay documenaci�n en otro lugar ?

Otro modo m�s simple aqu� ser�a: EncodeStream.CopyFrom(Buffer2,0); // 0 significa todo el stream.

ahora hay tres ejemplos y se arm� una ensalada grand�sima!!

1) La soluci�n propuesta por Carlos en
http://lists.lazarus.freepascal.org/pipermail/lazarus-es/2009-October/001384.html funciona bien, pude comprobar que Codea [0]

2) La soluci�n propuesta por Carlos en
http://lists.lazarus.freepascal.org/pipermail/lazarus-es/2009-October/001383.html funciona correctamente si reemplazo
EncodeStream.Write(buffer2, buffer2.size);
por
EncodeStream.CopyFrom(Buffer2,0);
tal como indica JoshyFun en su email.

3) El ejemplo que propuse yo al inicio del thread mejor� mucho con la propuesta de JoshyFun
a la l�nea:
EncodeStream.Write(buffer, buffer.size);
la reemplace con:
EncodeStream.Write(buffer.Memory^, buffer.size);

Con esto el resultado ya no cambia en cada ejecuci�n, aunque es ligeramente diferente a las dos versiones de Carlos. esto es lo que encodea (con la entrada "Memo1")
TWVtdDEK
pero el resultado correcto es:
TWVtbzEK

[0] desde una consola de linux ejecuto: echo "Memo1"|base64 y el resultado es TWVtbzEK

Rafael Bidegain Ya que los cuerdos no hablan, hablar� el loco. (The Fool, Padraic Pearse)

Reply by email

JoshyFun
to Rafael Bidegain

Hello Rafael,

you wrote
> EncodeStream.Write(buffer2.Memory^, buffer2.size);

RB> Esto no funciona en el ejemplo de Carlos, pero si funciona en el mio.

La diferencia entre los dos que te he propuesto y la de Carlos es que mis dos propuestas hacen la conversi�n toda en una sola llamada, mientras que la de Carlos lo hace byte a byte, lo que en buena medida debe de ser por lo menos unas 20 veces m�s lento.

Cual es el c�digo que te da un encode diferente ?

Best regards, JoshyFun

Reply by email

Rafael Bidegain
to JoshyFun

El d�a 4 de octubre de 2009 12:40, JoshyFun <joshyfun en gmail.com> escribi�:

Show quoted text 11 lines
Hello Rafael, Sunday, October 4, 2009, 5:12:20 PM, you wrote: >> EncodeStream.Write(buffer2.Memory^, buffer2.size); RB> Esto no funciona en el ejemplo de Carlos, pero si funciona en el mio. La diferencia entre los dos que te he propuesto y la de Carlos es que mis dos propuestas hacen la conversi�n toda en una sola llamada, mientras que la de Carlos lo hace byte a byte, lo que en buena medida debe de ser por lo menos unas 20 veces m�s lento.

tengo claro que el segundo ejemplo de carlos es mas lento. pero tus soluciones no se pueden aplicar exactamente al ejemplo, de Carlos. una funciona en el ejemplo de Carlos y la otra puede hacerla funcionar con mi ejemplo.

Cual es el c�digo que te da un encode diferente ?

este:

procedure TForm1.Button1Click(Sender: TObject);
var
buffer       : TMemoryStream;
EncodeStream : TBase64EncodingStream;
begin
     buffer := TMemoryStream.create();
     Memo1.Lines.SaveToStream(buffer);
     EncodeStream := TBase64EncodingStream.Create(buffer);
     buffer.position := 0;
     EncodeStream.Write(buffer.Memory^, buffer.size);
     buffer.position := 0;
     Memo2.Lines.LoadFromStream(buffer);
     EncodeStream.free;
     buffer.free;
end;
Rafael Bidegain Ya que los cuerdos no hablan, hablar� el loco. (The Fool, Padraic Pearse)

Reply by email

JoshyFun
to Rafael Bidegain

Hello Rafael,

you wrote
> Cual es el c�digo que te da un encode diferente ?

RB> este:

Te das cuenta que est�s usando buffer para todo ? Lo usas como intermediario y como resultado.

procedure TForm1.Button1Click(Sender: TObject);
var
bufferEncoded: TMemoryStream;
BufferData:    TMemoryStream;
EncodeStream : TBase64EncodingStream;
begin
     bufferEncoded := TMemoryStream.create();
     bufferData := TMemoryStream.Create();
     Memo1.Lines.SaveToStream(bufferData);
     EncodeStream := TBase64EncodingStream.Create(bufferEncoded);
     bufferData.position := 0;
     EncodeStream.Write(bufferData.Memory^, bufferData.size);
     //EncodeStream.Write hace que se graben los datos
     //en base64 en el stream esclavo, en este caso BufferEncoded.
     bufferEncoded.position := 0;
     Memo2.Lines.LoadFromStream(bufferEncoded);
     EncodeStream.free;
     bufferEncoded.free;
     bufferData.free;
end;
RB> procedure TForm1.Button1Click(Sender: TObject);
RB> var
RB> buffer       : TMemoryStream;
RB> EncodeStream : TBase64EncodingStream;
RB> begin
RB>      buffer := TMemoryStream.create();
RB>      Memo1.Lines.SaveToStream(buffer);
RB>      EncodeStream := TBase64EncodingStream.Create(buffer);
RB>      buffer.position := 0;
RB>      EncodeStream.Write(buffer.Memory^, buffer.size);
RB>      buffer.position := 0;
RB>      Memo2.Lines.LoadFromStream(buffer);
RB>      EncodeStream.free;
RB>      buffer.free;
RB> end;
Best regards, JoshyFun

Reply by email

Rafael Bidegain
to JoshyFun

2009/10/4 JoshyFun <joshyfun en gmail.com>:

Show quoted text 9 lines
Hello Rafael, Sunday, October 4, 2009, 6:15:37 PM, you wrote: >> Cual es el c�digo que te da un encode diferente ? RB> este: Te das cuenta que est�s usando buffer para todo ? Lo usas como intermediario y como resultado.

si si, acabo de leer sobre eso en
Free Component Library (FCL):
Reference guide.
versi�n de marzo de 2009, pagina 48

Declaration: function Write(const Buffer;Count: LongInt) : LongInt; Override

me qued� claro que tengo que usar dos buffers ya que el parametro de la funci�n write puede ser una constante.

gracias a todos, ya puedo seguir adelante con el tema que me ocupaba.

� hacemos una entrada en el wiki para que les sirva a otros ?

Rafael Bidegain Ya que los cuerdos no hablan, hablar� el loco. (The Fool, Padraic Pearse)

Reply by email