I am the guy still trying to achieve a file transfer using the winsock control. Somebody pointed me to a solution where I can convert the binary file to a base64 text file then send this text file in small chunks then accumulate the text file on the other end and decode the base64 textfile back to binary. The idea here was fine. I tried it with a 26kb photo and that worked like a breeze. But when I attempted a 393kb file it was taking like for ever to just encode to file to base64 text file the following is the code.
I first run the following code with a name as parameter. I can subsequently refer to that name as an object.
IF i had pass [oBase] as the parameter, I would encode a file as
obase.encode(cFileToCode,cCodedFile)
Is there a way that I chop up a file in VFP+API maybe and bring them back together in a way that is faster than this base64 approach.
Using Daves FTPPUT/GET suggestion works with a target computer hosting an FTP Server.
[\code]
**************************************************************************
*
* Class: Base64
*
* Purpose: Encode/Decodes a file using the Base64 encoding standard
*
* Author: Jeff Bowman <jbowman@jeffbowman.com>
*
* Credits: -Ankit Fadia <ankit@bol.net.in>
* ---------------------------------
* Provided explanation of the Base64 encoding standard:
* *
*
* -Albert Ballinger <albert_j_ballinger@dresser-rand.com>
* -------------------------------------------------------------
* Assisted with code execution speed
* The first few lines before the DEFINE CLASS Code was modified from the original to include the mSub codes.
*
**************************************************************************
LPARAMETERS cSessionName
#DEFINE vfpCr CHR(13)
#DEFINE vfpLf CHR(10)
#DEFINE vfpCrLf vfpCr + vfpLf
mSub1 = [PUBLIC ]+ALLTRIM(cSessionName)+[ AS Session ]
&mSub1
mSub2 = ALLTRIM(cSessionName) + [= CREATEOBJECT("Base64"]
&mSub2
*!* *************************************************
DEFINE CLASS Base64 AS Session
DIMENSION aBase64[64]
*********************************************************************************
PROCEDURE Encode(tcInFile, tcOutFile)
*********************************************************************************
*
* Method: Encode()
*
* Purpose: Converts the specified file to Base64 encoding
*
* Remarks:
*
*******************************************************************************
* Character variables
LOCAL ;
lcOutFile, ;
lcBase64, ;
lcInFile, ;
lcLine, ;
lcStr, ;
lcBin
* Integer variables
LOCAL ;
liDecimal, ;
liHandle, ;
i, ;
j
* Only proceed if the specified file exists
IF FILE(tcInFile)
* Create the output file, overwriting it if it exists
liHandle = FCREATE(tcOutFile)
* Only proceed if we could create the output file
IF liHandle > 0
* Set some starting values
lcInFile = FILETOSTR(tcInFile)
lcBase64 = ""
lcOutFile = ""
* Get the characters from the input
* file, in groups of three each
FOR i = 1 TO LEN(lcInFile) STEP 3
lcStr = SUBSTR(lcInFile, i, 3)
* Encode the binary code to Base64 and
* add it to the existing output string
lcBase64 = lcBase64 + This.Split4(lcStr)
ENDFOR
* Build the encoded output string,
* in lines of 76 characters each
FOR i = 1 TO LEN(lcBase64) STEP 76
lcOutFile = lcOutFile + SUBSTR(lcBase64, i, 76) + vfpCrLf
ENDFOR
* Write & close the output file
FWRITE(liHandle, lcOutFile)
FCLOSE(liHandle)
ENDIF
ENDIF
ENDPROC
*********************************************************************************
PROCEDURE Decode(tcInFile, tcOutFile)
*********************************************************************************
*
* Method: Decode()
*
* Purpose: Converts the specified file from Base64 encoding
*
* Remarks: Input file must contain no extra characters
* other than Base64 encoded characters, and each
* line must be exactly 76 characters long
*
*******************************************************************************
* Character variables
LOCAL ;
lcOutFile, ;
lcInFile, ;
lcString, ;
lcBinary, ;
lcChr, ;
lcBin
* Integer variables
LOCAL ;
liHandle, ;
liDec, ;
i, ;
j
* Only proceed if the specified file exists
IF FILE(tcInFile)
* Create the output file, overwriting it if it exists
liHandle = FCREATE(tcOutFile)
* Only proceed if we could create the output file
IF liHandle > 0
* Set some starting values
lcInFile = FILETOSTR(tcInFile)
lcOutFile = ""
* Strip out linefeeds, so we have
* one continous string to process
lcInFile = CHRTRAN(lcInFile, vfpCrLf, ""
* Get the characters from the input
* file, in groups of four each
FOR i = 1 TO LEN(lcInFile) STEP 4
lcString = SUBSTR(lcInFile, i, 4)
WITH This
lcString = ;
CHR(ASCAN(.aBase64, SUBSTR(lcString, 1, 1)) - 1) + ;
CHR(ASCAN(.aBase64, SUBSTR(lcString, 2, 1)) - 1) + ;
CHR(ASCAN(.aBase64, SUBSTR(lcString, 3, 1)) - 1) + ;
CHR(ASCAN(.aBase64, SUBSTR(lcString, 4, 1)) - 1)
* Decode the binary code from Base64
* and build the existing output string
lcOutFile = lcOutFile + .Split3(lcString)
ENDWITH
ENDFOR
* Write & close the output file
FWRITE(liHandle, lcOutFile)
FCLOSE(liHandle)
ENDIF
ENDIF
ENDPROC
*********************************************************************************
HIDDEN PROCEDURE Split3(tcBinary)
*********************************************************************************
*
* Method: Split3()
*
* Purpose: Splits a 24-bit binary string into 3 8-bit
* strings, converts them into decimal values and
* returns them as concatenated ASCII characters
*
* Remarks:
*
*******************************************************************************
WITH This
LOCAL ;
liOutByte1, ;
liOutByte2, ;
liOutByte3, ;
liInByte1, ;
liInByte2, ;
liInByte3, ;
liInByte4
liInByte1 = ASC(SUBSTR(tcBinary, 1, 1))
liInByte2 = ASC(SUBSTR(tcBinary, 2, 1))
liInByte3 = ASC(SUBSTR(tcBinary, 3, 1))
liInByte4 = ASC(SUBSTR(tcBinary, 4, 1))
liOutByte1 = BITLSHIFT(BITAND(liInByte1, 0x3f), 2) + BITRSHIFT(liInByte2, 4)
liOutByte2 = BITLSHIFT(BITAND(liInByte2, 0x0f), 4) + BITRSHIFT(liInByte3, 2)
liOutByte3 = BITLSHIFT(BITAND(liInByte3, 0x03), 6) + BITAND(liInByte4, 0x3f)
RETURN ;
CHR(liOutByte1) + ;
CHR(liOutByte2) + ;
CHR(liOutByte3)
ENDWITH
ENDPROC
*********************************************************************************
HIDDEN PROCEDURE Split4(tcBinary)
*********************************************************************************
*
* Method: Split4()
*
* Purpose: Splits a 24-bit binary string into 4 6-bit
* strings, converts them into decimal values and
* returns them as concatenated Base64 characters
*
* Remarks:
*
*******************************************************************************
LOCAL ;
liOutByte1, ;
liOutByte2, ;
liOutByte3, ;
liOutByte4, ;
liInByte1, ;
liInByte2, ;
liInByte3
liInByte1 = ASC(SUBSTR(tcBinary, 1, 1))
liInByte2 = ASC(SUBSTR(tcBinary, 2, 1))
liInByte3 = ASC(SUBSTR(tcBinary, 3, 1))
liOutByte1 = BITRSHIFT(liInByte1, 2)
liOutByte2 = BITLSHIFT(BITAND(liInByte1, 0x03), 4) + BITRSHIFT(BITAND(liInByte2, 0xf0), 4)
liOutByte3 = BITLSHIFT(BITAND(liInByte2, 0x0f), 2) + BITRSHIFT(BITAND(liInByte3, 0xc0), 6)
liOutByte4 = BITAND(liInByte3, 0x3f)
WITH This
RETURN ;
.aBase64[liOutByte1 + 1] + ;
.aBase64[liOutByte2 + 1] + ;
.aBase64[liOutByte3 + 1] + ;
.aBase64[liOutByte4 + 1]
ENDWITH
ENDPROC
*********************************************************************************
HIDDEN PROCEDURE Init()
*********************************************************************************
*
* Method: Init()
*
* Purpose:
*
* Remarks: Build the encode/decode array, based
* on the following Base64 lookup table
*
* -------------------------------------------
* | 0 = A | 16 = Q | 32 = g | 48 = w |
* | 1 = B | 17 = R | 33 = h | 49 = x |
* | 2 = C | 18 = S | 34 = i | 50 = y |
* | 3 = D | 19 = T | 35 = j | 51 = z |
* | 4 = E | 20 = U | 36 = k | 52 = 0 |
* | 5 = F | 21 = V | 37 = l | 53 = 1 |
* | 6 = G | 22 = W | 38 = m | 54 = 2 |
* | 7 = H | 23 = X | 39 = n | 55 = 3 |
* | 8 = I | 24 = Y | 40 = o | 56 = 4 |
* | 9 = J | 25 = Z | 41 = p | 57 = 5 |
* | 10 = K | 26 = a | 42 = q | 58 = 6 |
* | 11 = L | 27 = b | 43 = r | 59 = 7 |
* | 12 = M | 28 = c | 44 = s | 60 = 8 |
* | 13 = N | 29 = d | 45 = t | 61 = 9 |
* | 14 = O | 30 = e | 46 = u | 62 = + |
* | 15 = P | 31 = f | 47 = v | 63 = / |
* -------------------------------------------
*
*******************************************************************************
LOCAL i
FOR i = 0 TO 63
DO CASE
CASE BETWEEN(i, 0, 25)
This.aBase64[i + 1] = CHR(i + 65)
CASE BETWEEN(i, 26, 51)
This.aBase64[i + 1] = CHR(i + 71)
CASE BETWEEN(i, 52, 61)
This.aBase64[i + 1] = CHR(i - 4)
CASE i = 62
This.aBase64[i + 1] = "+"
CASE i = 63
This.aBase64[i + 1] = "/"
ENDCASE
ENDFOR
ENDPROC
ENDDEFINE
I first run the following code with a name as parameter. I can subsequently refer to that name as an object.
IF i had pass [oBase] as the parameter, I would encode a file as
obase.encode(cFileToCode,cCodedFile)
Is there a way that I chop up a file in VFP+API maybe and bring them back together in a way that is faster than this base64 approach.
Using Daves FTPPUT/GET suggestion works with a target computer hosting an FTP Server.
[\code]
**************************************************************************
*
* Class: Base64
*
* Purpose: Encode/Decodes a file using the Base64 encoding standard
*
* Author: Jeff Bowman <jbowman@jeffbowman.com>
*
* Credits: -Ankit Fadia <ankit@bol.net.in>
* ---------------------------------
* Provided explanation of the Base64 encoding standard:
* *
*
* -Albert Ballinger <albert_j_ballinger@dresser-rand.com>
* -------------------------------------------------------------
* Assisted with code execution speed
* The first few lines before the DEFINE CLASS Code was modified from the original to include the mSub codes.
*
**************************************************************************
LPARAMETERS cSessionName
#DEFINE vfpCr CHR(13)
#DEFINE vfpLf CHR(10)
#DEFINE vfpCrLf vfpCr + vfpLf
mSub1 = [PUBLIC ]+ALLTRIM(cSessionName)+[ AS Session ]
&mSub1
mSub2 = ALLTRIM(cSessionName) + [= CREATEOBJECT("Base64"]
&mSub2
*!* *************************************************
DEFINE CLASS Base64 AS Session
DIMENSION aBase64[64]
*********************************************************************************
PROCEDURE Encode(tcInFile, tcOutFile)
*********************************************************************************
*
* Method: Encode()
*
* Purpose: Converts the specified file to Base64 encoding
*
* Remarks:
*
*******************************************************************************
* Character variables
LOCAL ;
lcOutFile, ;
lcBase64, ;
lcInFile, ;
lcLine, ;
lcStr, ;
lcBin
* Integer variables
LOCAL ;
liDecimal, ;
liHandle, ;
i, ;
j
* Only proceed if the specified file exists
IF FILE(tcInFile)
* Create the output file, overwriting it if it exists
liHandle = FCREATE(tcOutFile)
* Only proceed if we could create the output file
IF liHandle > 0
* Set some starting values
lcInFile = FILETOSTR(tcInFile)
lcBase64 = ""
lcOutFile = ""
* Get the characters from the input
* file, in groups of three each
FOR i = 1 TO LEN(lcInFile) STEP 3
lcStr = SUBSTR(lcInFile, i, 3)
* Encode the binary code to Base64 and
* add it to the existing output string
lcBase64 = lcBase64 + This.Split4(lcStr)
ENDFOR
* Build the encoded output string,
* in lines of 76 characters each
FOR i = 1 TO LEN(lcBase64) STEP 76
lcOutFile = lcOutFile + SUBSTR(lcBase64, i, 76) + vfpCrLf
ENDFOR
* Write & close the output file
FWRITE(liHandle, lcOutFile)
FCLOSE(liHandle)
ENDIF
ENDIF
ENDPROC
*********************************************************************************
PROCEDURE Decode(tcInFile, tcOutFile)
*********************************************************************************
*
* Method: Decode()
*
* Purpose: Converts the specified file from Base64 encoding
*
* Remarks: Input file must contain no extra characters
* other than Base64 encoded characters, and each
* line must be exactly 76 characters long
*
*******************************************************************************
* Character variables
LOCAL ;
lcOutFile, ;
lcInFile, ;
lcString, ;
lcBinary, ;
lcChr, ;
lcBin
* Integer variables
LOCAL ;
liHandle, ;
liDec, ;
i, ;
j
* Only proceed if the specified file exists
IF FILE(tcInFile)
* Create the output file, overwriting it if it exists
liHandle = FCREATE(tcOutFile)
* Only proceed if we could create the output file
IF liHandle > 0
* Set some starting values
lcInFile = FILETOSTR(tcInFile)
lcOutFile = ""
* Strip out linefeeds, so we have
* one continous string to process
lcInFile = CHRTRAN(lcInFile, vfpCrLf, ""
* Get the characters from the input
* file, in groups of four each
FOR i = 1 TO LEN(lcInFile) STEP 4
lcString = SUBSTR(lcInFile, i, 4)
WITH This
lcString = ;
CHR(ASCAN(.aBase64, SUBSTR(lcString, 1, 1)) - 1) + ;
CHR(ASCAN(.aBase64, SUBSTR(lcString, 2, 1)) - 1) + ;
CHR(ASCAN(.aBase64, SUBSTR(lcString, 3, 1)) - 1) + ;
CHR(ASCAN(.aBase64, SUBSTR(lcString, 4, 1)) - 1)
* Decode the binary code from Base64
* and build the existing output string
lcOutFile = lcOutFile + .Split3(lcString)
ENDWITH
ENDFOR
* Write & close the output file
FWRITE(liHandle, lcOutFile)
FCLOSE(liHandle)
ENDIF
ENDIF
ENDPROC
*********************************************************************************
HIDDEN PROCEDURE Split3(tcBinary)
*********************************************************************************
*
* Method: Split3()
*
* Purpose: Splits a 24-bit binary string into 3 8-bit
* strings, converts them into decimal values and
* returns them as concatenated ASCII characters
*
* Remarks:
*
*******************************************************************************
WITH This
LOCAL ;
liOutByte1, ;
liOutByte2, ;
liOutByte3, ;
liInByte1, ;
liInByte2, ;
liInByte3, ;
liInByte4
liInByte1 = ASC(SUBSTR(tcBinary, 1, 1))
liInByte2 = ASC(SUBSTR(tcBinary, 2, 1))
liInByte3 = ASC(SUBSTR(tcBinary, 3, 1))
liInByte4 = ASC(SUBSTR(tcBinary, 4, 1))
liOutByte1 = BITLSHIFT(BITAND(liInByte1, 0x3f), 2) + BITRSHIFT(liInByte2, 4)
liOutByte2 = BITLSHIFT(BITAND(liInByte2, 0x0f), 4) + BITRSHIFT(liInByte3, 2)
liOutByte3 = BITLSHIFT(BITAND(liInByte3, 0x03), 6) + BITAND(liInByte4, 0x3f)
RETURN ;
CHR(liOutByte1) + ;
CHR(liOutByte2) + ;
CHR(liOutByte3)
ENDWITH
ENDPROC
*********************************************************************************
HIDDEN PROCEDURE Split4(tcBinary)
*********************************************************************************
*
* Method: Split4()
*
* Purpose: Splits a 24-bit binary string into 4 6-bit
* strings, converts them into decimal values and
* returns them as concatenated Base64 characters
*
* Remarks:
*
*******************************************************************************
LOCAL ;
liOutByte1, ;
liOutByte2, ;
liOutByte3, ;
liOutByte4, ;
liInByte1, ;
liInByte2, ;
liInByte3
liInByte1 = ASC(SUBSTR(tcBinary, 1, 1))
liInByte2 = ASC(SUBSTR(tcBinary, 2, 1))
liInByte3 = ASC(SUBSTR(tcBinary, 3, 1))
liOutByte1 = BITRSHIFT(liInByte1, 2)
liOutByte2 = BITLSHIFT(BITAND(liInByte1, 0x03), 4) + BITRSHIFT(BITAND(liInByte2, 0xf0), 4)
liOutByte3 = BITLSHIFT(BITAND(liInByte2, 0x0f), 2) + BITRSHIFT(BITAND(liInByte3, 0xc0), 6)
liOutByte4 = BITAND(liInByte3, 0x3f)
WITH This
RETURN ;
.aBase64[liOutByte1 + 1] + ;
.aBase64[liOutByte2 + 1] + ;
.aBase64[liOutByte3 + 1] + ;
.aBase64[liOutByte4 + 1]
ENDWITH
ENDPROC
*********************************************************************************
HIDDEN PROCEDURE Init()
*********************************************************************************
*
* Method: Init()
*
* Purpose:
*
* Remarks: Build the encode/decode array, based
* on the following Base64 lookup table
*
* -------------------------------------------
* | 0 = A | 16 = Q | 32 = g | 48 = w |
* | 1 = B | 17 = R | 33 = h | 49 = x |
* | 2 = C | 18 = S | 34 = i | 50 = y |
* | 3 = D | 19 = T | 35 = j | 51 = z |
* | 4 = E | 20 = U | 36 = k | 52 = 0 |
* | 5 = F | 21 = V | 37 = l | 53 = 1 |
* | 6 = G | 22 = W | 38 = m | 54 = 2 |
* | 7 = H | 23 = X | 39 = n | 55 = 3 |
* | 8 = I | 24 = Y | 40 = o | 56 = 4 |
* | 9 = J | 25 = Z | 41 = p | 57 = 5 |
* | 10 = K | 26 = a | 42 = q | 58 = 6 |
* | 11 = L | 27 = b | 43 = r | 59 = 7 |
* | 12 = M | 28 = c | 44 = s | 60 = 8 |
* | 13 = N | 29 = d | 45 = t | 61 = 9 |
* | 14 = O | 30 = e | 46 = u | 62 = + |
* | 15 = P | 31 = f | 47 = v | 63 = / |
* -------------------------------------------
*
*******************************************************************************
LOCAL i
FOR i = 0 TO 63
DO CASE
CASE BETWEEN(i, 0, 25)
This.aBase64[i + 1] = CHR(i + 65)
CASE BETWEEN(i, 26, 51)
This.aBase64[i + 1] = CHR(i + 71)
CASE BETWEEN(i, 52, 61)
This.aBase64[i + 1] = CHR(i - 4)
CASE i = 62
This.aBase64[i + 1] = "+"
CASE i = 63
This.aBase64[i + 1] = "/"
ENDCASE
ENDFOR
ENDPROC
ENDDEFINE
Code:
------------------------------------->
"I have sought your assistance on this matter because I have exhausted all the help that I can find. You are free to direct me to other source of help"