| // Copyright 2019 The Wuffs Authors. | |
| // | |
| // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
| // https://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
| // <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your | |
| // option. This file may not be copied, modified, or distributed | |
| // except according to those terms. | |
| // | |
| // SPDX-License-Identifier: Apache-2.0 OR MIT | |
| #include <stdio.h> | |
| // TODO: this 'rough edge' shouldn't be necessary. See | |
| // https://github.com/google/wuffs/issues/24 | |
| #define WUFFS_CONFIG__MODULE__BASE | |
| #define WUFFS_IMPLEMENTATION | |
| #include "./parse.c" | |
| uint32_t parse(char* p, size_t n) { | |
| wuffs_base__status status; | |
| // This next line of code allocates a wuffs_demo__parser on the stack. Stack | |
| // allocation in C means uninitialized memory, so we need to call | |
| // wuffs_demo__parser__initialize afterwards. | |
| // | |
| // An alternative, allocating on the heap and initializing in a single | |
| // function call, is to say: | |
| // | |
| // wuffs_demo__parser* parser = wuffs_demo__parser__alloc(); | |
| // if (!parser) { | |
| // // Out of memory. | |
| // return 0; | |
| // } | |
| // // No need to call wuffs_demo__parser__initialize, but don't forget to | |
| // // free(parser) before this function returns, taking extra care if this | |
| // // function has multiple return points. Wuffs has no destructor functions | |
| // // and Wuffs types never hold or own any resources in the RAII sense. | |
| // // Just free the memory. | |
| // | |
| // For stack allocation, the C compiler needs to know | |
| // sizeof(wuffs_demo__parser), but that compile-time value isn't guaranteed | |
| // to be stable across Wuffs versions. Stack allocation is therefore only | |
| // valid when the C file also #define's WUFFS_IMPLEMENTATION. When linking | |
| // against a separately built Wuffs library (and the Wuffs types in this | |
| // compilation are incomplete types), you'll have to use heap allocation. | |
| wuffs_demo__parser parser; | |
| // Initialize (and check status). An error here means that bad arguments were | |
| // passed to wuffs_demo__parser__initialize. | |
| // | |
| // There are two other categories of not-OK status values, notes and | |
| // suspensions, but they won't be encountered in this example. | |
| status = wuffs_demo__parser__initialize(&parser, sizeof__wuffs_demo__parser(), | |
| WUFFS_VERSION, 0); | |
| if (!wuffs_base__status__is_ok(&status)) { | |
| printf("initialize: %s\n", wuffs_base__status__message(&status)); | |
| return 0; | |
| } | |
| // True means that the wuffs_base__io_buffer is closed - we are at the end of | |
| // the input. False would mean that there might be additional data in the | |
| // byte stream (that this buffer is not large enough to hold all at once). | |
| // | |
| // In general, Wuffs' coroutine and suspension status mechanisms let it parse | |
| // arbitrarily large data streams using fixed sized buffers, but that won't | |
| // be encountered in this example. | |
| wuffs_base__io_buffer iobuf = | |
| wuffs_base__ptr_u8__reader((uint8_t*)p, n, true); | |
| // Parse (and check status). An error here means that we had invalid input | |
| // (i.e. "#not a digit" or "#too large"). | |
| // | |
| // There are two other categories of not-OK status values, notes and | |
| // suspensions, but they won't be encountered in this example. | |
| status = wuffs_demo__parser__parse(&parser, &iobuf); | |
| if (!wuffs_base__status__is_ok(&status)) { | |
| printf("parse: %s\n", wuffs_base__status__message(&status)); | |
| return 0; | |
| } | |
| return wuffs_demo__parser__value(&parser); | |
| } |