├── README.md ├── bin ├── linux │ ├── README.txt │ ├── mini_export.xml │ └── pooleditparser └── win │ ├── README.txt │ ├── mini_export.xml │ └── pooleditparser.exe ├── include ├── expat.h └── expat_external.h ├── lib ├── libexpat.dll └── libexpat.lib ├── manual ├── PoolEditParser150.odt └── PoolEditParser150.pdf ├── parserxterm.png ├── src ├── Makefile.win ├── parser.cxx ├── parser.h ├── parserdef.h ├── pooleditparser.cxx ├── pooleditparser.dev ├── xml.cxx └── xml.h └── virtualterminal.jpg /README.md: -------------------------------------------------------------------------------- 1 | # PoolEditParser 2 | 3 | Parser for reading [PoolEdit](https://github.com/moehman/PoolEditDist) 4 | XML files and writing binary ISOBUS object pools. This parser is a 5 | part of the implement control application which: 6 | 7 | * reads the XML document 8 | * generates the ISO 11783 binary presentation 9 | * and loads it to the virtual terminal. 10 | 11 | ![Virtual terminal](virtualterminal.jpg) 12 | 13 | Because the XML file is parsed at run-time when the VT properties are 14 | known, the PoolEdit parser can resize the GUI objects and reduce the 15 | number of colors accordingly. Another benefit of the XML format is 16 | that it allows the use of symbolic names for referencing the GUI 17 | objects. The symbolic names are easier to remember than numeric IDs 18 | used in the binary object pool format. 19 | 20 | ![Parser in xterm window](parserxterm.png) 21 | 22 | Please read the manual for more information! 23 | 24 | Current development environment: 25 | * OS: Windows 7 26 | * IDE: Dev-C++ 5.11 (2015-04-27) 27 | * Expat: expat-win32bin-2.2.9.exe 28 | 29 | Or alternatively: 30 | * OS: Oracle Linux 8 (x86_64) 31 | * Compiler: GCC 32 | * Expat: just say `dnf install expat-devel` 33 | 34 | Compiler command to get started: 35 | ``` 36 | g++ pooleditparser.cxx xml.cxx parser.cxx -o pooleditparser -lexpat -O2 -W -Wall -Wextra -pedantic 37 | ``` 38 | -------------------------------------------------------------------------------- /bin/linux/README.txt: -------------------------------------------------------------------------------- 1 | The program executable in this folder has been compiled in Oracle 2 | Linux 8 (x86_64). To run the program, you need to have the Expat 3 | library installed. The easiest way to do this is to use the package 4 | manager: 5 | 6 | $ dnf install expat 7 | 8 | ... or 9 | 10 | $ yum install expat 11 | 12 | ... depending on your system. 13 | 14 | 15 | To compile the code, you also need the header files which are in a 16 | separate package: 17 | 18 | $ dnf install expat-devel 19 | -------------------------------------------------------------------------------- /bin/linux/mini_export.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /bin/linux/pooleditparser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moehman/PoolEditParser/1d06097adbbdef016691c4c1e2f4ff3492f87e9a/bin/linux/pooleditparser -------------------------------------------------------------------------------- /bin/win/README.txt: -------------------------------------------------------------------------------- 1 | To run the program, you need to copy the libexpat.dll file from the 2 | lib directory somewhere so that Windows can find it. The easiest way 3 | is to copy it to the same directory with the program executable. 4 | -------------------------------------------------------------------------------- /bin/win/mini_export.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /bin/win/pooleditparser.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moehman/PoolEditParser/1d06097adbbdef016691c4c1e2f4ff3492f87e9a/bin/win/pooleditparser.exe -------------------------------------------------------------------------------- /include/expat.h: -------------------------------------------------------------------------------- 1 | /* 2 | __ __ _ 3 | ___\ \/ /_ __ __ _| |_ 4 | / _ \\ /| '_ \ / _` | __| 5 | | __// \| |_) | (_| | |_ 6 | \___/_/\_\ .__/ \__,_|\__| 7 | |_| XML parser 8 | 9 | Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 | Copyright (c) 2000-2017 Expat development team 11 | Licensed under the MIT license: 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining 14 | a copy of this software and associated documentation files (the 15 | "Software"), to deal in the Software without restriction, including 16 | without limitation the rights to use, copy, modify, merge, publish, 17 | distribute, sublicense, and/or sell copies of the Software, and to permit 18 | persons to whom the Software is furnished to do so, subject to the 19 | following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included 22 | in all copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 27 | NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 28 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 29 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 30 | USE OR OTHER DEALINGS IN THE SOFTWARE. 31 | */ 32 | 33 | #ifndef Expat_INCLUDED 34 | #define Expat_INCLUDED 1 35 | 36 | #include 37 | #include "expat_external.h" 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | struct XML_ParserStruct; 44 | typedef struct XML_ParserStruct *XML_Parser; 45 | 46 | typedef unsigned char XML_Bool; 47 | #define XML_TRUE ((XML_Bool)1) 48 | #define XML_FALSE ((XML_Bool)0) 49 | 50 | /* The XML_Status enum gives the possible return values for several 51 | API functions. The preprocessor #defines are included so this 52 | stanza can be added to code that still needs to support older 53 | versions of Expat 1.95.x: 54 | 55 | #ifndef XML_STATUS_OK 56 | #define XML_STATUS_OK 1 57 | #define XML_STATUS_ERROR 0 58 | #endif 59 | 60 | Otherwise, the #define hackery is quite ugly and would have been 61 | dropped. 62 | */ 63 | enum XML_Status { 64 | XML_STATUS_ERROR = 0, 65 | #define XML_STATUS_ERROR XML_STATUS_ERROR 66 | XML_STATUS_OK = 1, 67 | #define XML_STATUS_OK XML_STATUS_OK 68 | XML_STATUS_SUSPENDED = 2 69 | #define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED 70 | }; 71 | 72 | enum XML_Error { 73 | XML_ERROR_NONE, 74 | XML_ERROR_NO_MEMORY, 75 | XML_ERROR_SYNTAX, 76 | XML_ERROR_NO_ELEMENTS, 77 | XML_ERROR_INVALID_TOKEN, 78 | XML_ERROR_UNCLOSED_TOKEN, 79 | XML_ERROR_PARTIAL_CHAR, 80 | XML_ERROR_TAG_MISMATCH, 81 | XML_ERROR_DUPLICATE_ATTRIBUTE, 82 | XML_ERROR_JUNK_AFTER_DOC_ELEMENT, 83 | XML_ERROR_PARAM_ENTITY_REF, 84 | XML_ERROR_UNDEFINED_ENTITY, 85 | XML_ERROR_RECURSIVE_ENTITY_REF, 86 | XML_ERROR_ASYNC_ENTITY, 87 | XML_ERROR_BAD_CHAR_REF, 88 | XML_ERROR_BINARY_ENTITY_REF, 89 | XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, 90 | XML_ERROR_MISPLACED_XML_PI, 91 | XML_ERROR_UNKNOWN_ENCODING, 92 | XML_ERROR_INCORRECT_ENCODING, 93 | XML_ERROR_UNCLOSED_CDATA_SECTION, 94 | XML_ERROR_EXTERNAL_ENTITY_HANDLING, 95 | XML_ERROR_NOT_STANDALONE, 96 | XML_ERROR_UNEXPECTED_STATE, 97 | XML_ERROR_ENTITY_DECLARED_IN_PE, 98 | XML_ERROR_FEATURE_REQUIRES_XML_DTD, 99 | XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, 100 | /* Added in 1.95.7. */ 101 | XML_ERROR_UNBOUND_PREFIX, 102 | /* Added in 1.95.8. */ 103 | XML_ERROR_UNDECLARING_PREFIX, 104 | XML_ERROR_INCOMPLETE_PE, 105 | XML_ERROR_XML_DECL, 106 | XML_ERROR_TEXT_DECL, 107 | XML_ERROR_PUBLICID, 108 | XML_ERROR_SUSPENDED, 109 | XML_ERROR_NOT_SUSPENDED, 110 | XML_ERROR_ABORTED, 111 | XML_ERROR_FINISHED, 112 | XML_ERROR_SUSPEND_PE, 113 | /* Added in 2.0. */ 114 | XML_ERROR_RESERVED_PREFIX_XML, 115 | XML_ERROR_RESERVED_PREFIX_XMLNS, 116 | XML_ERROR_RESERVED_NAMESPACE_URI, 117 | /* Added in 2.2.1. */ 118 | XML_ERROR_INVALID_ARGUMENT 119 | }; 120 | 121 | enum XML_Content_Type { 122 | XML_CTYPE_EMPTY = 1, 123 | XML_CTYPE_ANY, 124 | XML_CTYPE_MIXED, 125 | XML_CTYPE_NAME, 126 | XML_CTYPE_CHOICE, 127 | XML_CTYPE_SEQ 128 | }; 129 | 130 | enum XML_Content_Quant { 131 | XML_CQUANT_NONE, 132 | XML_CQUANT_OPT, 133 | XML_CQUANT_REP, 134 | XML_CQUANT_PLUS 135 | }; 136 | 137 | /* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be 138 | XML_CQUANT_NONE, and the other fields will be zero or NULL. 139 | If type == XML_CTYPE_MIXED, then quant will be NONE or REP and 140 | numchildren will contain number of elements that may be mixed in 141 | and children point to an array of XML_Content cells that will be 142 | all of XML_CTYPE_NAME type with no quantification. 143 | 144 | If type == XML_CTYPE_NAME, then the name points to the name, and 145 | the numchildren field will be zero and children will be NULL. The 146 | quant fields indicates any quantifiers placed on the name. 147 | 148 | CHOICE and SEQ will have name NULL, the number of children in 149 | numchildren and children will point, recursively, to an array 150 | of XML_Content cells. 151 | 152 | The EMPTY, ANY, and MIXED types will only occur at top level. 153 | */ 154 | 155 | typedef struct XML_cp XML_Content; 156 | 157 | struct XML_cp { 158 | enum XML_Content_Type type; 159 | enum XML_Content_Quant quant; 160 | XML_Char *name; 161 | unsigned int numchildren; 162 | XML_Content *children; 163 | }; 164 | 165 | /* This is called for an element declaration. See above for 166 | description of the model argument. It's the caller's responsibility 167 | to free model when finished with it. 168 | */ 169 | typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData, 170 | const XML_Char *name, 171 | XML_Content *model); 172 | 173 | XMLPARSEAPI(void) 174 | XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl); 175 | 176 | /* The Attlist declaration handler is called for *each* attribute. So 177 | a single Attlist declaration with multiple attributes declared will 178 | generate multiple calls to this handler. The "default" parameter 179 | may be NULL in the case of the "#IMPLIED" or "#REQUIRED" 180 | keyword. The "isrequired" parameter will be true and the default 181 | value will be NULL in the case of "#REQUIRED". If "isrequired" is 182 | true and default is non-NULL, then this is a "#FIXED" default. 183 | */ 184 | typedef void(XMLCALL *XML_AttlistDeclHandler)( 185 | void *userData, const XML_Char *elname, const XML_Char *attname, 186 | const XML_Char *att_type, const XML_Char *dflt, int isrequired); 187 | 188 | XMLPARSEAPI(void) 189 | XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl); 190 | 191 | /* The XML declaration handler is called for *both* XML declarations 192 | and text declarations. The way to distinguish is that the version 193 | parameter will be NULL for text declarations. The encoding 194 | parameter may be NULL for XML declarations. The standalone 195 | parameter will be -1, 0, or 1 indicating respectively that there 196 | was no standalone parameter in the declaration, that it was given 197 | as no, or that it was given as yes. 198 | */ 199 | typedef void(XMLCALL *XML_XmlDeclHandler)(void *userData, 200 | const XML_Char *version, 201 | const XML_Char *encoding, 202 | int standalone); 203 | 204 | XMLPARSEAPI(void) 205 | XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler xmldecl); 206 | 207 | typedef struct { 208 | void *(*malloc_fcn)(size_t size); 209 | void *(*realloc_fcn)(void *ptr, size_t size); 210 | void (*free_fcn)(void *ptr); 211 | } XML_Memory_Handling_Suite; 212 | 213 | /* Constructs a new parser; encoding is the encoding specified by the 214 | external protocol or NULL if there is none specified. 215 | */ 216 | XMLPARSEAPI(XML_Parser) 217 | XML_ParserCreate(const XML_Char *encoding); 218 | 219 | /* Constructs a new parser and namespace processor. Element type 220 | names and attribute names that belong to a namespace will be 221 | expanded; unprefixed attribute names are never expanded; unprefixed 222 | element type names are expanded only if there is a default 223 | namespace. The expanded name is the concatenation of the namespace 224 | URI, the namespace separator character, and the local part of the 225 | name. If the namespace separator is '\0' then the namespace URI 226 | and the local part will be concatenated without any separator. 227 | It is a programming error to use the separator '\0' with namespace 228 | triplets (see XML_SetReturnNSTriplet). 229 | */ 230 | XMLPARSEAPI(XML_Parser) 231 | XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); 232 | 233 | /* Constructs a new parser using the memory management suite referred to 234 | by memsuite. If memsuite is NULL, then use the standard library memory 235 | suite. If namespaceSeparator is non-NULL it creates a parser with 236 | namespace processing as described above. The character pointed at 237 | will serve as the namespace separator. 238 | 239 | All further memory operations used for the created parser will come from 240 | the given suite. 241 | */ 242 | XMLPARSEAPI(XML_Parser) 243 | XML_ParserCreate_MM(const XML_Char *encoding, 244 | const XML_Memory_Handling_Suite *memsuite, 245 | const XML_Char *namespaceSeparator); 246 | 247 | /* Prepare a parser object to be re-used. This is particularly 248 | valuable when memory allocation overhead is disproportionately high, 249 | such as when a large number of small documnents need to be parsed. 250 | All handlers are cleared from the parser, except for the 251 | unknownEncodingHandler. The parser's external state is re-initialized 252 | except for the values of ns and ns_triplets. 253 | 254 | Added in Expat 1.95.3. 255 | */ 256 | XMLPARSEAPI(XML_Bool) 257 | XML_ParserReset(XML_Parser parser, const XML_Char *encoding); 258 | 259 | /* atts is array of name/value pairs, terminated by 0; 260 | names and values are 0 terminated. 261 | */ 262 | typedef void(XMLCALL *XML_StartElementHandler)(void *userData, 263 | const XML_Char *name, 264 | const XML_Char **atts); 265 | 266 | typedef void(XMLCALL *XML_EndElementHandler)(void *userData, 267 | const XML_Char *name); 268 | 269 | /* s is not 0 terminated. */ 270 | typedef void(XMLCALL *XML_CharacterDataHandler)(void *userData, 271 | const XML_Char *s, int len); 272 | 273 | /* target and data are 0 terminated */ 274 | typedef void(XMLCALL *XML_ProcessingInstructionHandler)(void *userData, 275 | const XML_Char *target, 276 | const XML_Char *data); 277 | 278 | /* data is 0 terminated */ 279 | typedef void(XMLCALL *XML_CommentHandler)(void *userData, const XML_Char *data); 280 | 281 | typedef void(XMLCALL *XML_StartCdataSectionHandler)(void *userData); 282 | typedef void(XMLCALL *XML_EndCdataSectionHandler)(void *userData); 283 | 284 | /* This is called for any characters in the XML document for which 285 | there is no applicable handler. This includes both characters that 286 | are part of markup which is of a kind that is not reported 287 | (comments, markup declarations), or characters that are part of a 288 | construct which could be reported but for which no handler has been 289 | supplied. The characters are passed exactly as they were in the XML 290 | document except that they will be encoded in UTF-8 or UTF-16. 291 | Line boundaries are not normalized. Note that a byte order mark 292 | character is not passed to the default handler. There are no 293 | guarantees about how characters are divided between calls to the 294 | default handler: for example, a comment might be split between 295 | multiple calls. 296 | */ 297 | typedef void(XMLCALL *XML_DefaultHandler)(void *userData, const XML_Char *s, 298 | int len); 299 | 300 | /* This is called for the start of the DOCTYPE declaration, before 301 | any DTD or internal subset is parsed. 302 | */ 303 | typedef void(XMLCALL *XML_StartDoctypeDeclHandler)(void *userData, 304 | const XML_Char *doctypeName, 305 | const XML_Char *sysid, 306 | const XML_Char *pubid, 307 | int has_internal_subset); 308 | 309 | /* This is called for the start of the DOCTYPE declaration when the 310 | closing > is encountered, but after processing any external 311 | subset. 312 | */ 313 | typedef void(XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); 314 | 315 | /* This is called for entity declarations. The is_parameter_entity 316 | argument will be non-zero if the entity is a parameter entity, zero 317 | otherwise. 318 | 319 | For internal entities (), value will 320 | be non-NULL and systemId, publicID, and notationName will be NULL. 321 | The value string is NOT nul-terminated; the length is provided in 322 | the value_length argument. Since it is legal to have zero-length 323 | values, do not use this argument to test for internal entities. 324 | 325 | For external entities, value will be NULL and systemId will be 326 | non-NULL. The publicId argument will be NULL unless a public 327 | identifier was provided. The notationName argument will have a 328 | non-NULL value only for unparsed entity declarations. 329 | 330 | Note that is_parameter_entity can't be changed to XML_Bool, since 331 | that would break binary compatibility. 332 | */ 333 | typedef void(XMLCALL *XML_EntityDeclHandler)( 334 | void *userData, const XML_Char *entityName, int is_parameter_entity, 335 | const XML_Char *value, int value_length, const XML_Char *base, 336 | const XML_Char *systemId, const XML_Char *publicId, 337 | const XML_Char *notationName); 338 | 339 | XMLPARSEAPI(void) 340 | XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler); 341 | 342 | /* OBSOLETE -- OBSOLETE -- OBSOLETE 343 | This handler has been superseded by the EntityDeclHandler above. 344 | It is provided here for backward compatibility. 345 | 346 | This is called for a declaration of an unparsed (NDATA) entity. 347 | The base argument is whatever was set by XML_SetBase. The 348 | entityName, systemId and notationName arguments will never be 349 | NULL. The other arguments may be. 350 | */ 351 | typedef void(XMLCALL *XML_UnparsedEntityDeclHandler)( 352 | void *userData, const XML_Char *entityName, const XML_Char *base, 353 | const XML_Char *systemId, const XML_Char *publicId, 354 | const XML_Char *notationName); 355 | 356 | /* This is called for a declaration of notation. The base argument is 357 | whatever was set by XML_SetBase. The notationName will never be 358 | NULL. The other arguments can be. 359 | */ 360 | typedef void(XMLCALL *XML_NotationDeclHandler)(void *userData, 361 | const XML_Char *notationName, 362 | const XML_Char *base, 363 | const XML_Char *systemId, 364 | const XML_Char *publicId); 365 | 366 | /* When namespace processing is enabled, these are called once for 367 | each namespace declaration. The call to the start and end element 368 | handlers occur between the calls to the start and end namespace 369 | declaration handlers. For an xmlns attribute, prefix will be 370 | NULL. For an xmlns="" attribute, uri will be NULL. 371 | */ 372 | typedef void(XMLCALL *XML_StartNamespaceDeclHandler)(void *userData, 373 | const XML_Char *prefix, 374 | const XML_Char *uri); 375 | 376 | typedef void(XMLCALL *XML_EndNamespaceDeclHandler)(void *userData, 377 | const XML_Char *prefix); 378 | 379 | /* This is called if the document is not standalone, that is, it has an 380 | external subset or a reference to a parameter entity, but does not 381 | have standalone="yes". If this handler returns XML_STATUS_ERROR, 382 | then processing will not continue, and the parser will return a 383 | XML_ERROR_NOT_STANDALONE error. 384 | If parameter entity parsing is enabled, then in addition to the 385 | conditions above this handler will only be called if the referenced 386 | entity was actually read. 387 | */ 388 | typedef int(XMLCALL *XML_NotStandaloneHandler)(void *userData); 389 | 390 | /* This is called for a reference to an external parsed general 391 | entity. The referenced entity is not automatically parsed. The 392 | application can parse it immediately or later using 393 | XML_ExternalEntityParserCreate. 394 | 395 | The parser argument is the parser parsing the entity containing the 396 | reference; it can be passed as the parser argument to 397 | XML_ExternalEntityParserCreate. The systemId argument is the 398 | system identifier as specified in the entity declaration; it will 399 | not be NULL. 400 | 401 | The base argument is the system identifier that should be used as 402 | the base for resolving systemId if systemId was relative; this is 403 | set by XML_SetBase; it may be NULL. 404 | 405 | The publicId argument is the public identifier as specified in the 406 | entity declaration, or NULL if none was specified; the whitespace 407 | in the public identifier will have been normalized as required by 408 | the XML spec. 409 | 410 | The context argument specifies the parsing context in the format 411 | expected by the context argument to XML_ExternalEntityParserCreate; 412 | context is valid only until the handler returns, so if the 413 | referenced entity is to be parsed later, it must be copied. 414 | context is NULL only when the entity is a parameter entity. 415 | 416 | The handler should return XML_STATUS_ERROR if processing should not 417 | continue because of a fatal error in the handling of the external 418 | entity. In this case the calling parser will return an 419 | XML_ERROR_EXTERNAL_ENTITY_HANDLING error. 420 | 421 | Note that unlike other handlers the first argument is the parser, 422 | not userData. 423 | */ 424 | typedef int(XMLCALL *XML_ExternalEntityRefHandler)(XML_Parser parser, 425 | const XML_Char *context, 426 | const XML_Char *base, 427 | const XML_Char *systemId, 428 | const XML_Char *publicId); 429 | 430 | /* This is called in two situations: 431 | 1) An entity reference is encountered for which no declaration 432 | has been read *and* this is not an error. 433 | 2) An internal entity reference is read, but not expanded, because 434 | XML_SetDefaultHandler has been called. 435 | Note: skipped parameter entities in declarations and skipped general 436 | entities in attribute values cannot be reported, because 437 | the event would be out of sync with the reporting of the 438 | declarations or attribute values 439 | */ 440 | typedef void(XMLCALL *XML_SkippedEntityHandler)(void *userData, 441 | const XML_Char *entityName, 442 | int is_parameter_entity); 443 | 444 | /* This structure is filled in by the XML_UnknownEncodingHandler to 445 | provide information to the parser about encodings that are unknown 446 | to the parser. 447 | 448 | The map[b] member gives information about byte sequences whose 449 | first byte is b. 450 | 451 | If map[b] is c where c is >= 0, then b by itself encodes the 452 | Unicode scalar value c. 453 | 454 | If map[b] is -1, then the byte sequence is malformed. 455 | 456 | If map[b] is -n, where n >= 2, then b is the first byte of an 457 | n-byte sequence that encodes a single Unicode scalar value. 458 | 459 | The data member will be passed as the first argument to the convert 460 | function. 461 | 462 | The convert function is used to convert multibyte sequences; s will 463 | point to a n-byte sequence where map[(unsigned char)*s] == -n. The 464 | convert function must return the Unicode scalar value represented 465 | by this byte sequence or -1 if the byte sequence is malformed. 466 | 467 | The convert function may be NULL if the encoding is a single-byte 468 | encoding, that is if map[b] >= -1 for all bytes b. 469 | 470 | When the parser is finished with the encoding, then if release is 471 | not NULL, it will call release passing it the data member; once 472 | release has been called, the convert function will not be called 473 | again. 474 | 475 | Expat places certain restrictions on the encodings that are supported 476 | using this mechanism. 477 | 478 | 1. Every ASCII character that can appear in a well-formed XML document, 479 | other than the characters 480 | 481 | $@\^`{}~ 482 | 483 | must be represented by a single byte, and that byte must be the 484 | same byte that represents that character in ASCII. 485 | 486 | 2. No character may require more than 4 bytes to encode. 487 | 488 | 3. All characters encoded must have Unicode scalar values <= 489 | 0xFFFF, (i.e., characters that would be encoded by surrogates in 490 | UTF-16 are not allowed). Note that this restriction doesn't 491 | apply to the built-in support for UTF-8 and UTF-16. 492 | 493 | 4. No Unicode character may be encoded by more than one distinct 494 | sequence of bytes. 495 | */ 496 | typedef struct { 497 | int map[256]; 498 | void *data; 499 | int(XMLCALL *convert)(void *data, const char *s); 500 | void(XMLCALL *release)(void *data); 501 | } XML_Encoding; 502 | 503 | /* This is called for an encoding that is unknown to the parser. 504 | 505 | The encodingHandlerData argument is that which was passed as the 506 | second argument to XML_SetUnknownEncodingHandler. 507 | 508 | The name argument gives the name of the encoding as specified in 509 | the encoding declaration. 510 | 511 | If the callback can provide information about the encoding, it must 512 | fill in the XML_Encoding structure, and return XML_STATUS_OK. 513 | Otherwise it must return XML_STATUS_ERROR. 514 | 515 | If info does not describe a suitable encoding, then the parser will 516 | return an XML_UNKNOWN_ENCODING error. 517 | */ 518 | typedef int(XMLCALL *XML_UnknownEncodingHandler)(void *encodingHandlerData, 519 | const XML_Char *name, 520 | XML_Encoding *info); 521 | 522 | XMLPARSEAPI(void) 523 | XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, 524 | XML_EndElementHandler end); 525 | 526 | XMLPARSEAPI(void) 527 | XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler handler); 528 | 529 | XMLPARSEAPI(void) 530 | XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler handler); 531 | 532 | XMLPARSEAPI(void) 533 | XML_SetCharacterDataHandler(XML_Parser parser, 534 | XML_CharacterDataHandler handler); 535 | 536 | XMLPARSEAPI(void) 537 | XML_SetProcessingInstructionHandler(XML_Parser parser, 538 | XML_ProcessingInstructionHandler handler); 539 | XMLPARSEAPI(void) 540 | XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler); 541 | 542 | XMLPARSEAPI(void) 543 | XML_SetCdataSectionHandler(XML_Parser parser, 544 | XML_StartCdataSectionHandler start, 545 | XML_EndCdataSectionHandler end); 546 | 547 | XMLPARSEAPI(void) 548 | XML_SetStartCdataSectionHandler(XML_Parser parser, 549 | XML_StartCdataSectionHandler start); 550 | 551 | XMLPARSEAPI(void) 552 | XML_SetEndCdataSectionHandler(XML_Parser parser, 553 | XML_EndCdataSectionHandler end); 554 | 555 | /* This sets the default handler and also inhibits expansion of 556 | internal entities. These entity references will be passed to the 557 | default handler, or to the skipped entity handler, if one is set. 558 | */ 559 | XMLPARSEAPI(void) 560 | XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler); 561 | 562 | /* This sets the default handler but does not inhibit expansion of 563 | internal entities. The entity reference will not be passed to the 564 | default handler. 565 | */ 566 | XMLPARSEAPI(void) 567 | XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler); 568 | 569 | XMLPARSEAPI(void) 570 | XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, 571 | XML_EndDoctypeDeclHandler end); 572 | 573 | XMLPARSEAPI(void) 574 | XML_SetStartDoctypeDeclHandler(XML_Parser parser, 575 | XML_StartDoctypeDeclHandler start); 576 | 577 | XMLPARSEAPI(void) 578 | XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end); 579 | 580 | XMLPARSEAPI(void) 581 | XML_SetUnparsedEntityDeclHandler(XML_Parser parser, 582 | XML_UnparsedEntityDeclHandler handler); 583 | 584 | XMLPARSEAPI(void) 585 | XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler); 586 | 587 | XMLPARSEAPI(void) 588 | XML_SetNamespaceDeclHandler(XML_Parser parser, 589 | XML_StartNamespaceDeclHandler start, 590 | XML_EndNamespaceDeclHandler end); 591 | 592 | XMLPARSEAPI(void) 593 | XML_SetStartNamespaceDeclHandler(XML_Parser parser, 594 | XML_StartNamespaceDeclHandler start); 595 | 596 | XMLPARSEAPI(void) 597 | XML_SetEndNamespaceDeclHandler(XML_Parser parser, 598 | XML_EndNamespaceDeclHandler end); 599 | 600 | XMLPARSEAPI(void) 601 | XML_SetNotStandaloneHandler(XML_Parser parser, 602 | XML_NotStandaloneHandler handler); 603 | 604 | XMLPARSEAPI(void) 605 | XML_SetExternalEntityRefHandler(XML_Parser parser, 606 | XML_ExternalEntityRefHandler handler); 607 | 608 | /* If a non-NULL value for arg is specified here, then it will be 609 | passed as the first argument to the external entity ref handler 610 | instead of the parser object. 611 | */ 612 | XMLPARSEAPI(void) 613 | XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg); 614 | 615 | XMLPARSEAPI(void) 616 | XML_SetSkippedEntityHandler(XML_Parser parser, 617 | XML_SkippedEntityHandler handler); 618 | 619 | XMLPARSEAPI(void) 620 | XML_SetUnknownEncodingHandler(XML_Parser parser, 621 | XML_UnknownEncodingHandler handler, 622 | void *encodingHandlerData); 623 | 624 | /* This can be called within a handler for a start element, end 625 | element, processing instruction or character data. It causes the 626 | corresponding markup to be passed to the default handler. 627 | */ 628 | XMLPARSEAPI(void) 629 | XML_DefaultCurrent(XML_Parser parser); 630 | 631 | /* If do_nst is non-zero, and namespace processing is in effect, and 632 | a name has a prefix (i.e. an explicit namespace qualifier) then 633 | that name is returned as a triplet in a single string separated by 634 | the separator character specified when the parser was created: URI 635 | + sep + local_name + sep + prefix. 636 | 637 | If do_nst is zero, then namespace information is returned in the 638 | default manner (URI + sep + local_name) whether or not the name 639 | has a prefix. 640 | 641 | Note: Calling XML_SetReturnNSTriplet after XML_Parse or 642 | XML_ParseBuffer has no effect. 643 | */ 644 | 645 | XMLPARSEAPI(void) 646 | XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); 647 | 648 | /* This value is passed as the userData argument to callbacks. */ 649 | XMLPARSEAPI(void) 650 | XML_SetUserData(XML_Parser parser, void *userData); 651 | 652 | /* Returns the last value set by XML_SetUserData or NULL. */ 653 | #define XML_GetUserData(parser) (*(void **)(parser)) 654 | 655 | /* This is equivalent to supplying an encoding argument to 656 | XML_ParserCreate. On success XML_SetEncoding returns non-zero, 657 | zero otherwise. 658 | Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer 659 | has no effect and returns XML_STATUS_ERROR. 660 | */ 661 | XMLPARSEAPI(enum XML_Status) 662 | XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); 663 | 664 | /* If this function is called, then the parser will be passed as the 665 | first argument to callbacks instead of userData. The userData will 666 | still be accessible using XML_GetUserData. 667 | */ 668 | XMLPARSEAPI(void) 669 | XML_UseParserAsHandlerArg(XML_Parser parser); 670 | 671 | /* If useDTD == XML_TRUE is passed to this function, then the parser 672 | will assume that there is an external subset, even if none is 673 | specified in the document. In such a case the parser will call the 674 | externalEntityRefHandler with a value of NULL for the systemId 675 | argument (the publicId and context arguments will be NULL as well). 676 | Note: For the purpose of checking WFC: Entity Declared, passing 677 | useDTD == XML_TRUE will make the parser behave as if the document 678 | had a DTD with an external subset. 679 | Note: If this function is called, then this must be done before 680 | the first call to XML_Parse or XML_ParseBuffer, since it will 681 | have no effect after that. Returns 682 | XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. 683 | Note: If the document does not have a DOCTYPE declaration at all, 684 | then startDoctypeDeclHandler and endDoctypeDeclHandler will not 685 | be called, despite an external subset being parsed. 686 | Note: If XML_DTD is not defined when Expat is compiled, returns 687 | XML_ERROR_FEATURE_REQUIRES_XML_DTD. 688 | Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. 689 | */ 690 | XMLPARSEAPI(enum XML_Error) 691 | XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); 692 | 693 | /* Sets the base to be used for resolving relative URIs in system 694 | identifiers in declarations. Resolving relative identifiers is 695 | left to the application: this value will be passed through as the 696 | base argument to the XML_ExternalEntityRefHandler, 697 | XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base 698 | argument will be copied. Returns XML_STATUS_ERROR if out of memory, 699 | XML_STATUS_OK otherwise. 700 | */ 701 | XMLPARSEAPI(enum XML_Status) 702 | XML_SetBase(XML_Parser parser, const XML_Char *base); 703 | 704 | XMLPARSEAPI(const XML_Char *) 705 | XML_GetBase(XML_Parser parser); 706 | 707 | /* Returns the number of the attribute/value pairs passed in last call 708 | to the XML_StartElementHandler that were specified in the start-tag 709 | rather than defaulted. Each attribute/value pair counts as 2; thus 710 | this correspondds to an index into the atts array passed to the 711 | XML_StartElementHandler. Returns -1 if parser == NULL. 712 | */ 713 | XMLPARSEAPI(int) 714 | XML_GetSpecifiedAttributeCount(XML_Parser parser); 715 | 716 | /* Returns the index of the ID attribute passed in the last call to 717 | XML_StartElementHandler, or -1 if there is no ID attribute or 718 | parser == NULL. Each attribute/value pair counts as 2; thus this 719 | correspondds to an index into the atts array passed to the 720 | XML_StartElementHandler. 721 | */ 722 | XMLPARSEAPI(int) 723 | XML_GetIdAttributeIndex(XML_Parser parser); 724 | 725 | #ifdef XML_ATTR_INFO 726 | /* Source file byte offsets for the start and end of attribute names and values. 727 | The value indices are exclusive of surrounding quotes; thus in a UTF-8 source 728 | file an attribute value of "blah" will yield: 729 | info->valueEnd - info->valueStart = 4 bytes. 730 | */ 731 | typedef struct { 732 | XML_Index nameStart; /* Offset to beginning of the attribute name. */ 733 | XML_Index nameEnd; /* Offset after the attribute name's last byte. */ 734 | XML_Index valueStart; /* Offset to beginning of the attribute value. */ 735 | XML_Index valueEnd; /* Offset after the attribute value's last byte. */ 736 | } XML_AttrInfo; 737 | 738 | /* Returns an array of XML_AttrInfo structures for the attribute/value pairs 739 | passed in last call to the XML_StartElementHandler that were specified 740 | in the start-tag rather than defaulted. Each attribute/value pair counts 741 | as 1; thus the number of entries in the array is 742 | XML_GetSpecifiedAttributeCount(parser) / 2. 743 | */ 744 | XMLPARSEAPI(const XML_AttrInfo *) 745 | XML_GetAttributeInfo(XML_Parser parser); 746 | #endif 747 | 748 | /* Parses some input. Returns XML_STATUS_ERROR if a fatal error is 749 | detected. The last call to XML_Parse must have isFinal true; len 750 | may be zero for this call (or any other). 751 | 752 | Though the return values for these functions has always been 753 | described as a Boolean value, the implementation, at least for the 754 | 1.95.x series, has always returned exactly one of the XML_Status 755 | values. 756 | */ 757 | XMLPARSEAPI(enum XML_Status) 758 | XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); 759 | 760 | XMLPARSEAPI(void *) 761 | XML_GetBuffer(XML_Parser parser, int len); 762 | 763 | XMLPARSEAPI(enum XML_Status) 764 | XML_ParseBuffer(XML_Parser parser, int len, int isFinal); 765 | 766 | /* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. 767 | Must be called from within a call-back handler, except when aborting 768 | (resumable = 0) an already suspended parser. Some call-backs may 769 | still follow because they would otherwise get lost. Examples: 770 | - endElementHandler() for empty elements when stopped in 771 | startElementHandler(), 772 | - endNameSpaceDeclHandler() when stopped in endElementHandler(), 773 | and possibly others. 774 | 775 | Can be called from most handlers, including DTD related call-backs, 776 | except when parsing an external parameter entity and resumable != 0. 777 | Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. 778 | Possible error codes: 779 | - XML_ERROR_SUSPENDED: when suspending an already suspended parser. 780 | - XML_ERROR_FINISHED: when the parser has already finished. 781 | - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. 782 | 783 | When resumable != 0 (true) then parsing is suspended, that is, 784 | XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. 785 | Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() 786 | return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. 787 | 788 | *Note*: 789 | This will be applied to the current parser instance only, that is, if 790 | there is a parent parser then it will continue parsing when the 791 | externalEntityRefHandler() returns. It is up to the implementation of 792 | the externalEntityRefHandler() to call XML_StopParser() on the parent 793 | parser (recursively), if one wants to stop parsing altogether. 794 | 795 | When suspended, parsing can be resumed by calling XML_ResumeParser(). 796 | */ 797 | XMLPARSEAPI(enum XML_Status) 798 | XML_StopParser(XML_Parser parser, XML_Bool resumable); 799 | 800 | /* Resumes parsing after it has been suspended with XML_StopParser(). 801 | Must not be called from within a handler call-back. Returns same 802 | status codes as XML_Parse() or XML_ParseBuffer(). 803 | Additional error code XML_ERROR_NOT_SUSPENDED possible. 804 | 805 | *Note*: 806 | This must be called on the most deeply nested child parser instance 807 | first, and on its parent parser only after the child parser has finished, 808 | to be applied recursively until the document entity's parser is restarted. 809 | That is, the parent parser will not resume by itself and it is up to the 810 | application to call XML_ResumeParser() on it at the appropriate moment. 811 | */ 812 | XMLPARSEAPI(enum XML_Status) 813 | XML_ResumeParser(XML_Parser parser); 814 | 815 | enum XML_Parsing { XML_INITIALIZED, XML_PARSING, XML_FINISHED, XML_SUSPENDED }; 816 | 817 | typedef struct { 818 | enum XML_Parsing parsing; 819 | XML_Bool finalBuffer; 820 | } XML_ParsingStatus; 821 | 822 | /* Returns status of parser with respect to being initialized, parsing, 823 | finished, or suspended and processing the final buffer. 824 | XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, 825 | XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED 826 | */ 827 | XMLPARSEAPI(void) 828 | XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); 829 | 830 | /* Creates an XML_Parser object that can parse an external general 831 | entity; context is a '\0'-terminated string specifying the parse 832 | context; encoding is a '\0'-terminated string giving the name of 833 | the externally specified encoding, or NULL if there is no 834 | externally specified encoding. The context string consists of a 835 | sequence of tokens separated by formfeeds (\f); a token consisting 836 | of a name specifies that the general entity of the name is open; a 837 | token of the form prefix=uri specifies the namespace for a 838 | particular prefix; a token of the form =uri specifies the default 839 | namespace. This can be called at any point after the first call to 840 | an ExternalEntityRefHandler so longer as the parser has not yet 841 | been freed. The new parser is completely independent and may 842 | safely be used in a separate thread. The handlers and userData are 843 | initialized from the parser argument. Returns NULL if out of memory. 844 | Otherwise returns a new XML_Parser object. 845 | */ 846 | XMLPARSEAPI(XML_Parser) 847 | XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context, 848 | const XML_Char *encoding); 849 | 850 | enum XML_ParamEntityParsing { 851 | XML_PARAM_ENTITY_PARSING_NEVER, 852 | XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, 853 | XML_PARAM_ENTITY_PARSING_ALWAYS 854 | }; 855 | 856 | /* Controls parsing of parameter entities (including the external DTD 857 | subset). If parsing of parameter entities is enabled, then 858 | references to external parameter entities (including the external 859 | DTD subset) will be passed to the handler set with 860 | XML_SetExternalEntityRefHandler. The context passed will be 0. 861 | 862 | Unlike external general entities, external parameter entities can 863 | only be parsed synchronously. If the external parameter entity is 864 | to be parsed, it must be parsed during the call to the external 865 | entity ref handler: the complete sequence of 866 | XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and 867 | XML_ParserFree calls must be made during this call. After 868 | XML_ExternalEntityParserCreate has been called to create the parser 869 | for the external parameter entity (context must be 0 for this 870 | call), it is illegal to make any calls on the old parser until 871 | XML_ParserFree has been called on the newly created parser. 872 | If the library has been compiled without support for parameter 873 | entity parsing (ie without XML_DTD being defined), then 874 | XML_SetParamEntityParsing will return 0 if parsing of parameter 875 | entities is requested; otherwise it will return non-zero. 876 | Note: If XML_SetParamEntityParsing is called after XML_Parse or 877 | XML_ParseBuffer, then it has no effect and will always return 0. 878 | Note: If parser == NULL, the function will do nothing and return 0. 879 | */ 880 | XMLPARSEAPI(int) 881 | XML_SetParamEntityParsing(XML_Parser parser, 882 | enum XML_ParamEntityParsing parsing); 883 | 884 | /* Sets the hash salt to use for internal hash calculations. 885 | Helps in preventing DoS attacks based on predicting hash 886 | function behavior. This must be called before parsing is started. 887 | Returns 1 if successful, 0 when called after parsing has started. 888 | Note: If parser == NULL, the function will do nothing and return 0. 889 | */ 890 | XMLPARSEAPI(int) 891 | XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt); 892 | 893 | /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then 894 | XML_GetErrorCode returns information about the error. 895 | */ 896 | XMLPARSEAPI(enum XML_Error) 897 | XML_GetErrorCode(XML_Parser parser); 898 | 899 | /* These functions return information about the current parse 900 | location. They may be called from any callback called to report 901 | some parse event; in this case the location is the location of the 902 | first of the sequence of characters that generated the event. When 903 | called from callbacks generated by declarations in the document 904 | prologue, the location identified isn't as neatly defined, but will 905 | be within the relevant markup. When called outside of the callback 906 | functions, the position indicated will be just past the last parse 907 | event (regardless of whether there was an associated callback). 908 | 909 | They may also be called after returning from a call to XML_Parse 910 | or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then 911 | the location is the location of the character at which the error 912 | was detected; otherwise the location is the location of the last 913 | parse event, as described above. 914 | 915 | Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber 916 | return 0 to indicate an error. 917 | Note: XML_GetCurrentByteIndex returns -1 to indicate an error. 918 | */ 919 | XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); 920 | XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); 921 | XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); 922 | 923 | /* Return the number of bytes in the current event. 924 | Returns 0 if the event is in an internal entity. 925 | */ 926 | XMLPARSEAPI(int) 927 | XML_GetCurrentByteCount(XML_Parser parser); 928 | 929 | /* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets 930 | the integer pointed to by offset to the offset within this buffer 931 | of the current parse position, and sets the integer pointed to by size 932 | to the size of this buffer (the number of input bytes). Otherwise 933 | returns a NULL pointer. Also returns a NULL pointer if a parse isn't 934 | active. 935 | 936 | NOTE: The character pointer returned should not be used outside 937 | the handler that makes the call. 938 | */ 939 | XMLPARSEAPI(const char *) 940 | XML_GetInputContext(XML_Parser parser, int *offset, int *size); 941 | 942 | /* For backwards compatibility with previous versions. */ 943 | #define XML_GetErrorLineNumber XML_GetCurrentLineNumber 944 | #define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber 945 | #define XML_GetErrorByteIndex XML_GetCurrentByteIndex 946 | 947 | /* Frees the content model passed to the element declaration handler */ 948 | XMLPARSEAPI(void) 949 | XML_FreeContentModel(XML_Parser parser, XML_Content *model); 950 | 951 | /* Exposing the memory handling functions used in Expat */ 952 | XMLPARSEAPI(void *) 953 | XML_ATTR_MALLOC 954 | XML_ATTR_ALLOC_SIZE(2) 955 | XML_MemMalloc(XML_Parser parser, size_t size); 956 | 957 | XMLPARSEAPI(void *) 958 | XML_ATTR_ALLOC_SIZE(3) 959 | XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); 960 | 961 | XMLPARSEAPI(void) 962 | XML_MemFree(XML_Parser parser, void *ptr); 963 | 964 | /* Frees memory used by the parser. */ 965 | XMLPARSEAPI(void) 966 | XML_ParserFree(XML_Parser parser); 967 | 968 | /* Returns a string describing the error. */ 969 | XMLPARSEAPI(const XML_LChar *) 970 | XML_ErrorString(enum XML_Error code); 971 | 972 | /* Return a string containing the version number of this expat */ 973 | XMLPARSEAPI(const XML_LChar *) 974 | XML_ExpatVersion(void); 975 | 976 | typedef struct { 977 | int major; 978 | int minor; 979 | int micro; 980 | } XML_Expat_Version; 981 | 982 | /* Return an XML_Expat_Version structure containing numeric version 983 | number information for this version of expat. 984 | */ 985 | XMLPARSEAPI(XML_Expat_Version) 986 | XML_ExpatVersionInfo(void); 987 | 988 | /* Added in Expat 1.95.5. */ 989 | enum XML_FeatureEnum { 990 | XML_FEATURE_END = 0, 991 | XML_FEATURE_UNICODE, 992 | XML_FEATURE_UNICODE_WCHAR_T, 993 | XML_FEATURE_DTD, 994 | XML_FEATURE_CONTEXT_BYTES, 995 | XML_FEATURE_MIN_SIZE, 996 | XML_FEATURE_SIZEOF_XML_CHAR, 997 | XML_FEATURE_SIZEOF_XML_LCHAR, 998 | XML_FEATURE_NS, 999 | XML_FEATURE_LARGE_SIZE, 1000 | XML_FEATURE_ATTR_INFO 1001 | /* Additional features must be added to the end of this enum. */ 1002 | }; 1003 | 1004 | typedef struct { 1005 | enum XML_FeatureEnum feature; 1006 | const XML_LChar *name; 1007 | long int value; 1008 | } XML_Feature; 1009 | 1010 | XMLPARSEAPI(const XML_Feature *) 1011 | XML_GetFeatureList(void); 1012 | 1013 | /* Expat follows the semantic versioning convention. 1014 | See http://semver.org. 1015 | */ 1016 | #define XML_MAJOR_VERSION 2 1017 | #define XML_MINOR_VERSION 2 1018 | #define XML_MICRO_VERSION 9 1019 | 1020 | #ifdef __cplusplus 1021 | } 1022 | #endif 1023 | 1024 | #endif /* not Expat_INCLUDED */ 1025 | -------------------------------------------------------------------------------- /include/expat_external.h: -------------------------------------------------------------------------------- 1 | /* 2 | __ __ _ 3 | ___\ \/ /_ __ __ _| |_ 4 | / _ \\ /| '_ \ / _` | __| 5 | | __// \| |_) | (_| | |_ 6 | \___/_/\_\ .__/ \__,_|\__| 7 | |_| XML parser 8 | 9 | Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10 | Copyright (c) 2000-2017 Expat development team 11 | Licensed under the MIT license: 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining 14 | a copy of this software and associated documentation files (the 15 | "Software"), to deal in the Software without restriction, including 16 | without limitation the rights to use, copy, modify, merge, publish, 17 | distribute, sublicense, and/or sell copies of the Software, and to permit 18 | persons to whom the Software is furnished to do so, subject to the 19 | following conditions: 20 | 21 | The above copyright notice and this permission notice shall be included 22 | in all copies or substantial portions of the Software. 23 | 24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 27 | NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 28 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 29 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 30 | USE OR OTHER DEALINGS IN THE SOFTWARE. 31 | */ 32 | 33 | #ifndef Expat_External_INCLUDED 34 | #define Expat_External_INCLUDED 1 35 | 36 | /* External API definitions */ 37 | 38 | /* Expat tries very hard to make the API boundary very specifically 39 | defined. There are two macros defined to control this boundary; 40 | each of these can be defined before including this header to 41 | achieve some different behavior, but doing so it not recommended or 42 | tested frequently. 43 | 44 | XMLCALL - The calling convention to use for all calls across the 45 | "library boundary." This will default to cdecl, and 46 | try really hard to tell the compiler that's what we 47 | want. 48 | 49 | XMLIMPORT - Whatever magic is needed to note that a function is 50 | to be imported from a dynamically loaded library 51 | (.dll, .so, or .sl, depending on your platform). 52 | 53 | The XMLCALL macro was added in Expat 1.95.7. The only one which is 54 | expected to be directly useful in client code is XMLCALL. 55 | 56 | Note that on at least some Unix versions, the Expat library must be 57 | compiled with the cdecl calling convention as the default since 58 | system headers may assume the cdecl convention. 59 | */ 60 | #ifndef XMLCALL 61 | # if defined(_MSC_VER) 62 | # define XMLCALL __cdecl 63 | # elif defined(__GNUC__) && defined(__i386) && ! defined(__INTEL_COMPILER) 64 | # define XMLCALL __attribute__((cdecl)) 65 | # else 66 | /* For any platform which uses this definition and supports more than 67 | one calling convention, we need to extend this definition to 68 | declare the convention used on that platform, if it's possible to 69 | do so. 70 | 71 | If this is the case for your platform, please file a bug report 72 | with information on how to identify your platform via the C 73 | pre-processor and how to specify the same calling convention as the 74 | platform's malloc() implementation. 75 | */ 76 | # define XMLCALL 77 | # endif 78 | #endif /* not defined XMLCALL */ 79 | 80 | #if ! defined(XML_STATIC) && ! defined(XMLIMPORT) 81 | # ifndef XML_BUILDING_EXPAT 82 | /* using Expat from an application */ 83 | 84 | # if defined(_MSC_EXTENSIONS) && ! defined(__BEOS__) && ! defined(__CYGWIN__) 85 | # define XMLIMPORT __declspec(dllimport) 86 | # endif 87 | 88 | # endif 89 | #endif /* not defined XML_STATIC */ 90 | 91 | #ifndef XML_ENABLE_VISIBILITY 92 | # define XML_ENABLE_VISIBILITY 0 93 | #endif 94 | 95 | #if ! defined(XMLIMPORT) && XML_ENABLE_VISIBILITY 96 | # define XMLIMPORT __attribute__((visibility("default"))) 97 | #endif 98 | 99 | /* If we didn't define it above, define it away: */ 100 | #ifndef XMLIMPORT 101 | # define XMLIMPORT 102 | #endif 103 | 104 | #if defined(__GNUC__) \ 105 | && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)) 106 | # define XML_ATTR_MALLOC __attribute__((__malloc__)) 107 | #else 108 | # define XML_ATTR_MALLOC 109 | #endif 110 | 111 | #if defined(__GNUC__) \ 112 | && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) 113 | # define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x))) 114 | #else 115 | # define XML_ATTR_ALLOC_SIZE(x) 116 | #endif 117 | 118 | #define XMLPARSEAPI(type) XMLIMPORT type XMLCALL 119 | 120 | #ifdef __cplusplus 121 | extern "C" { 122 | #endif 123 | 124 | #ifdef XML_UNICODE_WCHAR_T 125 | # ifndef XML_UNICODE 126 | # define XML_UNICODE 127 | # endif 128 | # if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2) 129 | # error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc" 130 | # endif 131 | #endif 132 | 133 | #ifdef XML_UNICODE /* Information is UTF-16 encoded. */ 134 | # ifdef XML_UNICODE_WCHAR_T 135 | typedef wchar_t XML_Char; 136 | typedef wchar_t XML_LChar; 137 | # else 138 | typedef unsigned short XML_Char; 139 | typedef char XML_LChar; 140 | # endif /* XML_UNICODE_WCHAR_T */ 141 | #else /* Information is UTF-8 encoded. */ 142 | typedef char XML_Char; 143 | typedef char XML_LChar; 144 | #endif /* XML_UNICODE */ 145 | 146 | #ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */ 147 | typedef long long XML_Index; 148 | typedef unsigned long long XML_Size; 149 | #else 150 | typedef long XML_Index; 151 | typedef unsigned long XML_Size; 152 | #endif /* XML_LARGE_SIZE */ 153 | 154 | #ifdef __cplusplus 155 | } 156 | #endif 157 | 158 | #endif /* not Expat_External_INCLUDED */ 159 | -------------------------------------------------------------------------------- /lib/libexpat.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moehman/PoolEditParser/1d06097adbbdef016691c4c1e2f4ff3492f87e9a/lib/libexpat.dll -------------------------------------------------------------------------------- /lib/libexpat.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moehman/PoolEditParser/1d06097adbbdef016691c4c1e2f4ff3492f87e9a/lib/libexpat.lib -------------------------------------------------------------------------------- /manual/PoolEditParser150.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moehman/PoolEditParser/1d06097adbbdef016691c4c1e2f4ff3492f87e9a/manual/PoolEditParser150.odt -------------------------------------------------------------------------------- /manual/PoolEditParser150.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moehman/PoolEditParser/1d06097adbbdef016691c4c1e2f4ff3492f87e9a/manual/PoolEditParser150.pdf -------------------------------------------------------------------------------- /parserxterm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moehman/PoolEditParser/1d06097adbbdef016691c4c1e2f4ff3492f87e9a/parserxterm.png -------------------------------------------------------------------------------- /src/Makefile.win: -------------------------------------------------------------------------------- 1 | # Project: pooleditparser 2 | # Makefile created by Dev-C++ 5.11 3 | 4 | CPP = g++.exe 5 | CC = gcc.exe 6 | WINDRES = windres.exe 7 | OBJ = parser.o pooleditparser.o xml.o 8 | LINKOBJ = parser.o pooleditparser.o xml.o 9 | LIBS = -L"C:/Software/Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib32" -static-libgcc -L"../lib" -lexpat -m32 -s 10 | INCS = -I"C:/Software/Dev-Cpp/MinGW64/include" -I"C:/Software/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Software/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" 11 | CXXINCS = -I"C:/Software/Dev-Cpp/MinGW64/include" -I"C:/Software/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Software/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -I"C:/Software/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++" 12 | BIN = pooleditparser.exe 13 | CXXFLAGS = $(CXXINCS) -O2 -m32 -Wall -Wextra -pedantic 14 | CFLAGS = $(INCS) -O2 -m32 -Wall -Wextra -pedantic 15 | RM = rm.exe -f 16 | 17 | .PHONY: all all-before all-after clean clean-custom 18 | 19 | all: all-before $(BIN) all-after 20 | 21 | clean: clean-custom 22 | ${RM} $(OBJ) $(BIN) 23 | 24 | $(BIN): $(OBJ) 25 | $(CPP) $(LINKOBJ) -o $(BIN) $(LIBS) 26 | 27 | parser.o: parser.cxx 28 | $(CPP) -c parser.cxx -o parser.o $(CXXFLAGS) 29 | 30 | pooleditparser.o: pooleditparser.cxx 31 | $(CPP) -c pooleditparser.cxx -o pooleditparser.o $(CXXFLAGS) 32 | 33 | xml.o: xml.cxx 34 | $(CPP) -c xml.cxx -o xml.o $(CXXFLAGS) 35 | -------------------------------------------------------------------------------- /src/parser.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2019 Automation technology laboratory, 3 | * Helsinki University of Technology 4 | * 5 | * Visit automation.tkk.fi for information about the automation 6 | * technology laboratory. 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 3 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 21 | * MA 02111-1307, USA. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "xml.h" 29 | #include "parser.h" 30 | #include "../include/expat.h" 31 | #include "parserdef.h" 32 | 33 | // the maxium depth of xml-tree 34 | #define MAX_STACK 256 35 | void *objectStack[MAX_STACK]; 36 | int objectsInStack = 0; 37 | 38 | // info about working sets and softkey dimensions 39 | int vtDimension; 40 | int vtSkWidth; 41 | int vtSkHeight; 42 | 43 | pool_xform_t xform; 44 | /* 45 | int dm_dx, dm_dy; 46 | int sk_dx, sk_dy; 47 | 48 | float dm_mult, sk_mult; // how much should all coordinates be multiplied 49 | */ 50 | float multiplier; // current multiplier 51 | 52 | // number of colors (2, 16 or 256) in the VT 53 | int vtColors; 54 | 55 | // pictureData that is in Base64 56 | int dataReading = 0; // tells if now reading data 57 | char *dataText = NULL; 58 | int dataLength =0; 59 | 60 | void (*readyFunct)(char *data, int length); 61 | void (*startFunct)(void *data, char *el, const char ** attr); 62 | void (*endFunct)(void *data, char *el); 63 | 64 | pool_xform_t *get_pool_xform() 65 | { 66 | return &xform; 67 | } 68 | 69 | // returns the type of object 70 | int getObjectType(void *object) 71 | { 72 | return ((ObjectHeader *) object)->type; 73 | } 74 | 75 | // returns the object id of object 76 | int getObjectId(void *object) 77 | { 78 | return ((ObjectHeader *) object)->objectId; 79 | } 80 | 81 | // returns the number (function) of a command or -1 if no such command 82 | // is supported 83 | int getCommandFunction(const char *name) 84 | { 85 | if (name == NULL) 86 | return -1; 87 | 88 | int i; 89 | for (i = 0; (commands[i] != NULL) && (strcmp(commands[i], name) != 0); i++) 90 | ; 91 | 92 | if (commands[i] == NULL) 93 | return -1; 94 | 95 | return commandFunction[i]; 96 | } 97 | 98 | // returns the type of the given event, or -1 if no such event 99 | int getEventId(const char *name) 100 | { 101 | if (name == NULL) 102 | return -1; 103 | 104 | for (int i = 0; i < 26; i++) 105 | if (strcmp(events[i], name) == 0) 106 | return i + 1; 107 | 108 | return -1; 109 | } 110 | 111 | #define OBJECT_MACRO_INDEX(type, object) (sizeof(type) + ((type *) object)->objects * sizeof(ObjectReference) + ((type *) object)->macros * sizeof(MacroReference)) 112 | #define MACRO_INDEX(type, object) (sizeof(type) + ((type *) object)->macros * sizeof(MacroReference)) 113 | 114 | // this function returns the real size of a object given to it 115 | // use this instead of sizeof()-function. 116 | // objects must be initialized before calling this! 117 | int getRealSize(void *object) { 118 | 119 | switch (getObjectType(object)) { 120 | case 0: 121 | { 122 | WorkingSet *workingSet = (WorkingSet *) object; 123 | return sizeof(WorkingSet) + workingSet->objects * sizeof(ObjectReference) 124 | + workingSet->macros * sizeof(MacroReference) 125 | + workingSet->languageCodes * sizeof(LanguageCode); 126 | } 127 | case 1: 128 | return OBJECT_MACRO_INDEX(DataMask, object); 129 | 130 | case 2: 131 | return OBJECT_MACRO_INDEX(AlarmMask, object); 132 | 133 | case 3: 134 | return OBJECT_MACRO_INDEX(Container, object); 135 | 136 | case 4: 137 | // special case! 138 | { 139 | SoftKeyMask *softKeyMask = (SoftKeyMask *) object; 140 | return sizeof(SoftKeyMask) + softKeyMask->objects * sizeof(unsigned short) 141 | + softKeyMask->macros * sizeof(MacroReference); 142 | } 143 | 144 | case 5: 145 | return OBJECT_MACRO_INDEX(Key, object); 146 | 147 | case 6: 148 | return OBJECT_MACRO_INDEX(Button, object); 149 | 150 | case 7: 151 | return MACRO_INDEX(InputBoolean, object); 152 | 153 | case 8: 154 | { 155 | InputString *inputString = (InputString *) object; 156 | return sizeof(InputString) + inputString->length * sizeof(unsigned char) 157 | + *inputStringMacros(inputString) * sizeof(MacroReference) + 2; 158 | } 159 | 160 | case 9: 161 | return MACRO_INDEX(InputNumber, object); 162 | 163 | case 10: 164 | { 165 | InputList *inputList = (InputList *) object; 166 | return sizeof(InputList) + inputList->numberOfListItems * sizeof(unsigned short) 167 | + inputList->macros * sizeof(MacroReference); 168 | } 169 | 170 | case 11: 171 | { 172 | OutputString *outputString = (OutputString *) object; 173 | return sizeof(OutputString) + outputString->length * sizeof(unsigned char) 174 | + *outputStringMacros(outputString) * sizeof(MacroReference) +1; 175 | } 176 | 177 | case 12: 178 | return MACRO_INDEX(OutputNumber, object); 179 | 180 | case 13: 181 | return MACRO_INDEX(Line, object); 182 | 183 | case 14: 184 | return MACRO_INDEX(Rectangle, object); 185 | 186 | case 15: 187 | return MACRO_INDEX(Ellipse, object); 188 | 189 | case 16: 190 | { 191 | Polygon *polygon = (Polygon *) object; 192 | return sizeof(Polygon) + polygon->macros * sizeof(MacroReference) 193 | + polygon->numberOfPoints * sizeof(Point); 194 | } 195 | case 17: 196 | return MACRO_INDEX(Meter, object); 197 | 198 | case 18: 199 | return MACRO_INDEX(LinearBarGraph, object); 200 | 201 | case 19: 202 | return MACRO_INDEX(ArchedBarGraph, object); 203 | 204 | case 20: 205 | { 206 | PictureGraphic *pictureGraphic = (PictureGraphic *) object; 207 | return sizeof(PictureGraphic) + pictureGraphic->macros * sizeof(MacroReference) 208 | + pictureGraphic->rawDataLength; 209 | } 210 | 211 | case 21: 212 | return sizeof(NumberVariable); 213 | 214 | case 22: 215 | { 216 | StringVariable *stringVariable = (StringVariable *) object; 217 | return sizeof(StringVariable) + stringVariable->length; 218 | } 219 | 220 | case 23: 221 | return MACRO_INDEX(FontAttributes, object); 222 | 223 | case 24: 224 | return MACRO_INDEX(LineAttributes, object); 225 | 226 | case 25: 227 | return MACRO_INDEX(FillAttributes, object); 228 | 229 | case 26: 230 | { 231 | InputAttributes *inputAttributes = (InputAttributes *) object; 232 | return sizeof(InputAttributes) + inputAttributes->length 233 | + *inputAttributesMacros(inputAttributes) * sizeof(PictureGraphic)+1; 234 | } 235 | 236 | case 27: 237 | return sizeof(ObjectPointer); 238 | 239 | case 28: 240 | { 241 | Macro *macro = (Macro *) object; 242 | return sizeof(Macro) + macro->numberOfBytes; 243 | } 244 | case 29: 245 | { 246 | AuxiliaryFunction *auxiliaryFunction = (AuxiliaryFunction *) object; 247 | return sizeof(AuxiliaryFunction) + auxiliaryFunction->objects * sizeof(ObjectReference); 248 | } 249 | case 30: 250 | { 251 | AuxiliaryInput *auxiliaryInput = (AuxiliaryInput *) object; 252 | return sizeof(AuxiliaryInput) + auxiliaryInput->objects * sizeof(ObjectReference); 253 | } 254 | 255 | } 256 | return -1; 257 | } 258 | 259 | #define OBJECT_INDEX(type, object) (sizeof(type) + ((type *) object)->objects * sizeof(ObjectReference)) 260 | #define OBJECTS_PLUS_PLUS(type, object) ( ((type *) object)->objects++ ) 261 | 262 | // function adds a reference to an object 263 | // if role is none, then reference is a real include_object otherwise 264 | // it is just an attribute 265 | void addObjectReference(void **object, ObjectReference objectReference, int role) 266 | { 267 | int startIndex = 0; 268 | int orginalSize = getRealSize(*object); 269 | int error = 0; 270 | int objectType = getObjectType(*object); 271 | 272 | if (role == ROLE_NONE) { 273 | switch (objectType) { 274 | case 0: 275 | startIndex = OBJECT_INDEX(WorkingSet, *object); 276 | OBJECTS_PLUS_PLUS(WorkingSet, *object); 277 | break; 278 | 279 | case 1: 280 | startIndex = OBJECT_INDEX(DataMask, *object); 281 | OBJECTS_PLUS_PLUS(DataMask, *object); 282 | objectReference.x += xform.dm_dx; 283 | objectReference.y += xform.dm_dy; 284 | break; 285 | 286 | case 2: 287 | startIndex = OBJECT_INDEX(AlarmMask, *object); 288 | OBJECTS_PLUS_PLUS(AlarmMask, *object); 289 | objectReference.x += xform.dm_dx; 290 | objectReference.y += xform.dm_dy; 291 | break; 292 | 293 | case 3: 294 | startIndex = OBJECT_INDEX(Container, *object); 295 | OBJECTS_PLUS_PLUS(Container, *object); 296 | break; 297 | 298 | case 4: 299 | { 300 | *object = realloc(*object, getRealSize(*object) + 2); 301 | SoftKeyMask *softKeyMask = (SoftKeyMask *) *object; 302 | unsigned char *ptr = ((unsigned char *) softKeyMask) + sizeof(SoftKeyMask) 303 | + softKeyMask->objects * sizeof(unsigned short); 304 | softKeyMask->objects++; 305 | 306 | // move macros 307 | memmove(ptr, ptr + 2, softKeyMask->macros * sizeof(MacroReference)); 308 | 309 | *((unsigned short *) ptr) = objectReference.objectId; 310 | } 311 | return; 312 | 313 | case 5: 314 | startIndex = OBJECT_INDEX(Key, *object); 315 | OBJECTS_PLUS_PLUS(Key, *object); 316 | objectReference.x += xform.sk_dx; 317 | objectReference.y += xform.sk_dy; 318 | break; 319 | 320 | case 6: 321 | startIndex = OBJECT_INDEX(Button, *object); 322 | OBJECTS_PLUS_PLUS(Button, *object); 323 | // the inside of a button does not scale like other objects 324 | // so a padding is added to it 325 | objectReference.x += (int) (4 * multiplier) - 4; 326 | objectReference.y += (int) (4 * multiplier) - 4; 327 | break; 328 | 329 | case 10: 330 | { 331 | *object = realloc(*object, getRealSize(*object) + 2); 332 | InputList *inputList = (InputList*) *object; 333 | unsigned char *ptr = ((unsigned char *) inputList) + sizeof(InputList) 334 | + inputList->numberOfListItems * sizeof(unsigned short); 335 | inputList->numberOfListItems++; 336 | 337 | // move macros 338 | memmove(ptr, ptr + 2, inputList->macros * sizeof(MacroReference)); 339 | 340 | *((unsigned short *) ptr) = objectReference.objectId; 341 | } 342 | return; 343 | 344 | case 29: 345 | startIndex = OBJECT_INDEX(AuxiliaryFunction, *object); 346 | OBJECTS_PLUS_PLUS(AuxiliaryFunction, *object); 347 | break; 348 | 349 | case 30: 350 | startIndex = OBJECT_INDEX(AuxiliaryInput, *object); 351 | OBJECTS_PLUS_PLUS(AuxiliaryInput, *object); 352 | break; 353 | 354 | default: 355 | error = 1; 356 | break; 357 | 358 | } 359 | 360 | if (error) { 361 | printf("ERROR. Object %i (Id=%i) can't have objects contained!\n", 362 | ((ObjectHeader *) *object)->type, ((ObjectHeader *) *object)->objectId); 363 | return; 364 | } 365 | 366 | *object = realloc(*object, getRealSize(*object)); 367 | 368 | // move events and language codes 369 | memmove( ( ((char *) *object) + startIndex + sizeof( ObjectReference )), (((char *) *object) + startIndex), orginalSize - startIndex); 370 | 371 | memmove( ( ((char *) *object) + startIndex), &objectReference, sizeof( ObjectReference ) ); 372 | } 373 | if (role == ROLE_ACTIVE_MASK) { 374 | if (objectType == 0) 375 | ((WorkingSet *) *object)->activeMask = objectReference.objectId; 376 | else 377 | error = 1; 378 | } 379 | if (role == ROLE_FONT_ATTRIBUTES) { 380 | if (objectType == 8) 381 | ((InputString *) *object)->fontAttributes = objectReference.objectId; 382 | 383 | else if (objectType == 9) 384 | ((InputNumber *) *object)->fontAttributes = objectReference.objectId; 385 | 386 | else if (objectType == 11) 387 | ((OutputString *) *object)->fontAttributes = objectReference.objectId; 388 | 389 | else if (objectType == 12) 390 | ((OutputNumber *) *object)->fontAttributes = objectReference.objectId; 391 | 392 | else 393 | error = 1; 394 | } 395 | if (role == ROLE_SOFT_KEY_MASK) { 396 | if (objectType == 1) 397 | ((DataMask *) *object)->softKeyMask = objectReference.objectId; 398 | 399 | else if (objectType == 2) 400 | ((AlarmMask *) *object)->softKeyMask = objectReference.objectId; 401 | 402 | else 403 | error = 1; 404 | } 405 | if (role == ROLE_VARIABLE_REFERENCE) { 406 | if (objectType == 7) 407 | ((InputBoolean *) *object)->variableReference = objectReference.objectId; 408 | 409 | else if (objectType == 8) 410 | ((InputString *) *object)->variableReference = objectReference.objectId; 411 | 412 | else if (objectType == 9) 413 | ((InputNumber *) *object)->variableReference = objectReference.objectId; 414 | 415 | else if (objectType == 10) 416 | ((InputList *) *object)->variableReference = objectReference.objectId; 417 | 418 | else if (objectType == 11) 419 | ((OutputString *) *object)->variableReference = objectReference.objectId; 420 | 421 | else if (objectType == 12) 422 | ((OutputNumber *) *object)->variableReference = objectReference.objectId; 423 | 424 | else if (objectType == 17) 425 | ((Meter *) *object)->variableReference = objectReference.objectId; 426 | 427 | else if (objectType == 18) 428 | ((LinearBarGraph *) *object)->variableReference = objectReference.objectId; 429 | 430 | else if (objectType == 19) 431 | ((ArchedBarGraph *) *object)->variableReference = objectReference.objectId; 432 | 433 | else 434 | error = 1; 435 | } 436 | if (role == ROLE_TARGET_VARIABLE_REFERENCE) { 437 | if (objectType == 18) 438 | ((LinearBarGraph *) *object)->targetValueVariableReference = objectReference.objectId; 439 | else if (objectType == 19) 440 | ((ArchedBarGraph *) *object)->targetValueVariableReference = objectReference.objectId; 441 | else 442 | error = 1; 443 | } 444 | if (role == ROLE_FOREGROUND_COLOR) { 445 | if (objectType == 7) 446 | ((InputBoolean *) *object)->foregroundColor = objectReference.objectId; 447 | 448 | else 449 | error = 1; 450 | } 451 | if (role == ROLE_INPUT_ATTRIBUTES) { 452 | if (objectType == 8) 453 | ((InputString *) *object)->inputAttributes = objectReference.objectId; 454 | else 455 | error = 1; 456 | } 457 | if (role == ROLE_LINE_ATTRIBUTES) { 458 | if (objectType == 13) 459 | ((Line *) *object)->lineAttributes = objectReference.objectId; 460 | else if (objectType == 14) 461 | ((Rectangle *) *object)->lineAttributes = objectReference.objectId; 462 | else if (objectType == 15) 463 | ((Ellipse *) *object)->lineAttributes = objectReference.objectId; 464 | else if (objectType == 16) 465 | ((Polygon *) *object)->lineAttributes = objectReference.objectId; 466 | else 467 | error = 1; 468 | } 469 | if (role == ROLE_FILL_ATTRIBUTES) { 470 | if (objectType == 14) 471 | ((Rectangle *) *object)->fillAttributes = objectReference.objectId; 472 | else if (objectType == 15) 473 | ((Ellipse *) *object)->fillAttributes = objectReference.objectId; 474 | else if (objectType == 16) 475 | ((Polygon *) *object)->fillAttributes = objectReference.objectId; 476 | else 477 | error = 1; 478 | } 479 | if (role == ROLE_FILL_PATTERN) { 480 | if (objectType == 25) 481 | ((FillAttributes *) *object)->fillPattern = objectReference.objectId; 482 | else 483 | error = 1; 484 | } 485 | if (role == ROLE_OBJECT_POINTER_VALUE) { 486 | if (objectType == 27) 487 | ((ObjectPointer *) *object)->value = objectReference.objectId; 488 | else 489 | error = 1; 490 | } 491 | if (error) 492 | printf("ERROR. Object %i (Id=%i) can't have objects of role %i contained!\n", 493 | ((ObjectHeader *) *object)->type, ((ObjectHeader *) *object)->objectId, role); 494 | 495 | } 496 | 497 | // adds a point to a polygon-object 498 | void addPoint(void **object, Point point) 499 | { 500 | if (getObjectType(*object) != 16) { 501 | printf("ERROR. Object %i can't have points contained!\n", 502 | ((ObjectHeader *) *object)->type); 503 | return; 504 | } 505 | 506 | Polygon *polygon = (Polygon *) *object; 507 | int orginalSize = getRealSize(*object); 508 | int startIndex = sizeof(Polygon) + polygon->numberOfPoints * sizeof(Point); 509 | polygon->numberOfPoints++; 510 | 511 | *object = realloc(*object, getRealSize(*object)); 512 | 513 | // move events 514 | // FIXME, might not work! 515 | memmove(( ((char *) *object) + startIndex + sizeof(Point)), (((char *) *object) + startIndex), orginalSize - startIndex); 516 | 517 | // copy point 518 | memmove(( ((char *) *object) + startIndex), &point, sizeof(Point) ); 519 | } 520 | 521 | // converts one character from base64 to number 522 | // A-Z = 0-25, a-z = 26-51, 0-9 = 52-16, + = 62 and / = 63 523 | int base64toIndex(const char base64) { 524 | if (base64 >= 'A' && base64 <= 'Z') 525 | return base64 - 'A'; 526 | else if (base64 >= 'a' && base64 <= 'z') 527 | return base64 - 'a' + 26; 528 | else if (base64 >= '0' && base64 <= '9') 529 | return base64 - '0' + 52; 530 | else if (base64 == '+') 531 | return 62; 532 | else if (base64 == '/') 533 | return 63; 534 | 535 | printf("ERROR: wrong character %c in Base64", base64); 536 | return -1; 537 | } 538 | 539 | // calculates the real data length when base64 lenght is given 540 | int getDataLength(int base64Length) { 541 | int length = base64Length / 4 * 3; 542 | if (base64Length % 4 == 2) 543 | length += 1; 544 | if (base64Length % 4 == 3) 545 | length += 2; 546 | return length; 547 | } 548 | 549 | // converts a string (or an array of characters), from base64 to 550 | // binary data 551 | unsigned char *convertFromBase64(const char *base64, int dataLength) { 552 | 553 | unsigned char *datas = (unsigned char *) malloc(sizeof(char) * dataLength); 554 | 555 | for (int i = 0; i < dataLength; i++) { 556 | int indexStart = base64toIndex(base64[i * 4 / 3]); 557 | int indexEnd = base64toIndex(base64[i * 4 / 3 + 1]); 558 | if ((i % 3) == 0) 559 | datas[i] = (indexStart << 2) + (indexEnd >> 4); 560 | if ((i % 3) == 1) 561 | datas[i] = ((indexStart & 15) << 4) + (indexEnd >> 2); 562 | if ((i % 3) == 2) 563 | datas[i] = ((indexStart & 3) << 6) + indexEnd; 564 | } 565 | return datas; 566 | } 567 | 568 | // Adds image data to image object 569 | // Image will have 2,16 or 256 colors according to VT's color depth 570 | void addPictureData(void **object) 571 | { 572 | if (getObjectType(*object) != 20) { 573 | printf("ERROR. Object %i can't have pictureData!\n", 574 | ((ObjectHeader *) *object)->type); 575 | return; 576 | } 577 | PictureGraphic *picture = (PictureGraphic *) *object; 578 | int size = picture->actualWidth * picture->actualHeight; 579 | if (size != getDataLength(dataLength)) { 580 | printf("ERROR. Data length miss match (size = %i, size2 = %i)\n", 581 | size, getDataLength(dataLength)); 582 | return; 583 | } 584 | unsigned char *data = convertFromBase64(dataText, size); 585 | unsigned char *reducedData = data; 586 | 587 | // reduce colors and rearrenge data 588 | if (vtColors == 16) { 589 | int dataWidth = (picture->actualWidth + 1) / 2; 590 | reducedData = (unsigned char *) calloc(dataWidth * picture->actualHeight, sizeof(char)); 591 | 592 | for (int y = 0; y < picture->actualHeight; y++) 593 | for (int x = 0; x < picture->actualWidth; x += 2) 594 | for (int i = 0; (i < 2) && ((x + i) < picture->actualWidth); i++) 595 | reducedData[y * dataWidth + x / 2] += (reduceColor(data[y * picture->actualWidth + x + i], vtColors) << (1 - i) * 4); 596 | 597 | size = dataWidth * picture->actualHeight; 598 | free(data); 599 | data = reducedData; 600 | } 601 | else if (vtColors == 2) { 602 | int dataWidth = (picture->actualWidth + 7) / 8; 603 | reducedData = (unsigned char *) calloc(dataWidth * picture->actualHeight, sizeof(char)); 604 | 605 | for (int y = 0; y < picture->actualHeight; y++) 606 | for (int x = 0; x < picture->actualWidth; x += 8) 607 | for (int i = 0; (i < 8) && ((x + i) < picture->actualWidth); i++) 608 | reducedData[y * dataWidth + x / 8] += (reduceColor(data[y * picture->actualWidth + x + i], vtColors) << (7 - i)); 609 | 610 | size = dataWidth * picture->actualHeight; 611 | free(data); 612 | data = reducedData; 613 | } 614 | 615 | // int originalSize = getRealSize(*object); 616 | // int startIndex = sizeof(PictureGraphic) + picture->rawDataLength; 617 | picture->rawDataLength = size; 618 | *object = realloc(*object, getRealSize(*object)); 619 | 620 | // move events ???? 621 | // memcpy( ( ((char *) *object) + size + sizeof( PictureGraphic )), (((char *) *object) + sizeof( PictureGraphic )), orginalSize - sizeof( PictureGraphic )); 622 | 623 | // copy data 624 | memmove(( ((char *) *object) + sizeof(PictureGraphic)), data, size); 625 | 626 | free(data); 627 | } 628 | 629 | #define INIT_OBJECT(oType, object) oType *object = (oType *) calloc(sizeof(oType), 1); object->objectId = id; object->type = type 630 | 631 | // creates a new object of given type, using the xml-attributes 632 | void *createObject(int type, const char **attr){ 633 | int id = getId(attr); 634 | 635 | multiplier = getMultiplier(attr, multiplier, xform.dm_mult, xform.sk_mult); 636 | 637 | switch (type) { 638 | case 0: // WorkingSet 639 | { 640 | INIT_OBJECT(WorkingSet, workingset); 641 | workingset->backgroundColor = getBackgroundColor(attr, vtColors); 642 | workingset->selectable = isSelectable(attr); 643 | return workingset; 644 | } 645 | case 1: // DataMask 646 | { 647 | INIT_OBJECT(DataMask, dataMask); 648 | dataMask->backgroundColor = getBackgroundColor(attr, vtColors); 649 | dataMask->softKeyMask = 65535; 650 | return dataMask; 651 | } 652 | case 2: // AlarmMask 653 | { 654 | INIT_OBJECT(AlarmMask, alarmMask); 655 | alarmMask->backgroundColor = getBackgroundColor(attr, vtColors); 656 | alarmMask->softKeyMask = 65535; 657 | alarmMask->priority = getPriority(attr); 658 | alarmMask->acousticSignal = getAcousticSignal(attr); 659 | return alarmMask; 660 | } 661 | case 3: // Container 662 | { 663 | INIT_OBJECT(Container, container); 664 | container->width = (int) (multiplier * getWidth(attr)); 665 | container->height = (int) (multiplier * getHeight(attr)); 666 | container->hidden = isHidden(attr); 667 | return container; 668 | } 669 | case 4: // SoftKeyMask 670 | { 671 | INIT_OBJECT(SoftKeyMask, softKeyMask); 672 | softKeyMask->backgroundColor = getBackgroundColor(attr, vtColors); 673 | return softKeyMask; 674 | } 675 | case 5: // Key 676 | { 677 | INIT_OBJECT(Key, key); 678 | key->backgroundColor = getBackgroundColor(attr, vtColors); 679 | key->keyCode = getKeyCode(attr); 680 | return key; 681 | } 682 | case 6: // Button 683 | { 684 | INIT_OBJECT(Button, button); 685 | button->width = (int) (multiplier * getWidth(attr)); 686 | button->height = (int) (multiplier * getHeight(attr)); 687 | button->backgroundColor = getBackgroundColor(attr, vtColors); 688 | button->borderColor = getBorderColor(attr, vtColors); 689 | button->keyCode = getKeyCode(attr); 690 | button->latchable = isLatchable(attr); 691 | return button; 692 | } 693 | case 7: // InputBoolean 694 | { 695 | INIT_OBJECT(InputBoolean, inputBoolean); 696 | inputBoolean->backgroundColor = getBackgroundColor(attr, vtColors); 697 | inputBoolean->width = (int) (multiplier * getWidth(attr)); 698 | inputBoolean->foregroundColor = 65535; 699 | inputBoolean->variableReference = 65535; 700 | inputBoolean->value = getValue(attr); 701 | inputBoolean->enabled = isEnabled(attr); 702 | return inputBoolean; 703 | } 704 | case 8: // InputString 705 | { 706 | // length of string + 2 must be counted 707 | InputString *inputString = (InputString *) calloc(sizeof(InputString) + getLength(attr) + 2, 1); 708 | inputString->objectId = id; 709 | inputString->type = type; 710 | 711 | inputString->width = (int) (multiplier * getWidth(attr)); 712 | inputString->height = (int) (multiplier * getHeight(attr)); 713 | inputString->backgroundColor = getBackgroundColor(attr, vtColors); 714 | inputString->fontAttributes = 65535; 715 | inputString->inputAttributes = 65535; 716 | inputString->options = getInputStringOptions(attr); 717 | inputString->variableReference = 65535; 718 | inputString->horizontalJustification = getHorizontalJustification(attr); 719 | inputString->length = getLength(attr); 720 | 721 | // copy string 722 | char *string = getValueString(attr, getLength(attr)); 723 | memcpy( inputString->value, string, getLength(attr) ); 724 | free( string ); 725 | 726 | *inputStringEnabled(inputString) = isEnabled(attr); 727 | return inputString; 728 | } 729 | case 9: // InputNumber 730 | { 731 | INIT_OBJECT(InputNumber, inputNumber); 732 | inputNumber->width = (int) (multiplier * getWidth(attr)); 733 | inputNumber->height = (int) (multiplier * getHeight(attr)); 734 | inputNumber->backgroundColor = getBackgroundColor(attr, vtColors); 735 | inputNumber->fontAttributes = 65535; 736 | inputNumber->options = getInputNumberOptions(attr); 737 | inputNumber->variableReference = 65535; 738 | inputNumber->value = getValue(attr); 739 | inputNumber->minValue = getMinValue(attr); 740 | inputNumber->maxValue = getMaxValue(attr); 741 | inputNumber->offset = getOffset(attr); 742 | inputNumber->scale = getScale(attr); 743 | inputNumber->numberOfDecimals = getNumberOfDecimals(attr); 744 | inputNumber->format = getNumberFormat(attr); 745 | inputNumber->horizontalJustification = getHorizontalJustification(attr); 746 | inputNumber->enabled = isEnabled(attr); 747 | return inputNumber; 748 | } 749 | case 10: // InputList 750 | { 751 | INIT_OBJECT(InputList, inputList); 752 | inputList->width = (int) (multiplier * getWidth(attr)); 753 | inputList->height = (int) (multiplier * getHeight(attr)); 754 | inputList->variableReference = 65535; 755 | inputList->value = getValue(attr); 756 | inputList->enabled = isEnabled(attr); 757 | return inputList; 758 | } 759 | case 11: // OutputString 760 | { 761 | OutputString *outputString = (OutputString *) calloc(sizeof(OutputString) + getLength(attr) + 1, 1); 762 | outputString->objectId = id; 763 | outputString->type = type; 764 | 765 | outputString->width = (int) (multiplier * getWidth(attr)); 766 | outputString->height = (int) (multiplier * getHeight(attr)); 767 | outputString->backgroundColor = getBackgroundColor(attr, vtColors); 768 | outputString->fontAttributes = 65535; 769 | outputString->options = getInputStringOptions(attr); 770 | outputString->variableReference = 65535; 771 | outputString->horizontalJustification = getHorizontalJustification(attr); 772 | outputString->length = getLength(attr); 773 | 774 | // copy string 775 | char *string = getValueString(attr, getLength(attr)); 776 | memcpy(outputString->value, string, getLength(attr)); 777 | free(string); 778 | 779 | return outputString; 780 | } 781 | case 12: // OutputNumber 782 | { 783 | INIT_OBJECT(OutputNumber, outputNumber); 784 | outputNumber->width = (int) (multiplier * getWidth(attr)); 785 | outputNumber->height = (int) (multiplier * getHeight(attr)); 786 | outputNumber->backgroundColor = getBackgroundColor(attr, vtColors); 787 | outputNumber->fontAttributes = 65535; 788 | outputNumber->options = getInputNumberOptions(attr); 789 | outputNumber->variableReference = 65535; 790 | outputNumber->value = getValue(attr); 791 | outputNumber->offset = getOffset(attr); 792 | outputNumber->scale = getScale(attr); 793 | outputNumber->numberOfDecimals = getNumberOfDecimals(attr); 794 | outputNumber->format = getNumberFormat(attr); 795 | outputNumber->horizontalJustification = getHorizontalJustification(attr); 796 | return outputNumber; 797 | } 798 | case 13: // Line 799 | { 800 | INIT_OBJECT(Line, line); 801 | line->lineAttributes = 65535; 802 | line->width = (int) (multiplier * getWidth(attr)); 803 | line->height = (int) (multiplier * getHeight(attr)); 804 | line->lineDirection = getLineDirection(attr); 805 | return line; 806 | } 807 | case 14: // Rectangle 808 | { 809 | INIT_OBJECT(Rectangle, rectangle); 810 | rectangle->lineAttributes = 65535; 811 | rectangle->width = (int) (multiplier * getWidth(attr)); 812 | rectangle->height = (int) (multiplier * getHeight(attr)); 813 | rectangle->lineSupression = getLineSuppression(attr); 814 | rectangle->fillAttributes = 65535; 815 | return rectangle; 816 | } 817 | case 15: // Ellipse 818 | { 819 | INIT_OBJECT(Ellipse, ellipse); 820 | ellipse->lineAttributes = 65535; 821 | ellipse->width = (int) (multiplier * getWidth(attr)); 822 | ellipse->height = (int) (multiplier * getHeight(attr)); 823 | ellipse->ellipseType = getEllipseType(attr); 824 | ellipse->startAngle = getStartAngle(attr); 825 | ellipse->endAngle = getEndAngle(attr); 826 | ellipse->fillAttributes = 65535; 827 | return ellipse; 828 | } 829 | case 16: // Polygon 830 | { 831 | INIT_OBJECT(Polygon, polygon); 832 | polygon->width = (int) (multiplier * getWidth(attr)); 833 | polygon->height = (int) (multiplier * getHeight(attr)); 834 | polygon->lineAttributes = 65535; 835 | polygon->fillAttributes = 65535; 836 | polygon->polygonType = getPolygonType(attr); 837 | return polygon; 838 | } 839 | case 17: // Meter 840 | { 841 | INIT_OBJECT(Meter, meter); 842 | meter->width = (int) (multiplier * getWidth(attr)); 843 | meter->needleColor = getNeedleColor(attr, vtColors); 844 | meter->borderColor = getBorderColor(attr, vtColors); 845 | meter->arcAndTickColor = getArcAndTickColor(attr, vtColors); 846 | meter->options = getMeterOptions(attr); 847 | meter->numberOfTicks = getNumberOfTicks(attr); 848 | meter->startAngle = getStartAngle(attr); 849 | meter->endAngle = getEndAngle(attr); 850 | meter->minValue = getMinValue(attr); 851 | meter->maxValue = getMaxValue(attr); 852 | meter->variableReference = 65535; 853 | meter->value = getValue(attr); 854 | return meter; 855 | } 856 | case 18: // LinearBarGraph 857 | { 858 | INIT_OBJECT(LinearBarGraph, linearBarGraph); 859 | linearBarGraph->width = (int) (multiplier * getWidth(attr)); 860 | linearBarGraph->height = (int) (multiplier * getHeight(attr)); 861 | linearBarGraph->color = getColorColor(attr, vtColors); 862 | linearBarGraph->targetLineColor = getTargetLineColor(attr, vtColors); 863 | linearBarGraph->options = getLinearBarGraphOptions(attr); 864 | linearBarGraph->numberOfTicks = getNumberOfTicks(attr); 865 | linearBarGraph->minValue = getMinValue(attr); 866 | linearBarGraph->maxValue = getMaxValue(attr); 867 | linearBarGraph->variableReference = 65535; 868 | linearBarGraph->value = getValue(attr); 869 | linearBarGraph->targetValueVariableReference = 65535; 870 | linearBarGraph->targetValue = getTargetValue(attr); 871 | return linearBarGraph; 872 | } 873 | case 19: // ArchedBarGraph 874 | { 875 | INIT_OBJECT(ArchedBarGraph, archedBarGraph); 876 | archedBarGraph->width = (int) (multiplier * getWidth(attr)); 877 | archedBarGraph->height = (int) (multiplier * getHeight(attr)); 878 | archedBarGraph->color = getColorColor(attr, vtColors); 879 | archedBarGraph->targetLineColor = getTargetLineColor(attr, vtColors); 880 | archedBarGraph->options = getArchedBarGraphOptions(attr); 881 | archedBarGraph->startAngle = getStartAngle(attr); 882 | archedBarGraph->endAngle = getEndAngle(attr); 883 | archedBarGraph->barGraphWidth = getBarGraphWidth(attr); 884 | archedBarGraph->minValue = getMinValue(attr); 885 | archedBarGraph->maxValue = getMaxValue(attr); 886 | archedBarGraph->variableReference = 65535; 887 | archedBarGraph->value = getValue(attr); 888 | archedBarGraph->targetValueVariableReference = 65535; 889 | archedBarGraph->targetValue = getTargetValue(attr); 890 | return archedBarGraph; 891 | } 892 | case 20: // PictureGraphic 893 | { 894 | INIT_OBJECT(PictureGraphic, pictureGraphic); 895 | pictureGraphic->width = (int) (multiplier * getWidth(attr)); 896 | //pictureGraphic->actualWidth = getActualWidth(attr); 897 | //pictureGraphic->actualHeight = getActualHeight(attr); 898 | pictureGraphic->format = 0; // = 2 colors 899 | if (vtColors == 16) 900 | pictureGraphic->format = 1; // = 16 colors 901 | else if (vtColors == 256) 902 | pictureGraphic->format = 2; // = 256 colors 903 | 904 | pictureGraphic->options = getPictureGraphicOptions(attr); 905 | pictureGraphic->transparencyColor = getTransparencyColor(attr); 906 | 907 | return pictureGraphic; 908 | } 909 | case 21: // NumberVariable 910 | { 911 | INIT_OBJECT(NumberVariable, numberVariable); 912 | numberVariable->value = getValue(attr); 913 | return numberVariable; 914 | } 915 | case 22: // StringVariable 916 | { 917 | StringVariable *stringVariable = (StringVariable *) calloc(sizeof(StringVariable) + getLength(attr), 1); 918 | stringVariable->objectId = id; 919 | stringVariable->type = type; 920 | stringVariable->length = getLength(attr); 921 | 922 | // copy string 923 | char *string = getValueString(attr, getLength(attr)); 924 | memcpy(( ((char *) stringVariable) + 5), string, getLength(attr)); 925 | free(string); 926 | return stringVariable; 927 | } 928 | case 23: // FontAttributes 929 | { 930 | INIT_OBJECT(FontAttributes, fontAttributes); 931 | fontAttributes->fontColor = getFontColor(attr, vtColors); 932 | fontAttributes->fontSize = getFontSize(attr) + ((int) (multiplier) - 1) * 3; 933 | fontAttributes->fontType = getFontType(attr); 934 | fontAttributes->fontStyle = getFontStyle(attr); 935 | 936 | return fontAttributes; 937 | } 938 | case 24: // LineAttributes 939 | { 940 | INIT_OBJECT(LineAttributes, lineAttributes); 941 | lineAttributes->lineColor = getLineColor(attr, vtColors); 942 | lineAttributes->lineWidth = (int) (multiplier * getLineWidth(attr)); // ??? 943 | lineAttributes->lineArt = getLineArt(attr); 944 | return lineAttributes; 945 | } 946 | case 25: // FillAttributes 947 | { 948 | INIT_OBJECT(FillAttributes, fillAttributes); 949 | fillAttributes->fillType = getFillType(attr); 950 | fillAttributes->fillColor = getFillColor(attr, vtColors); 951 | return fillAttributes; 952 | } 953 | case 26: // InputAttributes 954 | { 955 | InputAttributes *inputAttributes = (InputAttributes *) calloc(sizeof(InputAttributes) + getLength(attr) + 1, 1); 956 | inputAttributes->objectId = id; 957 | inputAttributes->type = type; 958 | 959 | inputAttributes->validationType = getValidationType(attr); 960 | inputAttributes->length = getLength(attr); 961 | 962 | // copy string 963 | char *string = getValidatioinString(attr, getLength(attr)); 964 | memcpy(inputAttributes->validationString, string, getLength(attr)); 965 | free(string); 966 | return inputAttributes; 967 | } 968 | case 27: // ObjectPointer 969 | { 970 | INIT_OBJECT(ObjectPointer, objectPointer); 971 | objectPointer->value = 65535; 972 | return objectPointer; 973 | } 974 | case 28: // Macro 975 | { 976 | INIT_OBJECT(Macro, macro); 977 | return macro; 978 | } 979 | case 29: 980 | { 981 | INIT_OBJECT(AuxiliaryFunction, auxiliaryFunction); 982 | auxiliaryFunction->backgroundColor = getBackgroundColor(attr, vtColors); 983 | auxiliaryFunction->functionType = getFunctionType(attr); 984 | return auxiliaryFunction; 985 | } 986 | case 30: 987 | { 988 | INIT_OBJECT(AuxiliaryInput, auxiliaryInput); 989 | auxiliaryInput->backgroundColor = getBackgroundColor(attr, vtColors); 990 | auxiliaryInput->functionType = getFunctionType(attr); 991 | auxiliaryInput->inputId = getInputID(attr); 992 | return auxiliaryInput; 993 | } 994 | default: 995 | printf("ERROR. Object %i not implemented yet!\n", type); 996 | return NULL; 997 | } 998 | } 999 | 1000 | int getCommandSize(const void *object) 1001 | { 1002 | int type = *((unsigned char *) object); 1003 | switch (type) { 1004 | case 179: 1005 | return sizeof(ChangeStringValue) + ((ChangeStringValue *) object)->length; 1006 | case 180: 1007 | return sizeof(ChangeChildPosition); 1008 | default: 1009 | return 8; 1010 | } 1011 | } 1012 | 1013 | void *createCommand(int command, const char **attr) 1014 | { 1015 | multiplier = getMultiplier(attr, multiplier, xform.dm_mult, xform.sk_mult); 1016 | 1017 | // this works for all other commands, except change string value 1018 | void *object = calloc(8, 1); 1019 | 1020 | switch (command) { 1021 | case 160: 1022 | { 1023 | HideShowObject *hideShowObject = (HideShowObject *) object; 1024 | hideShowObject->VTFunction = 160; 1025 | hideShowObject->objectId = getObjectId(attr); 1026 | hideShowObject->show = getHideShow(attr); 1027 | hideShowObject->padding = 0xFFFFFFFF; 1028 | return hideShowObject; 1029 | } 1030 | case 161: 1031 | { 1032 | EnableDisableObject *enableDisableObject = (EnableDisableObject *) object; 1033 | enableDisableObject->VTFunction = 161; 1034 | enableDisableObject->objectId = getObjectId(attr); 1035 | enableDisableObject->enable = getEnableDisable(attr); 1036 | enableDisableObject->padding = 0xFFFFFFFF; 1037 | return enableDisableObject; 1038 | } 1039 | case 162: 1040 | { 1041 | SelectInputObject *selectInputObject = (SelectInputObject *) object; 1042 | selectInputObject->VTFunction = 162; 1043 | selectInputObject->objectId = getObjectId(attr); 1044 | selectInputObject->padding1 = 0xFFFFFFFF; 1045 | selectInputObject->padding2 = 0xFF; 1046 | return selectInputObject; 1047 | } 1048 | case 163: 1049 | { 1050 | ControlAudioDevice *controlAudioDevice = (ControlAudioDevice *) object; 1051 | controlAudioDevice->VTFunction = 163; 1052 | controlAudioDevice->repetitions = getRepetitions(attr); 1053 | controlAudioDevice->frequency = getFrequency(attr); 1054 | controlAudioDevice->onTime = getOnTime(attr); 1055 | controlAudioDevice->offTime = getOffTime(attr); 1056 | return controlAudioDevice; 1057 | } 1058 | case 164: 1059 | { 1060 | SetAudioVolume *setAudioVolume = (SetAudioVolume *) object; 1061 | setAudioVolume->VTFunction = 164; 1062 | setAudioVolume->volume = getVolume(attr); 1063 | setAudioVolume->padding1 = 0xFFFFFFFF; 1064 | setAudioVolume->padding2 = 0xFFFF; 1065 | return setAudioVolume; 1066 | } 1067 | case 165: 1068 | { 1069 | ChangeChildLocation *changeChildLocation = (ChangeChildLocation *) object; 1070 | changeChildLocation->VTFunction = 165; 1071 | changeChildLocation->parentId = getParentId(attr); 1072 | changeChildLocation->childId = getChildId(attr); 1073 | changeChildLocation->dx = ((int) multiplier * getDx(attr)) +127; // this can be dangerous! 1074 | changeChildLocation->dy = ((int) multiplier * getDy(attr)) +127; 1075 | changeChildLocation->padding = 0xFF; 1076 | return changeChildLocation; 1077 | } 1078 | case 166: 1079 | { 1080 | ChangeSize *changeSize = (ChangeSize *) object; 1081 | changeSize->VTFunction = 166; 1082 | changeSize->objectId = getObjectId(attr); 1083 | changeSize->width = ((int) multiplier * getWidth(attr)); 1084 | changeSize->height = ((int) multiplier * getHeight(attr)); 1085 | changeSize->padding = 0xFF; 1086 | return changeSize; 1087 | } 1088 | case 167: 1089 | { 1090 | ChangeBackgroundColor *changeBackgroundColor = (ChangeBackgroundColor *) object; 1091 | changeBackgroundColor->VTFunction = 167; 1092 | changeBackgroundColor->objectId = getObjectId(attr); 1093 | changeBackgroundColor->backgroundColor = getBackgroundColor(attr, vtColors); 1094 | changeBackgroundColor->padding = 0xFFFFFFFF; 1095 | return changeBackgroundColor; 1096 | } 1097 | case 168: 1098 | { 1099 | ChangeNumericValue *changeNumericValue = (ChangeNumericValue *) object; 1100 | changeNumericValue->VTFunction = 168; 1101 | changeNumericValue->objectId = getObjectId(attr); 1102 | changeNumericValue->padding = 0xFF; 1103 | changeNumericValue->value = getValue(attr); 1104 | return changeNumericValue; 1105 | } 1106 | case 179: 1107 | { 1108 | int length = getLength(attr); 1109 | object = realloc(object, sizeof(ChangeStringValue) + length); 1110 | ChangeStringValue *changeStringValue = (ChangeStringValue *) object; 1111 | changeStringValue->VTFunction = 179; 1112 | changeStringValue->objectId = getObjectId(attr); 1113 | changeStringValue->length = length; 1114 | 1115 | char *string = getValueString(attr, length); 1116 | memmove(changeStringValue->string, string, length); 1117 | free(string); 1118 | return changeStringValue; 1119 | } 1120 | case 169: 1121 | { 1122 | ChangeEndPoint *changeEndPoint = (ChangeEndPoint *) object; 1123 | changeEndPoint->VTFunction = 169; 1124 | changeEndPoint->objectId = getObjectId(attr); 1125 | changeEndPoint->width = ((int) multiplier * getWidth(attr)); 1126 | changeEndPoint->height = ((int) multiplier * getHeight(attr)); 1127 | changeEndPoint->lineDirection = getLineDirection(attr); 1128 | return changeEndPoint; 1129 | } 1130 | case 170: 1131 | { 1132 | ChangeFontAttributes *changeFontAttributes = (ChangeFontAttributes *) object; 1133 | changeFontAttributes->VTFunction = 170; 1134 | changeFontAttributes->objectId = getObjectId(attr); 1135 | changeFontAttributes->fontColor = getFontColor(attr, vtColors); 1136 | changeFontAttributes->fontSize = getFontSize(attr) + ((int) multiplier - 1) * 3; 1137 | changeFontAttributes->fontType = getFontType(attr); 1138 | changeFontAttributes->fontStyle = getFontStyle(attr); 1139 | changeFontAttributes->padding = 0xFF; 1140 | return changeFontAttributes; 1141 | } 1142 | case 171: 1143 | { 1144 | ChangeLineAttributes *changeLineAttributes = (ChangeLineAttributes *) object; 1145 | changeLineAttributes->VTFunction = 171; 1146 | changeLineAttributes->objectId = getObjectId(attr); 1147 | changeLineAttributes->lineColor = getLineColor(attr, vtColors); 1148 | changeLineAttributes->lineWidth = (int) multiplier * getLineWidth(attr); 1149 | changeLineAttributes->lineArt = getLineArt(attr); 1150 | changeLineAttributes->padding = 0xFF; 1151 | return changeLineAttributes; 1152 | } 1153 | case 172: 1154 | { 1155 | ChangeFillAttributes *changeFillAttributes = (ChangeFillAttributes *) object; 1156 | changeFillAttributes->VTFunction = 172; 1157 | changeFillAttributes->objectId = getObjectId(attr); 1158 | changeFillAttributes->fillType = getFillType(attr); 1159 | changeFillAttributes->fillColor = getFillColor(attr, vtColors); 1160 | changeFillAttributes->fillPattern = getFillPatternID(attr); 1161 | changeFillAttributes->padding = 0xFF; 1162 | return changeFillAttributes; 1163 | } 1164 | case 173: 1165 | { 1166 | ChangeActiveMask *changeActiveMask = (ChangeActiveMask *) object; 1167 | changeActiveMask->VTFunction = 173; 1168 | changeActiveMask->parentId = getParentId(attr); 1169 | changeActiveMask->childId = getChildId(attr); 1170 | changeActiveMask->padding1 = 0xFFFF; 1171 | changeActiveMask->padding2 = 0xFF; 1172 | return changeActiveMask; 1173 | } 1174 | case 174: 1175 | { 1176 | ChangeSoftKeyMask *changeSoftKeyMask = (ChangeSoftKeyMask *) object; 1177 | changeSoftKeyMask->VTFunction = 174; 1178 | changeSoftKeyMask->maskType = getMaskType(attr); 1179 | changeSoftKeyMask->parentId = getParentId(attr); 1180 | changeSoftKeyMask->childId = getChildId(attr); 1181 | changeSoftKeyMask->padding1 = 0xFFFF; 1182 | return changeSoftKeyMask; 1183 | } 1184 | case 175: 1185 | { 1186 | ChangeAttribute *changeAttribute = (ChangeAttribute *) object; 1187 | changeAttribute->VTFunction = 175; 1188 | changeAttribute->objectId = getObjectId(attr); 1189 | changeAttribute->AID = getAID(attr); 1190 | changeAttribute->value = getValue(attr); 1191 | return changeAttribute; 1192 | } 1193 | case 176: 1194 | { 1195 | ChangePriority *changePriority = (ChangePriority *) object; 1196 | changePriority->VTFunction = 176; 1197 | changePriority->objectId = getObjectId(attr); 1198 | changePriority->priority = getPriority(attr); 1199 | changePriority->padding = 0xFFFFFFFF; 1200 | return changePriority; 1201 | } 1202 | case 177: 1203 | { 1204 | ChangeListItem *changeListItem = (ChangeListItem *) object; 1205 | changeListItem->VTFunction = 177; 1206 | changeListItem->parentId = getParentId(attr); 1207 | changeListItem->listIndex = getListIndex(attr); 1208 | changeListItem->childId = getChildId(attr); 1209 | changeListItem->padding = 0xFFFF; 1210 | return changeListItem; 1211 | } 1212 | case 180: 1213 | { 1214 | object = realloc(object, sizeof(ChangeChildPosition)); 1215 | ChangeChildPosition *changeChildPosition = (ChangeChildPosition *) object; 1216 | changeChildPosition->VTFunction = 180; 1217 | changeChildPosition->parentId = getParentId(attr); 1218 | changeChildPosition->childId = getChildId(attr); 1219 | changeChildPosition->x = ((int) multiplier * getPosX(attr)); 1220 | changeChildPosition->y = ((int) multiplier * getPosY(attr)); 1221 | return changeChildPosition; 1222 | } 1223 | default: 1224 | printf("ERROR: command %i, not implemented!\n", command); 1225 | } 1226 | return NULL; 1227 | } 1228 | 1229 | // adds a command to a macro 1230 | void addCommand(void **object, void *command) 1231 | { 1232 | int objectType = getObjectType(*object); 1233 | if (objectType != 28) { 1234 | printf("ERROR: object of type %i , can't have commands!\n", objectType); 1235 | return; 1236 | } 1237 | 1238 | *object = realloc(*object, getRealSize(*object) + getCommandSize(command)); 1239 | Macro *macro = (Macro *) *object; 1240 | memmove(((char *) macro) + getRealSize( macro ), command, getCommandSize(command)); 1241 | macro->numberOfBytes += getCommandSize(command); 1242 | } 1243 | 1244 | // adds a macro to a object 1245 | #define MACROS_PLUS_PLUS(type, object) ( ((type *) object)->macros++ ) 1246 | void addEventReference(void **object, MacroReference macroRef) 1247 | { 1248 | int objectType = getObjectType(*object); 1249 | if (objectType < 0 || objectType == 21 || objectType == 22 || objectType > 26) { 1250 | printf("ERROR: object of type %i , can't have macros!\n", objectType); 1251 | return; 1252 | } 1253 | int orginalSize = getRealSize(*object); 1254 | 1255 | switch (objectType) { 1256 | case 0: 1257 | MACROS_PLUS_PLUS(WorkingSet, *object); 1258 | break; 1259 | case 1: 1260 | MACROS_PLUS_PLUS(DataMask, *object); 1261 | break; 1262 | case 2: 1263 | MACROS_PLUS_PLUS(AlarmMask, *object); 1264 | break; 1265 | case 3: 1266 | MACROS_PLUS_PLUS(Container, *object); 1267 | break; 1268 | case 4: 1269 | MACROS_PLUS_PLUS(SoftKeyMask, *object); 1270 | break; 1271 | case 5: 1272 | MACROS_PLUS_PLUS(Key, *object); 1273 | break; 1274 | case 6: 1275 | MACROS_PLUS_PLUS(Button, *object); 1276 | break; 1277 | case 7: 1278 | MACROS_PLUS_PLUS(InputBoolean, *object); 1279 | break; 1280 | case 8: 1281 | (*inputStringMacros((InputString *) *object))++; 1282 | break; 1283 | case 9: 1284 | MACROS_PLUS_PLUS(InputNumber, *object); 1285 | break; 1286 | case 10: 1287 | MACROS_PLUS_PLUS(InputList, *object); 1288 | break; 1289 | case 11: 1290 | (*outputStringMacros((OutputString *) *object))++; 1291 | break; 1292 | case 12: 1293 | MACROS_PLUS_PLUS(OutputNumber, *object); 1294 | break; 1295 | case 13: 1296 | MACROS_PLUS_PLUS(Line, *object); 1297 | break; 1298 | case 14: 1299 | MACROS_PLUS_PLUS(Rectangle, *object); 1300 | break; 1301 | case 15: 1302 | MACROS_PLUS_PLUS(Ellipse, *object); 1303 | break; 1304 | case 16: 1305 | MACROS_PLUS_PLUS(Polygon, *object); 1306 | break; 1307 | case 17: 1308 | MACROS_PLUS_PLUS(Meter, *object); 1309 | break; 1310 | case 18: 1311 | MACROS_PLUS_PLUS(LinearBarGraph, *object); 1312 | break; 1313 | case 19: 1314 | MACROS_PLUS_PLUS(ArchedBarGraph, *object); 1315 | break; 1316 | case 20: 1317 | MACROS_PLUS_PLUS(PictureGraphic, *object); 1318 | break; 1319 | 1320 | case 23: 1321 | MACROS_PLUS_PLUS(FontAttributes, *object); 1322 | break; 1323 | case 24: 1324 | MACROS_PLUS_PLUS(LineAttributes, *object); 1325 | break; 1326 | case 25: 1327 | MACROS_PLUS_PLUS(FillAttributes, *object); 1328 | break; 1329 | case 26: 1330 | (*inputAttributesMacros((InputAttributes *) *object))++; 1331 | break; 1332 | default: 1333 | printf("ERROR: object of type %i , can't have macros??\n", objectType); 1334 | return; 1335 | } 1336 | *object = realloc(*object, getRealSize(*object)); 1337 | 1338 | // copy reference 1339 | memmove(((char *) *object) + orginalSize, ¯oRef, sizeof(MacroReference)); 1340 | } 1341 | 1342 | // when object is read, main program is informed and memory released 1343 | void objectReady(void *object) { 1344 | int size = getRealSize(object); 1345 | readyFunct((char *) object, size); 1346 | free(object); 1347 | } 1348 | 1349 | float min(float a, float b) { 1350 | if (a < b) 1351 | return a; 1352 | else 1353 | return b; 1354 | } 1355 | 1356 | // expat-parser calls this function when new xml-element is found 1357 | void start(void *data, const char *el, const char **attr) { 1358 | 1359 | // check if element is an ISOBUS object - if so, get the type 1360 | int type = -1; 1361 | for (int i = 0; i <= 30; i++) 1362 | if (strcmp(xmlNames[i], el) == 0) 1363 | type = i; 1364 | 1365 | int command = getCommandFunction(el); 1366 | int eventId = getEventId(getAttribute(attr, "role")); 1367 | 1368 | // create new object (if it is a real object) 1369 | if (type >= 0) { 1370 | objectStack[ objectsInStack ] = createObject(type, attr); 1371 | } 1372 | 1373 | // if object is a macro or a reference to macro (checked from 1374 | // "role" attribute) 1375 | if ((objectsInStack > 0) && (eventId > 0)) { 1376 | //printf("add macro\n"); 1377 | MacroReference macro; 1378 | macro.eventId = eventId; 1379 | macro.macroId = getId(attr); 1380 | addEventReference(&objectStack[objectsInStack - 1], macro); 1381 | } 1382 | 1383 | // add object to its parent (unless object is in objectpool) 1384 | else if ((objectsInStack > 0) && (type >= 0 || strcmp( el, "include_object") == 0)) { 1385 | 1386 | multiplier = getMultiplier(attr, multiplier, xform.dm_mult, xform.sk_mult); 1387 | 1388 | ObjectReference objectReference; 1389 | objectReference.objectId = getId(attr); 1390 | 1391 | // calculate using block font and multipliers 1392 | 1393 | objectReference.x = (int) (multiplier * getX(attr)) + getBlockCol(attr) * getBlockFontWidth(attr, (int) multiplier); 1394 | objectReference.y = (int) (multiplier * getY(attr)) + getBlockRow(attr) * getBlockFontHeight(attr, (int) multiplier); 1395 | addObjectReference(&objectStack[ objectsInStack - 1], objectReference, getRole(attr)); 1396 | } 1397 | 1398 | // if elment is the root element "objectpool", calculate deltas 1399 | else if (strcmp(el, "objectpool") == 0) { 1400 | 1401 | // calculate scales and deltas 1402 | xform.dm_mult = ((float) vtDimension) / ((float) getDimension(attr)); 1403 | xform.sk_mult = min(((float) vtSkWidth) / ((float) getSkWidth(attr)), 1404 | ((float) vtSkHeight) / ((float) getSkHeight(attr))); 1405 | 1406 | multiplier = min(xform.dm_mult, xform.sk_mult); 1407 | 1408 | xform.dm_dx = (int) (vtDimension - xform.dm_mult * getDimension(attr)) / 2; 1409 | if (xform.dm_dx < 0) { 1410 | xform.dm_dx = 0; 1411 | } 1412 | xform.dm_dy = xform.dm_dx; 1413 | 1414 | xform.sk_dx = (int) (vtSkWidth - xform.sk_mult * getSkWidth(attr)) / 2; 1415 | if (xform.sk_dx < 0) { 1416 | xform.sk_dx = 0; 1417 | } 1418 | 1419 | xform.sk_dy = (int) (vtSkHeight - xform.sk_mult * getSkHeight(attr)) / 2; 1420 | if (xform.sk_dy < 0) { 1421 | xform.sk_dy = 0; 1422 | } 1423 | 1424 | //printf("dm_mult: %f sk_mult: %f dm_dx: %i dm_dy: %i sk_dx: %i sk_dy: %i\n", 1425 | // dm_mult, sk_mult, dm_dx, dm_dy, sk_dx, sk_dy); 1426 | 1427 | } 1428 | 1429 | // if element is point, add it to its parent (should be a polygon) 1430 | else if (strcmp(el, "point") == 0) { 1431 | Point point; 1432 | point.x = (int) (multiplier * getX(attr)); 1433 | point.y = (int) (multiplier * getY(attr)); 1434 | addPoint(&objectStack[ objectsInStack - 1], point); 1435 | } 1436 | 1437 | // if element is image_data start reading data 1438 | else if (strcmp(el, "image_data") == 0) { 1439 | PictureGraphic *pictureGraphic = (PictureGraphic *) objectStack[ objectsInStack-1]; 1440 | pictureGraphic->actualWidth = getActualWidth(attr); 1441 | pictureGraphic->actualHeight = getActualHeight(attr); 1442 | dataReading = 1; 1443 | } 1444 | else if (strcmp(el, "language") == 0) { 1445 | // FIXME not implemented yet 1446 | } 1447 | 1448 | // if elment is a command, add it to a macro 1449 | else if ((command >= 0) && (objectsInStack > 0)) { 1450 | //printf("command: %s\n", el); 1451 | void *comm = createCommand(command, attr); 1452 | addCommand(&objectStack[objectsInStack - 1], comm); 1453 | free(comm); 1454 | } 1455 | else if (objectsInStack == 0) { 1456 | } 1457 | else { 1458 | printf("ERROR: element: %s\n", el); 1459 | } 1460 | 1461 | if (type >= 0) { 1462 | objectsInStack++; 1463 | } 1464 | 1465 | // call startFunct() in the main program 1466 | startFunct(data, (char *) el, attr); 1467 | } 1468 | 1469 | // expat-parser calls this function when xml-element is 'closed' 1470 | void end(void *data, const char *el) { 1471 | 1472 | // if element was image_data, all data is readed and can be 1473 | // parsed, and aded to image 1474 | if (strcmp(el, "image_data") == 0) { 1475 | addPictureData(&objectStack[objectsInStack - 1]); 1476 | 1477 | dataReading = 0; 1478 | free(dataText); 1479 | dataText = NULL; 1480 | dataLength = 0; 1481 | } 1482 | int type = -1; 1483 | for (int i = 0; i <= 30; i++) 1484 | if (strcmp(xmlNames[i], el) == 0) 1485 | type = i; 1486 | 1487 | // object is ready (if it is a real object) 1488 | if (type >= 0) { 1489 | objectsInStack--; 1490 | objectReady(objectStack[objectsInStack]); 1491 | } 1492 | 1493 | // call endFunct() in the main program 1494 | endFunct(data, (char *) el); 1495 | } 1496 | 1497 | // expat-parser calls this function when data is read inside xml-element 1498 | // if current element is image_data, then data is saved to an array 1499 | void characterDataHandler(void *userData, const XML_Char *s, int len) 1500 | { 1501 | (void) userData; 1502 | if (dataReading) { 1503 | dataText = (char *) realloc(dataText, len + dataLength); 1504 | memcpy(dataText + dataLength, s, len); 1505 | dataLength += len; 1506 | } 1507 | } 1508 | 1509 | // Fuction parses a .xml file that is imported from PoolEdit program. 1510 | // - start() and end() functions are called when a new element is 1511 | // started or ended. 1512 | // - ready() is called when parsing is done, and an array with 1513 | // ISOBUS data is returned parameters vtDimension_, vtSkWidth_, 1514 | // vtSkHeight_ and vtColors_ give info about VT 1515 | void parse(FILE *file, void (*start_)(void *data, char *el, const char **attr), 1516 | void (*end_) (void *data, char *el), void (*ready)(char *data, int length), 1517 | int vtDimension_, int vtSkWidth_, int vtSkHeight_, int vtColors_) 1518 | { 1519 | readyFunct = ready; 1520 | startFunct = start_; 1521 | endFunct = end_; 1522 | vtDimension = vtDimension_; 1523 | vtSkWidth = vtSkWidth_; 1524 | vtSkHeight = vtSkHeight_; 1525 | vtColors = vtColors_; 1526 | 1527 | objectsInStack = 0; 1528 | 1529 | XML_Parser p = XML_ParserCreate(NULL); 1530 | XML_SetElementHandler(p, start, end); 1531 | XML_SetCharacterDataHandler(p, characterDataHandler); 1532 | 1533 | if (file == NULL) { 1534 | fprintf(stderr, "No such file!\n"); 1535 | return; 1536 | } 1537 | 1538 | char Buff[256]; 1539 | while (!feof(file)) { 1540 | int len = fread(Buff, 1, 256, file); 1541 | 1542 | if (ferror(file)) { 1543 | fprintf(stderr, "Read error\n"); 1544 | exit(-1); 1545 | } 1546 | 1547 | if (!XML_Parse(p, Buff, len, feof(file))) { 1548 | fprintf(stderr, "Parse error at line %ld:\n%s\n", 1549 | XML_GetCurrentLineNumber(p), 1550 | XML_ErrorString(XML_GetErrorCode(p))); 1551 | exit(-1); 1552 | } 1553 | } 1554 | XML_ParserFree(p); 1555 | } 1556 | -------------------------------------------------------------------------------- /src/parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2019 Automation technology laboratory, 3 | * Helsinki University of Technology 4 | * 5 | * Visit automation.tkk.fi for information about the automation 6 | * technology laboratory. 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 3 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 21 | * MA 02111-1307, USA. 22 | */ 23 | 24 | #ifndef XML_PARSER_H 25 | #define XML_PARSER_H 26 | 27 | // Function parses a .xml file that is imported from PoolEdit program. 28 | // - start() and end() functions are called when a new element is 29 | // started or ended. 30 | // - ready() is called when parsing is done, and an array with 31 | // ISOBUS data is returned parameters vtDimension_, vtSkWidth_, 32 | // vtSkHeight_ and vtColors_ give info about VT 33 | 34 | typedef struct pool_xform { 35 | float dm_mult; 36 | float sk_mult; 37 | int dm_dx; 38 | int dm_dy; 39 | int sk_dx; 40 | int sk_dy; 41 | } pool_xform_t; 42 | 43 | // the transform becomes available after the root object has been 44 | // parsed 45 | pool_xform_t *get_pool_xform(); 46 | 47 | void parse(FILE *file, void (*start_)(void *data, char *el, const char **attr), 48 | void (*end_) (void *data, char *el), void (*ready)(char *data, int length), 49 | int vtDimension_, int vtSkWidth_, int vtSkHeight_, int vtColors_); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/parserdef.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2019 Automation technology laboratory, 3 | * Helsinki University of Technology 4 | * 5 | * Visit automation.tkk.fi for information about the automation 6 | * technology laboratory. 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 3 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 21 | * MA 02111-1307, USA. 22 | */ 23 | 24 | // parsedef.h 25 | 26 | #ifndef PARSERDEF 27 | #define PARSERDEF 28 | 29 | #pragma pack(1) 30 | 31 | // this is the start of every object in pool 32 | typedef struct 33 | { 34 | unsigned short objectId; 35 | unsigned char type; 36 | } ObjectHeader; 37 | 38 | // when a object has xy-coordinates inside of another object, this 39 | // reference is used 40 | typedef struct 41 | { 42 | unsigned short objectId; 43 | unsigned short x; 44 | unsigned short y; 45 | } ObjectReference; 46 | 47 | // struct is used referring a macro 48 | typedef struct 49 | { 50 | unsigned char eventId; 51 | unsigned char macroId; 52 | } MacroReference; 53 | 54 | // language code 55 | typedef struct 56 | { 57 | unsigned char char1; 58 | unsigned char char2; 59 | } LanguageCode; 60 | 61 | // a polygon point 62 | typedef struct 63 | { 64 | unsigned short x; 65 | unsigned short y; 66 | } Point; 67 | 68 | 69 | /**************** ISOBUS objects ****************/ 70 | 71 | typedef struct 72 | { 73 | unsigned short objectId; 74 | unsigned char type; 75 | 76 | unsigned char backgroundColor; 77 | unsigned char selectable; 78 | unsigned short activeMask; 79 | unsigned char objects; 80 | unsigned char macros; 81 | unsigned char languageCodes; 82 | } WorkingSet; 83 | 84 | typedef struct 85 | { 86 | unsigned short objectId; 87 | unsigned char type; 88 | 89 | unsigned char backgroundColor; 90 | unsigned short softKeyMask; 91 | unsigned char objects; 92 | unsigned char macros; 93 | } DataMask; 94 | 95 | typedef struct 96 | { 97 | unsigned short objectId; 98 | unsigned char type; 99 | 100 | unsigned char backgroundColor; 101 | unsigned short softKeyMask; 102 | unsigned char priority; 103 | unsigned char acousticSignal; 104 | unsigned char objects; 105 | unsigned char macros; 106 | } AlarmMask; 107 | 108 | typedef struct 109 | { 110 | unsigned short objectId; 111 | unsigned char type; 112 | 113 | unsigned short width; 114 | unsigned short height; 115 | unsigned char hidden; 116 | unsigned char objects; 117 | unsigned char macros; 118 | } Container; 119 | 120 | typedef struct 121 | { 122 | unsigned short objectId; 123 | unsigned char type; 124 | 125 | unsigned char backgroundColor; 126 | unsigned char objects; 127 | unsigned char macros; 128 | // objects here, only 2 bytes long (no x,y) 129 | } SoftKeyMask; 130 | 131 | typedef struct 132 | { 133 | unsigned short objectId; 134 | unsigned char type; 135 | 136 | unsigned char backgroundColor; 137 | unsigned char keyCode; 138 | unsigned char objects; 139 | unsigned char macros; 140 | } Key; 141 | 142 | typedef struct 143 | { 144 | unsigned short objectId; 145 | unsigned char type; 146 | 147 | unsigned short width; 148 | unsigned short height; 149 | unsigned char backgroundColor; 150 | unsigned char borderColor; 151 | unsigned char keyCode; 152 | unsigned char latchable; 153 | unsigned char objects; 154 | unsigned char macros; 155 | } Button; 156 | 157 | typedef struct 158 | { 159 | unsigned short objectId; 160 | unsigned char type; 161 | 162 | unsigned char backgroundColor; 163 | unsigned short width; 164 | unsigned short foregroundColor; // id! 165 | unsigned short variableReference; 166 | unsigned char value; 167 | unsigned char enabled; 168 | unsigned char macros; 169 | } InputBoolean; 170 | 171 | typedef struct 172 | { 173 | unsigned short objectId; 174 | unsigned char type; 175 | 176 | unsigned short width; 177 | unsigned short height; 178 | unsigned char backgroundColor; 179 | unsigned short fontAttributes; 180 | unsigned short inputAttributes; 181 | unsigned char options; 182 | unsigned short variableReference; 183 | unsigned char horizontalJustification; 184 | unsigned char length; 185 | 186 | unsigned char value[]; // length of value is the 'length' 187 | 188 | // 2 bytes! 189 | //unsigned char enabled; 190 | //unsigned char macros; 191 | } InputString; 192 | 193 | // returns a pointer to the number of macros 194 | unsigned char* inputStringMacros(InputString *ptr) 195 | { 196 | return ptr->value + ptr->length * sizeof(unsigned char) + 1; 197 | } 198 | 199 | // returns a pointer to enabled-attribute 200 | unsigned char* inputStringEnabled(InputString *ptr) 201 | { 202 | return ptr->value + ptr->length * sizeof(unsigned char); 203 | } 204 | 205 | typedef struct 206 | { 207 | unsigned short objectId; 208 | unsigned char type; 209 | 210 | unsigned short width; 211 | unsigned short height; 212 | unsigned char backgroundColor; 213 | unsigned short fontAttributes; 214 | unsigned char options; 215 | unsigned short variableReference; 216 | unsigned int value; 217 | unsigned int minValue; 218 | unsigned int maxValue; 219 | int offset; 220 | float scale; 221 | unsigned char numberOfDecimals; 222 | unsigned char format; 223 | unsigned char horizontalJustification; 224 | unsigned char enabled; 225 | unsigned char macros; 226 | } InputNumber; 227 | 228 | typedef struct 229 | { 230 | unsigned short objectId; 231 | unsigned char type; 232 | 233 | unsigned short width; 234 | unsigned short height; 235 | unsigned short variableReference; 236 | unsigned char value; 237 | unsigned char numberOfListItems; 238 | unsigned char enabled; 239 | unsigned char macros; 240 | // objects here, only 2 bytes long (no x,y) 241 | } InputList; 242 | 243 | 244 | typedef struct 245 | { 246 | unsigned short objectId; 247 | unsigned char type; 248 | 249 | unsigned short width; 250 | unsigned short height; 251 | unsigned char backgroundColor; 252 | unsigned short fontAttributes; 253 | unsigned char options; 254 | unsigned short variableReference; 255 | unsigned char horizontalJustification; 256 | unsigned short length; 257 | unsigned char value[]; 258 | // the value (string) comes here! length of value is the 'length' 259 | 260 | // unsigned char macros; 261 | } OutputString; 262 | 263 | // returns a pointer to the number of macros 264 | unsigned char *outputStringMacros(OutputString *ptr) 265 | { 266 | return ptr->value + ptr->length * sizeof(unsigned char); 267 | } 268 | 269 | 270 | typedef struct 271 | { 272 | unsigned short objectId; 273 | unsigned char type; 274 | 275 | unsigned short width; 276 | unsigned short height; 277 | unsigned char backgroundColor; 278 | unsigned short fontAttributes; 279 | unsigned char options; 280 | unsigned short variableReference; 281 | unsigned int value; 282 | int offset; 283 | float scale; 284 | unsigned char numberOfDecimals; 285 | unsigned char format; 286 | unsigned char horizontalJustification; 287 | unsigned char macros; 288 | } OutputNumber; 289 | 290 | typedef struct 291 | { 292 | unsigned short objectId; 293 | unsigned char type; 294 | 295 | unsigned short lineAttributes; 296 | unsigned short width; 297 | unsigned short height; 298 | unsigned char lineDirection; 299 | unsigned char macros; 300 | } Line; 301 | 302 | typedef struct 303 | { 304 | unsigned short objectId; 305 | unsigned char type; 306 | 307 | unsigned short lineAttributes; 308 | unsigned short width; 309 | unsigned short height; 310 | unsigned char lineSupression; 311 | unsigned short fillAttributes; 312 | unsigned char macros; 313 | } Rectangle; 314 | 315 | typedef struct 316 | { 317 | unsigned short objectId; 318 | unsigned char type; 319 | 320 | unsigned short lineAttributes; 321 | unsigned short width; 322 | unsigned short height; 323 | unsigned char ellipseType; 324 | unsigned char startAngle; 325 | unsigned char endAngle; 326 | unsigned short fillAttributes; 327 | unsigned char macros; 328 | } Ellipse; 329 | 330 | typedef struct 331 | { 332 | unsigned short objectId; 333 | unsigned char type; 334 | 335 | unsigned short width; 336 | unsigned short height; 337 | unsigned short lineAttributes; 338 | unsigned short fillAttributes; 339 | unsigned char polygonType; 340 | unsigned char numberOfPoints; 341 | unsigned char macros; 342 | // points (x,y) 343 | // macros 344 | } Polygon; 345 | 346 | typedef struct 347 | { 348 | unsigned short objectId; 349 | unsigned char type; 350 | 351 | unsigned short width; 352 | unsigned char needleColor; 353 | unsigned char borderColor; 354 | unsigned char arcAndTickColor; 355 | unsigned char options; 356 | unsigned char numberOfTicks; 357 | unsigned char startAngle; 358 | unsigned char endAngle; 359 | unsigned short minValue; 360 | unsigned short maxValue; 361 | unsigned short variableReference; 362 | unsigned short value; 363 | unsigned char macros; 364 | } Meter; 365 | 366 | typedef struct 367 | { 368 | unsigned short objectId; 369 | unsigned char type; 370 | 371 | unsigned short width; 372 | unsigned short height; 373 | unsigned char color; 374 | unsigned char targetLineColor; 375 | unsigned char options; 376 | unsigned char numberOfTicks; 377 | unsigned short minValue; 378 | unsigned short maxValue; 379 | unsigned short variableReference; 380 | unsigned short value; 381 | unsigned short targetValueVariableReference; 382 | unsigned short targetValue; 383 | unsigned char macros; 384 | } LinearBarGraph; 385 | 386 | typedef struct 387 | { 388 | unsigned short objectId; 389 | unsigned char type; 390 | 391 | unsigned short width; 392 | unsigned short height; 393 | unsigned char color; 394 | unsigned char targetLineColor; 395 | unsigned char options; 396 | unsigned char startAngle; 397 | unsigned char endAngle; 398 | unsigned short barGraphWidth; 399 | unsigned short minValue; 400 | unsigned short maxValue; 401 | unsigned short variableReference; 402 | unsigned short value; 403 | unsigned short targetValueVariableReference; 404 | unsigned short targetValue; 405 | unsigned char macros; 406 | } ArchedBarGraph; 407 | 408 | typedef struct 409 | { 410 | unsigned short objectId; 411 | unsigned char type; 412 | 413 | unsigned short width; 414 | unsigned short actualWidth; 415 | unsigned short actualHeight; 416 | unsigned char format; 417 | unsigned char options; 418 | unsigned char transparencyColor; 419 | unsigned int rawDataLength; 420 | unsigned char macros; 421 | // raw-data 422 | // macros 423 | } PictureGraphic; 424 | 425 | typedef struct 426 | { 427 | unsigned short objectId; 428 | unsigned char type; 429 | 430 | unsigned int value; 431 | } NumberVariable; 432 | 433 | typedef struct 434 | { 435 | unsigned short objectId; 436 | unsigned char type; 437 | 438 | unsigned short length; 439 | // data 440 | } StringVariable; 441 | 442 | typedef struct 443 | { 444 | unsigned short objectId; 445 | unsigned char type; 446 | 447 | unsigned char fontColor; 448 | unsigned char fontSize; 449 | unsigned char fontType; 450 | unsigned char fontStyle; 451 | unsigned char macros; 452 | } FontAttributes; 453 | 454 | typedef struct 455 | { 456 | unsigned short objectId; 457 | unsigned char type; 458 | 459 | unsigned char lineColor; 460 | unsigned char lineWidth; 461 | unsigned short lineArt; 462 | unsigned char macros; 463 | } LineAttributes; 464 | 465 | typedef struct 466 | { 467 | unsigned short objectId; 468 | unsigned char type; 469 | 470 | unsigned char fillType; 471 | unsigned char fillColor; 472 | unsigned short fillPattern; 473 | unsigned char macros; 474 | } FillAttributes; 475 | 476 | typedef struct 477 | { 478 | unsigned short objectId; 479 | unsigned char type; 480 | 481 | unsigned char validationType; 482 | unsigned char length; 483 | unsigned char validationString[]; 484 | 485 | // unsigned char macros; 486 | } InputAttributes; 487 | 488 | // returns a pointer to the number of macros 489 | unsigned char *inputAttributesMacros(InputAttributes *ptr) 490 | { 491 | return ptr->validationString + ptr->length * sizeof(unsigned char); 492 | } 493 | 494 | typedef struct 495 | { 496 | unsigned short objectId; 497 | unsigned char type; 498 | 499 | unsigned short value; 500 | } ObjectPointer; 501 | 502 | 503 | typedef struct 504 | { 505 | unsigned short objectId; 506 | unsigned char type; 507 | 508 | unsigned short numberOfBytes; 509 | unsigned char commands[]; 510 | } Macro; 511 | 512 | // auxiliary control 513 | 514 | typedef struct 515 | { 516 | unsigned short objectId; 517 | unsigned char type; 518 | 519 | unsigned char backgroundColor; 520 | unsigned char functionType; 521 | 522 | unsigned char objects; 523 | } AuxiliaryFunction; 524 | 525 | typedef struct 526 | { 527 | unsigned short objectId; 528 | unsigned char type; 529 | 530 | unsigned char backgroundColor; 531 | unsigned char functionType; 532 | unsigned char inputId; 533 | 534 | unsigned char objects; 535 | } AuxiliaryInput; 536 | 537 | /*********** COMMANDS ***************/ 538 | 539 | typedef struct 540 | { 541 | unsigned char VTFunction; 542 | 543 | unsigned short objectId; 544 | unsigned char show; 545 | unsigned int padding; 546 | } HideShowObject; 547 | 548 | typedef struct 549 | { 550 | unsigned char VTFunction; 551 | 552 | unsigned short objectId; 553 | unsigned char enable; 554 | unsigned int padding; 555 | } EnableDisableObject; 556 | 557 | typedef struct 558 | { 559 | unsigned char VTFunction; 560 | 561 | unsigned short objectId; 562 | unsigned int padding1; 563 | unsigned char padding2; 564 | } SelectInputObject; 565 | 566 | typedef struct 567 | { 568 | unsigned char VTFunction; 569 | 570 | unsigned char repetitions; 571 | unsigned short frequency; 572 | unsigned short onTime; 573 | unsigned short offTime; 574 | } ControlAudioDevice; 575 | 576 | typedef struct 577 | { 578 | unsigned char VTFunction; 579 | 580 | unsigned char volume; 581 | unsigned int padding1; 582 | unsigned short padding2; 583 | } SetAudioVolume; 584 | 585 | typedef struct 586 | { 587 | unsigned char VTFunction; 588 | 589 | unsigned short parentId; 590 | unsigned short childId; 591 | unsigned char dx; 592 | unsigned char dy; 593 | unsigned char padding; 594 | } ChangeChildLocation; 595 | 596 | typedef struct 597 | { 598 | unsigned char VTFunction; 599 | 600 | unsigned short objectId; 601 | unsigned short width; 602 | unsigned short height; 603 | unsigned char padding; 604 | } ChangeSize; 605 | 606 | typedef struct 607 | { 608 | unsigned char VTFunction; 609 | 610 | unsigned short objectId; 611 | unsigned char backgroundColor; 612 | unsigned int padding; 613 | } ChangeBackgroundColor; 614 | 615 | typedef struct 616 | { 617 | unsigned char VTFunction; 618 | 619 | unsigned short objectId; 620 | unsigned char padding; 621 | unsigned int value; 622 | } ChangeNumericValue; 623 | 624 | typedef struct 625 | { 626 | unsigned char VTFunction; 627 | 628 | unsigned short objectId; 629 | unsigned short length; 630 | unsigned char string[]; 631 | } ChangeStringValue; 632 | 633 | typedef struct 634 | { 635 | unsigned char VTFunction; 636 | 637 | unsigned short objectId; 638 | unsigned short width; 639 | unsigned short height; 640 | unsigned char lineDirection; 641 | } ChangeEndPoint; 642 | 643 | typedef struct 644 | { 645 | unsigned char VTFunction; 646 | 647 | unsigned short objectId; 648 | unsigned char fontColor; 649 | unsigned char fontSize; 650 | unsigned char fontType; 651 | unsigned char fontStyle; 652 | unsigned char padding; 653 | } ChangeFontAttributes; 654 | 655 | typedef struct 656 | { 657 | unsigned char VTFunction; 658 | 659 | unsigned short objectId; 660 | unsigned char lineColor; 661 | unsigned char lineWidth; 662 | unsigned short lineArt; 663 | unsigned char padding; 664 | } ChangeLineAttributes; 665 | 666 | typedef struct 667 | { 668 | unsigned char VTFunction; 669 | 670 | unsigned short objectId; 671 | unsigned char fillType; 672 | unsigned char fillColor; 673 | unsigned short fillPattern; 674 | unsigned char padding; 675 | } ChangeFillAttributes; 676 | 677 | 678 | typedef struct 679 | { 680 | unsigned char VTFunction; 681 | 682 | unsigned short parentId; 683 | unsigned short childId; 684 | unsigned short padding1; 685 | unsigned char padding2; 686 | } ChangeActiveMask; 687 | 688 | typedef struct 689 | { 690 | unsigned char VTFunction; 691 | 692 | unsigned char maskType; 693 | unsigned short parentId; 694 | unsigned short childId; 695 | unsigned short padding1; 696 | } ChangeSoftKeyMask; 697 | 698 | typedef struct 699 | { 700 | unsigned char VTFunction; 701 | 702 | unsigned short objectId; 703 | unsigned char AID; 704 | unsigned int value; 705 | } ChangeAttribute; 706 | 707 | typedef struct 708 | { 709 | unsigned char VTFunction; 710 | 711 | unsigned short objectId; 712 | unsigned char priority; 713 | unsigned int padding; 714 | } ChangePriority; 715 | 716 | typedef struct 717 | { 718 | unsigned char VTFunction; 719 | 720 | unsigned short parentId; 721 | unsigned short childId; 722 | unsigned short x; 723 | unsigned short y; 724 | } ChangeChildPosition; 725 | 726 | typedef struct 727 | { 728 | unsigned char VTFunction; 729 | 730 | unsigned short parentId; 731 | unsigned char listIndex; 732 | unsigned short childId; 733 | unsigned short padding; 734 | } ChangeListItem; 735 | 736 | #pragma pack() 737 | 738 | // an array of all XML elements that have a corresponding ISOBUS 739 | // object 740 | 741 | // names are ordered by object type 742 | const char *xmlNames[] = 743 | {"workingset", "datamask", "alarmmask", "container", "softkeymask", "key", 744 | "button", "inputboolean", "inputstring", "inputnumber", 745 | "inputlist", "outputstring", "outputnumber", "line", "rectangle", 746 | "ellipse", "polygon", "meter", "linearbargraph", "archedbargraph", 747 | "picturegraphic", "numbervariable", "stringvariable", "fontattributes", 748 | "lineattributes", "fillattributes", "inputattributes", 749 | "objectpointer", "macro", "auxiliaryfunction", "auxiliaryinput"}; 750 | 751 | 752 | // commands-array has xml-names of all supported commands 753 | const char *commands[] = 754 | {"command_hide_show_object", "command_enable_disable_object", "command_select_input_object", 755 | "command_control_audio_device", "command_set_audio_volume", "command_change_child_location", 756 | "command_change_size", "command_change_background_colour", "command_change_numeric_value", 757 | "command_change_string_value", "command_change_end_point", "command_change_font_attributes", 758 | "command_change_line_attributes", "command_change_fill_attributes", "command_change_active_mask", 759 | "command_change_soft_key_mask", "command_change_attribute", "command_change_priority", 760 | "command_change_child_position", "command_change_list_item", 761 | NULL}; 762 | 763 | // commandFunction-array has the function numbers of the commands in 764 | // the commands-array 765 | int commandFunction[] = 766 | {160, 161, 162, 767 | 163, 164, 165, 768 | 166, 167, 168, 769 | 179, 169, 170, 770 | 171, 172, 173, 771 | 174, 175, 176, 772 | 180, 177}; 773 | 774 | // XML names of all events, ordered by event number 775 | const char *events[] = 776 | {"on_activate", "on_deactivate", "on_show", "on_hide", "on_enable", "on_disable", 777 | "on_change_active_mask", "on_change_soft_key_mask", "on_change_attribute", 778 | "on_change_background_colour", "on_change_font_attributes", "on_change_line_attributes", 779 | "on_change_fill_attributes", "on_change_child_location", "on_change_size", "on_change_value", 780 | "on_change_priority", "on_change_end_point", "on_input_field_selection", 781 | "on_input_field_deselection", "on_esc", "on_entry_of_value", "on_entry_of_new_value", 782 | "on_key_press", "on_key_release" , "on_change_child_position"}; 783 | 784 | #endif /* #ifndef PARSERDEF */ 785 | -------------------------------------------------------------------------------- /src/pooleditparser.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2019 Automation technology laboratory, 3 | * Helsinki University of Technology 4 | * 5 | * Visit automation.tkk.fi for information about the automation 6 | * technology laboratory. 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 3 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 21 | * MA 02111-1307, USA. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include "parser.h" 28 | #include "xml.h" 29 | 30 | #define VERSION "1.5.0" 31 | 32 | // linked list node 33 | struct node { 34 | char *head; 35 | struct node *tail; 36 | }; 37 | 38 | typedef struct node node_t; 39 | 40 | // start and end nodes of the linked list 41 | node_t *list_start = NULL; 42 | node_t *list_end = NULL; 43 | 44 | // output file 45 | FILE *fileOut; 46 | 47 | int pool_size = 0; 48 | int nro_total_objects = 0; 49 | int nro_root_objects = 0; 50 | 51 | int depth = 0; 52 | int printTable = false; 53 | int firstByte = true; 54 | 55 | // 56 | // function for adding a new string to the linked list 57 | // 58 | void addToList(char *bff) 59 | { 60 | // allocate and init new node 61 | node_t *node = (node_t *) malloc(sizeof(node_t)); 62 | if (node == NULL) { 63 | printf("out of memory!\n"); 64 | exit(-1); 65 | } 66 | node->head = bff; 67 | node->tail = NULL; 68 | 69 | // add node to list 70 | if (list_start == NULL) { 71 | list_start = node; 72 | list_end = node; 73 | } 74 | else { 75 | list_end->tail = node; 76 | list_end = node; 77 | } 78 | } 79 | 80 | // 81 | // function for printing the linked list 82 | // 83 | void printList() 84 | { 85 | node_t *node = list_start; 86 | while (node != NULL) { 87 | fprintf(fileOut, "%s", node->head); 88 | node = node->tail; 89 | } 90 | } 91 | 92 | // 93 | // callback function that prints ascii formatted numbers to file 94 | // 95 | void ascii_ready(char *data, int length) 96 | { 97 | for (int i = 0; i < length; i++) { 98 | if (firstByte) { 99 | firstByte = false; 100 | } 101 | else { 102 | fprintf(fileOut, ", "); 103 | if (i == 0) { 104 | fprintf(fileOut, "\n "); 105 | } 106 | } 107 | fprintf(fileOut, "%i", (unsigned char) data[i]); 108 | } 109 | pool_size += length; 110 | nro_total_objects++; 111 | } 112 | 113 | // 114 | // callback function that prints raw bytes to file 115 | // 116 | void binary_ready(char *data, int length) 117 | { 118 | for (int i = 0; i < length; i++) { 119 | fputc((unsigned char) data[i], fileOut); 120 | } 121 | pool_size += length; 122 | nro_total_objects++; 123 | } 124 | 125 | // 126 | // callback function 127 | // 128 | void starts(void *userData, char *el, const char ** attr) 129 | { 130 | (void) userData; 131 | (void) el; 132 | 133 | char tmp[256]; 134 | char *bff; 135 | char *name; 136 | int id; 137 | int len; 138 | 139 | if (depth == 1) { 140 | name = getName(attr); 141 | id = getId(attr); 142 | 143 | // print string to tmp, allocate bff accordingly and copy 144 | // string 145 | sprintf(tmp, "#define %s %d\n", name, id); 146 | len = strlen(tmp) + 1; 147 | bff = (char *) malloc(len); 148 | memcpy(bff, tmp, len); 149 | 150 | addToList(bff); 151 | 152 | nro_root_objects++; 153 | } 154 | depth++; 155 | } 156 | 157 | // 158 | // callback function 159 | // 160 | void ends(void *userData, char *el) 161 | { 162 | (void) userData; 163 | (void) el; 164 | depth--; 165 | } 166 | 167 | // 168 | // function for printing usage information on stdout 169 | // 170 | void printUseage() 171 | { 172 | printf("Usage: pooleditparser xml-filename output-filename -d=[dimension] " 173 | "-sw=[softkey width] -sh=[softkey height] -c=[colors] [-table] [-v]\n"); 174 | } 175 | 176 | // 177 | // main program 178 | // 179 | int main(int argc, char *argv[]) 180 | { 181 | // input file handle 182 | FILE *fileIn; 183 | 184 | // setting defaults 185 | int dimension = 200; 186 | int skWidth = 60; 187 | int skHeight = 32; 188 | int colors = 256; 189 | 190 | for (int i = 0; i < argc; i++) { 191 | if (strncmp("-v", argv[i], 2) == 0) { 192 | printf("version: %s\n", VERSION); 193 | exit(0); 194 | } 195 | } 196 | 197 | // check arguments 198 | if (argc < 3) { 199 | printUseage(); 200 | exit(-1); 201 | } 202 | 203 | // open files 204 | fileIn = fopen(argv[1], "r"); 205 | if (fileIn == NULL) { 206 | printf("Can't open file: %s\n", argv[1]); 207 | exit(-2); 208 | } 209 | 210 | fileOut = fopen(argv[2], "w"); 211 | if (fileOut == NULL) { 212 | printf("Can't open file: %s\n", argv[2]); 213 | exit(-3); 214 | } 215 | 216 | // evaluate other arguments 217 | for (int i = 3; i < argc; i++) { 218 | if (strncmp("-d=", argv[i], 3) == 0) { 219 | strtok(argv[i], "="); 220 | dimension = atoi(strtok(NULL, "=")); 221 | } 222 | else if (strncmp("-sw=", argv[i], 4) == 0) { 223 | strtok(argv[i], "="); 224 | skWidth = atoi(strtok(NULL, "=")); 225 | } 226 | else if (strncmp("-sh=", argv[i], 4) == 0) { 227 | strtok(argv[i], "="); 228 | skHeight = atoi(strtok(NULL, "=")); 229 | } 230 | else if (strncmp("-c=", argv[i], 3) == 0) { 231 | strtok(argv[i], "="); 232 | colors = atoi(strtok(NULL, "=")); 233 | } 234 | else if (strncmp("-table", argv[i], 6) == 0) { 235 | printTable = true; 236 | } 237 | else { 238 | printUseage(); 239 | exit(-1); 240 | } 241 | } 242 | 243 | // sanity checks for arguments 244 | if (dimension < 200) { 245 | printf("Too small dimension (%d), using 200\n", dimension); 246 | dimension = 200; 247 | } 248 | if (skWidth < 60) { 249 | printf("Too small soft key width (%d), using 60\n", skWidth); 250 | skWidth = 60; 251 | } 252 | if (skHeight < 32) { 253 | printf("Too small soft key height (%d), using 32\n", skHeight); 254 | skHeight = 32; 255 | } 256 | if (colors != 2 && colors != 16 && colors != 256) { 257 | printf("Invalid number of colors (%d), using 256\n", colors); 258 | colors = 256; 259 | } 260 | 261 | // print settings 262 | printf( 263 | "***************************************************\n" 264 | "* Parsing: %s to %s\n" 265 | "* dimension: %i\n" 266 | "* softkey size: %ix%i\n" 267 | "* colors: %i\n", 268 | argv[1], argv[2], dimension, skWidth, skHeight, colors); 269 | 270 | if (printTable) { 271 | fprintf(fileOut, "unsigned char *pool = {\n "); 272 | parse(fileIn, starts, ends, ascii_ready, dimension, skWidth, skHeight, colors); 273 | fprintf(fileOut, "\n};\n\n#define POOL_SIZE %d\n\n", pool_size); 274 | printList(); 275 | } 276 | else { 277 | parse(fileIn, starts, ends, binary_ready, dimension, skWidth, skHeight, colors); 278 | } 279 | 280 | // close files 281 | fclose(fileIn); 282 | fclose(fileOut); 283 | 284 | pool_xform_t *xform = get_pool_xform(); 285 | 286 | // print statistics 287 | printf("* dmMultiplier: %f\n" 288 | "* skMultiplier: %f\n" 289 | "* dmDeltaX: %d\n" 290 | "* dmDeltaY: %d\n" 291 | "* skDeltaX: %d\n" 292 | "* skDeltaY: %d\n" 293 | "* generated pool size: %d\n" 294 | "* total number of objects: %d\n" 295 | "* number of root level objects: %d\n" 296 | "***************************************************\n", 297 | xform->dm_mult, xform->sk_mult, 298 | xform->dm_dx, xform->dm_dy, xform->sk_dx, xform->sk_dy, 299 | pool_size, nro_total_objects, nro_root_objects); 300 | 301 | return 0; 302 | } 303 | -------------------------------------------------------------------------------- /src/pooleditparser.dev: -------------------------------------------------------------------------------- 1 | [Project] 2 | FileName=pooleditparser.dev 3 | Name=pooleditparser 4 | UnitCount=6 5 | Type=1 6 | Ver=2 7 | ObjFiles= 8 | Includes= 9 | Libs=..\lib 10 | PrivateResource= 11 | ResourceIncludes= 12 | MakeIncludes= 13 | Compiler= 14 | CppCompiler= 15 | Linker=-lexpat_@@_ 16 | IsCpp=1 17 | Icon= 18 | ExeOutput= 19 | ObjectOutput= 20 | OverrideOutput=0 21 | OverrideOutputName=pooleditparser.exe 22 | HostApplication= 23 | Folders= 24 | CommandLine= 25 | UseCustomMakefile=0 26 | CustomMakefile= 27 | IncludeVersionInfo=0 28 | SupportXPThemes=0 29 | CompilerSet=3 30 | CompilerSettings=000000a100111000000001000 31 | LogOutput= 32 | LogOutputEnabled=0 33 | 34 | [Unit1] 35 | FileName=parser.cxx 36 | CompileCpp=1 37 | Folder=pooleditparser 38 | Compile=1 39 | Link=1 40 | Priority=1000 41 | OverrideBuildCmd=0 42 | BuildCmd= 43 | 44 | [Unit2] 45 | FileName=parser.h 46 | CompileCpp=1 47 | Folder=pooleditparser 48 | Compile=1 49 | Link=1 50 | Priority=1000 51 | OverrideBuildCmd=0 52 | BuildCmd= 53 | 54 | [Unit3] 55 | FileName=parserdef.h 56 | CompileCpp=1 57 | Folder=pooleditparser 58 | Compile=1 59 | Link=1 60 | Priority=1000 61 | OverrideBuildCmd=0 62 | BuildCmd= 63 | 64 | [Unit4] 65 | FileName=pooleditparser.cxx 66 | CompileCpp=1 67 | Folder=pooleditparser 68 | Compile=1 69 | Link=1 70 | Priority=1000 71 | OverrideBuildCmd=0 72 | BuildCmd=$(CPP) -c pooleditparser.cxx -o pooleditparser.o $(CXXFLAGS) 73 | 74 | [Unit5] 75 | FileName=xml.cxx 76 | CompileCpp=1 77 | Folder=pooleditparser 78 | Compile=1 79 | Link=1 80 | Priority=1000 81 | OverrideBuildCmd=0 82 | BuildCmd= 83 | 84 | [Unit6] 85 | FileName=xml.h 86 | CompileCpp=1 87 | Folder=pooleditparser 88 | Compile=1 89 | Link=1 90 | Priority=1000 91 | OverrideBuildCmd=0 92 | BuildCmd= 93 | 94 | [VersionInfo] 95 | Major=0 96 | Minor=1 97 | Release=1 98 | Build=1 99 | LanguageID=1033 100 | CharsetID=1252 101 | CompanyName= 102 | FileVersion=0.1.1.1 103 | FileDescription=Developed using the Dev-C++ IDE 104 | InternalName= 105 | LegalCopyright= 106 | LegalTrademarks= 107 | OriginalFilename= 108 | ProductName= 109 | ProductVersion= 110 | AutoIncBuildNr=0 111 | SyncProduct=0 112 | 113 | -------------------------------------------------------------------------------- /src/xml.cxx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2019 Automation technology laboratory, 3 | * Helsinki University of Technology 4 | * 5 | * Visit automation.tkk.fi for information about the automation 6 | * technology laboratory. 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 3 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 21 | * MA 02111-1307, USA. 22 | */ 23 | 24 | #include "xml.h" 25 | 26 | // look xml.h for function definitions 27 | 28 | int atoi2(char *str) 29 | { 30 | // check for empty string 31 | if (str == NULL || str[0] == 0) 32 | return 0; 33 | 34 | return atoi(str); 35 | } 36 | 37 | /* 38 | float atof2(char *str) 39 | { 40 | //check for empty string 41 | if (str == NULL || str[0] == 0) 42 | return 0.0f; 43 | 44 | return atof(str); 45 | } 46 | */ 47 | 48 | char *getAttribute(const char **attrs, const char *name) 49 | { 50 | for (int i = 0; attrs[i]; i += 2) { 51 | if (strcmp(attrs[i], name) == 0) 52 | return (char *) attrs[i + 1]; // !! 53 | } 54 | return NULL; 55 | } 56 | 57 | ////////// utf-8 to latin-1 conversion functions ////////// 58 | 59 | char *str_dup(const char *p) 60 | { 61 | size_t len = strlen(p); 62 | char *rv = (char *) malloc(len + 1); 63 | if (rv == NULL) { 64 | fprintf(stderr, "malloc failed!\n"); 65 | exit(1); 66 | } 67 | strcpy(rv, p); 68 | return rv; 69 | } 70 | 71 | size_t get_length(unsigned char c) 72 | { 73 | if (c < 0x80) return 1; 74 | else if (!(c & 0x20)) return 2; 75 | else if (!(c & 0x10)) return 3; 76 | else if (!(c & 0x08)) return 4; 77 | else if (!(c & 0x04)) return 5; 78 | else return 6; 79 | } 80 | 81 | int utf8toLatin1Char(char **p) 82 | { 83 | size_t len = get_length(**p); 84 | if (len == 1) 85 | return **p; 86 | 87 | int res = (**p & (0xFF >> (len + 1))) << ((len - 1) * 6); 88 | 89 | for (--len; len; --len) { 90 | ++(*p); 91 | res |= ((**p) - 0x80) << ((len - 1) * 6); 92 | } 93 | return res; 94 | } 95 | 96 | // in-place conversion 97 | char *utf8toLatin1Str(char *rv) 98 | { 99 | int i = 0; 100 | for (char *p = rv; *p; ++p, ++i) { 101 | int value = utf8toLatin1Char(&p); 102 | if (value > 0xFF) { 103 | fprintf(stderr, "utf8toLatin1Char() failed!\n"); 104 | exit(1); 105 | } 106 | rv[i] = value; 107 | } 108 | rv[i] = '\0'; 109 | return rv; 110 | } 111 | 112 | // user must free the returned pointer! 113 | char *getAttributeLatin1(const char **attrs, const char *name) 114 | { 115 | char *value = getAttribute(attrs, name); 116 | if (value == NULL) 117 | return NULL; 118 | char *rv = str_dup(value); 119 | return utf8toLatin1Str(rv); 120 | } 121 | 122 | 123 | ///////////////// 124 | 125 | char *getAttributeError(const char **attrs, const char *name) 126 | { 127 | char *retval = getAttribute(attrs, name); 128 | if (retval == NULL) { 129 | printf("ERROR: can't find attribute: %s", name); 130 | exit(0); 131 | } 132 | return retval; 133 | } 134 | 135 | char *getName(const char **attrs) 136 | { 137 | return getAttribute(attrs, "name"); 138 | } 139 | 140 | int isName(const char **attrs, const char *name) 141 | { 142 | char *value = getAttribute(attrs, "name"); 143 | return strcmp(value, name) == 0; 144 | } 145 | 146 | // returns the value of id-attribute 147 | int getId(const char **attrs) 148 | { 149 | char attr[] = "id"; 150 | char *value = getAttribute(attrs, attr); 151 | return atoi2(value); 152 | } 153 | 154 | // returns the value of pos_x-attribute 155 | int getX(const char **attrs) 156 | { 157 | char attr[] = "pos_x"; 158 | char *value = getAttribute(attrs, attr); 159 | return atoi2(value); 160 | } 161 | 162 | // returns the value of pos_y-attribute 163 | int getY(const char **attrs) 164 | { 165 | char attr[] = "pos_y"; 166 | char *value = getAttribute(attrs, attr); 167 | return atoi2(value); 168 | } 169 | 170 | // returns the role of object or include_object 171 | int getRole(const char **attrs) 172 | { 173 | char attr[] = "role"; 174 | char *value = getAttribute(attrs, attr); 175 | 176 | if (value == NULL || strcmp(value, "") == 0) 177 | return ROLE_NONE; 178 | 179 | if (strcmp(value, "active_mask") == 0) 180 | return ROLE_ACTIVE_MASK; 181 | 182 | if (strcmp(value, "font_attributes") == 0) 183 | return ROLE_FONT_ATTRIBUTES; 184 | 185 | if (strcmp(value, "soft_key_mask") == 0) 186 | return ROLE_SOFT_KEY_MASK; 187 | 188 | if (strcmp(value, "variable_reference") == 0) 189 | return ROLE_VARIABLE_REFERENCE; 190 | 191 | if (strcmp(value, "foreground_colour") == 0) 192 | return ROLE_FOREGROUND_COLOR; 193 | 194 | if (strcmp(value, "input_attributes") == 0) 195 | return ROLE_INPUT_ATTRIBUTES; 196 | 197 | if (strcmp(value, "line_attributes") == 0) 198 | return ROLE_LINE_ATTRIBUTES; 199 | 200 | if (strcmp(value, "fill_attributes") == 0) 201 | return ROLE_FILL_ATTRIBUTES; 202 | 203 | if (strcmp(value, "target_value_variable_reference") == 0) 204 | return ROLE_TARGET_VARIABLE_REFERENCE; 205 | 206 | if (strcmp(value, "fill_pattern") == 0) 207 | return ROLE_FILL_PATTERN; 208 | 209 | if (strcmp(value, "value") == 0) 210 | return ROLE_OBJECT_POINTER_VALUE; 211 | 212 | printf("ERROR: unknown role: %s\n", value); 213 | return 0; 214 | } 215 | 216 | int getColor(const char **attrs, const char *name) 217 | { 218 | static const char *colors[] = 219 | {"black", "white", "green", "teal", 220 | "maroon", "purple", "olive", "silver", 221 | "grey", "blue", "lime", "cyan", 222 | "red", "magenta", "yellow", "navy"}; 223 | 224 | char *value = getAttribute(attrs, name); 225 | for (int i = 0; i < 16; i++) 226 | if (strcmp(colors[i], value) == 0) 227 | return i; 228 | 229 | return atoi2(value); 230 | } 231 | 232 | int reduceColor(int color, int colors) 233 | { 234 | // these tables tell what is the nearest color 235 | unsigned char Colors256to16[] = 236 | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 237 | 0, 0, 15, 15, 9, 9, 0, 0, 15, 15, 9, 9, 2, 2, 3, 3, 238 | 3, 9, 2, 2, 3, 3, 3, 3, 2, 2, 3, 3, 3, 11, 10, 10, 239 | 10, 3, 11, 11, 0, 0, 15, 15, 9, 9, 0, 0, 15, 15, 9, 9, 240 | 2, 2, 3, 3, 3, 9, 2, 2, 3, 3, 3, 3, 2, 2, 3, 3, 241 | 3, 11, 10, 10, 10, 3, 11, 11, 4, 4, 5, 5, 5, 9, 4, 4, 242 | 5, 5, 5, 9, 6, 6, 8, 8, 8, 8, 6, 6, 8, 8, 8, 8, 243 | 6, 6, 8, 8, 7, 7, 10, 10, 8, 8, 7, 11, 4, 4, 5, 5, 244 | 5, 5, 4, 4, 5, 5, 5, 5, 6, 6, 8, 8, 8, 8, 6, 6, 245 | 8, 8, 8, 8, 6, 6, 8, 8, 7, 7, 6, 6, 8, 8, 7, 1, 246 | 4, 4, 5, 5, 5, 13, 4, 4, 5, 5, 5, 13, 6, 6, 8, 8, 247 | 7, 7, 6, 6, 8, 8, 7, 7, 6, 6, 7, 7, 7, 7, 14, 14, 248 | 7, 7, 7, 1, 12, 12, 12, 5, 13, 13, 12, 12, 12, 5, 13, 13, 249 | 12, 12, 8, 8, 7, 13, 6, 6, 8, 8, 7, 1, 14, 14, 7, 7, 250 | 7, 1, 14, 14, 14, 1, 1, 1}; 251 | 252 | unsigned char Colors256to2[] = 253 | {0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 254 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255 | 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 256 | 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 257 | 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 258 | 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 259 | 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 260 | 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 261 | 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 262 | 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 263 | 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 264 | 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 265 | 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 266 | 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 267 | 1, 1, 1, 1, 1, 1, 1, 1}; 268 | 269 | if (colors == 256) 270 | return color; 271 | else if (colors == 16) 272 | return Colors256to16[color]; 273 | else 274 | return Colors256to2[color]; 275 | } 276 | 277 | int getReducedColor(const char **attrs, const char *name, int colors) { 278 | return reduceColor(getColor(attrs, name), colors); 279 | } 280 | 281 | int getBackgroundColor(const char **attrs, int colors) { 282 | return getReducedColor(attrs, "background_colour", colors); 283 | } 284 | 285 | int getBorderColor(const char **attrs, int colors) { 286 | return getReducedColor(attrs, "border_colour", colors); 287 | } 288 | 289 | int getFontColor(const char **attrs, int colors) { 290 | return getReducedColor(attrs, "font_colour", colors); 291 | } 292 | 293 | int getLineColor(const char **attrs, int colors) { 294 | return getReducedColor(attrs, "line_colour", colors); 295 | } 296 | 297 | int getNeedleColor(const char **attrs, int colors) { 298 | return getReducedColor(attrs, "needle_colour", colors); 299 | } 300 | 301 | int getArcAndTickColor(const char **attrs, int colors) { 302 | return getReducedColor(attrs, "arc_and_tick_colour", colors); 303 | } 304 | 305 | int getColorColor(const char **attrs, int colors) { 306 | return getReducedColor(attrs, "colour", colors); 307 | } 308 | 309 | int getTargetLineColor(const char **attrs, int colors) { 310 | return getReducedColor(attrs, "target_line_colour", colors); 311 | } 312 | 313 | //FIXME what should this return??? 314 | int getTransparencyColor(const char **attrs) { 315 | return getColor(attrs, "transparency_colour"); 316 | } 317 | 318 | int getFillColor(const char **attrs, int colors) { 319 | return getReducedColor(attrs, "fill_colour", colors); 320 | } 321 | 322 | int getBoolean(const char **attrs, const char *name) { 323 | static const char *trues[] = {"yes", "true", "on", "show", "enable", "1"}; 324 | char *value = getAttribute(attrs, name); 325 | for (int i = 0; i < 6; i++) 326 | if (strcmp(trues[i], value) == 0) 327 | return 1; 328 | 329 | return 0; 330 | } 331 | 332 | // returns the value of selectable-attribute (0 or 1) 333 | int isSelectable(const char **attrs) { 334 | return getBoolean(attrs, "selectable"); 335 | } 336 | 337 | int isHidden(const char **attrs) { 338 | return getBoolean(attrs, "hidden"); 339 | } 340 | 341 | int isLatchable(const char **attrs) { 342 | return getBoolean(attrs, "latchable"); 343 | } 344 | 345 | int isEnabled(const char **attrs) { 346 | return getBoolean(attrs, "enabled"); 347 | } 348 | 349 | // returns the priority (0,1 or 2) 350 | int getPriority(const char **attrs) { 351 | static const char *priorities[] = {"high", "medium", "low"}; 352 | char *value = getAttribute(attrs, "priority"); 353 | for (int i = 0; i < 3; i++) 354 | if (strcmp(priorities[i], value) == 0) 355 | return i; 356 | 357 | return atoi2(value); 358 | } 359 | 360 | // returns the acoustic signal (0,1,2 or 3) 361 | int getAcousticSignal(const char **attrs) { 362 | static const char *priorities[] = {"high", "medium", "low", "none"}; 363 | char *value = getAttribute(attrs, "acoustic_signal"); 364 | for (int i = 0; i < 4; i++) 365 | if (strcmp(priorities[i], value) == 0) 366 | return i; 367 | 368 | return atoi2(value); 369 | } 370 | 371 | // returns the horizontal justification (0,1 or 2) 372 | int getHorizontalJustification(const char **attrs) { 373 | static const char *priorities[] = {"left", "middle", "right"}; 374 | char *value = getAttribute(attrs, "horizontal_justification"); 375 | for (int i = 0; i < 3; i++) 376 | if (strcmp(priorities[i], value) == 0) 377 | return i; 378 | 379 | return atoi2(value); 380 | } 381 | 382 | int getEllipseType(const char **attrs) { 383 | static const char *types[] = {"closed", "open", "closedsegment", "closedsection"}; 384 | char *value = getAttribute(attrs, "ellipse_type"); 385 | for (int i=0; i<4; i++) 386 | if (strcmp(types[i], value) == 0) 387 | return i; 388 | 389 | return atoi2(value); 390 | } 391 | 392 | int getPolygonType(const char **attrs) 393 | { 394 | static const char *types[] = {"convex", "nonconvex", "complex", "open"}; 395 | char *value = getAttribute(attrs, "polygon_type"); 396 | for (int i = 0; i < 4; i++) 397 | if (strcmp(types[i], value) == 0) 398 | return i; 399 | 400 | return atoi2(value); 401 | } 402 | 403 | int getFillType(const char **attrs) { 404 | static const char *types[] = {"nofill", "linecolour", "fillcolour", "pattern"}; 405 | char *value = getAttribute(attrs, "fill_type"); 406 | for (int i = 0; i < 4; i++) 407 | if (strcmp(types[i], value) == 0) 408 | return i; 409 | 410 | return atoi2(value); 411 | } 412 | 413 | int getFunctionType(const char **attrs) { 414 | static const char *types[] = {"boolean", "analog"}; 415 | char *value = getAttribute(attrs, "function_type"); 416 | for (int i = 0; i < 2; i++) 417 | if (strcmp(types[i], value) == 0 ) 418 | return i; 419 | 420 | return atoi2(value); 421 | } 422 | 423 | int getLineDirection(const char **attrs) 424 | { 425 | static const char *bltr[] = {"bottomlefttotopright", "1"}; 426 | char *value = getAttribute(attrs, "line_direction"); 427 | for (int i = 0; i < 2; i++) 428 | if (strcmp(bltr[i], value) == 0) 429 | return 1; 430 | 431 | return 0; 432 | } 433 | 434 | int getWidth(const char **attrs) { 435 | return atoi2(getAttribute(attrs, "width") ); 436 | } 437 | 438 | int getHeight(const char **attrs) { 439 | return atoi2(getAttribute(attrs, "height") ); 440 | } 441 | 442 | int getActualWidth(const char **attrs) { 443 | return atoi2(getAttribute(attrs, "image_width") ); 444 | } 445 | 446 | int getActualHeight(const char **attrs) { 447 | return atoi2(getAttribute(attrs, "image_height") ); 448 | } 449 | 450 | int getKeyCode(const char **attrs) { 451 | return atoi2(getAttribute(attrs, "key_code") ); 452 | } 453 | 454 | unsigned int getValue(const char **attrs) { 455 | // FIXME range 456 | return atoi2(getAttribute(attrs, "value") ); 457 | } 458 | 459 | unsigned int getTargetValue(const char **attrs) { 460 | return atoi2(getAttribute(attrs, "target_value") ); 461 | } 462 | 463 | unsigned int getMinValue(const char **attrs) { 464 | // FIXME range 465 | return atoi2(getAttribute(attrs, "min_value") ); 466 | } 467 | 468 | unsigned int getMaxValue(const char **attrs) { 469 | // FIXME range 470 | return atoi2(getAttribute(attrs, "max_value") ); 471 | } 472 | 473 | int getOffset(const char **attrs) { 474 | return atoi2(getAttribute(attrs, "offset") ); 475 | } 476 | 477 | float getScale(const char **attrs) { 478 | char *str = getAttribute(attrs, "scale"); 479 | 480 | // check for empty string, default to 1! 481 | if (str == NULL || str[0] == 0) 482 | return 1.0f; 483 | 484 | return atof(str); 485 | } 486 | 487 | int getNumberOfDecimals(const char **attrs) { 488 | return atoi2(getAttribute(attrs, "number_of_decimals") ); 489 | } 490 | 491 | int getNumberOfTicks(const char **attrs) { 492 | return atoi2(getAttribute(attrs, "number_of_ticks") ); 493 | } 494 | 495 | int getLength(const char **attrs) { 496 | return atoi2(getAttribute(attrs, "length") ); 497 | } 498 | 499 | int getStartAngle(const char **attrs) { 500 | return atoi2(getAttribute(attrs, "start_angle") ); 501 | } 502 | 503 | int getEndAngle(const char **attrs) { 504 | return atoi2(getAttribute(attrs, "end_angle") ); 505 | } 506 | 507 | int getLineWidth(const char **attrs) { 508 | return atoi2(getAttribute(attrs, "line_width") ); 509 | } 510 | 511 | int getBarGraphWidth(const char **attrs) { 512 | return atoi2(getAttribute(attrs, "bar_graph_width") ); 513 | } 514 | 515 | int getInputID(const char **attrs) { 516 | return atoi2(getAttribute(attrs, "input_id") ); 517 | } 518 | 519 | int getLineArt(const char **attrs) { 520 | int art = 0; 521 | char *value = getAttribute(attrs, "line_art"); 522 | for (int i = 0; value[i]; i++) { 523 | art *= 2; 524 | if (value[i] == '1') 525 | art++; 526 | } 527 | return art; 528 | } 529 | 530 | // only one supported 531 | int getFontType(const char **attrs) { 532 | if (strstr(getAttribute(attrs, "font_type"), "latin1") != NULL) 533 | return 0; 534 | 535 | return 0; 536 | } 537 | 538 | int getValidationType(const char **attrs) { 539 | if (strstr(getAttribute(attrs, "validation_type"), "invalidcharacters") != NULL) 540 | return 1; 541 | 542 | return 0; 543 | } 544 | 545 | // returns the value-attribute as string, that is given length. 546 | // given string must be freed! 547 | char *getValueString(const char **attrs, int length) 548 | { 549 | char *string = (char *) malloc(sizeof(char) * length); 550 | char *value = getAttributeLatin1(attrs, "value"); 551 | int valueLength = strlen(value); 552 | 553 | if (length <= valueLength) { 554 | memcpy(string, value, length); 555 | } 556 | else { 557 | memcpy(string, value, valueLength); 558 | memset(string + valueLength, ' ', length - valueLength); 559 | } 560 | free(value); 561 | return string; 562 | } 563 | 564 | char *getValidatioinString(const char **attrs, int length) 565 | { 566 | char *string = (char *) malloc(sizeof(char) * length); 567 | char *value = getAttributeLatin1(attrs, "validation_string"); 568 | int valueLength = strlen(value); 569 | 570 | if (length <= valueLength) { 571 | memcpy(string, value, length); 572 | } 573 | else { 574 | memcpy(string, value, valueLength); 575 | memset(string + valueLength, ' ', length - valueLength); 576 | } 577 | free(value); 578 | return string; 579 | } 580 | 581 | int getOptions(const char **attrs, const char **names, int bits, const char *name) 582 | { 583 | char *options = getAttribute(attrs, name); 584 | int retVal = 0; 585 | int base = 1; 586 | for (int i = 0; i < bits; i++) { 587 | if (strstr(options, names[i]) != NULL) 588 | retVal += base; 589 | base *= 2; 590 | } 591 | return retVal; 592 | } 593 | 594 | int getInputStringOptions(const char **attrs) 595 | { 596 | char *options = getAttribute(attrs, "options"); 597 | int retVal = 0; 598 | if (strstr(options, "transparent") != NULL) 599 | retVal += 1; 600 | if (strstr(options, "autowrap") != NULL) 601 | retVal += 2; 602 | 603 | return retVal; 604 | } 605 | 606 | int getInputNumberOptions(const char **attrs) 607 | { 608 | char *options = getAttribute(attrs, "options"); 609 | int retVal = 0; 610 | if (strstr(options, "transparent") != NULL) 611 | retVal += 1; 612 | if (strstr(options, "leadingzeros") != NULL) 613 | retVal += 2; 614 | if (strstr(options, "blankzero") != NULL) 615 | retVal += 4; 616 | 617 | return retVal; 618 | } 619 | 620 | int getMeterOptions(const char **attrs) 621 | { 622 | char *options = getAttribute(attrs, "options"); 623 | int retVal = 0; 624 | if (strstr(options, "arc") != NULL) 625 | retVal += 1; 626 | if (strstr(options, "border") != NULL) 627 | retVal += 2; 628 | if (strstr(options, "ticks") != NULL) 629 | retVal += 4; 630 | if (strstr(options, "clockwise") != NULL) 631 | retVal += 8; 632 | 633 | return retVal; 634 | } 635 | 636 | int getLinearBarGraphOptions(const char **attrs) 637 | { 638 | static const char *names[] = {"border", "targetline", "ticks", "nofill", "horizontal" , "growpositive"}; 639 | return getOptions(attrs, names, 6, "options"); 640 | } 641 | 642 | int getArchedBarGraphOptions(const char **attrs) 643 | { 644 | static const char *names[] = {"border", "targetline", "NOT_USED", "nofill", "clockwise"}; 645 | return getOptions(attrs, names, 5, "options"); 646 | } 647 | 648 | int getPictureGraphicOptions(const char **attrs) 649 | { 650 | static const char *names[] = {"transparent", "flashing"}; // No rle! 651 | return getOptions(attrs, names, 2, "options"); 652 | } 653 | 654 | int getFontStyle(const char **attrs) 655 | { 656 | const char *style = getAttribute(attrs, "font_style"); 657 | int retVal = 0; 658 | if (strstr(style, "bold") != NULL) 659 | retVal += 1; 660 | if (strstr(style, "crossed") != NULL) 661 | retVal += 2; 662 | if (strstr(style, "underlined") != NULL) 663 | retVal += 4; 664 | if (strstr(style, "italic") != NULL) 665 | retVal += 8; 666 | if (strstr(style, "inverted") != NULL) 667 | retVal += 16; 668 | if (strstr(style, "flashinginverted") != NULL) 669 | retVal += 32; 670 | if (strstr(style, "flashinghidden") != NULL) 671 | retVal += 64; 672 | 673 | return retVal; 674 | } 675 | 676 | int getLineSuppression(const char **attrs) 677 | { 678 | char *suppression = getAttribute(attrs, "line_suppression"); 679 | int retVal = 0; 680 | if (strstr(suppression, "top") != NULL) 681 | retVal += 1; 682 | if (strstr(suppression, "right") != NULL) 683 | retVal += 2; 684 | if (strstr(suppression, "bottom") != NULL) 685 | retVal += 4; 686 | if (strstr(suppression, "left") != NULL) 687 | retVal += 8; 688 | 689 | return retVal + atoi2(suppression); 690 | } 691 | 692 | int getNumberFormat(const char **attrs) 693 | { 694 | if (strcmp(getAttribute(attrs, "format"), "exponential") == 0) 695 | return 1; 696 | 697 | return 0; 698 | } 699 | 700 | int getFontSize2(const char **attrs, const char *name) 701 | { 702 | static const char *fonts[] = {"6x8", "8x8", "8x12", 703 | "12x16", "16x16", "16x24", 704 | "24x32", "32x32", "32x48", 705 | "48x64", "64x64", "64x96", 706 | "96x128", "128x128", "128x192"}; 707 | 708 | char *value = getAttribute(attrs, name); 709 | for (int i = 0; i < 15; i++) 710 | if (strcmp(fonts[i], value) == 0 ) 711 | return i; 712 | 713 | return atoi2(value); 714 | } 715 | 716 | int getFontSize(const char **attrs){ 717 | return getFontSize2(attrs, "font_size"); 718 | } 719 | 720 | int getBlockFontWidth(const char **attrs, int fontMultiplier) { 721 | int widths[] = {6, 8, 8, 722 | 12, 16, 16, 723 | 24, 32, 32, 724 | 48, 64, 64, 725 | 96, 128, 128}; 726 | 727 | if (getAttribute(attrs, "block_font_size") == NULL) 728 | return 0; 729 | 730 | int font = getFontSize2(attrs, "block_font_size") * fontMultiplier; 731 | if (font < 0 || font > 14) 732 | return 0; 733 | return widths[font]; 734 | } 735 | 736 | int getBlockFontHeight(const char **attrs, int fontMultiplier) { 737 | int heights[] = {8, 8, 12, 738 | 16, 16, 24, 739 | 32, 32, 48, 740 | 64, 64, 96, 741 | 128, 128, 192}; 742 | 743 | if (getAttribute(attrs, "block_font_size") == NULL) 744 | return 0; 745 | 746 | int font = getFontSize2(attrs, "block_font_size") * fontMultiplier; 747 | if (font < 0 || font > 14) 748 | return 0; 749 | return heights[font]; 750 | } 751 | 752 | int getBlockCol(const char **attrs) 753 | { 754 | return atoi2(getAttribute(attrs, "block_col")); 755 | } 756 | 757 | int getBlockRow(const char **attrs) 758 | { 759 | return atoi2(getAttribute(attrs, "block_row")); 760 | } 761 | 762 | int getDimension(const char **attrs) 763 | { 764 | return atoi2(getAttribute(attrs, "dimension")); 765 | } 766 | 767 | int getSkWidth(const char **attrs) 768 | { 769 | return atoi2(getAttribute(attrs, "sk_width")); 770 | } 771 | 772 | int getSkHeight(const char **attrs) 773 | { 774 | return atoi2(getAttribute(attrs, "sk_height")); 775 | } 776 | 777 | // for commands 778 | int getObjectId(const char **attrs) 779 | { 780 | return atoi2(getAttribute(attrs, "object_id")); 781 | } 782 | 783 | int getHideShow(const char **attrs) 784 | { 785 | if (strcmp(getAttribute(attrs, "hide_show"), "show") == 0) 786 | return 1; 787 | 788 | return 0; 789 | } 790 | 791 | int getEnableDisable(const char **attrs) 792 | { 793 | if (strcmp(getAttribute(attrs, "enable_disable"), "enable") == 0) 794 | return 1; 795 | 796 | return 0; 797 | } 798 | 799 | int getRepetitions(const char **attrs) 800 | { 801 | return atoi2(getAttribute(attrs, "number_of_repetitions")); 802 | } 803 | 804 | int getFrequency(const char **attrs) 805 | { 806 | return atoi2(getAttribute(attrs, "frequency")); 807 | } 808 | 809 | int getOnTime(const char **attrs) 810 | { 811 | return atoi2(getAttribute(attrs, "on_time")); 812 | } 813 | 814 | int getOffTime(const char **attrs) 815 | { 816 | return atoi2(getAttribute(attrs, "off_time")); 817 | } 818 | 819 | int getParentId(const char **attrs) 820 | { 821 | return atoi2(getAttribute(attrs, "parent_id")); 822 | } 823 | 824 | int getChildId(const char **attrs) 825 | { 826 | return atoi2(getAttribute(attrs, "child_id")); 827 | } 828 | 829 | int getVolume(const char **attrs) 830 | { 831 | return atoi2(getAttribute(attrs, "volume")); 832 | } 833 | 834 | int getDx(const char **attrs) 835 | { 836 | return atoi2(getAttribute(attrs, "d_pos_x")); 837 | } 838 | 839 | int getDy(const char **attrs) 840 | { 841 | return atoi2(getAttribute(attrs, "d_pos_y")); 842 | } 843 | 844 | int getMaskType(const char **attrs) 845 | { 846 | char *value = getAttribute(attrs, "mask_type"); 847 | if (strcmp(value, "alarmmask") == 0 || 848 | strcmp(value, "2") == 0) 849 | return 2; 850 | 851 | return 1; 852 | } 853 | 854 | int getAID(const char **attrs) 855 | { 856 | return atoi2(getAttribute(attrs, "attribute_id")); 857 | } 858 | 859 | int getFillPatternID(const char **attrs) 860 | { 861 | return atoi2(getAttribute(attrs, "fill_pattern")); 862 | } 863 | 864 | int getPosX(const char **attrs) 865 | { 866 | return atoi2(getAttribute(attrs, "c_pos_x")); 867 | } 868 | 869 | int getPosY(const char **attrs) 870 | { 871 | return atoi2(getAttribute(attrs, "c_pos_y")); 872 | } 873 | 874 | int getListIndex(const char **attrs) 875 | { 876 | return atoi2(getAttribute(attrs, "list_index")); 877 | } 878 | 879 | float getMultiplier(const char **attrs, float old, float mask, float designator) 880 | { 881 | float multip = old; 882 | char *value = getAttribute(attrs, "use"); 883 | 884 | if (value != NULL) { 885 | if (strcmp(value, "mask") == 0) 886 | multip = mask; 887 | else if (strcmp(value, "designator") == 0) 888 | multip = designator; 889 | else if (strcmp(value, "both") == 0) // if 'both' use smaller 890 | multip = (mask < designator) ? mask : designator; 891 | } 892 | return multip; 893 | } 894 | -------------------------------------------------------------------------------- /src/xml.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2019 Automation technology laboratory, 3 | * Helsinki University of Technology 4 | * 5 | * Visit automation.tkk.fi for information about the automation 6 | * technology laboratory. 7 | * 8 | * This program is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU General Public License 10 | * as published by the Free Software Foundation; either version 3 11 | * of the License, or (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, 21 | * MA 02111-1307, USA. 22 | */ 23 | 24 | #ifndef XML_HELP_H 25 | #define XML_HELP_H 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #define ROLE_NONE 0 32 | #define ROLE_ACTIVE_MASK 1 33 | #define ROLE_FONT_ATTRIBUTES 2 34 | #define ROLE_SOFT_KEY_MASK 3 35 | #define ROLE_VARIABLE_REFERENCE 4 36 | #define ROLE_FOREGROUND_COLOR 5 37 | #define ROLE_INPUT_ATTRIBUTES 6 38 | #define ROLE_LINE_ATTRIBUTES 7 39 | #define ROLE_FILL_ATTRIBUTES 8 40 | #define ROLE_TARGET_VARIABLE_REFERENCE 9 41 | #define ROLE_FILL_PATTERN 10 42 | #define ROLE_OBJECT_POINTER_VALUE 11 43 | 44 | // returns the value of given attribute, or null if attribute doesn't 45 | // exist 46 | char *getAttribute(const char **attrs, const char *name); 47 | 48 | // returns the value of given attribute, or ends program if attribute 49 | // doesn't exist 50 | char *getAttributeError(const char **attrs, const char *name); 51 | 52 | char *getName(const char **attrs); 53 | int isName(const char **attrs, const char *name); 54 | 55 | // returns the value of id-attribute 56 | int getId(const char **attrs); 57 | 58 | // returns the value of x-attribute 59 | int getX(const char **attrs); 60 | 61 | // returns the value of y-attribute 62 | int getY(const char **attrs); 63 | 64 | // returns the role of object or include_object 65 | int getRole(const char **attrs); 66 | 67 | // retruns the nearest color. colors is the maxium number of colors 68 | // (2,16 or 256) 69 | int reduceColor(int color, int colors); 70 | 71 | // returns the color 72 | int getBackgroundColor(const char **attrs, int colors); 73 | int getBorderColor(const char **attrs, int colors); 74 | int getFontColor(const char **attrs, int colors); 75 | int getLineColor(const char **attrs, int colors); 76 | int getNeedleColor(const char **attrs, int colors); 77 | int getArcAndTickColor(const char **attrs, int colors); 78 | int getColorColor(const char **attrs, int colors); 79 | int getTargetLineColor(const char **attrs, int colors); 80 | int getTransparencyColor(const char **attrs); 81 | int getFillColor(const char **attrs, int colors); 82 | 83 | // returns the value of selectable-attribute (0 or 1) 84 | int isSelectable(const char **attrs); 85 | int isHidden(const char **attrs); 86 | int isLatchable(const char **attrs); 87 | int isEnabled(const char **attrs); 88 | 89 | // returns the priority (0,1 or 2) 90 | int getPriority(const char **attrs); 91 | 92 | // returns the acoustic signal (0,1,2 or 3) 93 | int getAcousticSignal(const char **attrs); 94 | 95 | // returns the horizontal justification (0,1 or 2) 96 | int getHorizontalJustification(const char **attrs); 97 | 98 | // returns the line direction (0, 1) 99 | int getLineDirection(const char **attrs); 100 | 101 | // returns the line supression 102 | int getLineSuppression(const char **attrs); 103 | 104 | int getWidth(const char **attrs); 105 | int getHeight(const char **attrs); 106 | int getActualWidth(const char **attrs); 107 | int getActualHeight(const char **attrs); 108 | int getKeyCode(const char **attrs); 109 | unsigned int getValue(const char **attrs); 110 | unsigned int getTargetValue(const char **attrs); 111 | unsigned int getMinValue(const char **attrs); 112 | unsigned int getMaxValue(const char **attrs); 113 | int getOffset(const char **attrs); 114 | float getScale(const char **attrs); 115 | int getNumberOfDecimals(const char **attrs); 116 | int getNumberOfTicks(const char **attrs); 117 | int getLength(const char **attrs); 118 | int getStartAngle(const char **attrs); 119 | int getEndAngle(const char **attrs); 120 | int getLineWidth(const char **attrs); 121 | int getBarGraphWidth(const char **attrs); 122 | int getInputID(const char **attrs); 123 | 124 | int getLineArt(const char **attrs); 125 | 126 | int getFontType(const char **attrs); 127 | int getEllipseType(const char **attrs); 128 | int getPolygonType(const char **attrs); 129 | int getFunctionType(const char **attrs); 130 | 131 | // returns the value-attribute as string, that is given length given 132 | // string must be freed! 133 | char *getValueString(const char **attrs, int length); 134 | char *getValidatioinString(const char **attrs, int length); 135 | 136 | int getInputStringOptions(const char **attrs); 137 | int getInputNumberOptions(const char **attrs); 138 | int getMeterOptions(const char **attrs); 139 | int getLinearBarGraphOptions(const char **attrs); 140 | int getArchedBarGraphOptions(const char **attrs); 141 | int getPictureGraphicOptions(const char **attrs); 142 | int getNumberFormat(const char **attrs); 143 | int getFontStyle(const char **attrs); 144 | int getFillType(const char **attrs); 145 | int getFontSize(const char **attrs); 146 | int getValidationType(const char **attrs); 147 | 148 | // get dimensions 149 | int getDimension(const char **attrs); 150 | int getSkWidth(const char **attrs); 151 | int getSkHeight(const char **attrs); 152 | 153 | // for commands 154 | int getObjectId(const char **attrs); 155 | int getHideShow(const char **attrs); 156 | int getEnableDisable(const char **attrs); 157 | int getRepetitions(const char **attrs); 158 | int getFrequency(const char **attrs); 159 | int getOnTime(const char **attrs); 160 | int getOffTime(const char **attrs); 161 | int getParentId(const char **attrs); 162 | int getChildId(const char **attrs); 163 | int getVolume(const char **attrs); 164 | int getDx(const char **attrs); 165 | int getDy(const char **attrs); 166 | int getMaskType(const char **attrs); 167 | int getAID(const char **attrs); 168 | int getFillPatternID(const char **attrs); 169 | int getPosX(const char **attrs); 170 | int getPosY(const char **attrs); 171 | int getListIndex(const char **attrs); 172 | 173 | // for getting multipliers 174 | float getMultiplier(const char **attrs, float old, float mask, float designator); 175 | 176 | // for getting block font / col / row 177 | int getBlockFontWidth(const char **attrs, int fontMultiplier); 178 | int getBlockFontHeight(const char **attrs, int fontMultiplier); 179 | int getBlockCol(const char **attrs); 180 | int getBlockRow(const char **attrs); 181 | 182 | #endif 183 | -------------------------------------------------------------------------------- /virtualterminal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moehman/PoolEditParser/1d06097adbbdef016691c4c1e2f4ff3492f87e9a/virtualterminal.jpg --------------------------------------------------------------------------------