|  | // Copyright 2014 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "crypto/openssl_bio_string.h" | 
|  |  | 
|  | #include <openssl/bio.h> | 
|  | #include <string.h> | 
|  |  | 
|  | namespace crypto { | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | int bio_string_write(BIO* bio, const char* data, int len) { | 
|  | reinterpret_cast<std::string*>(bio->ptr)->append(data, len); | 
|  | return len; | 
|  | } | 
|  |  | 
|  | int bio_string_puts(BIO* bio, const char* data) { | 
|  | // Note: unlike puts(), BIO_puts does not add a newline. | 
|  | return bio_string_write(bio, data, strlen(data)); | 
|  | } | 
|  |  | 
|  | long bio_string_ctrl(BIO* bio, int cmd, long num, void* ptr) { | 
|  | std::string* str = reinterpret_cast<std::string*>(bio->ptr); | 
|  | switch (cmd) { | 
|  | case BIO_CTRL_RESET: | 
|  | str->clear(); | 
|  | return 1; | 
|  | case BIO_C_FILE_SEEK: | 
|  | return -1; | 
|  | case BIO_C_FILE_TELL: | 
|  | return str->size(); | 
|  | case BIO_CTRL_FLUSH: | 
|  | return 1; | 
|  | default: | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | int bio_string_new(BIO* bio) { | 
|  | bio->ptr = NULL; | 
|  | bio->init = 0; | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | int bio_string_free(BIO* bio) { | 
|  | // The string is owned by the caller, so there's nothing to do here. | 
|  | return bio != NULL; | 
|  | } | 
|  |  | 
|  | BIO_METHOD bio_string_methods = { | 
|  | // TODO(mattm): Should add some type number too? (bio.h uses 1-24) | 
|  | BIO_TYPE_SOURCE_SINK, | 
|  | "bio_string", | 
|  | bio_string_write, | 
|  | NULL, /* read */ | 
|  | bio_string_puts, | 
|  | NULL, /* gets */ | 
|  | bio_string_ctrl, | 
|  | bio_string_new, | 
|  | bio_string_free, | 
|  | NULL, /* callback_ctrl */ | 
|  | }; | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | BIO* BIO_new_string(std::string* out) { | 
|  | BIO* bio = BIO_new(&bio_string_methods); | 
|  | if (!bio) | 
|  | return bio; | 
|  | bio->ptr = out; | 
|  | bio->init = 1; | 
|  | return bio; | 
|  | } | 
|  |  | 
|  | }  // namespace crypto |