Skip to content

Commit

Permalink
v1.35
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeduglas committed Sep 4, 2018
1 parent d8ce7d8 commit 9133a68
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 12 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ Click on the Save icon 'floppy disk' and the Green arrow to close.


## Recent changes
v1.35

- NEW: TCurlMimeClass.SetDataCB method sets a callback-based data source for a mime part's body.
- CHG: MimePost example now demonstrates both SetData and SetDataCB approaches.

v1.34

- CHG: Now uses libcurl v7.61.0, see [changelog](https://curl.haxx.se/changes.html) for details. Old binaries were moved to bin_v_7.52.1 subfolder.
Expand Down
50 changes: 46 additions & 4 deletions examples/MimePost/MimePost.clw
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,23 @@
INCLUDE('libcurl.inc')

MAP
MimePost()
MimePostCB() !- callback-based data source for a mime part's body
END

curl TCurlHttpClass
mime TCurlMimeClass
part curl_mimepart
res CURLcode
CODE

IF 1
MimePost()
ELSE
MimePostCB()
END

MimePost PROCEDURE()
curl TCurlHttpClass
mime TCurlMimeClass
part curl_mimepart
res CURLcode
CODE

curl.Init()
Expand All @@ -30,3 +40,35 @@ res CURLcode
ELSE
MESSAGE('MimePost failed: '& curl.StrError(res), 'MimePost', ICON:Exclamation)
END

MimePostCB PROCEDURE()
curl TCurlHttpClass
mime TCurlMimeClass
part curl_mimepart
hugedata &STRING
res CURLcode
CODE

curl.Init()

!- create "huge" data
hugedata &= NEW STRING(512)
hugedata = 'This is the field data: '& ALL('+', 255)

!Build an HTTP form with a single field named "data"
mime.Init(curl)
part = mime.AddPart()
mime.SetDataCB(part, hugedata, TRUE) !- it will dispose hugedata after the transfer terminates
mime.SetName(part, 'data')

!Post and send it.
curl.SetMimePost(mime)
res = curl.SendRequest('http://example.com')
IF res = CURLE_OK
MESSAGE('Success', 'MimePost test', ICON:Asterisk)
ELSE
MESSAGE('MimePost failed: '& curl.StrError(res), 'MimePost', ICON:Exclamation)
END

!- clean up
! DISPOSE(hugedata)
4 changes: 4 additions & 0 deletions history/changes.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
## Version history
v1.35

- NEW: TCurlMimeClass.SetDataCB method sets a callback-based data source for a mime part's body.
- CHG: MimePost example now demonstrates both SetData and SetDataCB approaches.

v1.34

Expand Down
15 changes: 10 additions & 5 deletions libsrc/libcurl.inc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
!** libcurl for Clarion v1.34
!** 01.09.2018
!** libcurl for Clarion v1.35
!** 04.09.2018
!** [email protected]

INCLUDE('DynStr.inc'), ONCE
Expand Down Expand Up @@ -1373,14 +1373,14 @@ Init PROCEDURE(*TCurlClass curl), VIRTUAL
!!!<summary>free a previously built mime structure</summary>
Kill PROCEDURE(), VIRTUAL

!!!<summary>returns this mime handle</summary>
!!!<summary>returns this mime handle.</summary>
GetMime PROCEDURE(), curl_mime

!!!<summary>creates and appends a new empty part to the given mime structure and returns a handle to it</summary>
!!!<summary>creates and appends a new empty part to the given mime structure and returns a handle to it.</summary>
AddPart PROCEDURE(), curl_mimepart

!!!<summary>set a mime part's body data from memory</summary>
!!!<param name="pData">data bytes, those are copied to the part and their storage may safely be reused after call. </param>
!!!<param name="pData">data bytes, those are copied to the part and their storage may safely be reused after call.</param>
SetData PROCEDURE(curl_mimepart part, STRING pData), CURLcode, PROC

!!!<summary>set a mime part's body data from a file contents.
Expand Down Expand Up @@ -1427,4 +1427,9 @@ SetHeaders PROCEDURE(curl_mimepart part, TCurlSList headers
!!!</summary>
!!!<param name="subparts">a mime class instance holding the subparts.</param>
SetSubparts PROCEDURE(curl_mimepart part, TCurlMimeClass subparts), CURLcode, PROC

!!!<summary>set a callback-based data source for a mime part's body.</summary>
!!!<param name="pHugeData">pointer to the data bytes.</param>
!!!<param name="pDoDispose">call DISPOSE(pHugeData) after the transfer terminates.</param>
SetDataCB PROCEDURE(curl_mimepart part, CONST *STRING pHugeData, BOOL pDoDispose = FALSE), CURLcode, PROC
END
90 changes: 87 additions & 3 deletions libsrc/libcurlmime.clw
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
!** libcurl for Clarion v1.34
!** 01.09.2018
!** libcurl for Clarion v1.35
!** 04.09.2018
!** [email protected]

MEMBER
Expand Down Expand Up @@ -143,9 +143,80 @@
! int take_ownership);
curl_mime_headers(curl_mimepart part, LONG headers, LONG take_ownership), CURLcode, C, RAW, NAME('curl_mime_headers')
END

MODULE('WinAPI')
curl::memcpy(LONG lpDest,LONG lpSource,LONG nCount), LONG, PROC, NAME('_memcpy')
END

!- callbacks
!https://curl.haxx.se/libcurl/c/curl_mime_data_cb.html
curl::MimeRead(LONG buffer, size_t bufsize, size_t nitems, LONG arg), size_t, C
curl::MimeSeek(LONG arg, curl_off_t offset, SIGNED origin), LONG, C
curl::MimeFree(LONG arg), C

END

!region static functions

TMimeDataCtl CLASS, TYPE
buffer LONG !- ADDRESS(data to send)
size UNSIGNED !LIKE(curl_off_t)
position UNSIGNED !LIKE(curl_off_t)
doDispose BOOL
END

!region callbacks
curl::MimeRead PROCEDURE(LONG buffer, size_t bufsize, size_t nitems, LONG arg)
ptr &TMimeDataCtl
sz UNSIGNED, AUTO !LIKE(curl_off_t)
CODE
ptr &= (arg)
sz = ptr.size - ptr.position
nitems *= bufsize
IF sz > nitems
sz = nitems
END
IF sz
curl::memcpy(buffer, ptr.buffer + ptr.position, sz)
END
ptr.position += sz
RETURN sz

curl::MimeSeek PROCEDURE(LONG arg, curl_off_t offset, SIGNED origin)
ptr &TMimeDataCtl
!- C constants for fseek/lseek functions
C_SEEK_SET EQUATE(0)
C_SEEK_CUR EQUATE(1)
C_SEEK_END EQUATE(2)
!- These are the return codes for the seek callbacks
CURL_SEEKFUNC_OK EQUATE(0)
CURL_SEEKFUNC_FAIL EQUATE(1) !- fail the entire transfer
CURL_SEEKFUNC_CANTSEEK EQUATE(2) !- tell libcurl seeking can't be done, so libcurl might try other means instead
CODE
ptr &= (arg)
CASE origin
OF C_SEEK_END
! offset += ptr.size
offset.lo += ptr.size
OF C_SEEK_CUR
! offset += ptr.position
offset.lo += ptr.position
END
! IF offset < 0
IF offset.lo < 0
RETURN CURL_SEEKFUNC_FAIL
END
! ptr.position = offset
ptr.position = offset.lo
RETURN CURL_SEEKFUNC_OK

curl::MimeFree PROCEDURE(LONG arg)
ptr &TMimeDataCtl
CODE
ptr &= (arg)
IF ptr.doDispose
DISPOSE(ptr)
END

!endregion

!region TCurlMimeClass
Expand Down Expand Up @@ -236,4 +307,17 @@ TCurlMimeClass.SetSubparts PROCEDURE(curl_mimepart part, TCurlMimeClass subpa
CODE
RETURN curl_mime_subparts(part, subparts.GetMime())

TCurlMimeClass.SetDataCB PROCEDURE(curl_mimepart part, CONST *STRING pHugeData, BOOL pDoDispose = FALSE)
ptr &TMimeDataCtl
size64 LIKE(curl_off_t), AUTO
CODE
ptr &= NEW TMimeDataCtl
ptr.buffer = ADDRESS(pHugeData)
ptr.size = LEN(CLIP(pHugeData))
ptr.position = 0
ptr.doDispose = pDoDispose
!- fill curl_off_t (int64)
size64.lo = ptr.size
size64.hi = 0
RETURN curl_mime_data_cb(part, size64, curl::MimeRead, curl::MimeSeek, curl::MimeFree, ADDRESS(ptr))
!endregion

0 comments on commit 9133a68

Please sign in to comment.