io1.pas 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. (**
  2. * section: InputOutput
  3. * synopsis: Example of custom Input/Output
  4. * purpose: Demonstrate the use of xmlRegisterInputCallbacks
  5. * to build a custom I/O layer, this is used in an
  6. * XInclude method context to show how dynamic document can
  7. * be built in a clean way.
  8. * usage: io1
  9. * test: io1 > io1.tmp ; diff io1.tmp io1.res ; rm -f io1.tmp
  10. * author: Daniel Veillard
  11. * copy: see Copyright for the status of this software.
  12. *)
  13. program io1;
  14. {$mode objfpc}
  15. uses
  16. ctypes,
  17. libxml2,
  18. exutils;
  19. const
  20. include: pchar =
  21. '<?xml version=''1.0''?>'#10+
  22. '<document xmlns:xi="http://www.w3.org/2003/XInclude">'#10+
  23. '<p>List of people:</p>'#10+
  24. '<xi:include href="sql:select_name_from_people"/>'#10+
  25. '</document>'#10;
  26. (**
  27. * sqlMatch:
  28. * @URI: an URI to test
  29. *
  30. * Check for an sql: query
  31. *
  32. * Returns 1 if yes and 0 if another Input module should be used
  33. *)
  34. function sqlMatch(URI: pchar): cint; cdecl;
  35. begin
  36. if assigned(URI) {and (strncmp(URI, 'sql:', 4) = 0)} then
  37. result := 1
  38. else
  39. result := 0;
  40. end;
  41. (**
  42. * sqlOpen:
  43. * @URI: an URI to test
  44. *
  45. * Return a pointer to the sql: query handler, in this example simply
  46. * the current pointer...
  47. *
  48. * Returns an Input context or NULL in case or error
  49. *)
  50. function sqlOpen(URI: pchar): pointer; cdecl;
  51. begin
  52. if not assigned(URI) or (strncmp(URI, 'sql:', 4) <> 0) then
  53. exit(nil);
  54. end;
  55. {
  56. if ((URI == NULL) || (strncmp(URI, "sql:", 4)))
  57. return(NULL);
  58. cur = result;
  59. rlen = strlen(result);
  60. return((void *) cur);
  61. }
  62. (**
  63. * sqlClose:
  64. * @context: the read context
  65. *
  66. * Close the sql: query handler
  67. *
  68. * Returns 0 or -1 in case of error
  69. *)
  70. function sqlClose(context: pointer): cint; cdecl;
  71. begin
  72. end; {
  73. if (context == NULL) return(-1);
  74. cur = NULL;
  75. rlen = 0;
  76. return(0);
  77. }
  78. (**
  79. * sqlRead:
  80. * @context: the read context
  81. * @buffer: where to store data
  82. * @len: number of bytes to read
  83. *
  84. * Implement an sql: query read.
  85. *
  86. * Returns the number of bytes read or -1 in case of error
  87. *)
  88. function sqlRead(context: pointer; buffer: pchar; len: cint): cint; cdecl;
  89. begin
  90. end;
  91. {
  92. const char *ptr = (const char *) context;
  93. if ((context == NULL) || (buffer == NULL) || (len < 0))
  94. return(-1);
  95. if (len > rlen) len = rlen;
  96. memcpy(buffer, ptr, len);
  97. rlen -= len;
  98. return(len);
  99. }
  100. var
  101. doc: xmlDocPtr;
  102. begin
  103. (*
  104. * this initialize the library and check potential ABI mismatches
  105. * between the version it was compiled for and the actual shared
  106. * library used.
  107. *)
  108. LIBXML_TEST_VERSION;
  109. (*
  110. * register the new I/O handlers
  111. *)
  112. if xmlRegisterInputCallbacks(@sqlMatch, @sqlOpen, @sqlRead, @sqlClose) < 0 then
  113. begin
  114. printfn('failed to register SQL handler');
  115. halt(1);
  116. end;
  117. (*
  118. * parse include into a document
  119. *)
  120. doc := xmlReadMemory(include, strlen(include), 'include.xml', nil, 0);
  121. if doc = nil then
  122. begin
  123. printfn('failed to parse the including file');
  124. halt(1);
  125. end;
  126. (*
  127. * apply the XInclude process, this should trigger the I/O just
  128. * registered.
  129. *)
  130. if xmlXIncludeProcess(doc) <= 0 then
  131. begin
  132. printfn('XInclude processing failed');
  133. halt(1);
  134. end;
  135. (*
  136. * save the output for checking to stdout
  137. *)
  138. // xmlDocDump(stdout, doc);
  139. (*
  140. * Free the document
  141. *)
  142. xmlFreeDoc(doc);
  143. (*
  144. * Cleanup function for the XML library.
  145. *)
  146. xmlCleanupParser();
  147. end.