parent
c53921d2fe
commit
57ad204cea
2 changed files with 103 additions and 0 deletions
@ -0,0 +1,61 @@ |
||||
/*
|
||||
* upb - a minimalist implementation of protocol buffers. |
||||
* |
||||
* Copyright (c) 2010 Joshua Haberman. See LICENSE for details. |
||||
*/ |
||||
|
||||
#include "upb_stdio.h" |
||||
|
||||
// We can make this configurable if necessary.
|
||||
#define BLOCK_SIZE 4096 |
||||
|
||||
struct upb_stdio { |
||||
upb_bytesrc bytesrc; |
||||
upb_bytesink bytesink; |
||||
FILE *file; |
||||
} |
||||
|
||||
static bool upb_stdio_read(upb_stdio *stdio, upb_string *str, |
||||
int offset, int bytes_to_read) { |
||||
char *buf = upb_string_getrwbuf(offset + bytes_to_read) + offset; |
||||
size_t read = fread(buf, 1, bytes_to_read, stdio->file); |
||||
if(read < bytes_to_read) { |
||||
// Error or EOF.
|
||||
stdio->bytesrc.eof = feof(stdio->file); |
||||
if(ferror(stdio->file)) { |
||||
upb_seterr(&stdio->bytesrc.status, UPB_STATUS_ERROR, |
||||
"Error reading from stdio stream."); |
||||
return false; |
||||
} |
||||
// Resize to actual read size.
|
||||
upb_string_getrwbuf(str, offset + read); |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
bool upb_stdio_get(upb_bytesrc *src, upb_string *str, upb_strlen_t minlen) { |
||||
// We ignore "minlen" since the stdio interfaces always return a full read
|
||||
// unless they are at EOF.
|
||||
(void)minlen; |
||||
return upb_stdio_read((upb_stdio*)src, str, 0, BLOCK_SIZE); |
||||
} |
||||
|
||||
bool upb_stdio_append(upb_bytesrc *src, upb_string *str, upb_strlen_t len) { |
||||
return upb_stdio_read((upb_stdio*)src, str, upb_string_len(str), len); |
||||
} |
||||
|
||||
int32_t upb_bytesink_put(upb_bytesink *sink, upb_string *str) { |
||||
upb_stdio *stdio = (upb_stdio*)sink - offsetof(upb_stdio, bytesink); |
||||
upb_strlen_t len = upb_string_len(str); |
||||
size_t written = fwrite(upb_string_getrobuf(str), 1, len, stdio->file); |
||||
if(written < len) { |
||||
// Error or EOF.
|
||||
stdio->bytesink.eof = feof(stdio->file); |
||||
if(ferror(stdio->file)) { |
||||
upb_seterr(&stdio->bytesink.status, UPB_STATUS_ERROR, |
||||
"Error writing to stdio stream."); |
||||
return 0; |
||||
} |
||||
} |
||||
return written; |
||||
} |
@ -0,0 +1,42 @@ |
||||
/*
|
||||
* upb - a minimalist implementation of protocol buffers. |
||||
* |
||||
* This file provides upb_bytesrc and upb_bytesink implementations for |
||||
* ANSI C stdio. |
||||
* |
||||
* Copyright (c) 2010 Joshua Haberman. See LICENSE for details. |
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include "upb_stream.h" |
||||
|
||||
#ifndef UPB_STDIO_H_ |
||||
#define UPB_STDIO_H_ |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
struct upb_stdio; |
||||
typedef struct upb_stdio upb_stdio; |
||||
|
||||
// Creation/deletion.
|
||||
upb_stdio_ *upb_stdio__new(); |
||||
void upb_stdio_free(upb_stdio *stdio); |
||||
|
||||
// Reset/initialize the object for use. The src or sink will call
|
||||
// fread()/fwrite()/etc. on the given FILE*.
|
||||
void upb_stdio_reset(upb_stdio *stdio, FILE* file); |
||||
|
||||
// Gets a bytesrc or bytesink for the given stdio. The returned pointer is
|
||||
// invalidated by upb_stdio_reset above. It is perfectly valid to get both
|
||||
// a bytesrc and a bytesink for the same stdio if the FILE* is open for reading
|
||||
// and writing.
|
||||
upb_bytesrc* upb_stdio_bytesrc(upb_stdio *stdio); |
||||
upb_bytesink* upb_stdio_bytesink(upb_stdio *stdio); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#endif |
Loading…
Reference in new issue