Flatbuffers Merge commit '8cd6f0538a362ceefbcfcbf6c7b8b3f341d1fb41' into master
Upgrade flatbuffers to the latest.
Change-Id: I901787ac6fc5d7ce2c4019cc0d275de68086b4d8
diff --git a/aos/flatbuffer_merge.cc b/aos/flatbuffer_merge.cc
index 8bd020a..da0eb86 100644
--- a/aos/flatbuffer_merge.cc
+++ b/aos/flatbuffer_merge.cc
@@ -344,65 +344,65 @@
switch (elementary_type) {
case flatbuffers::ElementaryType::ET_UTYPE:
- if (!type_code.is_vector) continue;
+ if (!type_code.is_repeating) continue;
printf("ET_UTYPE, %s\n", typetable->names[field_index]);
break;
case flatbuffers::ElementaryType::ET_BOOL:
- if (!type_code.is_vector) continue;
+ if (!type_code.is_repeating) continue;
AddVector<uint8_t>(elementary_type, field_offset, t1, t2, fbb,
&elements);
break;
case flatbuffers::ElementaryType::ET_CHAR:
- if (!type_code.is_vector) continue;
+ if (!type_code.is_repeating) continue;
AddVector<int8_t>(elementary_type, field_offset, t1, t2, fbb,
&elements);
break;
case flatbuffers::ElementaryType::ET_UCHAR:
- if (!type_code.is_vector) continue;
+ if (!type_code.is_repeating) continue;
AddVector<uint8_t>(elementary_type, field_offset, t1, t2, fbb,
&elements);
break;
case flatbuffers::ElementaryType::ET_SHORT:
- if (!type_code.is_vector) continue;
+ if (!type_code.is_repeating) continue;
AddVector<int16_t>(elementary_type, field_offset, t1, t2, fbb,
&elements);
break;
case flatbuffers::ElementaryType::ET_USHORT:
- if (!type_code.is_vector) continue;
+ if (!type_code.is_repeating) continue;
AddVector<uint16_t>(elementary_type, field_offset, t1, t2, fbb,
&elements);
break;
case flatbuffers::ElementaryType::ET_INT:
- if (!type_code.is_vector) continue;
+ if (!type_code.is_repeating) continue;
AddVector<int32_t>(elementary_type, field_offset, t1, t2, fbb,
&elements);
break;
case flatbuffers::ElementaryType::ET_UINT:
- if (!type_code.is_vector) continue;
+ if (!type_code.is_repeating) continue;
AddVector<uint32_t>(elementary_type, field_offset, t1, t2, fbb,
&elements);
break;
case flatbuffers::ElementaryType::ET_LONG:
- if (!type_code.is_vector) continue;
+ if (!type_code.is_repeating) continue;
AddVector<int64_t>(elementary_type, field_offset, t1, t2, fbb,
&elements);
break;
case flatbuffers::ElementaryType::ET_ULONG:
- if (!type_code.is_vector) continue;
+ if (!type_code.is_repeating) continue;
AddVector<uint64_t>(elementary_type, field_offset, t1, t2, fbb,
&elements);
break;
case flatbuffers::ElementaryType::ET_FLOAT:
- if (!type_code.is_vector) continue;
+ if (!type_code.is_repeating) continue;
AddVector<float>(elementary_type, field_offset, t1, t2, fbb, &elements);
break;
case flatbuffers::ElementaryType::ET_DOUBLE:
- if (!type_code.is_vector) continue;
+ if (!type_code.is_repeating) continue;
AddVector<double>(elementary_type, field_offset, t1, t2, fbb,
&elements);
break;
case flatbuffers::ElementaryType::ET_STRING:
- if (!type_code.is_vector) {
+ if (!type_code.is_repeating) {
MergeString(field_offset, t1, t2, fbb, &elements);
} else {
AddVectorOfStrings(elementary_type, field_offset, t1, t2, fbb,
@@ -412,7 +412,7 @@
case flatbuffers::ElementaryType::ET_SEQUENCE: {
const flatbuffers::TypeTable *sub_typetable =
typetable->type_refs[type_code.sequence_ref]();
- if (!type_code.is_vector) {
+ if (!type_code.is_repeating) {
MergeTables(field_offset, t1, t2, sub_typetable, fbb, &elements);
} else {
const flatbuffers::TypeTable *sub_typetable =
@@ -433,7 +433,7 @@
for (size_t field_index = 0; field_index < typetable->num_elems;
++field_index) {
const flatbuffers::TypeCode type_code = typetable->type_codes[field_index];
- if (type_code.is_vector) {
+ if (type_code.is_repeating) {
continue;
}
const flatbuffers::ElementaryType elementary_type =
@@ -601,7 +601,7 @@
Extend(&b, field_span);
- if (type_code.is_vector) {
+ if (type_code.is_repeating) {
// Go look inside the vector and track the base size.
val += flatbuffers::ReadScalar<flatbuffers::uoffset_t>(val);
const flatbuffers::Vector<uint8_t> *vec =
diff --git a/aos/json_to_flatbuffer.cc b/aos/json_to_flatbuffer.cc
index d78fe99..f12014f 100644
--- a/aos/json_to_flatbuffer.cc
+++ b/aos/json_to_flatbuffer.cc
@@ -354,7 +354,7 @@
flatbuffers::TypeCode type_code =
stack_.back().typetable->type_codes[field_index];
- if (type_code.is_vector != in_vector()) {
+ if (type_code.is_repeating != in_vector()) {
fprintf(stderr, "Type and json disagree on if we are in a vector or not\n");
return false;
}
@@ -371,7 +371,7 @@
flatbuffers::TypeCode type_code =
stack_.back().typetable->type_codes[field_index];
- if (type_code.is_vector != in_vector()) {
+ if (type_code.is_repeating != in_vector()) {
fprintf(stderr, "Type and json disagree on if we are in a vector or not\n");
return false;
}
@@ -388,7 +388,7 @@
flatbuffers::TypeCode type_code =
stack_.back().typetable->type_codes[field_index];
- if (type_code.is_vector != in_vector()) {
+ if (type_code.is_repeating != in_vector()) {
fprintf(stderr, "Type and json disagree on if we are in a vector or not\n");
return false;
}
@@ -581,7 +581,7 @@
static_cast<flatbuffers::voffset_t>(field_index));
// Vectors will always be Offset<>'s.
- if (type_code.is_vector) {
+ if (type_code.is_repeating) {
fbb->AddOffset(field_offset, offset_element);
return true;
}
@@ -809,10 +809,10 @@
to_string_.EndSequence();
}
void Field(size_t field_idx, size_t set_idx, flatbuffers::ElementaryType type,
- bool is_vector, const flatbuffers::TypeTable *type_table,
+ bool is_repeating, const flatbuffers::TypeTable *type_table,
const char *name, const uint8_t *val) override {
if (should_skip()) return;
- to_string_.Field(field_idx, set_idx, type, is_vector, type_table, name,
+ to_string_.Field(field_idx, set_idx, type, is_repeating, type_table, name,
val);
}
void UType(uint8_t value, const char *name) override {
diff --git a/aos/network/www/config_handler.ts b/aos/network/www/config_handler.ts
index 048c2ba..c554647 100644
--- a/aos/network/www/config_handler.ts
+++ b/aos/network/www/config_handler.ts
@@ -1,4 +1,4 @@
-import {Configuration, Channel} from 'aos/configuration_generated';
+import {aos.Configuration as Configuration, aos.Channel as Channel} from 'aos/configuration_generated';
import {Connect} from 'aos/network/connect_generated';
import {Connection} from './proxy';
diff --git a/aos/network/www/graph_main.ts b/aos/network/www/graph_main.ts
index bbd70de..74fc54b 100644
--- a/aos/network/www/graph_main.ts
+++ b/aos/network/www/graph_main.ts
@@ -8,11 +8,11 @@
// timer in the the /aos timing report message (this message was chosen because
// it is already being published by the web proxy process, so the demo requires
// very little setup).
-import {Plot, Line} from 'aos/network/www/plotter';
-import {Channel, Configuration} from 'aos/configuration_generated';
-import {Connect} from 'aos/network/connect_generated';
-import {Connection} from 'aos/network/www/proxy';
-import {Parser, Table} from 'aos/network/www/reflection'
+import {Line, Plot} from 'aos/network/www/plotter';
+import {aos} from 'aos/configuration_generated';
+import {aos} from 'aos/network/connect_generated';
+import {aos} from 'aos/network/www/proxy';
+import {aos} from 'aos/network/www/reflection'
const width = 900;
const height = 400;
@@ -110,7 +110,7 @@
let reportParser = null;
-conn.addConfigHandler((config: Configuration) => {
+conn.addConfigHandler((config: aos.Configuration) => {
// Locate the timing report schema so that we can read the received messages.
let reportSchema = null;
for (let ii = 0; ii < config.channelsLength(); ++ii) {
@@ -129,17 +129,17 @@
for (const channel of [timingReport]) {
const nameFb = builder.createString(channel.name);
const typeFb = builder.createString(channel.type);
- Channel.startChannel(builder);
- Channel.addName(builder, nameFb);
- Channel.addType(builder, typeFb);
- const channelFb = Channel.endChannel(builder);
+ aos.Channel.startChannel(builder);
+ aos.Channel.addName(builder, nameFb);
+ aos.Channel.addType(builder, typeFb);
+ const channelFb = aos.Channel.endChannel(builder);
channels.push(channelFb);
}
- const channelsFb = Connect.createChannelsToTransferVector(builder, channels);
- Connect.startConnect(builder);
- Connect.addChannelsToTransfer(builder, channelsFb);
- const connect = Connect.endConnect(builder);
+ const channelsFb = aos.message_bridge.Connect.createChannelsToTransferVector(builder, channels);
+ aos.message_bridge.Connect.startConnect(builder);
+ aos.message_bridge.Connect.addChannelsToTransfer(builder, channelsFb);
+ const connect = aos.message_bridge.Connect.endConnect(builder);
builder.finish(connect);
conn.sendConnectMessage(builder);
});
diff --git a/aos/network/www/ping_handler.ts b/aos/network/www/ping_handler.ts
index df7635d..9b37d70 100644
--- a/aos/network/www/ping_handler.ts
+++ b/aos/network/www/ping_handler.ts
@@ -1,8 +1,8 @@
-import {Ping} from 'aos/events/ping_generated';
+import {aos} from 'aos/events/ping_generated';
export function HandlePing(data: Uint8Array) {
const fbBuffer = new flatbuffers.ByteBuffer(data);
- const ping = Ping.getRootAsPing(fbBuffer);
+ const ping = aos.examples.Ping.getRootAsPing(fbBuffer);
document.getElementById('val').innerHTML = ping.value();
document.getElementById('time').innerHTML = ping.sendTime().low;
diff --git a/aos/network/www/proxy.ts b/aos/network/www/proxy.ts
index 4ba7e39..29f055b 100644
--- a/aos/network/www/proxy.ts
+++ b/aos/network/www/proxy.ts
@@ -1,5 +1,5 @@
import {ConfigHandler} from './config_handler';
-import {Configuration} from 'aos/configuration_generated';
+import {aos} from 'aos/configuration_generated';
import * as WebProxy from 'aos/network/web_proxy_generated';
// There is one handler for each DataChannel, it maintains the state of
@@ -52,9 +52,9 @@
private dataChannel: DataChannel|null = null;
private webSocketUrl: string;
- private configInternal: Configuration|null = null;
+ private configInternal: aos.Configuration|null = null;
// A set of functions that accept the config to handle.
- private readonly configHandlers = new Set<(config: Configuration) => void>();
+ private readonly configHandlers = new Set<(config: aos.Configuration) => void>();
private readonly handlerFuncs =
new Map<string, (data: Uint8Array, sentTime: number) => void>();
@@ -65,7 +65,7 @@
this.webSocketUrl = `ws://${server}/ws`;
}
- addConfigHandler(handler: (config: Configuration) => void): void {
+ addConfigHandler(handler: (config: aos.Configuration) => void): void {
this.configHandlers.add(handler);
}
@@ -95,7 +95,7 @@
// all other messages are sent on specific DataChannels.
onConfigMessage(data: Uint8Array): void {
const fbBuffer = new flatbuffers.ByteBuffer(data);
- this.configInternal = Configuration.getRootAsConfiguration(fbBuffer);
+ this.configInternal = aos.Configuration.getRootAsConfiguration(fbBuffer);
for (const handler of Array.from(this.configHandlers)) {
handler(this.configInternal);
}
diff --git a/aos/network/www/reflection.ts b/aos/network/www/reflection.ts
index 5141790..62cfa61 100644
--- a/aos/network/www/reflection.ts
+++ b/aos/network/www/reflection.ts
@@ -6,88 +6,88 @@
// constructed flatbuffers.
// See reflection_test_main.ts for sample usage.
-import {BaseType, Schema, Object, Field} from 'aos/configuration_generated';
+import {reflection, aos} from 'aos/configuration_generated';
// Returns the size, in bytes, of the given type. For vectors/strings/etc.
// returns the size of the offset.
-function typeSize(baseType: BaseType): number {
+function typeSize(baseType: reflection.BaseType): number {
switch (baseType) {
- case BaseType.None:
- case BaseType.UType:
- case BaseType.Bool:
- case BaseType.Byte:
- case BaseType.UByte:
+ case reflection.BaseType.None:
+ case reflection.BaseType.UType:
+ case reflection.BaseType.Bool:
+ case reflection.BaseType.Byte:
+ case reflection.BaseType.UByte:
return 1;
- case BaseType.Short:
- case BaseType.UShort:
+ case reflection.BaseType.Short:
+ case reflection.BaseType.UShort:
return 2;
- case BaseType.Int:
- case BaseType.UInt:
+ case reflection.BaseType.Int:
+ case reflection.BaseType.UInt:
return 4;
- case BaseType.Long:
- case BaseType.ULong:
+ case reflection.BaseType.Long:
+ case reflection.BaseType.ULong:
return 8;
- case BaseType.Float:
+ case reflection.BaseType.Float:
return 4;
- case BaseType.Double:
+ case reflection.BaseType.Double:
return 8;
- case BaseType.String:
- case BaseType.Vector:
- case BaseType.Obj:
- case BaseType.Union:
- case BaseType.Array:
+ case reflection.BaseType.String:
+ case reflection.BaseType.Vector:
+ case reflection.BaseType.Obj:
+ case reflection.BaseType.Union:
+ case reflection.BaseType.Array:
return 4;
}
}
// Returns whether the given type is a scalar type.
-function isScalar(baseType: BaseType): boolean {
+function isScalar(baseType: reflection.BaseType): boolean {
switch (baseType) {
- case BaseType.UType:
- case BaseType.Bool:
- case BaseType.Byte:
- case BaseType.UByte:
- case BaseType.Short:
- case BaseType.UShort:
- case BaseType.Int:
- case BaseType.UInt:
- case BaseType.Long:
- case BaseType.ULong:
- case BaseType.Float:
- case BaseType.Double:
+ case reflection.BaseType.UType:
+ case reflection.BaseType.Bool:
+ case reflection.BaseType.Byte:
+ case reflection.BaseType.UByte:
+ case reflection.BaseType.Short:
+ case reflection.BaseType.UShort:
+ case reflection.BaseType.Int:
+ case reflection.BaseType.UInt:
+ case reflection.BaseType.Long:
+ case reflection.BaseType.ULong:
+ case reflection.BaseType.Float:
+ case reflection.BaseType.Double:
return true;
- case BaseType.None:
- case BaseType.String:
- case BaseType.Vector:
- case BaseType.Obj:
- case BaseType.Union:
- case BaseType.Array:
+ case reflection.BaseType.None:
+ case reflection.BaseType.String:
+ case reflection.BaseType.Vector:
+ case reflection.BaseType.Obj:
+ case reflection.BaseType.Union:
+ case reflection.BaseType.Array:
return false;
}
}
// Returns whether the given type is integer or not.
-function isInteger(baseType: BaseType): boolean {
+function isInteger(baseType: reflection.BaseType): boolean {
switch (baseType) {
- case BaseType.UType:
- case BaseType.Bool:
- case BaseType.Byte:
- case BaseType.UByte:
- case BaseType.Short:
- case BaseType.UShort:
- case BaseType.Int:
- case BaseType.UInt:
- case BaseType.Long:
- case BaseType.ULong:
+ case reflection.BaseType.UType:
+ case reflection.BaseType.Bool:
+ case reflection.BaseType.Byte:
+ case reflection.BaseType.UByte:
+ case reflection.BaseType.Short:
+ case reflection.BaseType.UShort:
+ case reflection.BaseType.Int:
+ case reflection.BaseType.UInt:
+ case reflection.BaseType.Long:
+ case reflection.BaseType.ULong:
return true;
- case BaseType.Float:
- case BaseType.Double:
- case BaseType.None:
- case BaseType.String:
- case BaseType.Vector:
- case BaseType.Obj:
- case BaseType.Union:
- case BaseType.Array:
+ case reflection.BaseType.Float:
+ case reflection.BaseType.Double:
+ case reflection.BaseType.None:
+ case reflection.BaseType.String:
+ case reflection.BaseType.Vector:
+ case reflection.BaseType.Obj:
+ case reflection.BaseType.Union:
+ case reflection.BaseType.Array:
return false;
}
}
@@ -96,7 +96,7 @@
// can be represented by the normal javascript number (8-byte integers require a
// special type, since the native number type is an 8-byte double, which won't
// represent 8-byte integers to full precision).
-function isLong(baseType: BaseType): boolean {
+function isLong(baseType: reflection.BaseType): boolean {
return isInteger(baseType) && (typeSize(baseType) > 4);
}
@@ -124,30 +124,30 @@
return new Table(bb, -1, bb.readInt32(bb.position()) + bb.position());
}
// Reads a scalar of a given type at a given offset.
- readScalar(fieldType: BaseType, offset: number) {
+ readScalar(fieldType: reflection.BaseType, offset: number) {
switch (fieldType) {
- case BaseType.UType:
- case BaseType.Bool:
+ case reflection.BaseType.UType:
+ case reflection.BaseType.Bool:
return this.bb.readUint8(offset);
- case BaseType.Byte:
+ case reflection.BaseType.Byte:
return this.bb.readInt8(offset);
- case BaseType.UByte:
+ case reflection.BaseType.UByte:
return this.bb.readUint8(offset);
- case BaseType.Short:
+ case reflection.BaseType.Short:
return this.bb.readInt16(offset);
- case BaseType.UShort:
+ case reflection.BaseType.UShort:
return this.bb.readUint16(offset);
- case BaseType.Int:
+ case reflection.BaseType.Int:
return this.bb.readInt32(offset);
- case BaseType.UInt:
+ case reflection.BaseType.UInt:
return this.bb.readUint32(offset);
- case BaseType.Long:
+ case reflection.BaseType.Long:
return this.bb.readInt64(offset);
- case BaseType.ULong:
+ case reflection.BaseType.ULong:
return this.bb.readUint64(offset);
- case BaseType.Float:
+ case reflection.BaseType.Float:
return this.bb.readFloat32(offset);
- case BaseType.Double:
+ case reflection.BaseType.Double:
return this.bb.readFloat64(offset);
}
throw new Error('Unsupported message type ' + baseType);
@@ -164,7 +164,7 @@
// then access the members using the various methods of the Parser (or just
// convert the entire object to a javascript Object/JSON using toObject()).
export class Parser {
- constructor(private readonly schema: Schema) {}
+ constructor(private readonly schema: reflection.Schema) {}
// Parse a Table to a javascript object. This is can be used, e.g., to convert
// a flatbuffer Table to JSON.
@@ -181,20 +181,20 @@
let fieldValue = null;
if (isScalar(baseType)) {
fieldValue = this.readScalar(table, field.name(), readDefaults);
- } else if (baseType === BaseType.String) {
+ } else if (baseType === reflection.BaseType.String) {
fieldValue = this.readString(table, field.name());
- } else if (baseType === BaseType.Obj) {
+ } else if (baseType === reflection.BaseType.Obj) {
const subTable = this.readTable(table, field.name());
if (subTable !== null) {
fieldValue = this.toObject(subTable, readDefaults);
}
- } else if (baseType === BaseType.Vector) {
+ } else if (baseType === reflection.BaseType.Vector) {
const elementType = field.type().element();
if (isScalar(elementType)) {
fieldValue = this.readVectorOfScalars(table, field.name());
- } else if (elementType === BaseType.String) {
+ } else if (elementType === reflection.BaseType.String) {
fieldValue = this.readVectorOfStrings(table, field.name());
- } else if (elementType === BaseType.Obj) {
+ } else if (elementType === reflection.BaseType.Obj) {
const tables = this.readVectorOfTables(table, field.name());
if (tables !== null) {
fieldValue = [];
@@ -229,7 +229,7 @@
// Retrieves the Field schema for the given field name within a given
// type index.
- getField(fieldName: string, typeIndex: number): Field {
+ getField(fieldName: string, typeIndex: number): reflection.Field {
const schema: Object = this.getType(typeIndex);
const numFields = schema.fieldsLength();
for (let ii = 0; ii < numFields; ++ii) {
@@ -292,7 +292,7 @@
readString(table: Table, fieldName: string): string|null {
const field = this.getField(fieldName, table.typeIndex);
const fieldType = field.type();
- if (fieldType.baseType() !== BaseType.String) {
+ if (fieldType.baseType() !== reflection.BaseType.String) {
throw new Error('Field ' + fieldName + ' is not a string.');
}
@@ -309,7 +309,7 @@
const field = this.getField(fieldName, table.typeIndex);
const fieldType = field.type();
const parentIsStruct = this.getType(table.typeIndex).isStruct();
- if (fieldType.baseType() !== BaseType.Obj) {
+ if (fieldType.baseType() !== reflection.BaseType.Obj) {
throw new Error('Field ' + fieldName + ' is not an object type.');
}
@@ -335,7 +335,7 @@
readVectorOfScalars(table: Table, fieldName: string): number[]|null {
const field = this.getField(fieldName, table.typeIndex);
const fieldType = field.type();
- if (fieldType.baseType() !== BaseType.Vector) {
+ if (fieldType.baseType() !== reflection.BaseType.Vector) {
throw new Error('Field ' + fieldName + ' is not an vector.');
}
if (!isScalar(fieldType.element())) {
@@ -361,10 +361,10 @@
readVectorOfTables(table: Table, fieldName: string) {
const field = this.getField(fieldName, table.typeIndex);
const fieldType = field.type();
- if (fieldType.baseType() !== BaseType.Vector) {
+ if (fieldType.baseType() !== reflection.BaseType.Vector) {
throw new Error('Field ' + fieldName + ' is not an vector.');
}
- if (fieldType.element() !== BaseType.Obj) {
+ if (fieldType.element() !== reflection.BaseType.Obj) {
throw new Error('Field ' + fieldName + ' is not an vector of objects.');
}
@@ -393,10 +393,10 @@
readVectorOfStrings(table: Table, fieldName: string): string[]|null {
const field = this.getField(fieldName, table.typeIndex);
const fieldType = field.type();
- if (fieldType.baseType() !== BaseType.Vector) {
+ if (fieldType.baseType() !== reflection.BaseType.Vector) {
throw new Error('Field ' + fieldName + ' is not an vector.');
}
- if (fieldType.element() !== BaseType.String) {
+ if (fieldType.element() !== reflection.BaseType.String) {
throw new Error('Field ' + fieldName + ' is not an vector of strings.');
}
diff --git a/aos/network/www/reflection_test_main.ts b/aos/network/www/reflection_test_main.ts
index 5c6436e..75cf107 100644
--- a/aos/network/www/reflection_test_main.ts
+++ b/aos/network/www/reflection_test_main.ts
@@ -1,12 +1,6 @@
-import {Configuration, Schema} from 'aos/configuration_generated'
-import {BaseType,
- Configuration as TestTable,
- FooStruct,
- FooStructNested,
- Location,
- Map,
- VectorOfStrings,
- VectorOfVectorOfString} from 'aos/json_to_flatbuffer_generated'
+import {aos} from 'aos/configuration_generated'
+// TODO(james): Fix all the things imported from here to actually run.
+import {aos} from 'aos/json_to_flatbuffer_generated'
import {Connection} from './proxy';
import {Parser, Table} from './reflection'
@@ -29,7 +23,7 @@
// Constructs a flatbuffer and then uses Parser.toObject to parse it and confirm
// that the start/end results are the same. This is largely meant to ensure
// that we are exercising most of the logic associated with parsing flatbuffers.
-function DoTest(config: Configuration): void {
+function DoTest(config: aos.Configuration): void {
const builder = new flatbuffers.Builder();
{
TestTable.startVectorFooStructVector(builder, 3);
@@ -70,7 +64,7 @@
TestTable.addFooEnum(builder, BaseType.Array);
}
- builder.finish(Configuration.endConfiguration(builder));
+ builder.finish(aos.Configuration.endConfiguration(builder));
const array = builder.asUint8Array();
const fbBuffer = new flatbuffers.ByteBuffer(array);