-/*
- All client code should use only the two macros
-
- TO_EXTERNAL_FORMAT (source_type, source, sink_type, sink, coding_system)
- TO_INTERNAL_FORMAT (source_type, source, sink_type, sink, coding_system)
-
- Typical use is
-
- TO_EXTERNAL_FORMAT (DATA, (ptr, len),
- LISP_BUFFER, buffer,
- Qfile_name);
-
- The source or sink can be specified in one of these ways:
-
- DATA, (ptr, len), // input data is a fixed buffer of size len
- ALLOCA, (ptr, len), // output data is in a alloca()ed buffer of size len
- MALLOC, (ptr, len), // output data is in a malloc()ed buffer of size len
- C_STRING_ALLOCA, ptr, // equivalent to ALLOCA (ptr, len_ignored) on output
- C_STRING_MALLOC, ptr, // equivalent to MALLOC (ptr, len_ignored) on output
- C_STRING, ptr, // equivalent to DATA, (ptr, strlen (ptr) + 1) on input
- LISP_STRING, string, // input or output is a Lisp_Object of type string
- LISP_BUFFER, buffer, // output is written to (point) in lisp buffer
- LISP_LSTREAM, lstream, // input or output is a Lisp_Object of type lstream
- LISP_OPAQUE, object, // input or output is a Lisp_Object of type opaque
-
- When specifying the sink, use lvalues, since the macro will assign to them,
- except when the sink is an lstream or a lisp buffer.
-
- The macros accept the kinds of sources and sinks appropriate for
- internal and external data representation. See the type_checking_assert
- macros below for the actual allowed types.
-
- Since some sources and sinks use one argument (a Lisp_Object) to
- specify them, while others take a (pointer, length) pair, we use
- some C preprocessor trickery to allow pair arguments to be specified
- by parenthesizing them, as in the examples above.
-
- Anything prefixed by dfc_ (`data format conversion') is private.
- They are only used to implement these macros.
-
- Using C_STRING* is appropriate for using with external APIs that take
- null-terminated strings. For internal data, we should try to be
- '\0'-clean - i.e. allow arbitrary data to contain embedded '\0'.
-
- Sometime in the future we might allow output to C_STRING_ALLOCA or
- C_STRING_MALLOC _only_ with TO_EXTERNAL_FORMAT(), not
- TO_INTERNAL_FORMAT(). */
-
-#define TO_EXTERNAL_FORMAT(source_type, source, sink_type, sink, coding_system) \
-do { \
- dfc_conversion_type dfc_simplified_source_type; \
- dfc_conversion_type dfc_simplified_sink_type; \
- dfc_conversion_data dfc_source; \
- dfc_conversion_data dfc_sink; \
- \
- type_checking_assert \
- ((DFC_TYPE_##source_type == DFC_TYPE_DATA || \
- DFC_TYPE_##source_type == DFC_TYPE_C_STRING || \
- DFC_TYPE_##source_type == DFC_TYPE_LISP_STRING || \
- DFC_TYPE_##source_type == DFC_TYPE_LISP_OPAQUE || \
- DFC_TYPE_##source_type == DFC_TYPE_LISP_LSTREAM) \
- && \
- (DFC_TYPE_##sink_type == DFC_TYPE_ALLOCA || \
- DFC_TYPE_##sink_type == DFC_TYPE_MALLOC || \
- DFC_TYPE_##sink_type == DFC_TYPE_C_STRING_ALLOCA || \
- DFC_TYPE_##sink_type == DFC_TYPE_C_STRING_MALLOC || \
- DFC_TYPE_##sink_type == DFC_TYPE_LISP_LSTREAM || \
- DFC_TYPE_##sink_type == DFC_TYPE_LISP_OPAQUE)); \
- \
- DFC_SOURCE_##source_type##_TO_ARGS (source); \
- DFC_SINK_##sink_type##_TO_ARGS (sink); \
- \
- DFC_CONVERT_TO_EXTERNAL_FORMAT (dfc_simplified_source_type, &dfc_source, \
- coding_system, \
- dfc_simplified_sink_type, &dfc_sink); \
- \
- DFC_##sink_type##_USE_CONVERTED_DATA (sink); \
-} while (0)