void Base64encoder::encode(std::istream& istream_in, std::ostream& ostream_in) { base64_init_encodestate(&_state); const int N = _buffersize; char* plaintext = new char[N]; char* code = new char[2*N]; int plainlength; int codelength; do { istream_in.read(plaintext, N); plainlength = istream_in.gcount(); codelength = encode(plaintext, plainlength, code); ostream_in.write(code, codelength); } while (istream_in.good() && plainlength > 0); codelength = encode_end(code); ostream_in.write(code, codelength); base64_init_encodestate(&_state); delete [] code; delete [] plaintext; }
bool serialize(const int devfd, struct bitcoin_storage *const st, bool serial_pad) { static struct encoder_state s; static bool first_run = true; static int buf_left = 0; // Bytes left to send static int buf_i = 0; // Bytes position of next unsent byte if (first_run) { encoder_state_init(&s); first_run = false; } gint queued = heap_size(&st->send_queue); if (!buf_left && queued) { // Try to fill send buffer struct msg *m = bitcoin_dequeue(st); // Should not happen if (m == NULL) errx(6,"Send queue handling error"); // Do not retransmit if it is already sent. if (m->sent) { printf("Already sent %s %s, skipping\n", bitcoin_type_str(m), hex256(bitcoin_inv_hash(m))); return true; } // Mark message as sent m->sent = true; // Calculate signature. FIXME: Include type in calculation! // Bitcoin message header in unidirectional // transfer. The signature is used to verify the // transmitter. Transactions have their own signature // inside message body, too. unsigned char sig[72]; int siglen; secp256k1_ecdsa_sign(m->payload,m->length,sig,&siglen,NULL,NULL); encode_start(&s); encode(&s,&siglen,1); // FIXME doesn't work on big endian archs encode(&s,&sig,siglen); encode(&s,&m->type,1); // FIXME doesn't work on big endian archs encode(&s,m->payload,m->length); // Finishing encoding and updating send buffer buf_left = encode_end(&s); buf_i = 0; // Debugging char height_buf[20] = ""; if (m->height != UNCONFIRMED) { snprintf(height_buf,sizeof(height_buf), " @ %d",m->height); } printf("Sending %s %s%s, %d bytes, %d items left\n", bitcoin_type_str(m), hex256(bitcoin_inv_hash(m)), height_buf, m->length, queued); } if (buf_left) { // Consume buffer as much as possible const int wrote = write(devfd, s.buf+buf_i, buf_left); if (wrote == 0) { errx(3,"Weird behaviour on serial port"); } else if (wrote == -1) { err(4,"Unable to write to serial port"); } buf_i += wrote; buf_left -= wrote; } else { if (!serial_pad) { // All is sent, do not come back until there // is more data availableq printf("Serial device idle\n"); return false; } // Send padding and go back to waiting loop. guint8 buf[PAD_COUNT*5]; int i = 0; while (i < sizeof(buf)) { // Z_SYNC_FLUSH is 5 bytes long: buf[i++] = 0x00; buf[i++] = 0x00; buf[i++] = 0x00; buf[i++] = 0xFF; buf[i++] = 0xFF; } const int ret = write(devfd,buf,sizeof(buf)); if (ret < 1) err(4,"Unable to write to serial port"); if (ret != sizeof(buf)) err(10,"Too large padding buffer or non-linuxy system"); printf("Sending %d bytes of padding\n",ret); } return true; }