001 /*
002 * Copyright (c) Andrey Kuznetsov. All Rights Reserved.
003 *
004 * http://uio.imagero.com
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions are met:
008 *
009 * o Redistributions of source code must retain the above copyright notice,
010 * this list of conditions and the following disclaimer.
011 *
012 * o Redistributions in binary form must reproduce the above copyright notice,
013 * this list of conditions and the following disclaimer in the documentation
014 * and/or other materials provided with the distribution.
015 *
016 * o Neither the name of Andrey Kuznetsov nor the names of
017 * its contributors may be used to endorse or promote products derived
018 * from this software without specific prior written permission.
019 *
020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
022 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
023 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
027 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
028 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
029 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
030 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031 */
032 package com.imagero.uio.bio.content;
033
034 import com.imagero.uio.Transformer;
035
036 import java.io.IOException;
037
038 /**
039 * Date: 05.01.2008
040 *
041 * @author Andrey Kuznetsov
042 */
043 public class CharArrayContent extends Content {
044 char[][] data;
045 boolean bigEndian;
046
047 static final int SHIFT = 1;
048
049 public CharArrayContent(char[][] data) {
050 this(data, true);
051 }
052
053 public CharArrayContent(char[][] data, boolean bigEndian) {
054 this.data = data;
055 this.bigEndian = bigEndian;
056 }
057
058 public int load(long offset, int bpos, byte[] dest) throws IOException {
059 //to simplify char to byte converting, we require two bytes boundary
060 if ((offset & 1) != 0 || ((dest.length - bpos) & 1) != 0) {
061 throw new IOException("Illegal offset or length");
062 }
063 final long off = offset >> SHIFT;
064 final int len = (dest.length - bpos) >> SHIFT;
065
066 IndexAndStart ias = getIAS(off);
067 if (ias == null) {
068 return 0;
069 }
070 int index = ias.index;
071 int pos = (int) (off - ias.start);
072 char[] src = data[index];
073 int toCopy = Math.min(src.length - pos, len);
074 if (toCopy > 0) {
075 com.imagero.uio.Transformer.charToByte(src, pos, toCopy, dest, bpos, bigEndian);
076 if ((toCopy < len)) {
077 int copiedBytes = (toCopy << SHIFT);
078 return toCopy + load(offset + copiedBytes, bpos + copiedBytes, dest);
079 }
080 }
081 return toCopy;
082 }
083
084 public void close() {
085 }
086
087 private IndexAndStart getIAS(long offset) {
088 long start = 0;
089 for (int i = 0; i < data.length; i++) {
090 char[] src = data[i];
091 int length = src.length;
092 long end = start + length;
093 if (offset >= start && offset <= end) {
094 return new IndexAndStart(i, start);
095 }
096 start += length;
097 }
098 return null;
099 }
100
101 /**
102 * Save data to current content (char array).
103 * All offsets and lengths must be
104 * @param offset
105 * @param spos
106 * @param src
107 * @param length
108 * @throws IOException
109 */
110 public void save(long offset, int spos, byte[] src, int length) throws IOException {
111 //to simplify char to byte converting we require two byte boundary
112 if ((offset & 1) != 0 || ((src.length - spos) & 1) != 0) {
113 throw new IOException("Illegal offset or length");
114 }
115 final long off = offset >> SHIFT;
116 final int len = Math.min((src.length - spos), length) >> SHIFT;
117
118 IndexAndStart ias = getIAS(off);
119 if (ias == null) {
120 return;
121 }
122 int index = ias.index;
123 long start = ias.start;
124 int dpos = (int) (off - start);
125 char[] dest = data[index];
126 int request = len;
127 int toCopy = Math.min((dest.length - dpos), request);
128 if (request > 0 && toCopy > 0) {
129 com.imagero.uio.Transformer.byteToChar(src, spos, toCopy, dest, dpos, true);
130 if (toCopy < request) {
131 int copiedBytes = (toCopy << SHIFT);
132 save(offset + copiedBytes, spos + copiedBytes, src, (request - toCopy) << SHIFT);
133 }
134 }
135 }
136
137 public boolean canReload() {
138 return true;
139 }
140
141 public long length() throws IOException {
142 long length = 0;
143 for (int i = 0; i < data.length; i++) {
144 char[] dest = data[i];
145 length += dest.length;
146 }
147 return length << SHIFT;
148 }
149
150 public boolean writable() {
151 return true;
152 }
153 }