/* Copyright (c) 2013 Arduino LLC. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include File::File(BridgeClass &b) : mode(255), bridge(b) { // Empty } File::File(const char *_filename, uint8_t _mode, BridgeClass &b) : mode(_mode), bridge(b) { filename = _filename; char modes[] = {'r','w','a'}; uint8_t cmd[] = {'F', modes[mode]}; uint8_t res[2]; bridge.transfer(cmd, 2, (uint8_t*)filename.c_str(), filename.length(), res, 2); if (res[0] != 0) { // res[0] contains error code mode = 255; // In case of error keep the file closed return; } handle = res[1]; buffered = 0; } File::operator bool() { return (mode != 255); } File::~File() { close(); } size_t File::write(uint8_t c) { return write(&c, 1); } size_t File::write(const uint8_t *buf, size_t size) { if (mode == 255) return -1; uint8_t cmd[] = {'g', handle}; uint8_t res[1]; bridge.transfer(cmd, 2, buf, size, res, 1); if (res[0] != 0) // res[0] contains error code return -res[0]; return size; } int File::read() { doBuffer(); if (buffered == 0) return -1; // no chars available else { buffered--; return buffer[readPos++]; } } int File::peek() { doBuffer(); if (buffered == 0) return -1; // no chars available else return buffer[readPos]; } boolean File::seek(uint32_t position) { uint8_t cmd[] = { 's', handle, (position >> 24) & 0xFF, (position >> 16) & 0xFF, (position >> 8) & 0xFF, position & 0xFF }; uint8_t res[1]; bridge.transfer(cmd, 6, res, 1); if (res[0]==0) { // If seek succeed then flush buffers buffered = 0; return true; } return false; } uint32_t File::position() { uint8_t cmd[] = {'S', handle}; uint8_t res[5]; bridge.transfer(cmd, 2, res, 5); //err = res[0]; // res[0] contains error code uint32_t pos = res[1] << 24; pos += res[2] << 16; pos += res[3] << 8; pos += res[4]; return pos - buffered; } void File::doBuffer() { // If there are already char in buffer exit if (buffered > 0) return; // Try to buffer up to 32 characters readPos = 0; uint8_t cmd[] = {'G', handle, sizeof(buffer)}; buffered = bridge.transfer(cmd, 3, buffer, sizeof(buffer)) - 1; //err = buff[0]; // First byte is error code if (buffered>0) { // Shift the reminder of buffer for (uint8_t i=0; i