00001 /* 00002 * Name: filter.m4 00003 * 00004 * Description: 00005 * DOXYGEN Input file filter for DRAMA source files. 00006 * 00007 * This file must be complatible with both Solaris and GNU m4. All 00008 * unused macros are deleted and this comment must end up as a C/C++ 00009 * compatible comment which is not picked up by DOXYGEN. 00010 * 00011 * Synopsis: 00012 * DCF(func) => Produces a link to a DRAMA C source file func.html 00013 * in ../routines. 00014 * DDL(link,text) => Produce a link to ../link.html, specified link text. 00015 * 00016 * Language: m4 macro. 00017 * 00018 * Author: Tony Farrell, AAO. 00019 * 00020 * "@(#) $Id: ACMM:DramaHtml/filter.m4,v 3.24 03-Nov-2009 09:07:29+11 tjf $" 00021 * 00022 * History: 00023 * 10-Nov-2004 - TJF - Original Version. 00024 */ 00025 00026 00027 00028 #ifndef SDPINC 00029 #define SDPINC 00030 /* S D P . H 00031 00032 * Module name: 00033 SDP.H 00034 00035 * Function: 00036 Simple Dits parameter system include file 00037 00038 * Description: 00039 00040 00041 Note - this file now uses DOXYGEN commands fro the C++ interfaces. 00042 00043 * Language: 00044 C 00045 00046 * Support: Tony Farrell, AAO 00047 00048 * 00049 00050 * History: 00051 08-Sep-1992 - TJF - Original version 00052 02-Aug-1993 - TJF - Use StatusType. 00053 00054 29-Sep-1993 - TJF - Add Sccs id 00055 06-Oct-1993 - TJF - Use drama.h 00056 21-Oct-1993 - TJF - Add new routines from sdpop.c 00057 25-Oct-1993 - TJF - SdpGet now has a delete flag. 00058 10-Aug-1995 - TJF - Add 64 bit calls. 00059 29-Jan-1997 - TJF - Parameter system id is now a DVOIDP. Add SdpMGet. 00060 19-May-2000 - TJF - Move extern "C" to just before prototypes since 00061 some C++ compilers get upset if we include the 00062 other include files after extern "C". 00063 05-Apr-2004 - TJF - Expand Sdp class to support bool, and std::string. 00064 Add doxygen comment for Sdp class. 00065 17-Feb-2005 - TJF - Was incorrectly defining and INT64 version of 00066 Sdp::Put when on LONG__64 architecture. 00067 10-Mar-2006 - TJF - Change from using long/unsigned long in C++ stuff 00068 to using INT32/UINT32, which cleans up the 64 bit 00069 stuff a lot. 00070 18-May-2009 - TJF - The version of Sdp::Get which fetech into a std::string 00071 value was not working correctly if the buffer was too small. 00072 In fact - it was a bit of a mess. 00073 {@change entry@} 00074 00075 00076 * @(#) $Id: ACMM:DramaDits/Sdp.h,v 3.68 02-Nov-2009 14:19:09+11 tjf $ 00077 00078 * Copyright (c) Anglo-Australian Telescope Board, 1995. 00079 Not to be used for commercial purposes without AATB permission. 00080 00081 00082 */ 00083 00084 /* 00085 * If under C++ and this is allowed, then we can add functions which 00086 * require the C++ Standard Library (say under GCC 2.95.2 or later). 00087 */ 00088 #ifdef DRAMA_ALLOW_CPP_STDLIB 00089 #include <string> 00090 #endif 00091 00092 00093 #include "drama.h" 00094 #include "sds.h" 00095 #include "arg.h" 00096 00097 /* 00098 * Define the parameter types. 00099 */ 00100 #define SDP_CHAR SDS_CHAR 00101 #define SDP_BYTE SDS_BYTE 00102 #define SDP_UBYTE SDS_UBYTE 00103 #define SDP_SHORT SDS_SHORT 00104 #define SDP_USHORT SDS_USHORT 00105 #define SDP_INT SDS_INT 00106 #define SDP_UINT SDS_UINT 00107 #define SDP_INT64 SDS_INT64 00108 #define SDP_UINT64 SDS_UINT64 00109 #define SDP_FLOAT SDS_FLOAT 00110 #define SDP_DOUBLE SDS_DOUBLE 00111 #define SDP_STRING ARG_STRING 00112 #define SDP_SDS ARG_SDS 00113 00114 typedef struct { 00115 DCONSTV char *name; 00116 DCONSTV DVOIDP value; 00117 int type; 00118 } SdpParDefType; 00121 #ifdef __cplusplus 00122 extern "C" { 00123 #endif 00124 00125 #ifdef DPROTOTYPES_OK 00126 DPUBLIC DVOID SdpInit ( SdsIdType *id , 00127 StatusType * DCONSTR status); 00128 DPUBLIC DVOID SdpCreate ( 00129 DCONSTV SdsIdType id, 00130 DCONSTV long int size, 00131 DCONSTV SdpParDefType pardefs[], 00132 StatusType * DCONSTR status); 00133 00134 DPUBLIC DVOID SdpCreateItem ( 00135 DCONSTV SdsIdType parsys, 00136 DCONSTV SdsIdType item, 00137 StatusType * DCONSTR status); 00138 00139 DPUBLIC DVOID SdpSetReadonly (StatusType * DCONSTR status); 00140 00141 DPUBLIC DVOID SdpGet ( 00142 DVOIDP id, 00143 DCONSTV char * name, 00144 SdsIdType * parid, 00145 int * delete_flag, 00146 StatusType * status); 00147 00148 DPUBLIC DVOID SdpMGet ( 00149 DVOIDP id, 00150 char * names, 00151 SdsIdType * parid, 00152 int * delete_flag, 00153 StatusType * status); 00154 00155 DPUBLIC DVOID SdpSet ( 00156 DVOIDP id, 00157 DCONSTV char * name, 00158 SdsIdType * parid, 00159 StatusType * status); 00160 00161 00162 DPUBLIC DVOID SdpPutc( 00163 DCONSTV char * DCONSTR name, 00164 DCONSTV char value, 00165 StatusType * DCONSTR status); 00166 00167 DPUBLIC DVOID SdpPutus( 00168 DCONSTV char * DCONSTR name, 00169 DCONSTV unsigned short value, 00170 StatusType * DCONSTR status); 00171 DPUBLIC DVOID SdpPuts( 00172 DCONSTV char *DCONSTR name, 00173 DCONSTV short value, 00174 StatusType *DCONSTR status); 00175 DPUBLIC DVOID SdpPuti( 00176 DCONSTV char * DCONSTR name, 00177 DCONSTV long value, 00178 StatusType * DCONSTR status); 00179 DPUBLIC DVOID SdpPutu( 00180 DCONSTV char * DCONSTR name, 00181 DCONSTV unsigned long value, 00182 StatusType *DCONSTR status); 00183 00184 # ifdef VAXC 00185 # pragma nostandard /* Structure by value . */ 00186 # endif 00187 DPUBLIC DVOID SdpPuti64( 00188 DCONSTV char * DCONSTR name, 00189 DCONSTV INT64 value, 00190 StatusType * DCONSTR status); 00191 00192 DPUBLIC DVOID SdpPutu64( 00193 DCONSTV char * DCONSTR name, 00194 DCONSTV UINT64 value, 00195 StatusType *DCONSTR status); 00196 # ifdef VAXC 00197 # pragma standard /* Structure by value . */ 00198 # endif 00199 00200 DPUBLIC DVOID SdpPutf( 00201 DCONSTV char *DCONSTR name, 00202 DCONSTV float value, 00203 StatusType *DCONSTR status); 00204 DPUBLIC DVOID SdpPutd( 00205 DCONSTV char *DCONSTR name, 00206 DCONSTV double value, 00207 StatusType *DCONSTR status); 00208 DPUBLIC DVOID SdpPutString( 00209 DCONSTV char * DCONSTR name, 00210 DCONSTV char *DCONSTR value, 00211 StatusType *DCONSTR status); 00212 DPUBLIC DVOID SdpPutSds( 00213 DCONSTV char * DCONSTR name, 00214 DCONSTV SdsIdType value, 00215 StatusType * DCONSTR status); 00216 DPUBLIC DVOID SdpUpdate( 00217 DCONSTV SdsIdType id, 00218 StatusType * DCONSTR status); 00219 DPUBLIC DVOID SdpGetc( 00220 DCONSTV char *DCONSTR name, 00221 char *DCONSTR value, 00222 StatusType *DCONSTR status); 00223 DPUBLIC DVOID SdpGets( 00224 DCONSTV char *DCONSTR name, 00225 short *DCONSTR value, 00226 StatusType * DCONSTR status); 00227 DPUBLIC DVOID SdpGetus( 00228 DCONSTV char * DCONSTR name, 00229 unsigned short * DCONSTR value, 00230 StatusType * DCONSTR status); 00231 DPUBLIC DVOID SdpGeti( 00232 DCONSTV char * DCONSTR name, 00233 long * DCONSTR value, 00234 StatusType * DCONSTR status); 00235 DPUBLIC DVOID SdpGetu( 00236 DCONSTV char * DCONSTR name, 00237 unsigned long * DCONSTR value, 00238 StatusType * DCONSTR status); 00239 DPUBLIC DVOID SdpGeti64( 00240 DCONSTV char * DCONSTR name, 00241 INT64 * DCONSTR value, 00242 StatusType * DCONSTR status); 00243 DPUBLIC DVOID SdpGetu64( 00244 DCONSTV char * DCONSTR name, 00245 UINT64 * DCONSTR value, 00246 StatusType * DCONSTR status); 00247 DPUBLIC DVOID SdpGetf( 00248 DCONSTV char * DCONSTR name, 00249 float * DCONSTR value, 00250 StatusType * DCONSTR status); 00251 DPUBLIC DVOID SdpGetd( 00252 DCONSTV char *DCONSTR name, 00253 double * DCONSTR value, 00254 StatusType *DCONSTR status); 00255 DPUBLIC DVOID SdpGetString( 00256 DCONSTV char * DCONSTR name, 00257 DCONSTV long len, 00258 char * DCONSTR value, 00259 StatusType * DCONSTR status); 00260 DPUBLIC DVOID SdpGetSds( 00261 DCONSTV char * DCONSTR name, 00262 SdsIdType *DCONSTR value, 00263 StatusType * DCONSTR status); 00264 00265 DPUBLIC DVOID SdpPutStruct( 00266 DCONSTV char * DCONSTR name, 00267 DCONSTV SdsIdType value, 00268 DCONSTV int copy, 00269 DCONSTV int create, 00270 StatusType * DCONSTR status); 00271 00272 #else /* if ! DPROTOTYPES_OK */ 00273 00274 DPUBLIC DVOID SdpInit (); 00275 DPUBLIC DVOID SdpCreate (); 00276 DPUBLIC DVOID SdpCreateItem (); 00277 DPUBLIC DVOID SdpSetReadonly(); 00278 00279 DPUBLIC DVOID SdpGet (); 00280 DPUBLIC DVOID SdpMGet (); 00281 DPUBLIC DVOID SdpSet (); 00282 DPUBLIC DVOID SdpPutc(); 00283 DPUBLIC DVOID SdpPutus(); 00284 DPUBLIC DVOID SdpPuts(); 00285 DPUBLIC DVOID SdpPuti(); 00286 DPUBLIC DVOID SdpPutu(); 00287 DPUBLIC DVOID SdpPutf(); 00288 DPUBLIC DVOID SdpPutd(); 00289 DPUBLIC DVOID SdpPutString(); 00290 DPUBLIC DVOID SdpPutSds(); 00291 DPUBLIC DVOID SdpUpdate(); 00292 DPUBLIC DVOID SdpGetc(); 00293 DPUBLIC DVOID SdpGets(); 00294 DPUBLIC DVOID SdpGetus(); 00295 DPUBLIC DVOID SdpGeti(); 00296 DPUBLIC DVOID SdpGetu(); 00297 DPUBLIC DVOID SdpGetf(); 00298 DPUBLIC DVOID SdpGetd(); 00299 DPUBLIC DVOID SdpGetString(); 00300 DPUBLIC DVOID SdpGetSds(); 00301 DPUBLIC DVOID SdpPutStruct(); 00302 00303 00304 #endif /* ! DPROTOTYPES_OK */ 00305 00306 #ifdef __cplusplus 00307 } /* extern "C" */ 00308 00309 00310 /* 00311 * C++ only section. 00312 * 00313 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00314 * 00315 * Here is the a C++ interface to Sdp. No object code required since 00316 * all code is inline. Note, there is no actual object, just static 00317 * members which provide access to the C interface using function 00318 * overloading. For example 00319 * Sdp::Put("FRED",1,status); 00320 */ 00335 class Sdp { 00336 public: 00354 static void CreateItem(const SdsId & parsys, 00355 SdsId &item, StatusType *status) { 00356 SdpCreateItem((SdsIdType)parsys,(SdsIdType)item,status); 00357 /* Ensure item is not deleted by destructor (id can go) */ 00358 if (*status == STATUS__OK) 00359 item.ClearDelete(); 00360 } 00361 # ifndef CPP_NOBOOL 00362 00377 static void Put(const char *name, bool value, StatusType *status) { 00378 SdpPutus(name,(short)value, status); 00379 } 00380 # endif /* ! defined CPP_NOBOOL */ 00381 00393 static void Put(const char *name, char value, StatusType *status) { 00394 SdpPutc(name,value,status); 00395 }; 00408 static void Put(const char *name, unsigned short value, 00409 StatusType *status) { 00410 SdpPutus(name,value,status); 00411 }; 00424 static void Put(const char *name, short value, StatusType *status) { 00425 SdpPuts(name,value,status); 00426 }; 00439 static void Put(const char *name, INT32 value , StatusType *status) { 00440 SdpPuti(name,value,status); 00441 }; 00454 static void Put(const char *name, UINT32 value, 00455 StatusType *status) { 00456 SdpPutu(name,value,status); 00457 }; 00470 static void Put(const char *name, INT64 value , StatusType *status) { 00471 SdpPuti64(name,value,status); 00472 }; 00485 static void Put(const char *name, UINT64 value, 00486 StatusType *status) { 00487 SdpPutu64(name,value,status); 00488 }; 00501 static void Put(const char *name, float value, StatusType *status) { 00502 SdpPutf(name,value,status); 00503 }; 00516 static void Put(const char *name, double value, StatusType *status) { 00517 SdpPutd(name,value,status); 00518 }; 00532 static void Put(const char *name, const char * value, StatusType *status) 00533 { 00534 SdpPutString(name,value,status); 00535 }; 00558 static void PutSds(const char *name, SdsIdType value, 00559 StatusType *status) { 00560 SdpPutSds(name,value,status); 00561 }; 00576 static void Update(SdsIdType id, StatusType *status) { 00577 SdpUpdate(id,status); 00578 }; 00579 # ifndef CPP_NOBOOL 00580 00595 static void Get(const char *name, bool * value, 00596 StatusType *status) { 00597 char cvalue; 00598 SdpGetc(name,&cvalue,status); 00599 *value = cvalue ? true : false; 00600 }; 00601 # endif /* ! defined CPP_NOBOOL */ 00602 00614 static void Get(const char *name, char * value, 00615 StatusType *status) { 00616 SdpGetc(name,value,status); 00617 }; 00631 static void Get(const char *name, short * value, 00632 StatusType *status) { 00633 SdpGets(name,value,status); 00634 }; 00648 static void Get(const char *name, unsigned short * value, 00649 StatusType *status) { 00650 SdpGetus(name,value,status); 00651 }; 00664 static void Get(const char *name, INT32 * value, 00665 StatusType *status) { 00666 long v; 00667 SdpGeti(name,&v,status); 00668 *value = v; 00669 }; 00682 static void Get(const char *name, UINT32 * value, 00683 StatusType *status) { 00684 unsigned long v; 00685 SdpGetu(name,&v,status); 00686 *value = v; 00687 }; 00702 static void Get(const char *name, INT64 * value, 00703 StatusType *status) { 00704 SdpGeti64(name,value,status); 00705 }; 00719 static void Get(const char *name, UINT64 * value, 00720 StatusType *status) { 00721 SdpGetu64(name,value,status); 00722 }; 00734 static void Get(const char *name, float * value, 00735 StatusType *status) { 00736 SdpGetf(name,value,status); 00737 }; 00749 static void Get(const char *name, double * value, 00750 StatusType *status) { 00751 SdpGetd(name,value,status); 00752 }; 00766 static void Get(const char *name, int len, char * value, 00767 StatusType *status) { 00768 SdpGetString(name,len,value,status); 00769 }; 00789 static void GetSds(const char *name, SdsIdType * value, 00790 StatusType * status) { 00791 SdpGetSds(name,value,status); 00792 } 00809 static void Get(const char *name, SdsId * value, 00810 StatusType * status) { 00811 /* 00812 * Need to get as and SdsIdType and shallow copy into the 00813 * id. 00814 */ 00815 SdsIdType id; 00816 SdpGetSds(name,&id,status); 00817 value->ShallowCopy(id, true, false, false); 00818 } 00819 00820 00843 static void Put(const char *name, const SdsId & value, 00844 StatusType *status) { 00845 SdpPutSds(name,(SdsIdType)value,status); 00846 } 00847 00870 static void PutStruct(const char *name, 00871 const SdsId &value, 00872 StatusType *status, 00873 const bool create=true ) { 00874 SdpPutStruct(name,(SdsIdType)value,(int)true, 00875 (int)create,status); 00876 }; 00901 static void PutStruct(const char *name, 00902 SdsId *value, 00903 StatusType *status, 00904 const bool create=true ) { 00905 SdpPutStruct(name, 00906 value->COut(true), /* Out value outlives */ 00907 (int)false, 00908 (int)create,status); 00909 }; 00910 00911 #ifdef DRAMA_ALLOW_CPP_STDLIB 00912 /* 00913 * If DRAMA is allowed to use the C++ Standard Template library, then 00914 * we add these functions to Sdp. All of these are about using 00915 * std::string instead of char[], and the only complicated one 00916 * is the Get function which gets the value as a string. 00917 * 00918 */ 00919 00937 static void Put (const std::string &name, bool value, StatusType * const status) { 00938 SdpPutus(name.c_str(),(unsigned short)value, status); 00939 }; 00954 static void Put (const std::string &name, char value, StatusType * const status) { 00955 SdpPutc(name.c_str(),value,status); 00956 }; 00971 static void Put (const std::string &name,short value, StatusType * const status) { 00972 SdpPuts(name.c_str(),value,status); 00973 }; 00988 static void Put (const std::string &name, unsigned short value, 00989 StatusType * const status) { 00990 SdpPutus(name.c_str(),value,status); 00991 }; 01006 static void Put (const std::string &name, INT32 value, 01007 StatusType * const status) { 01008 SdpPuti(name.c_str(),value,status); 01009 }; 01024 static void Put (const std::string &name, UINT32 value, 01025 StatusType * const status) { 01026 SdpPutu(name.c_str(),value,status); 01027 }; 01028 01043 static void Put (const std::string &name, INT64 value, StatusType * const status) { 01044 SdpPuti64(name.c_str(),value,status); 01045 }; 01060 static void Put (const std::string &name, UINT64 value, StatusType * const status) { 01061 SdpPutu64(name.c_str(),value,status); 01062 }; 01077 static void Put (const std::string &name, float value, StatusType * const status) { 01078 SdpPutf(name.c_str(),value,status); 01079 }; 01094 static void Put (const std::string &name, double value, StatusType * const status) { 01095 SdpPutd(name.c_str(),value,status); 01096 }; 01112 static void Put(const char *name, 01113 const std::string &value, 01114 StatusType *status) { 01115 SdpPutString(name, value.c_str(), status); 01116 } 01132 static void Put(const std::string &name, 01133 const std::string &value, 01134 StatusType *status) { 01135 /* Uses the above function */ 01136 Put(name.c_str(), value, status); 01137 } 01138 01156 static void Get (const std::string &name, bool * value, 01157 StatusType * const status) { 01158 unsigned short v; 01159 SdpGetus(name.c_str(),&v,status); 01160 *value = v ? true : false; 01161 } 01176 static void Get (const std::string &name, char * value, StatusType * const status) { 01177 SdpGetc(name.c_str(),value,status); 01178 } 01194 static void Get (const std::string &name, short * value, StatusType * const status) { 01195 SdpGets(name.c_str(),value,status); 01196 } 01211 static void Get (const std::string &name, unsigned short * value, 01212 StatusType * const status) { 01213 SdpGetus(name.c_str(),value,status); 01214 } 01229 static void Get (const std::string &name, INT32 * value, 01230 StatusType * const status) { 01231 Sdp::Get(name.c_str(),value,status); 01232 } 01247 static void Get (const std::string &name, UINT32 * value, 01248 StatusType * const status) { 01249 Sdp::Get(name.c_str(),value,status); 01250 } 01266 static void Get (const std::string &name, INT64 * value, StatusType * const status) { 01267 SdpGeti64(name.c_str(),value,status); 01268 } 01283 static void Get (const std::string &name, UINT64 * value, StatusType * const status) { 01284 SdpGetu64(name.c_str(),value,status); 01285 } 01300 static void Get (const std::string &name, float * value, StatusType * const status) { 01301 SdpGetf(name.c_str(),value,status); 01302 } 01316 static void Get (const std::string &name, double * value, StatusType * const status) { 01317 SdpGetd(name.c_str(),value,status); 01318 } 01339 static void Get(const char *name, 01340 std::string *value, 01341 StatusType *status, 01342 int buflen = 100) { 01343 01344 /* Find the item we are interested - accessing it via its SDS id */ 01345 SdsId ItemId; 01346 Sdp::Get(name, &ItemId, status); 01347 01348 if (*status != STATUS__OK) return; 01349 01350 char tname[SDS_C_NAMELEN]; 01351 SdsCodeType code; 01352 long ndims; 01353 unsigned long dims[7]; 01354 01355 /* Get details on this item */ 01356 01357 ItemId.Info(tname, &code, &ndims, dims, status); 01358 if (*status != STATUS__OK) return; 01359 01360 if ((code == SDS_CHAR)&&(ndims == 1)) 01361 { 01362 /* Character array. Ensure we have sufficent space */ 01363 buflen = dims[0] + 1; 01364 } 01365 /* 01366 * We need to allocate the buffer to put this into. 01367 */ 01368 char *buffer=0; 01369 buffer = new char[buflen]; 01370 if (buffer == 0) 01371 { 01372 *status = DITS__MALLOCERR; 01373 ErsRep(0, status, "Error allocating %d bytes for Sdp::Get into std::string", 01374 buflen); 01375 return; 01376 } 01377 /* Fetch the value */ 01378 SdpGetString(name, buflen, buffer, status); 01379 01380 /* 01381 * Set up the return and then free the buffer. 01382 */ 01383 if (*status == STATUS__OK) 01384 *value = buffer; 01385 01386 delete[] buffer; 01387 01388 } 01389 01390 /* 01391 * Interface to the above where the name string is a std::string. 01392 * 01393 */ 01414 static void Get(const std::string &name, 01415 std::string *value, 01416 StatusType *status, 01417 int buflen = 100) { 01418 Get(name.c_str(), value, status, buflen); 01419 } 01420 01442 static void GetSds(const std::string &name, SdsIdType * value, 01443 StatusType * status) { 01444 SdpGetSds(name.c_str(),value,status); 01445 } 01464 static void Get(const std::string &name, SdsId * value, 01465 StatusType * status) { 01466 /* 01467 * Need to get as and SdsIdType and shallow copy into the 01468 * id. 01469 */ 01470 SdsIdType id; 01471 SdpGetSds(name.c_str(),&id,status); 01472 value->ShallowCopy(id, true, false, false); 01473 } 01474 01498 static void Put(const std::string &name, const SdsId & value, 01499 StatusType *status) { 01500 SdpPutSds(name.c_str(),(SdsIdType)value,status); 01501 } 01526 static void PutStruct(const std::string &name, 01527 const SdsId &value, 01528 StatusType *status, 01529 const bool create=true ) { 01530 SdpPutStruct(name.c_str(),(SdsIdType)value,(int)true, 01531 (int)create,status); 01532 }; 01560 static void PutStruct(const std::string &name, 01561 SdsId *value, 01562 StatusType *status, 01563 const bool create=true ) { 01564 SdpPutStruct(name.c_str(), 01565 value->COut(true), /* Out value outlives */ 01566 (int)false, 01567 (int)create,status); 01568 }; 01569 01570 01571 #endif /* defined DRAMA_ALLOW_CPP_STDLIB */ 01572 01573 01574 }; 01575 #endif /* C++ */ 01576 01577 #endif /* !defined SDPINC */ 01578
Click here for the DRAMA home page and here for the AAO home page.
For more information, contact tjf@aaoepp.aao.gov.au Generated on Tue Nov 3 09:09:56 2009 for AAO DRAMA C++ Interfaces by
1.2.18