FAQ

svn commit: r830909 - in /lucene/lucy/trunk: core/Lucy/Store/ core/Lucy/Test/ core/Lucy/Test/Store/ perl/lib/Lucy/ perl/lib/Lucy/Store/ perl/t/binding/ perl/t/core/

Marvin
Oct 29, 2009 at 12:08 pm
Author: marvin
Date: Thu Oct 29 12:07:56 2009
New Revision: 830909

URL: http://svn.apache.org/viewvc?rev=830909&view=rev
Log:
Commit LUCY-63, adding InStream and OutStream.

Added:
lucene/lucy/trunk/core/Lucy/Store/InStream.bp (with props)
lucene/lucy/trunk/core/Lucy/Store/InStream.c (with props)
lucene/lucy/trunk/core/Lucy/Store/OutStream.bp (with props)
lucene/lucy/trunk/core/Lucy/Store/OutStream.c (with props)
lucene/lucy/trunk/core/Lucy/Test/Store/MockFileHandle.bp (with props)
lucene/lucy/trunk/core/Lucy/Test/Store/MockFileHandle.c (with props)
lucene/lucy/trunk/core/Lucy/Test/Store/TestIOChunks.bp (with props)
lucene/lucy/trunk/core/Lucy/Test/Store/TestIOChunks.c (with props)
lucene/lucy/trunk/core/Lucy/Test/Store/TestIOPrimitives.bp (with props)
lucene/lucy/trunk/core/Lucy/Test/Store/TestIOPrimitives.c (with props)
lucene/lucy/trunk/core/Lucy/Test/Store/TestInStream.bp (with props)
lucene/lucy/trunk/core/Lucy/Test/Store/TestInStream.c (with props)
lucene/lucy/trunk/core/Lucy/Test/TestUtils.bp (with props)
lucene/lucy/trunk/core/Lucy/Test/TestUtils.c (with props)
lucene/lucy/trunk/perl/lib/Lucy/Store/InStream.pm (with props)
lucene/lucy/trunk/perl/lib/Lucy/Store/OutStream.pm (with props)
lucene/lucy/trunk/perl/t/binding/
lucene/lucy/trunk/perl/t/binding/101-simple_io.t (with props)
lucene/lucy/trunk/perl/t/core/052-instream.t (with props)
lucene/lucy/trunk/perl/t/core/054-io_primitives.t (with props)
lucene/lucy/trunk/perl/t/core/055-io_chunks.t (with props)
Modified:
lucene/lucy/trunk/perl/lib/Lucy/Test.pm

