1/*
2 * Copyright 2008, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Michael Pfeiffer 	<laplace@users.sourceforge.net>
7 *		Fredrik Modéen		<fredrik@modeen.se>
8 */
9#include "FileReadWrite.h"
10
11#include <UTF8.h>
12#include <Path.h>
13
14
15FileReadWrite::FileReadWrite(BFile* file, int32 sourceEncoding)
16	: fFile(file),
17	  fSourceEncoding(sourceEncoding),
18	  fPositionInBuffer(0),
19	  fAmtRead(0)
20{}
21
22
23void
24FileReadWrite::SetEncoding(int32 sourceEncoding)
25{
26	fSourceEncoding = sourceEncoding;
27}
28
29
30uint32
31FileReadWrite::GetEncoding() const
32{
33	return fSourceEncoding;
34}
35
36
37status_t
38FileReadWrite::Write(const BString& contents) const
39{
40	ssize_t written = fFile->Write(contents.String(), contents.Length());
41	if (written != contents.Length())
42		return written < 0 ? (status_t)written : B_IO_ERROR;
43
44	return B_OK;
45}
46
47
48bool
49FileReadWrite::Next(BString& string)
50{
51	// Fill up the buffer with the first chunk of data
52	if (fPositionInBuffer == 0)
53		fAmtRead = fFile->Read(&fBuffer, sizeof(fBuffer));
54	while (fAmtRead > 0) {
55		while (fPositionInBuffer < fAmtRead) {
56			// Return true if we hit a newline or the end of the file
57			// TODO: If the source file is expected to have different encoding,
58			// don't we need to check for the line endings in that encoding?!
59			if (fBuffer[fPositionInBuffer] == '\n') {
60				fPositionInBuffer++;
61				if (fSourceEncoding != -1) {
62					int32 state = 0;
63					int32 bufferLen = string.Length();
64					int32 destBufferLen = bufferLen;
65					char destination[destBufferLen];
66					convert_to_utf8(fSourceEncoding, string.String(),
67						&bufferLen, destination, &destBufferLen, &state);
68					string = destination;
69				}
70				return true;
71			}
72			// TODO: Adding one char at a time is very inefficient!
73			string += fBuffer[fPositionInBuffer];
74			fPositionInBuffer++;
75		}
76
77		// Once the buffer runs out, grab some more and start again
78		fAmtRead = fFile->Read(&fBuffer, sizeof(fBuffer));
79		fPositionInBuffer = 0;
80	}
81	return false;
82}
83