Added: lucene/lucy/trunk/core/Lucy/Store/InStream.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Store/InStream.bp?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Store/InStream.bp (added)
+++ lucene/lucy/trunk/core/Lucy/Store/InStream.bp Thu Oct 29 12:07:56 2009
@@ -0,0 +1,195 @@
+parcel Lucy;
+
+/** Read index files.
+ *
+ * InStream objects are the primary interface for reading from index files.
+ * They are high-level (relatively speaking), media-agnostic wrappers
+ * around low-level, media-specific FileHandle objects.
+ *
+ * InStreams provide a number of routines for safely decoding common constructs
+ * such as big-endian or compressed integers; for the most part, these
+ * routines throw exceptions rather than require manual checking of return
+ * values for error conditions.
+ *
+ * Multiple InStream objects often share the same underlying FileHandle; this
+ * practice is safe because InStreams do not modify or rely upon the file
+ * position or other state within the FileHandle.
+ */
+class Lucy::Store::InStream extends Lucy::Object::Obj {
+
+ i64_t offset;
+ i64_t len;
+ char *buf;
+ char *limit;
+ CharBuf *filename;
+ FileHandle *file_handle;
+ FileWindow *window;
+
+ inert incremented InStream*
+ open(Obj *file);
+
+ /** Return a new InStream, or set Err_error and return NULL on failure.
+ *
+ * @param file A FileHandle, a file path, or a RAMFile.
+ */
+ inert InStream*
+ do_open(InStream *self, Obj *file);
+
+ /** Clone the instream, but specify a new offset, length, and possibly
+ * filename. Initial file position will be set to the top of the file
+ * (taking <code>offset</code> into account).
+ *
+ * @param filename An alias filename. If NULL, the filename of the
+ * underlying FileHandle will be used.
+ * @param offset Top of the file as seen by the new InStream, in bytes
+ * from the top of the file as seen by the underlying FileHandle.
+ * @param len Length of the file as seen by the new InStream.
+ */
+ incremented InStream*
+ Reopen(InStream *self, const CharBuf *filename = NULL, i64_t offset,
+ i64_t len);
+
+ /** Clone the InStream. Clones share the same underlying FileHandle and
+ * start at the current file position, but are able to seek and read
+ * independently.
+ */
+ public incremented InStream*
+ Clone(InStream *self);
+
+ /** Decrement the number of streams using the underlying FileHandle. When
+ * the number drops to zero, possibly release system resources.
+ */
+ void
+ Close(InStream *self);
+
+ public void
+ Destroy(InStream *self);
+
+ /** Seek to <code>target</code>.
+ */
+ final void
+ Seek(InStream *self, i64_t target);
+
+ /** Return the current file position.
+ */
+ final i64_t
+ Tell(InStream *self);
+
+ /** Return the length of the "file" in bytes.
+ */
+ final i64_t
+ Length(InStream *self);
+
+ /** Fill the InStream's buffer, letting the FileHandle decide how many bytes
+ * of data to fill it with.
+ */
+ void
+ Refill(InStream *self);
+
+ /** Pour an exact number of bytes into the InStream's buffer.
+ */
+ void
+ Fill(InStream *self, i64_t amount);
+
+ /** Get the InStream's buffer. Check to see whether <code>request</code>
+ * bytes are already in the buffer. If not, fill the buffer with either
+ * <code>request</code> bytes or the number of bytes remaining before EOF,
+ * whichever is smaller.
+ *
+ * @param request Advisory byte size request.
+ * @return Pointer to the InStream's internal buffer.
+ */
+ final char*
+ Buf(InStream *self, size_t request);
+
+ /** Set the buf to a new value, checking for overrun. The idiom is for
+ * the caller to call Buf(), use no more bytes than requested, then use
+ * Advance_Buf() to update the InStream object.
+ */
+ final void
+ Advance_Buf(InStream *self, char *buf);
+
+ /** Read <code>len</code> bytes from the InStream into <code>buf</code>.
+ */
+ final void
+ Read_Bytes(InStream *self, char *buf, size_t len);
+
+ /** Read a signed 8-bit integer.
+ */
+ final i8_t
+ Read_I8(InStream *self);
+
+ /** Read an unsigned 8-bit integer.
+ */
+ final u8_t
+ Read_U8(InStream *self);
+
+ /** Read a signed 32-bit integer.
+ */
+ final i32_t
+ Read_I32(InStream *self);
+
+ /** Read an unsigned 32-bit integer.
+ */
+ final u32_t
+ Read_U32(InStream *self);
+
+ /** Read a signed 64-bit integer.
+ */
+ final i64_t
+ Read_I64(InStream *self);
+
+ /** Read an unsigned 64-bit integer.
+ */
+ final u64_t
+ Read_U64(InStream *self);
+
+ /** Read an IEEE 764 32-bit floating point number.
+ */
+ final float
+ Read_F32(InStream *self);
+
+ /** Read an IEEE 764 64-bit floating point number.
+ */
+ final double
+ Read_F64(InStream *self);
+
+ /** Read in a compressed 32-bit unsigned integer.
+ */
+ u32_t
+ Read_C32(InStream *self);
+
+ /** Read a 64-bit integer, using the same encoding as a C32 but occupying
+ * as many as 10 bytes.
+ */
+ final u64_t
+ Read_C64(InStream *self);
+
+ /** Read the bytes for a C32/C64 into <code>buf</code>. Return the number
+ * of bytes read. The caller must ensure that sufficient space exists in
+ * <code>buf</code> (worst case is 10 bytes).
+ */
+ final int
+ Read_Raw_C64(InStream *self, char *buf);
+
+ /** Accessor for filename member.
+ */
+ CharBuf*
+ Get_Filename(InStream *self);
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Store/InStream.bp
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Store/InStream.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Store/InStream.c?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Store/InStream.c (added)
+++ lucene/lucy/trunk/core/Lucy/Store/InStream.c Thu Oct 29 12:07:56 2009
@@ -0,0 +1,471 @@
+#define C_LUCY_INSTREAM
+#define C_LUCY_FILEWINDOW
+#include "Lucy/Util/ToolSet.h"
+
+#include "Lucy/Store/InStream.h"
+#include "Lucy/Store/FileHandle.h"
+#include "Lucy/Store/FileWindow.h"
+#include "Lucy/Store/RAMFile.h"
+#include "Lucy/Store/RAMFileHandle.h"
+
+/* Inlined version of InStream_Tell. */
+static INLINE i64_t
+SI_tell(InStream *self);
+
+/* Inlined version of InStream_Read_Bytes. */
+static INLINE void
+SI_read_bytes(InStream *self, char* buf, size_t len);
+
+/* Inlined version of InStream_Read_U8. */
+static INLINE u8_t
+SI_read_u8(InStream *self);
+
+/* Ensure that the buffer contains exactly the specified amount of data. */
+static void
+S_fill(InStream *self, i64_t amount);
+
+/* Refill the buffer, with either IO_STREAM_BUF_SIZE bytes or all remaining
+ * file content -- whichever is smaller. Throw an error if we're at EOF and
+ * can't load at least one byte. */
+static void
+S_refill(InStream *self);
+
+InStream*
+InStream_open(Obj *file)
+{
+ InStream *self = (InStream*)VTable_Make_Obj(INSTREAM);
+ return InStream_do_open(self, file);
+}
+
+InStream*
+InStream_do_open(InStream *self, Obj *file)
+{
+ /* Init. */
+ self->buf = NULL;
+ self->limit = NULL;
+ self->offset = 0;
+ self->window = FileWindow_new();
+
+ /* Obtain a FileHandle. */
+ if (Obj_Is_A(file, FILEHANDLE)) {
+ self->file_handle = (FileHandle*)INCREF(file);
+ }
+ else if (Obj_Is_A(file, RAMFILE)) {
+ self->file_handle
+ = (FileHandle*)RAMFH_open(NULL, FH_READ_ONLY, (RAMFile*)file);
+ }
+ /*
+ else if (Obj_Is_A(file, CHARBUF)) {
+ self->file_handle
+ = (FileHandle*)FSFH_open((CharBuf*)file, FH_READ_ONLY);
+ }
+ */
+ else {
+ Err_set_error(Err_new(CB_newf("Invalid type for param 'file': '%o'",
+ Obj_Get_Class_Name(file))));
+ DECREF(self);
+ return NULL;
+ }
+ if (!self->file_handle) {
+ ERR_ADD_FRAME(Err_get_error());
+ DECREF(self);
+ return NULL;
+ }
+
+ /* Get length and filename from the FileHandle. */
+ self->filename = CB_Clone(FH_Get_Path(self->file_handle));
+ self->len = FH_Length(self->file_handle);
+ if (self->len == -1) {
+ ERR_ADD_FRAME(Err_get_error());
+ DECREF(self);
+ return NULL;
+ }
+
+ return self;
+}
+
+void
+InStream_close(InStream *self)
+{
+ if (self->file_handle) {
+ FH_Release_Window(self->file_handle, self->window);
+ /* Note that we don't close the FileHandle, because it's probably
+ * shared. */
+ DECREF(self->file_handle);
+ self->file_handle = NULL;
+ }
+}
+
+void
+InStream_destroy(InStream *self)
+{
+ if (self->file_handle) {
+ InStream_Close(self);
+ }
+ DECREF(self->filename);
+ DECREF(self->window);
+ SUPER_DESTROY(self, INSTREAM);
+}
+
+InStream*
+InStream_reopen(InStream *self, const CharBuf *filename, i64_t offset,
+ i64_t len)
+{
+ InStream *evil_twin = (InStream*)VTable_Make_Obj(self->vtable);
+ InStream_do_open(evil_twin, (Obj*)self->file_handle);
+ if (filename != NULL) { CB_Mimic(evil_twin->filename, (Obj*)filename); }
+ evil_twin->offset = offset;
+ evil_twin->len = len;
+ InStream_Seek(evil_twin, 0);
+ return evil_twin;
+}
+
+InStream*
+InStream_clone(InStream *self)
+{
+ InStream *evil_twin = (InStream*)VTable_Make_Obj(self->vtable);
+ InStream_do_open(evil_twin, (Obj*)self->file_handle);
+ InStream_Seek(evil_twin, SI_tell(self));
+ return evil_twin;
+}
+
+CharBuf*
+InStream_get_filename(InStream *self) { return self->filename; }
+
+static void
+S_refill(InStream *self)
+{
+ /* Determine the amount to request. */
+ const i64_t sub_file_pos = SI_tell(self);
+ const i64_t remaining = self->len - sub_file_pos;
+ const i64_t amount = remaining < IO_STREAM_BUF_SIZE
+ ? remaining
+ : IO_STREAM_BUF_SIZE;
+ if (!remaining) {
+ THROW(ERR, "Read past EOF of '%o' (offset: %i64 len: %i64)",
+ self->filename, self->offset, self->len);
+ }
+
+ /* Make the request. */
+ S_fill(self, amount);
+}
+
+void
+InStream_refill(InStream *self)
+{
+ S_refill(self);
+}
+
+static void
+S_fill(InStream *self, i64_t amount)
+{
+ FileWindow *const window = self->window;
+ const i64_t virtual_file_pos = SI_tell(self);
+ const i64_t real_file_pos = virtual_file_pos + self->offset;
+ const i64_t remaining = self->len - virtual_file_pos;
+
+ /* Throw an error if the requested amount would take us beyond EOF. */
+ if (amount > remaining) {
+ THROW(ERR, "Read past EOF of %o (pos: %u64 len: %u64 request: %u64)",
+ self->filename, virtual_file_pos, self->len, amount);
+ }
+
+ /* Make the request. */
+ if (FH_Window(self->file_handle, window, real_file_pos, amount) ) {
+ char *const window_limit = window->buf + window->len;
+ self->buf = window->buf
+ - window->offset /* theoretical start of real file */
+ + self->offset /* top of virtual file */
+ + virtual_file_pos; /* position within virtual file */
+ self->limit = window_limit - self->buf > remaining
+ ? self->buf + remaining
+ : window_limit;
+ }
+ else {
+ RETHROW(INCREF(Err_get_error()));
+ }
+}
+
+void
+InStream_fill(InStream *self, i64_t amount)
+{
+ S_fill(self, amount);
+}
+
+void
+InStream_seek(InStream *self, i64_t target)
+{
+ FileWindow *const window = self->window;
+ i64_t virtual_window_top = window->offset - self->offset;
+ i64_t virtual_window_end = virtual_window_top + window->len;
+
+ if (target < 0) {
+ THROW(ERR, "Can't Seek to negative target %i64", target);
+ }
+ /* Seek within window if possible. */
+ else if ( target >= virtual_window_top
+ && target <= virtual_window_end
+ ) {
+ self->buf = window->buf - window->offset + self->offset + target;
+ }
+ else {
+ /* Target is outside window. Set all buffer and limit variables to
+ * NULL to trigger refill on the next read. Store the file position
+ * in the FileWindow's offset. */
+ FH_Release_Window(self->file_handle, window);
+ self->buf = NULL;
+ self->limit = NULL;
+ FileWindow_Set_Offset(window, self->offset + target);
+ }
+}
+
+static INLINE i64_t
+SI_tell(InStream *self)
+{
+ FileWindow *const window = self->window;
+ i64_t pos_in_buf = PTR2I64(self->buf) - PTR2I64(window->buf);
+ return pos_in_buf + window->offset - self->offset;
+}
+
+i64_t
+InStream_tell(InStream *self)
+{
+ return SI_tell(self);
+}
+
+i64_t
+InStream_length(InStream *self)
+{
+ return self->len;
+}
+
+char*
+InStream_buf(InStream *self, size_t request)
+{
+ const i64_t bytes_in_buf = PTR2I64(self->limit) - PTR2I64(self->buf);
+
+ /* It's common for client code to overestimate how much is needed, because
+ * the request has to figure in worst-case for compressed data. However,
+ * if we can still serve them everything they request (e.g. they ask for 5
+ * bytes, they really need 1 byte, and there's 1k in the buffer), we can
+ * skip the following refill block. */
+ if ((i64_t)request > bytes_in_buf) {
+ const i64_t remaining_in_file = self->len - SI_tell(self);
+ i64_t amount = request;
+
+ /* Try to bump up small requests. */
+ if (amount < IO_STREAM_BUF_SIZE) { amount = IO_STREAM_BUF_SIZE; }
+
+ /* Don't read past EOF. */
+ if (remaining_in_file < amount) { amount = remaining_in_file; }
+
+ /* Only fill if the recalculated, possibly smaller request exceeds the
+ * amount available in the buffer. */
+ if (amount > bytes_in_buf) {
+ S_fill(self, amount);
+ }
+ }
+
+ return self->buf;
+}
+
+void
+InStream_advance_buf(InStream *self, char *buf)
+{
+ if (buf > self->limit) {
+ i64_t overrun = PTR2I64(buf) - PTR2I64(self->limit);
+ THROW(ERR, "Supplied value is %i64 bytes beyond end of buffer",
+ overrun);
+ }
+ else if (buf < self->buf) {
+ i64_t underrun = PTR2I64(self->buf) - PTR2I64(buf);
+ THROW(ERR, "Can't Advance_Buf backwards: (underrun: %i64))", underrun);
+ }
+ else {
+ self->buf = buf;
+ }
+}
+
+void
+InStream_read_bytes(InStream *self, char* buf, size_t len)
+{
+ SI_read_bytes(self, buf, len);
+}
+
+static INLINE void
+SI_read_bytes(InStream *self, char* buf, size_t len)
+{
+ const i64_t available = PTR2I64(self->limit) - PTR2I64(self->buf);
+ if (available >= (i64_t)len) {
+ /* Request is entirely within buffer, so copy. */
+ memcpy(buf, self->buf, len);
+ self->buf += len;
+ }
+ else {
+ /* Pass along whatever we've got in the buffer. */
+ if (available > 0) {
+ memcpy(buf, self->buf, (size_t)available);
+ buf += available;
+ len -= (size_t)available;
+ self->buf += available;
+ }
+
+ if (len < IO_STREAM_BUF_SIZE) {
+ /* Ensure that we have enough mapped, then copy the rest. */
+ S_refill(self);
+ memcpy(buf, self->buf, len);
+ self->buf += len;
+ }
+ else {
+ /* Too big to handle via the buffer, so resort to a brute-force
+ * read. */
+ const i64_t sub_file_pos = SI_tell(self);
+ const i64_t real_file_pos = sub_file_pos + self->offset;
+ bool_t success
+ = FH_Read(self->file_handle, buf, real_file_pos, len);
+ if (!success) {
+ RETHROW(INCREF(Err_get_error()));
+ }
+ InStream_seek(self, sub_file_pos + len);
+ }
+ }
+}
+
+i8_t
+InStream_read_i8(InStream *self)
+{
+ return (i8_t)SI_read_u8(self);
+}
+
+static INLINE u8_t
+SI_read_u8(InStream *self)
+{
+ if (self->buf >= self->limit) { S_refill(self); }
+ return (u8_t)*self->buf++;
+}
+
+u8_t
+InStream_read_u8(InStream *self)
+{
+ return SI_read_u8(self);
+}
+
+static INLINE u32_t
+SI_read_u32(InStream *self)
+{
+ u32_t retval;
+ SI_read_bytes(self, (char*)&retval, 4);
+#ifdef LITTLE_END
+ retval = NumUtil_decode_bigend_u32((char*)&retval);
+#endif
+ return retval;
+}
+
+u32_t
+InStream_read_u32(InStream *self)
+{
+ return SI_read_u32(self);
+}
+
+i32_t
+InStream_read_i32(InStream *self)
+{
+ return (i32_t)SI_read_u32(self);
+}
+
+static INLINE u64_t
+SI_read_u64 (InStream *self)
+{
+ u64_t retval;
+ SI_read_bytes(self, (char*)&retval, 8);
+#ifdef LITTLE_END
+ retval = NumUtil_decode_bigend_u64((char*)&retval);
+#endif
+ return retval;
+}
+
+u64_t
+InStream_read_u64(InStream *self)
+{
+ return SI_read_u64(self);
+}
+
+i64_t
+InStream_read_i64(InStream *self)
+{
+ return (i64_t)SI_read_u64(self);
+}
+
+float
+InStream_read_f32(InStream *self)
+{
+ union { float f; u32_t u32; } duo;
+ SI_read_bytes(self, (char*)&duo, sizeof(float));
+#ifdef LITTLE_END
+ duo.u32 = NumUtil_decode_bigend_u32(&duo.u32);
+#endif
+ return duo.f;
+}
+
+double
+InStream_read_f64(InStream *self)
+{
+ union { double d; u64_t u64; } duo;
+ SI_read_bytes(self, (char*)&duo, sizeof(double));
+#ifdef LITTLE_END
+ duo.u64 = NumUtil_decode_bigend_u64(&duo.u64);
+#endif
+ return duo.d;
+}
+
+u32_t
+InStream_read_c32(InStream *self)
+{
+ u32_t retval = 0;
+ while (1) {
+ const u8_t ubyte = SI_read_u8(self);
+ retval = (retval << 7) | (ubyte & 0x7f);
+ if ((ubyte & 0x80) == 0)
+ break;
+ }
+ return retval;
+}
+
+u64_t
+InStream_read_c64(InStream *self)
+{
+ u64_t retval = 0;
+ while (1) {
+ const u8_t ubyte = SI_read_u8(self);
+ retval = (retval << 7) | (ubyte & 0x7f);
+ if ((ubyte & 0x80) == 0)
+ break;
+ }
+ return retval;
+}
+
+int
+InStream_read_raw_c64(InStream *self, char *buf)
+{
+ u8_t *dest = (u8_t*)buf;
+ do {
+ *dest = SI_read_u8(self);
+ } while ((*dest++ & 0x80) != 0);
+ return dest - (u8_t*)buf;
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Store/InStream.c
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Store/OutStream.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Store/OutStream.bp?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Store/OutStream.bp (added)
+++ lucene/lucy/trunk/core/Lucy/Store/OutStream.bp Thu Oct 29 12:07:56 2009
@@ -0,0 +1,142 @@
+parcel Lucy;
+
+/** Write index files.
+ *
+ * OutStream objects are the primary interface for writing index files. They
+ * are media-agnostic wrappers around low-level, media-specific, unbuffered
+ * FileHandle objects, providing output buffering and routines for writing
+ * common constructs such as big-endian or compressed integers.
+ *
+ * OutStreams are write-once and cannot seek -- they must write all their data
+ * in order. Furthermore, each OutStream is associated with exactly one,
+ * unique FileHandle -- unlike InStreams, which can share a common FileHandle.
+ */
+class Lucy::Store::OutStream extends Lucy::Object::Obj {
+
+ char *buf;
+ i64_t buf_start;
+ size_t buf_pos;
+ FileHandle *file_handle;
+ CharBuf *path;
+
+ inert incremented OutStream*
+ open(Obj *file);
+
+ /** Return a new OutStream or set Err_error and return NULL on failure.
+ */
+ inert OutStream*
+ do_open(OutStream *self, Obj *file);
+
+ /** Return the current file position.
+ */
+ final i64_t
+ Tell(OutStream *self);
+
+ /** Flush output buffer to target FileHandle.
+ */
+ final void
+ Flush(OutStream *self);
+
+ /** Return the current length of the file in bytes.
+ */
+ final i64_t
+ Length(OutStream *self);
+
+ /** Advisory call informing the OutStream that it should prepare to occupy
+ * <code>length</code> bytes.
+ */
+ void
+ Grow(OutStream *self, i64_t length);
+
+ /** Write <code>len</code> bytes from <code>buf</code> to the OutStream.
+ */
+ final void
+ Write_Bytes(OutStream *self, const void *buf, size_t len);
+
+ /** Write a signed 8-bit integer.
+ */
+ final void
+ Write_I8(OutStream *self, i8_t value);
+
+ /** Write an unsigned 8-bit integer.
+ */
+ final void
+ Write_U8(OutStream *self, u8_t value);
+
+ /** Write a signed 32-bit integer.
+ */
+ final void
+ Write_I32(OutStream *self, i32_t value);
+
+ /** Write an unsigned 32-bit integer.
+ */
+ final void
+ Write_U32(OutStream *self, u32_t value);
+
+ /** Write a signed 64-bit integer.
+ */
+ final void
+ Write_I64(OutStream *self, i64_t value);
+
+ /** Write an unsigned 64-bit integer.
+ */
+ final void
+ Write_U64(OutStream *self, u64_t value);
+
+ /** Write a 32-bit integer using a compressed format.
+ */
+ final void
+ Write_C32(OutStream *self, u32_t value);
+
+ /** Write a 64-bit integer using a compressed format.
+ */
+ final void
+ Write_C64(OutStream *self, u64_t value);
+
+ /** Write an IEEE 764 32-bit floating point number in big-endian byte
+ * order.
+ */
+ final void
+ Write_F32(OutStream *self, float value);
+
+ /** Write an IEEE 764 64-bit double-precision floating point number in
+ * big-endian byte order.
+ */
+ final void
+ Write_F64(OutStream *self, double value);
+
+ /** Write a string as a C32 indicating length of content in bytes,
+ * followed by the content.
+ */
+ final void
+ Write_String(OutStream *self, const char *buf, size_t len);
+
+ /** Write the entire contents of an InStream to the OutStream.
+ */
+ void
+ Absorb(OutStream *self, InStream *instream);
+
+ /** Close down the stream.
+ */
+ void
+ Close(OutStream *self);
+
+ public void
+ Destroy(OutStream *self);
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Store/OutStream.bp
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Store/OutStream.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Store/OutStream.c?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Store/OutStream.c (added)
+++ lucene/lucy/trunk/core/Lucy/Store/OutStream.c Thu Oct 29 12:07:56 2009
@@ -0,0 +1,341 @@
+#define C_LUCY_OUTSTREAM
+#include "Lucy/Util/ToolSet.h"
+
+#include "Lucy/Store/OutStream.h"
+#include "Lucy/Store/FileHandle.h"
+#include "Lucy/Store/FileWindow.h"
+#include "Lucy/Store/InStream.h"
+#include "Lucy/Store/RAMFile.h"
+#include "Lucy/Store/RAMFileHandle.h"
+
+/* Inlined version of OutStream_Write_Bytes. */
+static INLINE void
+SI_write_bytes(OutStream *self, const void *bytes, size_t len);
+
+/* Inlined version of OutStream_Write_C32. */
+static INLINE void
+SI_write_c32(OutStream *self, u32_t value);
+
+/* Flush content in the buffer to the FileHandle. */
+static void
+S_flush(OutStream *self);
+
+OutStream*
+OutStream_open(Obj *file)
+{
+ OutStream *self = (OutStream*)VTable_Make_Obj(OUTSTREAM);
+ return OutStream_do_open(self, file);
+}
+
+OutStream*
+OutStream_do_open(OutStream *self, Obj *file)
+{
+ /* Init. */
+ self->buf = (char*)MALLOCATE(IO_STREAM_BUF_SIZE);
+ self->buf_start = 0;
+ self->buf_pos = 0;
+
+ /* Obtain a FileHandle. */
+ if (Obj_Is_A(file, FILEHANDLE)) {
+ self->file_handle = (FileHandle*)INCREF(file);
+ }
+ else if (Obj_Is_A(file, RAMFILE)) {
+ self->file_handle
+ = (FileHandle*)RAMFH_open(NULL, FH_WRITE_ONLY, (RAMFile*)file);
+ }
+ /*
+ else if (Obj_Is_A(file, CHARBUF)) {
+ self->file_handle = (FileHandle*)FSFH_open((CharBuf*)file,
+ FH_WRITE_ONLY | FH_CREATE | FH_EXCLUSIVE );
+ }
+ */
+ else {
+ Err_set_error(Err_new(CB_newf("Invalid type for param 'file': '%o'",
+ Obj_Get_Class_Name(file))));
+ DECREF(self);
+ return NULL;
+ }
+ if (!self->file_handle) {
+ ERR_ADD_FRAME(Err_get_error());
+ DECREF(self);
+ return NULL;
+ }
+
+ /* Derive filepath from FileHandle. */
+ self->path = CB_Clone(FH_Get_Path(self->file_handle));
+
+ return self;
+}
+
+void
+OutStream_destroy(OutStream *self)
+{
+ if (self->file_handle != NULL) {
+ /* Inlined flush, ignoring errors. */
+ if (self->buf_pos) {
+ FH_Write(self->file_handle, self->buf, self->buf_pos);
+ }
+ DECREF(self->file_handle);
+ }
+ DECREF(self->path);
+ FREEMEM(self->buf);
+ SUPER_DESTROY(self, OUTSTREAM);
+}
+
+void
+OutStream_absorb(OutStream *self, InStream *instream)
+{
+ char buf[IO_STREAM_BUF_SIZE];
+ i64_t bytes_left = InStream_Length(instream);
+
+ /* Read blocks of content into an intermediate buffer, than write them to
+ * the OutStream.
+ *
+ * TODO: optimize by utilizing OutStream's buffer directly, while still
+ * not flushing too frequently and keeping code complexity under control.
+ * */
+ OutStream_Grow(self, OutStream_Tell(self) + bytes_left);
+ while (bytes_left) {
+ const size_t bytes_this_iter = bytes_left < IO_STREAM_BUF_SIZE
+ ? (size_t)bytes_left
+ : IO_STREAM_BUF_SIZE;
+ InStream_Read_Bytes(instream, buf, bytes_this_iter);
+ SI_write_bytes(self, buf, bytes_this_iter);
+ bytes_left -= bytes_this_iter;
+ }
+}
+
+void
+OutStream_grow(OutStream *self, i64_t length)
+{
+ if (!FH_Grow(self->file_handle, length)) {
+ RETHROW(INCREF(Err_get_error()));
+ }
+}
+
+i64_t
+OutStream_tell(OutStream *self)
+{
+ return self->buf_start + self->buf_pos;
+}
+
+void
+OutStream_flush(OutStream *self)
+{
+ S_flush(self);
+}
+
+static void
+S_flush(OutStream *self)
+{
+ if (self->file_handle == NULL) {
+ THROW(ERR, "Can't write to a closed OutStream for %o", self->path);
+ }
+ if ( !FH_Write(self->file_handle, self->buf, self->buf_pos) ) {
+ RETHROW(INCREF(Err_get_error()));
+ }
+ self->buf_start += self->buf_pos;
+ self->buf_pos = 0;
+}
+
+i64_t
+OutStream_length(OutStream *self)
+{
+ return OutStream_tell(self);
+}
+
+void
+OutStream_write_bytes(OutStream *self, const void *bytes, size_t len)
+{
+ SI_write_bytes(self, bytes, len);
+}
+
+static INLINE void
+SI_write_bytes(OutStream *self, const void *bytes, size_t len)
+{
+ /* If this data is larger than the buffer size, flush and write. */
+ if (len >= IO_STREAM_BUF_SIZE) {
+ S_flush(self);
+ if ( !FH_Write(self->file_handle, bytes, len) ) {
+ RETHROW(INCREF(Err_get_error()));
+ }
+ self->buf_start += len;
+ }
+ /* If there's not enough room in the buffer, flush then add. */
+ else if (self->buf_pos + len >= IO_STREAM_BUF_SIZE) {
+ S_flush(self);
+ memcpy((self->buf + self->buf_pos), bytes, len);
+ self->buf_pos += len;
+ }
+ /* If there's room, just add these bytes to the buffer. */
+ else {
+ memcpy((self->buf + self->buf_pos), bytes, len);
+ self->buf_pos += len;
+ }
+}
+
+static INLINE void
+SI_write_u8(OutStream *self, u8_t value)
+{
+ if (self->buf_pos >= IO_STREAM_BUF_SIZE) {
+ S_flush(self);
+ }
+ self->buf[ self->buf_pos++ ] = (char)value;
+}
+
+void
+OutStream_write_i8(OutStream *self, i8_t value)
+{
+ SI_write_u8(self, (u8_t)value);
+}
+
+void
+OutStream_write_u8(OutStream *self, u8_t value)
+{
+ SI_write_u8(self, value);
+}
+
+static INLINE void
+SI_write_u32(OutStream *self, u32_t value)
+{
+#ifdef BIG_END
+ SI_write_bytes(self, &value, 4);
+#else
+ char buf[4];
+ char *buf_copy = buf;
+ NumUtil_encode_bigend_u32(value, &buf_copy);
+ SI_write_bytes(self, buf, 4);
+#endif
+}
+
+void
+OutStream_write_i32(OutStream *self, i32_t value)
+{
+ SI_write_u32(self, (u32_t)value);
+}
+
+void
+OutStream_write_u32(OutStream *self, u32_t value)
+{
+ SI_write_u32(self, value);
+}
+
+static INLINE void
+SI_write_u64(OutStream *self, u64_t value)
+{
+#ifdef BIG_END
+ SI_write_bytes(self, &value, 8);
+#else
+ char buf[sizeof(u64_t)];
+ char *buf_copy = buf;
+ NumUtil_encode_bigend_u64(value, &buf_copy);
+ SI_write_bytes(self, buf, sizeof(u64_t));
+#endif
+}
+
+void
+OutStream_write_i64(OutStream *self, i64_t value)
+{
+ SI_write_u64(self, (u64_t)value);
+}
+
+void
+OutStream_write_u64(OutStream *self, u64_t value)
+{
+ SI_write_u64(self, value);
+}
+
+void
+OutStream_write_f32(OutStream *self, float value)
+{
+ char buf[sizeof(float)];
+ char *buf_copy = buf;
+ NumUtil_encode_bigend_f32(value, &buf_copy);
+ SI_write_bytes(self, buf_copy, sizeof(float));
+}
+
+void
+OutStream_write_f64(OutStream *self, double value)
+{
+ char buf[sizeof(double)];
+ char *buf_copy = buf;
+ NumUtil_encode_bigend_f64(value, &buf_copy);
+ SI_write_bytes(self, buf_copy, sizeof(double));
+}
+
+void
+OutStream_write_c32(OutStream *self, u32_t value)
+{
+ SI_write_c32(self, value);
+}
+
+static INLINE void
+SI_write_c32(OutStream *self, u32_t value)
+{
+ u8_t buf[C32_MAX_BYTES];
+ u8_t *ptr = buf + sizeof(buf) - 1;
+
+ /* Write last byte first, which has no continue bit. */
+ *ptr = value & 0x7f;
+ value >>= 7;
+
+ while (value) {
+ /* Work backwards, writing bytes with continue bits set. */
+ *--ptr = ((value & 0x7f) | 0x80);
+ value >>= 7;
+ }
+
+ SI_write_bytes(self, ptr, (buf + sizeof(buf)) - ptr);
+}
+
+void
+OutStream_write_c64(OutStream *self, u64_t value)
+{
+ u8_t buf[C64_MAX_BYTES];
+ u8_t *ptr = buf + sizeof(buf) - 1;
+
+ /* Write last byte first, which has no continue bit. */
+ *ptr = value & 0x7f;
+ value >>= 7;
+
+ while (value) {
+ /* Work backwards, writing bytes with continue bits set. */
+ *--ptr = ((value & 0x7f) | 0x80);
+ value >>= 7;
+ }
+
+ SI_write_bytes(self, ptr, (buf + sizeof(buf)) - ptr);
+}
+
+void
+OutStream_write_string(OutStream *self, const char *string, size_t len)
+{
+ SI_write_c32(self, (u32_t)len);
+ SI_write_bytes(self, string, len);
+}
+
+void
+OutStream_close(OutStream *self)
+{
+ if (self->file_handle) {
+ S_flush(self);
+ DECREF(self->file_handle);
+ self->file_handle = NULL;
+ }
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Store/OutStream.c
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Test/Store/MockFileHandle.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/Store/MockFileHandle.bp?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/Store/MockFileHandle.bp (added)
+++ lucene/lucy/trunk/core/Lucy/Test/Store/MockFileHandle.bp Thu Oct 29 12:07:56 2009
@@ -0,0 +1,42 @@
+parcel Lucy;
+
+/** Mock-object FileHandle for testing InStream/OutStream.
+ */
+class Lucy::Store::MockFileHandle extends Lucy::Store::FileHandle {
+
+ i64_t len;
+
+ inert incremented MockFileHandle*
+ new(const CharBuf *path = NULL, i64_t length);
+
+ inert MockFileHandle*
+ init(MockFileHandle *self, const CharBuf *path = NULL, i64_t length);
+
+ bool_t
+ Window(MockFileHandle *self, FileWindow *window, i64_t offset, i64_t len);
+
+ bool_t
+ Release_Window(MockFileHandle *self, FileWindow *window);
+
+ i64_t
+ Length(MockFileHandle *self);
+
+ bool_t
+ Close(MockFileHandle *self);
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Test/Store/MockFileHandle.bp
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Test/Store/MockFileHandle.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/Store/MockFileHandle.c?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/Store/MockFileHandle.c (added)
+++ lucene/lucy/trunk/core/Lucy/Test/Store/MockFileHandle.c Thu Oct 29 12:07:56 2009
@@ -0,0 +1,67 @@
+#define C_LUCY_MOCKFILEHANDLE
+#define C_LUCY_FILEWINDOW
+#include "Lucy/Util/ToolSet.h"
+
+#include "Lucy/Test/Store/MockFileHandle.h"
+#include "Lucy/Store/FileWindow.h"
+
+MockFileHandle*
+MockFileHandle_new(const CharBuf *path, i64_t length)
+{
+ MockFileHandle *self = (MockFileHandle*)VTable_Make_Obj(MOCKFILEHANDLE);
+ return MockFileHandle_init(self, path, length);
+}
+
+MockFileHandle*
+MockFileHandle_init(MockFileHandle *self, const CharBuf *path, i64_t length)
+{
+ FH_do_open((FileHandle*)self, path, 0);
+ self->len = length;
+ return self;
+}
+
+bool_t
+MockFileHandle_window(MockFileHandle *self, FileWindow *window, i64_t offset,
+ i64_t len)
+{
+ UNUSED_VAR(self);
+ FileWindow_Set_Window(window, NULL, offset, len);
+ return true;
+}
+
+bool_t
+MockFileHandle_release_window(MockFileHandle *self, FileWindow *window)
+{
+ UNUSED_VAR(self);
+ FileWindow_Set_Window(window, NULL, 0, 0);
+ return true;
+}
+
+i64_t
+MockFileHandle_length(MockFileHandle *self)
+{
+ return self->len;
+}
+
+bool_t
+MockFileHandle_close(MockFileHandle *self)
+{
+ UNUSED_VAR(self);
+ return true;
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Test/Store/MockFileHandle.c
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Test/Store/TestIOChunks.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/Store/TestIOChunks.bp?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/Store/TestIOChunks.bp (added)
+++ lucene/lucy/trunk/core/Lucy/Test/Store/TestIOChunks.bp Thu Oct 29 12:07:56 2009
@@ -0,0 +1,24 @@
+parcel Lucy;
+
+/** Tests reading and writing of composite types using InStream/OutStream.
+ */
+inert class Lucy::Test::Store::TestIOChunks {
+ inert void
+ run_tests();
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Test/Store/TestIOChunks.bp
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Test/Store/TestIOChunks.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/Store/TestIOChunks.c?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/Store/TestIOChunks.c (added)
+++ lucene/lucy/trunk/core/Lucy/Test/Store/TestIOChunks.c Thu Oct 29 12:07:56 2009
@@ -0,0 +1,108 @@
+#define C_LUCY_TESTINSTREAM
+#define C_LUCY_INSTREAM
+#define C_LUCY_FILEWINDOW
+#include <stdlib.h>
+#include <time.h>
+
+#include "Lucy/Util/ToolSet.h"
+#include "Lucy/Test.h"
+#include "Lucy/Test/TestUtils.h"
+#include "Lucy/Test/Store/TestIOChunks.h"
+#include "Lucy/Store/InStream.h"
+#include "Lucy/Store/OutStream.h"
+#include "Lucy/Store/RAMFile.h"
+#include "Lucy/Store/RAMFileHandle.h"
+#include "Lucy/Util/NumberUtils.h"
+
+static void
+test_Read_Write_Bytes(TestBatch *batch)
+{
+ RAMFile *file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ InStream *instream;
+ char buf[4];
+
+ OutStream_Write_Bytes(outstream, "foo", 4);
+ OutStream_Close(outstream);
+
+ instream = InStream_open((Obj*)file);
+ InStream_Read_Bytes(instream, buf, 4);
+ ASSERT_TRUE(batch, strcmp(buf, "foo") == 0, "Read_Bytes Write_Bytes");
+
+ DECREF(instream);
+ DECREF(outstream);
+ DECREF(file);
+}
+
+static void
+test_Buf(TestBatch *batch)
+{
+ RAMFile *file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ InStream *instream;
+ size_t size = IO_STREAM_BUF_SIZE * 2 + 5;
+ u32_t i;
+ char *buf;
+
+ for (i = 0; i < size; i++) {
+ OutStream_Write_U8(outstream, 'a');
+ }
+ OutStream_Close(outstream);
+
+ instream = InStream_open((Obj*)file);
+ buf = InStream_Buf(instream, 5);
+ ASSERT_INT_EQ(batch, instream->limit - buf, IO_STREAM_BUF_SIZE,
+ "Small request bumped up");
+
+ buf += IO_STREAM_BUF_SIZE - 10; /* 10 bytes left in buffer. */
+ InStream_Advance_Buf(instream, buf);
+
+ buf = InStream_Buf(instream, 10);
+ ASSERT_INT_EQ(batch, instream->limit - buf, 10,
+ "Exact request doesn't trigger refill");
+
+ buf = InStream_Buf(instream, 11);
+ ASSERT_INT_EQ(batch, instream->limit - buf, IO_STREAM_BUF_SIZE,
+ "Requesting over limit triggers refill");
+
+ {
+ size_t expected = InStream_Length(instream) - InStream_Tell(instream);
+ buf = InStream_Buf(instream, 100000);
+ ASSERT_INT_EQ(batch, instream->limit - buf, expected,
+ "Requests greater than file size get pared down");
+ }
+
+ DECREF(instream);
+ DECREF(outstream);
+ DECREF(file);
+}
+
+void
+TestIOChunks_run_tests()
+{
+ TestBatch *batch = Test_new_batch("TestIOChunks", 5, NULL);
+
+ srand((unsigned int)time((time_t*)NULL));
+ PLAN(batch);
+
+ test_Read_Write_Bytes(batch);
+ test_Buf(batch);
+
+ batch->destroy(batch);
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Test/Store/TestIOChunks.c
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Test/Store/TestIOPrimitives.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/Store/TestIOPrimitives.bp?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/Store/TestIOPrimitives.bp (added)
+++ lucene/lucy/trunk/core/Lucy/Test/Store/TestIOPrimitives.bp Thu Oct 29 12:07:56 2009
@@ -0,0 +1,24 @@
+parcel Lucy;
+
+/** Tests reading and writing of primitive types using InStream/OutStream.
+ */
+inert class Lucy::Test::Store::TestIOPrimitives {
+ inert void
+ run_tests();
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Test/Store/TestIOPrimitives.bp
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Test/Store/TestIOPrimitives.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/Store/TestIOPrimitives.c?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/Store/TestIOPrimitives.c (added)
+++ lucene/lucy/trunk/core/Lucy/Test/Store/TestIOPrimitives.c Thu Oct 29 12:07:56 2009
@@ -0,0 +1,442 @@
+#define C_LUCY_TESTINSTREAM
+#define C_LUCY_INSTREAM
+#define C_LUCY_FILEWINDOW
+#include <stdlib.h>
+#include <time.h>
+
+#include "Lucy/Util/ToolSet.h"
+#include "Lucy/Test.h"
+#include "Lucy/Test/TestUtils.h"
+#include "Lucy/Test/Store/TestIOPrimitives.h"
+#include "Lucy/Store/InStream.h"
+#include "Lucy/Store/OutStream.h"
+#include "Lucy/Store/RAMFile.h"
+#include "Lucy/Store/RAMFileHandle.h"
+#include "Lucy/Util/NumberUtils.h"
+
+static void
+test_i8(TestBatch *batch)
+{
+ RAMFile *file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ InStream *instream;
+ int i;
+
+ for (i = -128; i < 128; i++) {
+ OutStream_Write_I8(outstream, i);
+ }
+ OutStream_Close(outstream);
+
+ instream = InStream_open((Obj*)file);
+ for (i = -128; i < 128; i++) {
+ if (InStream_Read_I8(instream) != i) { break; }
+ }
+ ASSERT_INT_EQ(batch, i, 128, "round trip i8 successful for %d out of 256",
+ i + 128);
+
+ DECREF(instream);
+ DECREF(outstream);
+ DECREF(file);
+}
+
+static void
+test_u8(TestBatch *batch)
+{
+ RAMFile *file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ InStream *instream;
+ int i;
+
+ for (i = 0; i < 256; i++) {
+ OutStream_Write_U8(outstream, i);
+ }
+ OutStream_Close(outstream);
+
+ instream = InStream_open((Obj*)file);
+ for (i = 0; i < 256; i++) {
+ if (InStream_Read_U8(instream) != i) { break; }
+ }
+ ASSERT_INT_EQ(batch, i, 256,
+ "round trip u8 successful for %d out of 256", i);
+
+ DECREF(instream);
+ DECREF(outstream);
+ DECREF(file);
+}
+
+static void
+test_i32(TestBatch *batch)
+{
+ i64_t *ints = TestUtils_random_i64s(NULL, 1000, I32_MIN, I32_MAX);
+ RAMFile *file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ InStream *instream;
+ u32_t i;
+
+ /* Test boundaries. */
+ ints[0] = I32_MIN;
+ ints[1] = I32_MIN + 1;
+ ints[2] = I32_MAX;
+ ints[3] = I32_MAX - 1;
+
+ for (i = 0; i < 1000; i++) {
+ OutStream_Write_I32(outstream, (i32_t)ints[i]);
+ }
+ OutStream_Close(outstream);
+
+ instream = InStream_open((Obj*)file);
+ for (i = 0; i < 1000; i++) {
+ i32_t got = InStream_Read_I32(instream);
+ if (got != ints[i]) {
+ FAIL(batch, "i32 round trip failed: %ld, %ld", (long)got,
+ (long)ints[i]);
+ break;
+ }
+ }
+ if (i == 1000) {
+ PASS(batch, "i32 round trip");
+ }
+
+ DECREF(instream);
+ DECREF(outstream);
+ DECREF(file);
+ FREEMEM(ints);
+}
+
+static void
+test_u32(TestBatch *batch)
+{
+ u64_t *ints = TestUtils_random_u64s(NULL, 1000, 0, U32_MAX);
+ RAMFile *file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ InStream *instream;
+ u32_t i;
+
+ /* Test boundaries. */
+ ints[0] = 0;
+ ints[1] = 1;
+ ints[2] = U32_MAX;
+ ints[3] = U32_MAX - 1;
+
+ for (i = 0; i < 1000; i++) {
+ OutStream_Write_U32(outstream, (u32_t)ints[i]);
+ }
+ OutStream_Close(outstream);
+
+ instream = InStream_open((Obj*)file);
+ for (i = 0; i < 1000; i++) {
+ u32_t got = InStream_Read_U32(instream);
+ if (got != ints[i]) {
+ FAIL(batch, "u32 round trip failed: %lu, %lu", (unsigned long)got,
+ (unsigned long)ints[i]);
+ break;
+ }
+ }
+ if (i == 1000) {
+ PASS(batch, "u32 round trip");
+ }
+
+ DECREF(instream);
+ DECREF(outstream);
+ DECREF(file);
+ FREEMEM(ints);
+}
+
+static void
+test_i64(TestBatch *batch)
+{
+ i64_t *ints = TestUtils_random_i64s(NULL, 1000, I64_MIN, I64_MAX);
+ RAMFile *file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ InStream *instream;
+ u32_t i;
+
+ /* Test boundaries. */
+ ints[0] = I64_MIN;
+ ints[1] = I64_MIN + 1;
+ ints[2] = I64_MAX;
+ ints[3] = I64_MAX - 1;
+
+ for (i = 0; i < 1000; i++) {
+ OutStream_Write_I64(outstream, ints[i]);
+ }
+ OutStream_Close(outstream);
+
+ instream = InStream_open((Obj*)file);
+ for (i = 0; i < 1000; i++) {
+ i64_t got = InStream_Read_I64(instream);
+ if (got != ints[i]) {
+ FAIL(batch, "i64 round trip failed: %" I64P ", %" I64P,
+ got, ints[i]);
+ break;
+ }
+ }
+ if (i == 1000) {
+ PASS(batch, "i64 round trip");
+ }
+
+ DECREF(instream);
+ DECREF(outstream);
+ DECREF(file);
+ FREEMEM(ints);
+}
+
+
+static void
+test_u64(TestBatch *batch)
+{
+ u64_t *ints = TestUtils_random_u64s(NULL, 1000, 0, U64_MAX);
+ RAMFile *file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ InStream *instream;
+ u32_t i;
+
+ /* Test boundaries. */
+ ints[0] = 0;
+ ints[1] = 1;
+ ints[2] = U64_MAX;
+ ints[3] = U64_MAX - 1;
+
+ for (i = 0; i < 1000; i++) {
+ OutStream_Write_U64(outstream, ints[i]);
+ }
+ OutStream_Close(outstream);
+
+ instream = InStream_open((Obj*)file);
+ for (i = 0; i < 1000; i++) {
+ u64_t got = InStream_Read_U64(instream);
+ if (got != ints[i]) {
+ FAIL(batch, "u64 round trip failed: %" U64P ", %" U64P,
+ got, ints[i]);
+ break;
+ }
+ }
+ if (i == 1000) {
+ PASS(batch, "u64 round trip");
+ }
+
+ DECREF(instream);
+ DECREF(outstream);
+ DECREF(file);
+ FREEMEM(ints);
+}
+
+static void
+test_c32(TestBatch *batch)
+{
+ u64_t *ints = TestUtils_random_u64s(NULL, 1000, 0, U32_MAX);
+ RAMFile *file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ InStream *instream;
+ u32_t i;
+
+ /* Test boundaries. */
+ ints[0] = 0;
+ ints[1] = 1;
+ ints[2] = U32_MAX;
+ ints[3] = U32_MAX - 1;
+
+ for (i = 0; i < 1000; i++) {
+ OutStream_Write_C32(outstream, (u32_t)ints[i]);
+ }
+ OutStream_Close(outstream);
+
+ instream = InStream_open((Obj*)file);
+ for (i = 0; i < 1000; i++) {
+ u32_t got = InStream_Read_C32(instream);
+ if (got != ints[i]) {
+ FAIL(batch, "c32 round trip failed: %lu, %lu", (unsigned long)got,
+ (unsigned long)ints[i]);
+ break;
+ }
+ }
+ if (i == 1000) {
+ PASS(batch, "c32 round trip");
+ }
+
+ DECREF(instream);
+ DECREF(outstream);
+ DECREF(file);
+ FREEMEM(ints);
+}
+
+static void
+test_c64(TestBatch *batch)
+{
+ u64_t *ints = TestUtils_random_u64s(NULL, 1000, 0, U64_MAX);
+ RAMFile *file = RAMFile_new(NULL, false);
+ RAMFile *raw_file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ OutStream *raw_outstream = OutStream_open((Obj*)raw_file);
+ InStream *instream;
+ InStream *raw_instream;
+ u32_t i;
+
+ /* Test boundaries. */
+ ints[0] = 0;
+ ints[1] = 1;
+ ints[2] = U64_MAX;
+ ints[3] = U64_MAX - 1;
+
+ for (i = 0; i < 1000; i++) {
+ OutStream_Write_C64(outstream, ints[i]);
+ OutStream_Write_C64(raw_outstream, ints[i]);
+ }
+ OutStream_Close(outstream);
+ OutStream_Close(raw_outstream);
+
+ instream = InStream_open((Obj*)file);
+ for (i = 0; i < 1000; i++) {
+ u64_t got = InStream_Read_C64(instream);
+ if (got != ints[i]) {
+ FAIL(batch, "c64 round trip failed: %" U64P ", %" U64P,
+ got, ints[i]);
+ break;
+ }
+ }
+ if (i == 1000) {
+ PASS(batch, "c64 round trip");
+ }
+
+ raw_instream = InStream_open((Obj*)raw_file);
+ for (i = 0; i < 1000; i++) {
+ char buffer[10];
+ char *buf = buffer;
+ size_t size = InStream_Read_Raw_C64(raw_instream, buffer);
+ u64_t got = NumUtil_decode_c64(&buf);
+ UNUSED_VAR(size);
+ if (got != ints[i]) {
+ FAIL(batch, "Read_Raw_C64 failed: %" U64P ", %" U64P,
+ got, ints[i]);
+ break;
+ }
+ }
+ if (i == 1000) {
+ PASS(batch, "Read_Raw_C64");
+ }
+
+ DECREF(raw_instream);
+ DECREF(instream);
+ DECREF(raw_outstream);
+ DECREF(outstream);
+ DECREF(raw_file);
+ DECREF(file);
+ FREEMEM(ints);
+}
+
+static void
+test_f32(TestBatch *batch)
+{
+ double *f64s = TestUtils_random_f64s(NULL, 1000);
+ float *values = (float*)MALLOCATE(1000 * sizeof(float));
+ RAMFile *file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ InStream *instream;
+ u32_t i;
+
+ /* Truncate. */
+ for (i = 0; i < 1000; i++) {
+ values[i] = f64s[i];
+ }
+
+ /* Test boundaries. */
+ values[0] = 0.0f;
+ values[1] = 1.0f;
+
+ for (i = 0; i < 1000; i++) {
+ OutStream_Write_F32(outstream, values[i]);
+ }
+ OutStream_Close(outstream);
+
+ instream = InStream_open((Obj*)file);
+ for (i = 0; i < 1000; i++) {
+ float got = InStream_Read_F32(instream);
+ if (got != values[i]) {
+ FAIL(batch, "f32 round trip failed: %f, %f", got, values[i]);
+ break;
+ }
+ }
+ if (i == 1000) {
+ PASS(batch, "f32 round trip");
+ }
+
+ DECREF(instream);
+ DECREF(outstream);
+ DECREF(file);
+ FREEMEM(values);
+ FREEMEM(f64s);
+}
+
+static void
+test_f64(TestBatch *batch)
+{
+ double *values = TestUtils_random_f64s(NULL, 1000);
+ RAMFile *file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ InStream *instream;
+ u32_t i;
+
+ /* Test boundaries. */
+ values[0] = 0.0;
+ values[1] = 1.0;
+
+ for (i = 0; i < 1000; i++) {
+ OutStream_Write_F64(outstream, values[i]);
+ }
+ OutStream_Close(outstream);
+
+ instream = InStream_open((Obj*)file);
+ for (i = 0; i < 1000; i++) {
+ double got = InStream_Read_F64(instream);
+ if (got != values[i]) {
+ FAIL(batch, "f64 round trip failed: %f, %f", got, values[i]);
+ break;
+ }
+ }
+ if (i == 1000) {
+ PASS(batch, "f64 round trip");
+ }
+
+ DECREF(instream);
+ DECREF(outstream);
+ DECREF(file);
+ FREEMEM(values);
+}
+
+void
+TestIOPrimitives_run_tests()
+{
+ TestBatch *batch = Test_new_batch("TestIOPrimitives", 11, NULL);
+
+ srand((unsigned int)time((time_t*)NULL));
+ PLAN(batch);
+
+ test_i8(batch);
+ test_u8(batch);
+ test_i32(batch);
+ test_u32(batch);
+ test_i64(batch);
+ test_u64(batch);
+ test_c32(batch);
+ test_c64(batch);
+ test_f32(batch);
+ test_f64(batch);
+
+ batch->destroy(batch);
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Test/Store/TestIOPrimitives.c
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Test/Store/TestInStream.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/Store/TestInStream.bp?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/Store/TestInStream.bp (added)
+++ lucene/lucy/trunk/core/Lucy/Test/Store/TestInStream.bp Thu Oct 29 12:07:56 2009
@@ -0,0 +1,26 @@
+parcel Lucy;
+
+/** Tests for basic functionality of InStream using both memory-mapped and
+ * streamed sources.
+ */
+
+inert class Lucy::Test::Store::TestInStream {
+ inert void
+ run_tests();
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Test/Store/TestInStream.bp
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Test/Store/TestInStream.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/Store/TestInStream.c?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/Store/TestInStream.c (added)
+++ lucene/lucy/trunk/core/Lucy/Test/Store/TestInStream.c Thu Oct 29 12:07:56 2009
@@ -0,0 +1,222 @@
+#define C_LUCY_TESTINSTREAM
+#define C_LUCY_INSTREAM
+#define C_LUCY_FILEWINDOW
+
+#include "Lucy/Util/ToolSet.h"
+#include "Lucy/Test.h"
+#include "Lucy/Test/TestUtils.h"
+#include "Lucy/Test/Store/TestInStream.h"
+#include "Lucy/Test/Store/MockFileHandle.h"
+#include "Lucy/Store/FileWindow.h"
+#include "Lucy/Store/InStream.h"
+#include "Lucy/Store/OutStream.h"
+#include "Lucy/Store/RAMFile.h"
+#include "Lucy/Store/RAMFileHandle.h"
+#include "Lucy/Util/NumberUtils.h"
+
+static void
+test_refill(TestBatch *batch)
+{
+ RAMFile *file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ InStream *instream;
+ char scratch[5];
+ i32_t i;
+
+ for (i = 0; i < 1023; i++) {
+ OutStream_Write_U8(outstream, 'x');
+ }
+ OutStream_Write_U8(outstream, 'y');
+ OutStream_Write_U8(outstream, 'z');
+ OutStream_Close(outstream);
+
+ instream = InStream_open((Obj*)file);
+ InStream_Refill(instream);
+ ASSERT_INT_EQ(batch, instream->limit - instream->buf, IO_STREAM_BUF_SIZE,
+ "Refill");
+ ASSERT_INT_EQ(batch, (long)InStream_Tell(instream), 0,
+ "Correct file pos after standing-start Refill()");
+ DECREF(instream);
+
+ instream = InStream_open((Obj*)file);
+ InStream_Fill(instream, 30);
+ ASSERT_INT_EQ(batch, instream->limit - instream->buf, 30, "Fill()");
+ ASSERT_INT_EQ(batch, (long)InStream_Tell(instream), 0,
+ "Correct file pos after standing-start Fill()");
+ DECREF(instream);
+
+ instream = InStream_open((Obj*)file);
+ InStream_Read_Bytes(instream, scratch, 5);
+ ASSERT_INT_EQ(batch, instream->limit - instream->buf,
+ IO_STREAM_BUF_SIZE - 5, "small read triggers refill");
+ DECREF(instream);
+
+ instream = InStream_open((Obj*)file);
+ ASSERT_INT_EQ(batch, InStream_Read_U8(instream), 'x', "Read_U8");
+ InStream_Seek(instream, 1023);
+ ASSERT_INT_EQ(batch, (long)instream->window->offset, 0,
+ "no unnecessary refill on Seek");
+ ASSERT_INT_EQ(batch, (long)InStream_Tell(instream), 1023, "Seek/Tell");
+ ASSERT_INT_EQ(batch, InStream_Read_U8(instream), 'y',
+ "correct data after in-buffer Seek()");
+ ASSERT_INT_EQ(batch, InStream_Read_U8(instream), 'z', "automatic Refill");
+ ASSERT_TRUE(batch, (instream->window->offset != 0), "refilled");
+
+ DECREF(instream);
+ DECREF(outstream);
+ DECREF(file);
+}
+
+static void
+test_Clone_and_Reopen(TestBatch *batch)
+{
+ ZombieCharBuf foo = ZCB_LITERAL("foo");
+ ZombieCharBuf bar = ZCB_LITERAL("bar");
+ RAMFile *file = RAMFile_new(NULL, false);
+ OutStream *outstream = OutStream_open((Obj*)file);
+ RAMFileHandle *fh;
+ InStream *instream;
+ InStream *clone;
+ InStream *reopened;
+ u32_t i;
+
+ for (i = 0; i < 26; i++) {
+ OutStream_Write_U8(outstream, 'a' + i);
+ }
+ OutStream_Close(outstream);
+
+ fh = RAMFH_open((CharBuf*)&foo, FH_READ_ONLY, file);
+ instream = InStream_open((Obj*)fh);
+ InStream_Seek(instream, 1);
+ ASSERT_TRUE(batch, CB_Equals(InStream_Get_Filename(instream), (Obj*)&foo),
+ "Get_Filename");
+
+ clone = InStream_Clone(instream);
+ ASSERT_TRUE(batch, CB_Equals(InStream_Get_Filename(clone), (Obj*)&foo),
+ "Clones have same filename");
+ ASSERT_TRUE(batch, InStream_Length(instream) == InStream_Length(clone),
+ "Clones have same length");
+ ASSERT_TRUE(batch, InStream_Read_U8(instream) == InStream_Read_U8(clone),
+ "Clones start at same file position");
+
+ reopened = InStream_Reopen(instream, (CharBuf*)&bar, 25, 1);
+ ASSERT_TRUE(batch, CB_Equals(InStream_Get_Filename(reopened), (Obj*)&bar),
+ "Reopened InStreams take new filename");
+ ASSERT_TRUE(batch, InStream_Read_U8(reopened) == 'z',
+ "Reopened stream starts at supplied offset");
+ ASSERT_TRUE(batch, InStream_Length(reopened) == 1,
+ "Reopened stream uses supplied length");
+ ASSERT_TRUE(batch, InStream_Tell(reopened) == 1,
+ "Tell() uses supplied offset for reopened stream");
+ InStream_Seek(reopened, 0);
+ ASSERT_TRUE(batch, InStream_Read_U8(reopened) == 'z',
+ "Seek() uses supplied offset for reopened stream");
+
+ DECREF(reopened);
+ DECREF(clone);
+ DECREF(instream);
+ DECREF(outstream);
+ DECREF(fh);
+ DECREF(file);
+}
+
+static void
+test_Close(TestBatch *batch)
+{
+ RAMFile *file = RAMFile_new(NULL, false);
+ InStream *instream = InStream_open((Obj*)file);
+ InStream_Close(instream);
+ ASSERT_TRUE(batch, instream->file_handle == NULL,
+ "Close decrements FileHandle's refcount");
+ DECREF(instream);
+ DECREF(file);
+}
+
+static void
+test_Seek_and_Tell(TestBatch *batch)
+{
+ i64_t gb1 = 0x40000000;
+ i64_t gb3 = gb1 * 3;
+ i64_t gb6 = gb1 * 6;
+ i64_t gb12 = gb1 * 12;
+ FileHandle *fh = (FileHandle*)MockFileHandle_new(NULL, gb12);
+ InStream *instream = InStream_open((Obj*)fh);
+
+ InStream_Buf(instream, 10000);
+ ASSERT_TRUE(batch, instream->limit == ((char*)NULL) + 10000,
+ "InStream_Buf sets limit");
+
+ InStream_Seek(instream, gb6);
+ ASSERT_TRUE(batch, InStream_Tell(instream) == gb6,
+ "Tell after seek forwards outside buffer");
+ ASSERT_TRUE(batch, instream->buf == NULL,
+ "Seek forwards outside buffer sets buf to NULL");
+ ASSERT_TRUE(batch, instream->limit == NULL,
+ "Seek forwards outside buffer sets limit to NULL");
+ ASSERT_TRUE(batch, instream->window->offset == gb6,
+ "Seek forwards outside buffer tracks pos in window offset");
+
+ InStream_Buf(instream, gb1);
+ ASSERT_TRUE(batch, instream->limit == ((char*)NULL) + gb1,
+ "InStream_Buf sets limit");
+
+ InStream_Seek(instream, gb6 + 10);
+ ASSERT_TRUE(batch, InStream_Tell(instream) == gb6 + 10,
+ "Tell after seek forwards within buffer");
+ ASSERT_TRUE(batch, instream->buf == ((char*)NULL) + 10,
+ "Seek within buffer sets buf");
+ ASSERT_TRUE(batch, instream->limit == ((char*)NULL) + gb1,
+ "Seek within buffer leaves limit alone");
+
+ InStream_Seek(instream, gb6 + 1);
+ ASSERT_TRUE(batch, InStream_Tell(instream) == gb6 + 1,
+ "Tell after seek backwards within buffer");
+ ASSERT_TRUE(batch, instream->buf == ((char*)NULL) + 1,
+ "Seek backwards within buffer sets buf");
+ ASSERT_TRUE(batch, instream->limit == ((char*)NULL) + gb1,
+ "Seek backwards within buffer leaves limit alone");
+
+ InStream_Seek(instream, gb3);
+ ASSERT_TRUE(batch, InStream_Tell(instream) == gb3,
+ "Tell after seek backwards outside buffer");
+ ASSERT_TRUE(batch, instream->buf == NULL,
+ "Seek backwards outside buffer sets buf to NULL");
+ ASSERT_TRUE(batch, instream->limit == NULL,
+ "Seek backwards outside buffer sets limit to NULL");
+ ASSERT_TRUE(batch, instream->window->offset == gb3,
+ "Seek backwards outside buffer tracks pos in window offset");
+
+ DECREF(instream);
+ DECREF(fh);
+}
+
+void
+TestInStream_run_tests()
+{
+ TestBatch *batch = Test_new_batch("TestInStream", 37, NULL);
+
+ PLAN(batch);
+
+ test_refill(batch);
+ test_Clone_and_Reopen(batch);
+ test_Close(batch);
+ test_Seek_and_Tell(batch);
+
+ batch->destroy(batch);
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Test/Store/TestInStream.c
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Test/TestUtils.bp
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/TestUtils.bp?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/TestUtils.bp (added)
+++ lucene/lucy/trunk/core/Lucy/Test/TestUtils.bp Thu Oct 29 12:07:56 2009
@@ -0,0 +1,63 @@
+parcel Lucy;
+
+inert class Lucy::Test::TestUtils {
+
+ /** Testing-only CharBuf factory which uses strlen().
+ */
+ inert incremented CharBuf*
+ get_cb(const char *utf8);
+
+ /** Return a random unsigned 64-bit integer.
+ */
+ inert u64_t
+ random_u64();
+
+ /** Return an array of <code>count</code> random 64-bit integers where
+ * <code>min <= n < limit</code>.
+ *
+ * If <code>buf</code> is NULL, it will be allocated, otherwise it will
+ * be used.
+ */
+ inert i64_t*
+ random_i64s(i64_t *buf, size_t count, i64_t min, i64_t limit);
+
+ /** Return an array of <code>count</code> random unsigned, 64-bit integers
+ * where <code>min <= n < limit</code>.
+ *
+ * If <code>buf</code> is NULL, it will be allocated, otherwise it will
+ * be used.
+ */
+ inert u64_t*
+ random_u64s(u64_t *buf, size_t count, u64_t min, u64_t limit);
+
+ /** Return an array of <code>count</code> random double-precision floating
+ * point numbers between 0 and 1.
+ *
+ * If <code>buf</code> is NULL, it will be allocated, otherwise it will
+ * be used.
+ */
+ inert double*
+ random_f64s(double *buf, size_t count);
+
+ /** Return a VArray of CharBufs, each representing the content for a
+ * document in the shared collection.
+ */
+ inert incremented VArray*
+ doc_set();
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Test/TestUtils.bp
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/core/Lucy/Test/TestUtils.c
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/core/Lucy/Test/TestUtils.c?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/core/Lucy/Test/TestUtils.c (added)
+++ lucene/lucy/trunk/core/Lucy/Test/TestUtils.c Thu Oct 29 12:07:56 2009
@@ -0,0 +1,91 @@
+#define C_LUCY_TESTUTILS
+#include "Lucy/Util/ToolSet.h"
+#include <stdarg.h>
+#include <string.h>
+
+#include "Lucy/Test/TestUtils.h"
+
+u64_t
+TestUtils_random_u64()
+{
+ u64_t num = ((u64_t)rand() << 60)
+ | ((u64_t)rand() << 45)
+ | ((u64_t)rand() << 30)
+ | ((u64_t)rand() << 15)
+ | ((u64_t)rand() << 0);
+ return num;
+}
+
+i64_t*
+TestUtils_random_i64s(i64_t *buf, size_t count, i64_t min, i64_t limit)
+{
+ u64_t range = min < limit ? limit - min : 0;
+ i64_t *ints = buf ? buf : (i64_t*)CALLOCATE(count, sizeof(i64_t));
+ size_t i;
+ for (i = 0; i < count; i++) {
+ ints[i] = min + TestUtils_random_u64() % range;
+ }
+ return ints;
+}
+
+u64_t*
+TestUtils_random_u64s(u64_t *buf, size_t count, u64_t min, u64_t limit)
+{
+ u64_t range = min < limit ? limit - min : 0;
+ u64_t *ints = buf ? buf : (u64_t*)CALLOCATE(count, sizeof(u64_t));
+ size_t i;
+ for (i = 0; i < count; i++) {
+ ints[i] = min + TestUtils_random_u64() % range;
+ }
+ return ints;
+}
+
+double*
+TestUtils_random_f64s(double *buf, size_t count)
+{
+ double *f64s = buf ? buf : (double*)CALLOCATE(count, sizeof(double));
+ size_t i;
+ for (i = 0; i < count; i++) {
+ u64_t num = TestUtils_random_u64();
+ f64s[i] = (double)num / U64_MAX;
+ }
+ return f64s;
+}
+
+VArray*
+TestUtils_doc_set()
+{
+ VArray *docs = VA_new(10);
+
+ VA_Push(docs, (Obj*)TestUtils_get_cb("x"));
+ VA_Push(docs, (Obj*)TestUtils_get_cb("y"));
+ VA_Push(docs, (Obj*)TestUtils_get_cb("z"));
+ VA_Push(docs, (Obj*)TestUtils_get_cb("x a"));
+ VA_Push(docs, (Obj*)TestUtils_get_cb("x a b"));
+ VA_Push(docs, (Obj*)TestUtils_get_cb("x a b c"));
+ VA_Push(docs, (Obj*)TestUtils_get_cb("x foo a b c d"));
+
+ return docs;
+}
+
+CharBuf*
+TestUtils_get_cb(const char *ptr)
+{
+ return CB_new_from_utf8(ptr, strlen(ptr));
+}
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/core/Lucy/Test/TestUtils.c
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/perl/lib/Lucy/Store/InStream.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/lib/Lucy/Store/InStream.pm?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/lib/Lucy/Store/InStream.pm (added)
+++ lucene/lucy/trunk/perl/lib/Lucy/Store/InStream.pm Thu Oct 29 12:07:56 2009
@@ -0,0 +1,108 @@
+use Lucy;
+
+1;
+
+__END__
+
+__BINDING__
+
+my $xs_code = <<'END_XS_CODE';
+MODULE = Lucy PACKAGE = Lucy::Store::InStream
+
+void
+read(self, buffer_sv, len, ...)
+ lucy_InStream *self;
+ SV *buffer_sv;
+ size_t len;
+PPCODE:
+{
+ UV offset = items == 4 ? SvUV(ST(3)) : 0;
+ char *ptr;
+ size_t total_len = offset + len;
+ SvUPGRADE(buffer_sv, SVt_PV);
+ if (!SvPOK(buffer_sv)) { SvCUR_set(buffer_sv, 0); }
+ ptr = SvGROW(buffer_sv, total_len + 1);
+ Lucy_InStream_Read_Bytes(self, ptr + offset, len);
+ SvPOK_on(buffer_sv);
+ if (SvCUR(buffer_sv) < total_len) {
+ SvCUR_set(buffer_sv, total_len);
+ *(SvEND(buffer_sv)) = '\0';
+ }
+}
+
+SV*
+read_string(self)
+ lucy_InStream *self;
+CODE:
+{
+ char *ptr;
+ size_t len = Lucy_InStream_Read_C32(self);
+ RETVAL = newSV(len + 1);
+ SvCUR_set(RETVAL, len);
+ SvPOK_on(RETVAL);
+ SvUTF8_on(RETVAL); /* Trust source. Reconsider if API goes public. */
+ *SvEND(RETVAL) = '\0';
+ ptr = SvPVX(RETVAL);
+ Lucy_InStream_Read_Bytes(self, ptr, len);
+}
+OUTPUT: RETVAL
+
+int
+read_raw_c64(self, buffer_sv)
+ lucy_InStream *self;
+ SV *buffer_sv;
+CODE:
+{
+ char *ptr;
+ SvUPGRADE(buffer_sv, SVt_PV);
+ ptr = SvGROW(buffer_sv, 10 + 1);
+ RETVAL = Lucy_InStream_Read_Raw_C64(self, ptr);
+ SvPOK_on(buffer_sv);
+ SvCUR_set(buffer_sv, RETVAL);
+}
+OUTPUT: RETVAL
+END_XS_CODE
+
+Boilerplater::Binding::Perl::Class->register(
+ parcel => "Lucy",
+ class_name => "Lucy::Store::InStream",
+ xs_code => $xs_code,
+ bind_methods => [
+ qw(
+ Seek
+ Tell
+ Length
+ Reopen
+ Close
+ Read_I8
+ Read_I32
+ Read_I64
+ Read_U8
+ Read_U32
+ Read_U64
+ Read_C32
+ Read_C64
+ Read_F32
+ Read_F64
+ )
+ ],
+ bind_constructors => ['open|do_open'],
+);
+
+__COPYRIGHT__
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/perl/lib/Lucy/Store/InStream.pm
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/perl/lib/Lucy/Store/OutStream.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/lib/Lucy/Store/OutStream.pm?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/lib/Lucy/Store/OutStream.pm (added)
+++ lucene/lucy/trunk/perl/lib/Lucy/Store/OutStream.pm Thu Oct 29 12:07:56 2009
@@ -0,0 +1,85 @@
+use Lucy;
+
+1;
+
+__END__
+
+__BINDING__
+
+my $xs_code = <<'END_XS_CODE';
+MODULE = Lucy PACKAGE = Lucy::Store::OutStream
+
+void
+print(self, ...)
+ lucy_OutStream *self;
+PPCODE:
+{
+ int i;
+ for (i = 1; i < items; i++) {
+ STRLEN len;
+ char *ptr = SvPV( ST(i), len);
+ Lucy_OutStream_Write_Bytes(self, ptr, len);
+ }
+}
+
+void
+write_string(self, aSV)
+ lucy_OutStream *self;
+ SV *aSV;
+PPCODE:
+{
+ STRLEN len = 0;
+ char *ptr = SvPVutf8(aSV, len);
+ Lucy_OutStream_Write_C32(self, len);
+ Lucy_OutStream_Write_Bytes(self, ptr, len);
+}
+END_XS_CODE
+
+my $synopsis = <<'END_SYNOPSIS'; # Don't use this yet.
+ my $outstream = $folder->open_out($filename) or die $@;
+ $outstream->write_u64($file_position);
+END_SYNOPSIS
+
+Boilerplater::Binding::Perl::Class->register(
+ parcel => "Lucy",
+ class_name => "Lucy::Store::OutStream",
+ xs_code => $xs_code,
+ bind_methods => [
+ qw(
+ Tell
+ Length
+ Flush
+ Close
+ Absorb
+ Write_I8
+ Write_I32
+ Write_I64
+ Write_U8
+ Write_U32
+ Write_U64
+ Write_C32
+ Write_C64
+ Write_F32
+ Write_F64
+ )
+ ],
+ bind_constructors => ['open|do_open'],
+);
+
+__COPYRIGHT__
+
+/* Copyright 2009 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+

Propchange: lucene/lucy/trunk/perl/lib/Lucy/Store/OutStream.pm
------------------------------------------------------------------------------
svn:eol-style = native

Modified: lucene/lucy/trunk/perl/lib/Lucy/Test.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/lib/Lucy/Test.pm?rev=830909&r1=830908&r2=830909&view=diff
==============================================================================
--- lucene/lucy/trunk/perl/lib/Lucy/Test.pm (original)
+++ lucene/lucy/trunk/perl/lib/Lucy/Test.pm Thu Oct 29 12:07:56 2009
@@ -40,6 +40,15 @@
else if (strEQ(package, "TestFileHandle")) {
lucy_TestFH_run_tests();
}
+ else if (strEQ(package, "TestInStream")) {
+ lucy_TestInStream_run_tests();
+ }
+ else if (strEQ(package, "TestIOChunks")) {
+ lucy_TestIOChunks_run_tests();
+ }
+ else if (strEQ(package, "TestIOPrimitives")) {
+ lucy_TestIOPrimitives_run_tests();
+ }
else if (strEQ(package, "TestRAMFileHandle")) {
lucy_TestRAMFH_run_tests();
}

Added: lucene/lucy/trunk/perl/t/binding/101-simple_io.t
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/t/binding/101-simple_io.t?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/t/binding/101-simple_io.t (added)
+++ lucene/lucy/trunk/perl/t/binding/101-simple_io.t Thu Oct 29 12:07:56 2009
@@ -0,0 +1,139 @@
+use strict;
+use warnings;
+use lib 'buildlib';
+
+use Lucy;
+use Test::More tests => 27;
+use Encode qw( _utf8_off );
+use bytes;
+no bytes;
+
+my ( @nums, $packed, $template, $ram_file );
+
+sub check_round_trip {
+ my ( $type, $expected ) = @_;
+ my $write_method = "write_$type";
+ my $read_method = "read_$type";
+ my $file = Lucy::Store::RAMFile->new;
+ my $outstream = Lucy::Store::OutStream->open( file => $file )
+ or die Lucy->error;
+ $outstream->$write_method($_) for @$expected;
+ $outstream->close;
+ my $instream = Lucy::Store::InStream->open( file => $file )
+ or die Lucy->error;
+ my @got;
+ push @got, $instream->$read_method for @$expected;
+ is_deeply( \@got, $expected, $type );
+ return $file;
+}
+
+sub check_round_trip_bytes {
+ my ( $message, $expected ) = @_;
+ my $file = Lucy::Store::RAMFile->new;
+ my $outstream = Lucy::Store::OutStream->open( file => $file );
+ for (@$expected) {
+ $outstream->write_c32( bytes::length($_) );
+ $outstream->print($_);
+ }
+ $outstream->close;
+ my $instream = Lucy::Store::InStream->open( file => $file )
+ or die Lucy->error;
+ my @got;
+ for (@$expected) {
+ my $buf;
+ my $len = $instream->read_c32;
+ $instream->read( $buf, $len );
+ push @got, $buf;
+ }
+ is_deeply( \@got, $expected, $message );
+ return $file;
+}
+
+@nums = ( -128 .. 127 );
+$packed = pack( 'c256', @nums );
+$ram_file = check_round_trip( 'i8', \@nums );
+is( $ram_file->get_contents, $packed,
+ "pack and write_i8 handle signed bytes identically" );
+
+@nums = ( 0 .. 255 );
+$packed = pack( 'C*', @nums );
+$ram_file = check_round_trip( 'u8', \@nums );
+is( $ram_file->get_contents, $packed,
+ "pack and write_u8 handle unsigned bytes identically" );
+
+@nums = map { $_ * 1_000_000 + int( rand() * 1_000_000 ) } -1000 .. 1000;
+push @nums, ( -1 * ( 2**31 ), 2**31 - 1 );
+check_round_trip( 'i32', \@nums );
+
+@nums = map { $_ * 1_000_000 + int( rand() * 1_000_000 ) } 1000 .. 3000;
+push @nums, ( 0, 1, 2**32 - 1 );
+$packed = pack( 'N*', @nums );
+$ram_file = check_round_trip( 'u32', \@nums );
+is( $ram_file->get_contents, $packed,
+ "pack and write_u32 handle unsigned int32s identically" );
+
+@nums = map { $_ * 2 } 0 .. 5;
+check_round_trip( 'u64', \@nums );
+
+@nums = map { $_ * 2**31 } 0 .. 2000;
+$_ += int( rand( 2**16 ) ) for @nums;
+check_round_trip( 'u64', \@nums );
+
+@nums = ( 0 .. 127 );
+check_round_trip( 'c32', \@nums );
+
+@nums = ( 128 .. 500 );
+$packed = pack( 'w*', @nums );
+$ram_file = check_round_trip( 'c32', \@nums );
+is( $ram_file->get_contents, $packed, "C32 is equivalent to Perl's pack w" );
+
+@nums = ( 0 .. 127 );
+check_round_trip( 'c64', \@nums );
+
+@nums = ( 128 .. 500 );
+$packed = pack( 'w*', @nums );
+$ram_file = check_round_trip( 'c64', \@nums );
+is( $ram_file->get_contents, $packed, "C64 is equivalent to Perl's pack w" );
+
+@nums = map { $_ * 2**31 } 0 .. 2000;
+$_ += int( rand( 2**16 ) ) for @nums;
+check_round_trip( 'c64', \@nums );
+
+# rand (always?) has 64-bit precision, but we need 32-bit - so truncate via
+# pack/unpack.
+@nums = map {rand} 0 .. 100;
+$packed = pack( 'f*', @nums );
+@nums = unpack( 'f*', $packed );
+check_round_trip( 'f32', \@nums );
+
+@nums = map {rand} 0 .. 100;
+check_round_trip( 'f64', \@nums );
+
+my @items;
+for ( 0, 22, 300 ) {
+ @items = ( 'a' x $_ );
+ check_round_trip_bytes( "buf of length $_", \@items );
+ check_round_trip( 'string', \@items );
+}
+
+{
+ my @stuff = ( qw( a b c d 1 ), "\n", "\0", " ", " ", "\xf0\x9d\x84\x9e" );
+ my @items = ();
+ for ( 1 .. 50 ) {
+ my $string_len = int( rand() * 5 );
+ my $str = '';
+ $str .= $stuff[ rand @stuff ] for 1 .. $string_len;
+ push @items, $str;
+ }
+ check_round_trip_bytes( "50 binary bufs", \@items );
+}
+
+my $latin = "ma\x{f1}ana";
+$ram_file = check_round_trip( "string", [$latin] );
+my $unibytes = $latin;
+utf8::upgrade($unibytes);
+_utf8_off($unibytes);
+my $slurped = $ram_file->get_contents;
+substr( $slurped, 0, 1, "" ); # ditch c32 at head of string;
+is( $slurped, $unibytes, "write_string upgrades to utf8" );
+

Propchange: lucene/lucy/trunk/perl/t/binding/101-simple_io.t
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/perl/t/core/052-instream.t
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/t/core/052-instream.t?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/t/core/052-instream.t (added)
+++ lucene/lucy/trunk/perl/t/core/052-instream.t Thu Oct 29 12:07:56 2009
@@ -0,0 +1,6 @@
+use strict;
+use warnings;
+
+use Lucy::Test;
+Lucy::Test::run_tests("TestInStream");
+

Propchange: lucene/lucy/trunk/perl/t/core/052-instream.t
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/perl/t/core/054-io_primitives.t
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/t/core/054-io_primitives.t?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/t/core/054-io_primitives.t (added)
+++ lucene/lucy/trunk/perl/t/core/054-io_primitives.t Thu Oct 29 12:07:56 2009
@@ -0,0 +1,6 @@
+use strict;
+use warnings;
+
+use Lucy::Test;
+Lucy::Test::run_tests("TestIOPrimitives");
+

Propchange: lucene/lucy/trunk/perl/t/core/054-io_primitives.t
------------------------------------------------------------------------------
svn:eol-style = native

Added: lucene/lucy/trunk/perl/t/core/055-io_chunks.t
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/perl/t/core/055-io_chunks.t?rev=830909&view=auto
==============================================================================
--- lucene/lucy/trunk/perl/t/core/055-io_chunks.t (added)
+++ lucene/lucy/trunk/perl/t/core/055-io_chunks.t Thu Oct 29 12:07:56 2009
@@ -0,0 +1,6 @@
+use strict;
+use warnings;
+
+use Lucy::Test;
+Lucy::Test::run_tests("TestIOChunks");
+

Propchange: lucene/lucy/trunk/perl/t/core/055-io_chunks.t
------------------------------------------------------------------------------
svn:eol-style = native
reply

Search Discussions

Related Discussions

Discussion Navigation
viewthread | post

1 user in discussion

Marvin: 1 post